Start integrating the onboarding flow with backend 7
This commit is contained in:
130
frontend/src/hooks/business/onboarding/useOnboardingData.ts
Normal file
130
frontend/src/hooks/business/onboarding/useOnboardingData.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* 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<OnboardingData>) => 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<OnboardingDataState>({
|
||||
data: {
|
||||
allStepData: {},
|
||||
},
|
||||
error: null,
|
||||
});
|
||||
|
||||
const updateStepData = useCallback((stepId: string, stepData: Partial<OnboardingData>) => {
|
||||
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;
|
||||
};
|
||||
Reference in New Issue
Block a user