'use client'; import { DnDFlowValidationSchema } from '@/utils/zod'; import useDnDStore from '@/stores/useDnDStore'; import _ from 'lodash'; import React from 'react'; import { Node } from 'reactflow'; type ErrorObjType = { [key: string]: { [key: string]: string; }; }; type ValidatorContextType = { errors: ErrorObjType; validate: (nds: Node[]) => boolean; }; export const ValidatorContext = React.createContext({ errors: {}, validate: () => false, }); type ModalContextProviderProps = { children: React.JSX.Element; }; const ValidatorContextProvider = ({ children }: ModalContextProviderProps) => { const [errors, setErrors] = React.useState({}); const [prev, setPrev] = React.useState<{ [x: string]: string }[]>(); const [nds, setNds] = React.useState([]); const { nodes } = useDnDStore(); const _getZodData = React.useCallback((nds: Node[]) => { return nds.map(({ type, data }) => { return { [type as string]: data }; }); }, []); const validate = React.useCallback( (nds: Node[]): boolean => { setNds(nds); try { setErrors({}); const zodData = _getZodData(nds); setPrev(zodData); const zodResults = DnDFlowValidationSchema.safeParse(zodData); // publish errors to consumers if (!zodResults.success) { const issues = zodResults.error.issues; const updatedErrors: ErrorObjType = {}; issues.forEach(({ path, message }) => { const nodeIndex = path[0] as number; const nodeId = nds[nodeIndex].id; const fieldName = path[path.length - 1]; if (!updatedErrors[nodeId as string]) { updatedErrors[nodeId as string] = {}; } updatedErrors[nodeId as string][fieldName as string] = message; }); setErrors(updatedErrors); } return zodResults.success; } catch (err) { // toast msg return true; } }, [_getZodData], ); React.useEffect(() => { const filteredNodes = nodes.filter((node) => nds?.find((n) => n.id === node.id)); if (prev && !_.isEqual(_getZodData(filteredNodes), prev)) { // after first submission, now validate the nodes has been validated in onChange event. validate(filteredNodes); } }, [_getZodData, nds, nodes, prev, validate]); return {children}; }; export default ValidatorContextProvider;