import React, { useState, useMemo } from 'react' import { Modal, View, StyleSheet, TextInput, TouchableOpacity, ScrollView, Platform } from 'react-native' import { Formik } from 'formik' import * as Yup from 'yup' import { pick } from '@react-native-documents/picker' import { useSelector } from 'react-redux' import { apiCall } from '../../../Axios/Axios' import { TECHNICAL_DOCUMENT_SUBMIT, TECHNICAL_VALUE_SUBMIT } from '../../../Services/ApiCall/ApiUrls' import { Props } from '../Type/BidType' import { Loader } from '../../../Component/Index' import { useNavigation } from '@react-navigation/native' import NavigationString from '../../../Constant/NavigationString' import { useTheme } from '../../../Hooks/useTheme' import AppText from '../../../components/AppText' import { Upload, FileText, X } from 'lucide-react-native' const TemplateFormModal: React.FC = ({ visible, template, setAllBoolean }) => { if (!template) return null const SelectedAuction = useSelector((state: any) => state.auction.auction) const Navigation: any = useNavigation() const { colors, spacing, typography } = useTheme() const styles = useMemo(() => makeStyles(colors, spacing, typography), [colors, spacing, typography]) const [loading, setLoading] = useState(false) const initialValues = template?.labels?.reduce((acc: any, label: any) => { acc[label.labelName] = '' return acc }, {}) const validationSchema = Yup.object( template.labels.reduce((acc: any, label: any) => { if (label.mandatory) { acc[label.labelName] = label.labelType === '3' ? Yup.mixed().required(`${label.labelName} is required`) : Yup.string().required(`${label.labelName} is required`) } return acc }, {}) ) const pickFile = async (fieldName: string, setFieldValue: any) => { try { const result = await pick({ type: ['application/pdf'], allowMultiSelection: false, }) const file = result[0] setFieldValue(fieldName, { name: file.name ?? 'document.pdf', uri: file.uri, type: 'application/pdf', size: file.size, }) } catch (e) { console.log(e) } } const renderInput = ( label: any, value: any, setFieldValue: any, error?: string, touched?: boolean ) => { const showError = touched && error if (label.labelType === '3') { return ( {label.labelName} {label.mandatory && *} pickFile(label.labelName, setFieldValue) } > {value?.name ? ( {value.name} ) : ( Upload PDF )} {showError && ( {error} )} ) } return ( {label.labelName} {label.mandatory && *} setFieldValue(label.labelName, text) } keyboardType={ label.labelType === '1' || label.labelType === '4' ? 'numeric' : 'default' } /> {showError && ( {error} )} ) } const onClose = () => { setAllBoolean((prev: any) => ({ ...prev, technicalDocModalVisible: false, })) } const onSubmit = async (payload: any) => { try { const jsonBody = { auctiontId: SelectedAuction.auctionId, technicalDocumentTemplateId: payload.templateNameId, labelValues: [] as any[], } const fileFormData = new FormData() let hasFile = false Object.entries(payload.values).forEach( ([labelName, labelValue]: any) => { if (typeof labelValue === 'object' && labelValue?.uri) { hasFile = true fileFormData.append('files', { uri: labelValue.uri, name: labelValue.name, type: labelValue.type, } as any) } else { jsonBody.labelValues.push({ labelName, labelValue: String(labelValue), }) } } ) const rs1: any = await apiCall('post', TECHNICAL_VALUE_SUBMIT, jsonBody) if (hasFile) { fileFormData.append( 'auctionTemplateValueIds', String(rs1?.data[0]?.valueId) ) fileFormData.append( 'templateNameId', String(payload.templateNameId) ) const res2: any = await apiCall( 'post', TECHNICAL_DOCUMENT_SUBMIT, fileFormData, {}, 'multipart/form-data' ) if (rs1.statusCode == 200 && res2.statusCode == 200) { Navigation.navigate(NavigationString.StartBidding) setAllBoolean((prev: any) => ({ ...prev, technicalDocModalVisible: false })) } } else { if (rs1.statusCode == 200) { Navigation.navigate(NavigationString.StartBidding) setAllBoolean((prev: any) => ({ ...prev, technicalDocModalVisible: false })) } } } catch (e) { console.log(e) } finally { setLoading(false) } } return ( Technical Documents Fill the form, Click save when you're done. Template {template.templateName} { setLoading(true) onSubmit({ templateNameId: template.templateNameId, auctionIds: template.auctionIds, values, }) }} > {({ handleSubmit, values, errors, touched, setFieldValue }) => ( <> {template.labels.map((label: any) => renderInput( label, values[label.labelName], setFieldValue, // errors[label.labelName], // touched[label.labelName] ) )} handleSubmit()} disabled={loading} > {loading ? ( ) : ( Submit )} )} ) } export default TemplateFormModal const makeStyles = (colors: any, spacing: any, typography: any) => StyleSheet.create({ screen: { flex: 1, backgroundColor: colors.background, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 16, paddingVertical: 14, backgroundColor: colors.surface, borderBottomWidth: 1, borderColor: colors.border, }, headerLeft: { flex: 1, }, closeBtn: { padding: 8, backgroundColor: colors.overlay, borderRadius: 10, }, content: { paddingHorizontal: 16, }, card: { backgroundColor: colors.surface, borderRadius: 18, marginTop: spacing.m, padding: spacing.m, ...Platform.select({ ios: { shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.06, shadowRadius: 12 }, android: { elevation: 3 }, }), }, templateBox: { borderWidth: 1, borderColor: colors.border, borderRadius: 14, padding: 16, }, field: { marginBottom: 14, }, label: { letterSpacing: 0.5, textTransform: 'uppercase', marginBottom: 6, } as any, input: { backgroundColor: colors.background, borderWidth: 1.2, borderColor: colors.border, borderRadius: 12, padding: 12, fontSize: 14, color: colors.text, }, filePicker: { borderWidth: 1.2, borderColor: colors.border, backgroundColor: colors.background, borderRadius: 12, padding: 12, }, fileSelectedRow: { flexDirection: 'row', alignItems: 'center', gap: 8, }, errorText: { marginTop: 4, } as any, errorBorder: { borderColor: colors.error, }, submitRow: { marginTop: 20, alignItems: 'flex-end', height: 50, }, submitBtn: { backgroundColor: colors.primary, paddingVertical: 12, paddingHorizontal: 24, borderRadius: 14, minWidth: 120, alignItems: 'center', }, submitText: { letterSpacing: 0.5, } as any, })