UNPKG

pagamio-frontend-commons-lib

Version:

Pagamio library for Frontend reusable components like the form engine and table container

104 lines (103 loc) 5.86 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { useForm } from 'react-hook-form'; import { useEffect, useState } from 'react'; import { Button } from '../../components'; import { FieldWrapper } from '../../form-engine'; const DrawerContent = ({ fields, onSubmit, isOpen, initialValues, submitButtonText = 'Submit', cancelButtonText = 'Cancel', handleCloseDrawer, onFieldUpdate, updateFieldOptions, updataFieldLabel, setFieldHidden, addField, updateFieldValidation, }) => { const { control, handleSubmit, watch, setValue, clearErrors, formState: { errors, isSubmitting }, reset, getValues, } = useForm({ mode: 'onBlur', defaultValues: initialValues }); const [submitError, setSubmitError] = useState(null); const password = watch('password'); // Watch all form fields for dependency tracking const allFieldValues = watch(); // Set up field dependencies for watching useEffect(() => { if (onFieldUpdate) { const allDependencies = new Set(); for (const [, updates] of Object.entries(onFieldUpdate)) { for (const update of updates) { if (update.dependencies) { update.dependencies.forEach((dependency) => allDependencies.add(dependency)); } else { // For backward compatibility - watch the main field itself allDependencies.add(update.field); } } } } }, [onFieldUpdate]); useEffect(() => { if (isOpen && onFieldUpdate) { const processInitialDependencies = async () => { for (const [fieldName, updates] of Object.entries(onFieldUpdate)) { const currentValue = getValues(fieldName); for (const update of updates) { try { const result = await update.action(currentValue); if (result) { if (result.hideField !== undefined && setFieldHidden) { setFieldHidden(result.field, result.hideField); } } } catch (error) { console.error(`Error processing initial dependency for ${fieldName}:`, error); } } } }; processInitialDependencies().then(); } }, [isOpen, onFieldUpdate]); const handleFormSubmit = async (data) => { setSubmitError(null); try { const visibleFieldsData = Object.fromEntries(Object.entries(data).filter(([key]) => !fields.find((field) => field.name === key && field.isHidden))); await onSubmit(visibleFieldsData); } catch (error) { setSubmitError(error instanceof Error ? error.message : 'An error occurred'); } }; useEffect(() => { // only reset the form the drawer is closed if (!isOpen) { reset(); } }, [isOpen]); // Helper function to process dependency validations const processDependencyValidation = (field) => { if (!field.validation?.dependency) { return field.validation; } const dependencies = Array.isArray(field.validation.dependency) ? field.validation.dependency : [field.validation.dependency]; let finalValidation = { ...field.validation }; delete finalValidation.dependency; // Apply each dependency validation if its condition is met for (const dep of dependencies) { const dependencyValue = watch(dep.field); if (dep.condition(dependencyValue)) { finalValidation = { ...finalValidation, ...dep.validationToApply }; } } return { ...finalValidation, validate: field.name === 'confirmPassword' ? (value) => value === password || 'Passwords do not match' : finalValidation.validate, }; }; return (_jsxs(_Fragment, { children: [_jsxs("form", { className: "grid grid-cols-12 gap-2 align-middle mb-6 border-gray-400 px-6 py-5", onSubmit: handleSubmit(handleFormSubmit), children: [fields?.map((field) => (_jsx(FieldWrapper, { field: { ...field, validation: processDependencyValidation(field), }, control: control, errors: errors, layout: "vertical", onFieldUpdate: onFieldUpdate, allFieldValues: allFieldValues, updateFieldOptions: updateFieldOptions, updataFieldLabel: updataFieldLabel, setFieldHidden: setFieldHidden, addField: addField, setValue: setValue, clearErrors: clearErrors, getValues: getValues }, field.name))), isSubmitting && _jsx("span", { children: "Submitting..." }), submitError && _jsx("p", { className: "text-red-500", children: submitError })] }), _jsxs("div", { className: "flex border-t bg-white", style: { height: '50px', position: 'fixed', bottom: 0, zIndex: 100, width: '420px', }, children: [_jsx(Button, { className: "bg-white border-customPurple-5 text-customPurple-15 hover:bg-customPurple-25 hover:text-white w-full flex-1 h-full rounded-none", disabled: isSubmitting, onClick: handleCloseDrawer, children: cancelButtonText }), _jsx(Button, { className: "bg-customPurple-15 text-white hover:bg-customPurple-15 flex-1 h-full rounded-none", disabled: isSubmitting, onClick: handleSubmit(handleFormSubmit), children: submitButtonText })] })] })); }; export default DrawerContent;