/* eslint-disable react-native/no-inline-styles */ import {Alert, FlatList, KeyboardAvoidingView, Platform, StyleSheet, Text, View} from 'react-native'; import React, { RefObject, createRef, forwardRef, useEffect, useImperativeHandle, useRef, useState, } from 'react'; import { Form, FormField as FormFieldType, MediaField, RadioGroupField, } from '@s20.ai/copilot-camera-sdk/src/types/Widgets'; import { FormField, FormFieldRef, RadioGroup, ToggleGroup, } from './form/FormFields'; import {useCopilotCameraSlot} from '@s20.ai/copilot-camera-sdk'; import {Slot} from '@s20.ai/copilot-camera-sdk/src/types/AOP'; import {Button} from 'react-native-paper'; import Media, {MediaRef} from './Media'; import {StyleProp} from 'react-native'; import {ViewStyle} from 'react-native'; import BottomSheet, {BottomSheetHandle} from './BottomSheet'; import {useTheme} from './Theme'; type Props = { onClose?: (widgets: Form[], requiredManualClose: boolean) => void; onDropdownSelect?: (widgets: RadioGroupField) => void; formSelectOptionsProp?: {[key: string]: string[]} containerStyle?: StyleProp; rules?: Rule[]; activeSlot: Slot }; interface Rule { ruleId: string; description: string; conditions: { [key: string]: boolean; }; action: string; target: string; } export type BottomDrawerRef = { put: (widgetId: string, fieldId: string, value: string) => void; } & BottomSheetHandle; const BottomDrawer = forwardRef( (props, bottomDrawerRef) => { const {activeSlot} = props const [formFieldRefs, setFormFieldRefs] = useState< RefObject[][] >([]); const target = "widgetEditButton"; // Component identifies its target const relevantRules = props.rules?.filter(rule => rule.target === target) || []; const bottomSheetRef = useRef(null); const slotHook = useCopilotCameraSlot(); const theme = useTheme(); const [FormData, setFormData] = useState(undefined) useEffect(() => { setFormFieldRefs(_ => []); if (activeSlot) { if (activeSlot.widgets !== undefined) { const formLength = ((activeSlot as Slot).widgets as Form[]) .length; let arr = []; for (let i = 0; i < formLength; i++) { const formSectionLength = ( (activeSlot as Slot).widgets as Form[] )[i].fields.length; let arr_2 = []; for (let k = 0; k < formSectionLength; k++) { arr_2.push(createRef()); } arr.push(arr_2); } setFormFieldRefs(arr as any); setFormData(activeSlot.widgets) } } }, [activeSlot]); useImperativeHandle( bottomDrawerRef, () => ({ close(doNotTriggerCallback?: boolean) { if (bottomSheetRef.current) { bottomSheetRef.current.close(doNotTriggerCallback); } }, open() { if (bottomSheetRef.current) { bottomSheetRef.current.open(); } }, opened: bottomSheetRef.current ? bottomSheetRef.current.opened : false, // putOptions(widgetId, fieldId, options) { // if (FormData) { // const widgetIndex = FormData.findIndex( // widget => widget.id === widgetId, // ); // if (widgetIndex >= 0) { // const fieldIndex = FormData[widgetIndex].fields.findIndex( // field => field.id === fieldId, // ); // if ( // fieldIndex >= 0 && // formFieldRefs[widgetIndex][fieldIndex].current // ) { // const selectDropdown = formFieldRefs[widgetIndex][fieldIndex].current as SelectDropdown; // if (selectDropdown) { // selectDropdown.reset(); // } // setFormSelectOptions(d => ({ // ...d, // [`${fieldId}`]: options, // // [`${widgetId}_${fieldId}`]: options, // })) // } // } // } // }, put(widgetId, fieldId, value) { if (FormData) { const widgetIndex = FormData.findIndex( widget => widget.id === widgetId, ); if (widgetIndex >= 0) { const fieldIndex = FormData[widgetIndex].fields.findIndex( field => field.id === fieldId, ); if ( fieldIndex >= 0 && formFieldRefs[widgetIndex][fieldIndex].current ) { ( formFieldRefs[widgetIndex][fieldIndex].current as FormFieldRef ).set(value); } } } }, }), [FormData, formFieldRefs], ); function evaluateRule(rule: Rule, state: Form[]): boolean { const { conditions, action } = rule; // Evaluate conditions let conditionMet = true; for (const key in conditions) { if (conditions.hasOwnProperty(key)) { switch (key) { case "widgetSubmitted": const isSubmitted = state.some(form => form.fields.some(field => field.value && field.value.length > 0)); if(isSubmitted){ conditionMet = true; break; } conditionMet = false; break; default: break; } } } // Determine action if (conditionMet) { return action === "disable"; } return false; // If conditions not met, button should not be disabled } const renderField = ( field: FormFieldType | RadioGroupField | MediaField, ref: RefObject, ) => { switch (field.type) { case 'number': case 'text': return ( {field.prefix && ( {field.prefix} )} } keyboardType={ field.inputType && field.inputType === 'number' ? 'numeric' : 'default' } textColor={ theme && theme.input ? theme.input.textColor ? theme.input.textColor : undefined : undefined } label={ theme && theme.input ? theme.input.showInputLabels ? field.label : '' : field.label } initialValue={field.value} mode="outlined" style={ { marginVertical: 10, textAlign: theme && theme.input ? theme.input.textAlign ? theme.input.textAlign : undefined : undefined, fontWeight: theme && theme.input ? theme.input.fontWeight ? theme.input.fontWeight : undefined : undefined, height: theme && theme.input ? theme.input.height ? theme.input.height : undefined : undefined, fontSize: theme && theme.input ? theme.input.fontSize ? theme.input.fontSize : undefined : undefined, fontFamily: theme && theme.input ? theme.input.fontFamily ? theme.input.fontFamily : undefined : undefined, minWidth: !field.prefix && !field.suffix ? '100%' : theme && theme.input ? theme.input.minWidth ? theme.input.minWidth : undefined : undefined, } as any } theme={{ roundness: theme && theme.input ? theme.input.roundness ? theme.input.roundness : undefined : undefined, colors: { primary: theme && theme.input ? theme.input.outlineColor ? theme.input.outlineColor : undefined : undefined, }, }} /> {field.suffix && ( {field.suffix} )} ); case 'media': return ( <> {activeSlot && activeSlot.action && activeSlot.action.storagePath && ( } captureType={activeSlot.action.captureType} sourceUrl={ (activeSlot.isUploaded ? activeSlot.uploadURL : activeSlot.action.storagePath) as string } /> )} ); // case 'select': // return ( // // // {field.label} // // } // data={field.options.length ? field.options : formSelectOptions[`${field.id}`] || []} // onSelect={(selectedItem, index) => { // setSelectValues(d => ({ // ...d, // [`${field.id}`]: selectedItem, // })) // if(props.onDropdownSelect) { // const parentField = FormData?.[0].fields.find(f => field.id === f.linkedTo) // props.onDropdownSelect({ // ...field, // value: selectedItem, // parentValue: selectValues[parentField?.id || ''] || '', // } as any) // } // }} // renderButton={(selectedItem, isOpened) => { // return ( // // // {(selectedItem) || `Select ${field.label}`} // // // // ); // }} // renderItem={(item, index, isSelected) => { // return ( // // {item} // // ); // }} // showsVerticalScrollIndicator={true} // // dropdownStyle={styles.dropdownMenuStyle} // /> // ) default: if (theme && theme.radio && theme.radio.type === 'toggle') { return ( } label={field.label} initialValue={field.value} viewStyle={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center', borderRadius: 50, borderWidth: 2, borderColor: '#B7B7B7', marginVertical: 10, overflow: 'hidden', }} /> ); } return ( } label={field.label} initialValue={field.value} /> ); } }; const isSumitButtonDisabled = relevantRules.some(rule => evaluateRule(rule, activeSlot?.widgets!)) return ( <> {FormData !== undefined && formFieldRefs.length === FormData.length && ( { if (props.onClose) { const updatedForm = FormData.map((form, formIndex) => ({ ...form, fields: form.fields.map((field, fieldIndex) => { return { ...field, value: !field.value || field.value.length === 0 ? formFieldRefs && formFieldRefs[formIndex][fieldIndex].current ? ( formFieldRefs[formIndex][fieldIndex] .current as any ).get() : '' : field.value, }; }), })) as Form[]; props.onClose(updatedForm, false); } }}> { return ( {(theme && theme.general && theme.general.hideTitles && ( <> )) || {item.title}} {item.fields.map((field, i) => ( {renderField(field, formFieldRefs[index][i])} ))} {index === FormData.length - 1 && ( )} ); }} /> )} ); }, ); export default BottomDrawer; const styles = StyleSheet.create({ contentContainer: { flex: 1, paddingHorizontal: 20, marginBottom: 20, padding: 10, }, viewContainer: { flex: 1, paddingHorizontal: 20, width: '100%', }, text: { color: 'black', fontSize: 20, fontWeight: 'bold', }, dropdownButtonStyle: { width: '100%', height: 50, backgroundColor: '#E9ECEF', borderRadius: 12, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', paddingHorizontal: 12, }, dropdownButtonTxtStyle: { flex: 1, fontSize: 18, fontWeight: '500', color: '#151E26', }, dropdownButtonArrowStyle: { fontSize: 28, }, dropdownButtonIconStyle: { fontSize: 28, marginRight: 8, }, dropdownMenuStyle: { backgroundColor: '#E9ECEF', borderRadius: 8, width: '100%', }, dropdownItemStyle: { width: '100%', flexDirection: 'row', paddingHorizontal: 12, justifyContent: 'center', alignItems: 'center', paddingVertical: 8, }, dropdownItemTxtStyle: { flex: 1, fontSize: 18, fontWeight: '500', color: '#151E26', }, dropdownItemIconStyle: { fontSize: 28, marginRight: 8, }, });