/** * Data persistence and validation for onboarding */ import { useState, useCallback } from 'react'; import { getStepById } from './steps'; import type { OnboardingData, OnboardingError, StepValidator } from './types'; interface OnboardingDataState { data: OnboardingData; error: OnboardingError | null; } interface OnboardingDataActions { updateStepData: (stepId: string, stepData: Partial) => void; validateStep: (stepId: string) => string | null; clearError: () => void; resetData: () => void; getStepData: (stepId: string) => any; setAllStepData: (allData: { [stepId: string]: any }) => void; getAllStepData: () => { [stepId: string]: any }; } export const useOnboardingData = () => { const [state, setState] = useState({ data: { allStepData: {}, }, error: null, }); const updateStepData = useCallback((stepId: string, stepData: Partial) => { setState(prev => ({ ...prev, data: { ...prev.data, ...stepData, // Also store in allStepData for cross-step access allStepData: { ...prev.data.allStepData, [stepId]: { ...prev.data.allStepData?.[stepId], ...stepData, }, }, }, error: null, // Clear error when data is updated successfully })); }, []); const validateStep = useCallback((stepId: string): string | null => { const step = getStepById(stepId); if (step?.validation) { try { const validationResult = step.validation(state.data); if (validationResult) { setState(prev => ({ ...prev, error: { step: stepId, message: validationResult, }, })); return validationResult; } } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Validation error'; setState(prev => ({ ...prev, error: { step: stepId, message: errorMessage, details: error, }, })); return errorMessage; } } return null; }, [state.data]); const clearError = useCallback(() => { setState(prev => ({ ...prev, error: null, })); }, []); const resetData = useCallback(() => { setState({ data: { allStepData: {}, }, error: null, }); }, []); const getStepData = useCallback((stepId: string): any => { return state.data.allStepData?.[stepId] || {}; }, [state.data.allStepData]); const setAllStepData = useCallback((allData: { [stepId: string]: any }) => { setState(prev => ({ ...prev, data: { ...prev.data, allStepData: allData, }, })); }, []); const getAllStepData = useCallback((): { [stepId: string]: any } => { return state.data.allStepData || {}; }, [state.data.allStepData]); return { // State data: state.data, error: state.error, // Actions updateStepData, validateStep, clearError, resetData, getStepData, setAllStepData, getAllStepData, } satisfies OnboardingDataState & OnboardingDataActions; };