Untitled

 avatar
unknown
plain_text
a year ago
16 kB
4
Indexable
import React, {useEffect, useRef, useState} from 'react';
import {
  Image,
  Pressable,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import {globalStyles} from '../../utils/styles';
import {useFormik} from 'formik';
import {Input} from '../../components/input';
import icons from '../../assets/icons';
import {COLORS, FONTS, SIZES} from '../../theme';
import {CustomButton} from '../../components/customButton';
import {UploadedFile} from '../../components/uploadedFile';
import {DropDown} from '../../components/dropDown';
import {BottomActionSheet} from '../../components/bottomActionSheet';
import Container from '../../components/container';
import {FormStore} from '../../store/form';
import Loading from '../../components/Loading';
import {Checkbox, RadioButton, Snackbar} from 'react-native-paper';
import DatePicker from 'react-native-date-picker';
import routes from '../../navigation/routes';
import images from '../../assets/images';
import NotFound from '../../components/NotFound';
import {useNetInfo} from '@react-native-community/netinfo';

export const FormFillOut = ({navigation, route}) => {
  const {id, name, items, submissions} = route.params;
  const actionSheetRef = useRef(null);
  const [data, setData] = useState([]);
  const [formName, setFormName] = useState('');
  const [openId, setOpenId] = useState(null);
  const [multipleImages, setMultipleImages] = useState(false);
  const [loading, setLoading] = useState(false);
  const [triggerEffect, setTriggerEffect] = useState(false);
  const [showMsg, setShowMsg] = useState([false, '']);
  const [checkedValues, setCheckedValues] = useState([]);
  const [calender, setCalender] = useState(false);
  const {type, isConnected} = useNetInfo();
  // console.log("this is subId",submissions[0].submissionDetails)

  useEffect(() => {
    createForm();
  }, []);
  useEffect(() => {
    if (triggerEffect) {
      actionSheetRef?.current?.show();
      setTriggerEffect(false);
    }
  }, [triggerEffect]);
  // console.log("this is ma data ",data)
  async function createForm() {
    setLoading('form');
    // await FormStore.getFormDetail(id, navigation)
    // if(items && Object.keys(items).length){
    // console.log('submissions=========', JSON.stringify(submissions));
    if (items) {
      if (submissions && submissions.length > 0) {
        const sub = submissions[0].submissionDetails;
        // Check if sub is defined and has elements

        if (sub && sub.length > 0) {
          // Iterate over the sub array and replace objects in the items array with matching elementId
          sub.forEach(subItem => {
            const index = items.findIndex(
              item => item.elementId === subItem.elementId,
            );
            if (index !== -1) {
              // Replace the item with the subItem
              items[index] = subItem;
              form.values;

              data.map(() => {
                form.setFieldValue(element.elementLabel, element.answer);
              });
            }
          });
        }
      }

      setData(items);
      setFormName(name);
      setLoading(false);
    } else {
      setLoading(false);
    }
    // let values = await FormStore.getFormDetail(id, navigation);
    // if (values && Object.keys(values).length) {
    //   // Filter out elements with elementType 7 and 8
    //   const filtered = values?.templateElements?.filter(
    //     a => a.elementType !== 7 && a.elementType !== 8,
    //   );
    //   setFormName(values.templateHeading);
    //   setLoading(false);
    //   setData(filtered);
    // } else setLoading(false);
  }
  const initialValues = {};

  data.forEach(element => {
    initialValues[element.elementLabel] = '';
  });
  const form = useFormik({
    initialValues,
    onSubmit: values => onSubmit(values, false),
  });
  async function onSubmit(values, isDraft) {
    const uploadPromises = data.map(async item => {
      if (
        form.values[item.elementLabel] &&
        Array.isArray(form.values[item.elementLabel])
      ) {
        const images = form.values[item.elementLabel];
        const uploadTasks = images.map(async image => {
          const formData = new FormData();
          formData.append('imageFile', {
            uri: image.uri,
            type: image.type,
            name: image.name,
          });
          formData.append('imageUrl', `images\\FormImages\\${image.name}`);
          const id = await FormStore.uploadFile(formData, navigation);
          return id;
        });
        const uploadedIds = await Promise.all(uploadTasks);
        // console.log('upload Image', uploadedIds);
        return {fieldId: item.elementId, answer: uploadedIds.join(',')};
      } else if (
        form.values[item.elementLabel] &&
        typeof form.values[item.elementLabel] === 'string'
      ) {
        return {
          fieldId: item.elementId,
          answer: form.values[item.elementLabel],
        };
      }
    });
    try {
      setLoading(isDraft ? 'draft' : 'submit');
      // console.log("This is Draft Value",isDraft)

      const validUploads = (await Promise.all(uploadPromises)).filter(
        result => result !== undefined && result !== null,
      );

      let body = {
        formSubmissions: [
          {
            formId: id,
            formStatus: isDraft ? 2 : 3,
            // isRecurring:false,
            formAnswers: validUploads,
            submissionId:
              submissions.length > 0 ? submissions[0].submissionId : null,
          },
        ],
      };
      // console.log('body', JSON.stringify(body, null, 2));

      await FormStore.submitForm(
        body,
        setLoading,
        setShowMsg,
        isDraft,
        navigation,
      );
    } catch (error) {
      console.error('Error uploading files:', error);
      // Handle errors or display a message to the user
    }
  }

  const toggleCheckbox = (value, elementLabel) => {
    const isChecked = checkedValues.includes(value);
    let updatedValues;
    if (isChecked) {
      updatedValues = checkedValues.filter(item => item !== value);
    } else {
      updatedValues = [...checkedValues, value];
    }
    setCheckedValues(updatedValues);
    let valuesString = updatedValues.join(',');
    // console.log(valuesString);
    form.setFieldValue(elementLabel, valuesString);
  };

  const renderFormField = element => {
    console.log('element=========', JSON.stringify(element));
    switch (element.elementType) {
      case 1: // Text input
      case 5:
        return (
          <Input
            element={element}
            defaultValue={element?.answer}
            label={element.elementLabel}
            form={form}
            id={element.elementLabel}
            //style={{marginTop: 0}}
            placeholder={element.placeHolder}
          />
        );
      // Dropdown
      case 2:
        return (
          <DropDown
            label={element.elementLabel}
            form={form}
            element={element}
            id={element.elementLabel}
            data={element.elementValues.split(',').map(value => ({value}))}
            placeholder="Select.."
          />
        );
      // Radio Btn
      case 3:
        return (
          <View>
            <Text style={styles.label}>{element.elementLabel}</Text>
            {element.elementValues.split(',').map(value => (
              <View
                key={value}
                style={{flexDirection: 'row', alignItems: 'center'}}>
                <RadioButton.Android
                  color={COLORS.primary}
                  onPress={() =>
                    form.setFieldValue(element.elementLabel, value)
                  }
                  status={
                    element.answer
                      ? 'checked'
                      : form.values[element.elementLabel] == value
                      ? 'checked'
                      : 'unchecked'
                  }
                />
                <Text
                  style={FONTS.regular}
                  onPress={() =>
                    form.setFieldValue(element.elementLabel, value)
                  }>
                  {value}
                </Text>
              </View>
            ))}
          </View>
        );
      // Checkbox
      case 4:
        return (
          <View>
            <Text style={styles.label}>{element.elementLabel}</Text>
            {element.elementValues.split(',').map(value => (
              <View
                key={value}
                style={{flexDirection: 'row', alignItems: 'center'}}>
                <Checkbox.Android
                  color={COLORS.primary}
                  onPress={() => toggleCheckbox(value, element.elementLabel)}
                  status={
                    element.answer
                      ? 'checked'
                      : checkedValues.includes(value)
                      ? 'checked'
                      : 'unchecked'
                  }
                />
                <Text
                  onPress={() => toggleCheckbox(value, element.elementLabel)}
                  style={FONTS.regular}>
                  {value}
                </Text>
              </View>
            ))}
          </View>
        );
      // date
      case 9:
        return (
          <>
            <Pressable onPress={() => setCalender(true)}>
              <Input
                element={element}
                label={element.elementLabel}
                form={form}
                id={element.elementLabel}
                editable={false}
                placeholder={element.placeHolder}
              />
            </Pressable>
            <DatePicker
              modal
              mode="date"
              open={calender}
              maximumDate={new Date()}
              onCancel={() => setCalender(false)}
              date={
                form.values[element.elementLabel]
                  ? new Date(form.values[element.elementLabel])
                  : new Date()
              } // Use current date if no value is selected
              onConfirm={date => {
                const formattedDate = new Date(date)
                  .toISOString()
                  ?.split('T')[0];
                form.setFieldValue(element.elementLabel, formattedDate);
                setCalender(false);
              }}
            />
          </>
        );
      // upload
      case 6:
      case 10:
        return (
          <>
            <Text style={styles.label}>{element.elementLabel}</Text>
            <TouchableOpacity
              style={styles.media_con}
              activeOpacity={0.8}
              onPress={() => {
                setMultipleImages(element.elementType == 11 ? true : false);
                setOpenId(element.elementLabel);
                setTriggerEffect(true);
              }}>
              <Image source={icons.upload} style={{height: 50, width: 50}} />
              <Text style={styles.upload}>Click to upload</Text>
            </TouchableOpacity>
            {Boolean(form.errors[element.elementLabel]) && (
              <Text style={globalStyles.error}>
                {form.errors[element.elementLabel]}
              </Text>
            )}
            {element?.answer !== null && (
              <UploadedFile
                key={0}
                item={element?.answer}
                form={form}
                id={element.elementLabel}
                index={0}
                navigation={navigation}
              />
            )}
            {form.values[element.elementLabel]?.map((file, i) => {
              console.log('file========,', file);
              return (
                <UploadedFile
                  key={i}
                  item={file}
                  form={form}
                  id={element.elementLabel}
                  index={i}
                  navigation={navigation}
                />
              );
            })}
          </>
        );
      // signature
      case 11:
        return (
          <>
            <Text style={styles.label}>{element.elementLabel}</Text>
            <TouchableOpacity
              style={styles.media_con}
              activeOpacity={0.8}
              onPress={() =>
                navigation.navigate(routes.free_hand, {
                  form: form,
                  id: element.elementLabel,
                  image: {
                    fileName: `signature-${
                      form.values[element.elementLabel]?.length + 1 || 1
                    }.png`,
                    uri: images.transparent,
                    type: 'image/png',
                    fileSize: 2860,
                  },
                  multiple: true,
                })
              }>
              <Image source={icons.upload} style={{height: 50, width: 50}} />
              <Text style={styles.upload}>Click to upload</Text>
            </TouchableOpacity>
            {Boolean(form.errors[element.elementLabel]) && (
              <Text style={globalStyles.error}>
                {form.errors[element.elementLabel]}
              </Text>
            )}
            {element?.answer !== null && (
              <UploadedFile
                // value={element.answer}
                key={0}
                item={element?.answer}
                form={form}
                id={element.elementLabel}
                index={0}
                navigation={navigation}
              />
            )}
            {form.values[element.elementLabel]?.map((file, i) => (
              <UploadedFile
                // value={element.answer}
                key={i}
                item={file}
                form={form}
                id={element.elementLabel}
                index={i}
                navigation={navigation}
              />
            ))}
          </>
        );
      // Add more cases for other element types as needed
      default:
        return null;
    }
  };

  return (
    <Container
      arrow
      // plus
      title={formName}
      headerStyle={{marginLeft: 10, marginRight: 20}}>
      {loading == 'form' ? (
        <></>
      ) : (
        // <Loading loading={loading == 'form'} style={{marginTop: '60%'}} />
        <ScrollView showsVerticalScrollIndicator={false}>
          <View style={globalStyles.padding}>
            {!data.length && !loading && (
              <NotFound
                text={'Empty Form'}
                visible={!data.length && !loading}
                style={{marginTop: '50%'}}
              />
            )}
            {data.map(element => (
              <View key={element.elementId}>
                {renderFormField(element, form)}
              </View>
            ))}

            {Boolean(data.length) && (
              <>
                {/* submit btn */}
                <CustomButton
                  text={'Submit'}
                  onPress={form.handleSubmit}
                  loading={loading == 'submit'}
                />
                {/* save as draft btn */}
                <CustomButton
                  text={'Save As Draft'}
                  loading={loading == 'draft'}
                  onPress={() => onSubmit(form.values, true)}
                  textStyle={{color: COLORS.black}}
                  btnStyle={styles.borderBtn}
                />
              </>
            )}
          </View>
        </ScrollView>
      )}
      <BottomActionSheet
        actionSheetRef={actionSheetRef}
        form={form}
        id={openId}
        multiple={multipleImages}
        navigation={navigation}
      />
      <Snackbar
        visible={showMsg[0]}
        style={{width: SIZES.width - 30, alignSelf: 'center'}}
        duration={2000}
        onDismiss={() => {
          setShowMsg([false, '']);
          navigation.goBack();
        }}>
        {showMsg[1]}
      </Snackbar>
    </Container>
  );
};

const styles = StyleSheet.create({
  media_con: {
    alignItems: 'center',
    height: 130,
    borderWidth: 1,
    backgroundColor: COLORS.white,
    borderColor: COLORS.light_gray4,
    borderRadius: 10,
    marginTop: 10,
    justifyContent: 'center',
  },
  label: {
    ...FONTS.semibold,
    fontSize: 14,
    marginTop: 20,
    color: COLORS.black2,
  },
  upload: {
    ...FONTS.semibold,
    fontSize: 14,
    color: COLORS.primary,
    marginTop: 10,
  },
  borderBtn: {
    backgroundColor: COLORS.white,
    borderWidth: 1,
    marginTop: 15,
    borderColor: COLORS.light_gray4,
  },
});
Editor is loading...
Leave a Comment