Files
gridpilot.gg/apps/website/client-wrapper/OnboardingWizardClient.tsx
2026-01-18 23:43:58 +01:00

124 lines
3.2 KiB
TypeScript

'use client';
import { OnboardingTemplate } from '@/templates/onboarding/OnboardingTemplate';
import { routes } from '@/lib/routing/RouteConfig';
import { completeOnboardingAction } from '@/app/actions/completeOnboardingAction';
import { generateAvatarsAction } from '@/app/actions/generateAvatarsAction';
import { useAuth } from '@/components/auth/AuthContext';
import { useState } from 'react';
import { PersonalInfo } from '@/components/onboarding/PersonalInfoStep';
import { AvatarInfo } from '@/components/onboarding/AvatarStep';
type OnboardingStep = 1 | 2;
interface FormErrors {
[key: string]: string | undefined;
firstName?: string;
lastName?: string;
displayName?: string;
country?: string;
facePhoto?: string;
avatar?: string;
submit?: string;
}
export function OnboardingWizardClient() {
const { session } = useAuth();
const [isProcessing, setIsProcessing] = useState(false);
const [step, setStep] = useState<OnboardingStep>(1);
const [errors, setErrors] = useState<FormErrors>({});
// Form state
const [personalInfo, setPersonalInfo] = useState<PersonalInfo>({
firstName: '',
lastName: '',
displayName: '',
country: '',
timezone: '',
});
const [avatarInfo, setAvatarInfo] = useState<AvatarInfo>({
facePhoto: null,
suitColor: 'blue',
generatedAvatars: [],
selectedAvatarIndex: null,
isGenerating: false,
isValidating: false,
});
const handleCompleteOnboarding = async (input: {
firstName: string;
lastName: string;
displayName: string;
country: string;
timezone?: string;
}) => {
setIsProcessing(true);
try {
const result = await completeOnboardingAction(input);
if (result.isErr()) {
setIsProcessing(false);
return { success: false, error: result.getError() };
}
window.location.href = routes.protected.dashboard;
return { success: true };
} catch (error) {
setIsProcessing(false);
return { success: false, error: 'Failed to complete onboarding' };
}
};
const handleGenerateAvatars = async (params: {
facePhotoData: string;
suitColor: string;
}) => {
if (!session?.user?.userId) {
return { success: false, error: 'Not authenticated' };
}
setIsProcessing(true);
try {
const result = await generateAvatarsAction({
userId: session.user.userId,
facePhotoData: params.facePhotoData,
suitColor: params.suitColor,
});
if (result.isErr()) {
setIsProcessing(false);
return { success: false, error: result.getError() };
}
const data = result.unwrap();
setIsProcessing(false);
return { success: true, data };
} catch (error) {
setIsProcessing(false);
return { success: false, error: 'Failed to generate avatars' };
}
};
return (
<OnboardingTemplate
viewData={{
onCompleted: () => {
window.location.href = routes.protected.dashboard;
},
onCompleteOnboarding: handleCompleteOnboarding,
onGenerateAvatars: handleGenerateAvatars,
isProcessing: isProcessing,
step,
setStep,
errors,
setErrors,
personalInfo,
setPersonalInfo,
avatarInfo,
setAvatarInfo,
}}
/>
);
}