/** * Signup Client Component * * Handles client-side signup flow. */ 'use client'; import { useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { useAuth } from '@/lib/auth/AuthContext'; import { SignupViewData } from '@/lib/builders/view-data/types/SignupViewData'; import { SignupTemplate } from '@/templates/auth/SignupTemplate'; import { SignupMutation } from '@/lib/mutations/auth/SignupMutation'; import { SignupViewModelBuilder } from '@/lib/builders/view-models/SignupViewModelBuilder'; import { SignupViewModel } from '@/lib/view-models/auth/SignupViewModel'; interface SignupClientProps { viewData: SignupViewData; } export function SignupClient({ viewData }: SignupClientProps) { const router = useRouter(); const searchParams = useSearchParams(); const { refreshSession } = useAuth(); // Build ViewModel from ViewData const [viewModel, setViewModel] = useState(() => SignupViewModelBuilder.build(viewData) ); const [formData, setFormData] = useState({ firstName: '', lastName: '', email: '', password: '', confirmPassword: '' }); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); // Validate passwords match if (formData.password !== formData.confirmPassword) { setViewModel(prev => prev.withMutationState(false, 'Passwords do not match')); return; } // Update submitting state setViewModel(prev => prev.withMutationState(true, null)); try { // Transform to DTO format const displayName = `${formData.firstName} ${formData.lastName}`.trim(); // Execute signup mutation const mutation = new SignupMutation(); const result = await mutation.execute({ email: formData.email, password: formData.password, displayName: displayName || formData.firstName || formData.lastName, }); if (result.isErr()) { const error = result.getError(); setViewModel(prev => prev.withMutationState(false, error)); return; } // Success - refresh session and redirect await refreshSession(); const returnTo = searchParams.get('returnTo') ?? '/onboarding'; router.push(returnTo); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Signup failed'; setViewModel(prev => prev.withMutationState(false, errorMessage)); } }; // Toggle password visibility const togglePassword = () => { setViewModel(prev => prev.withUIState({ ...prev.uiState, showPassword: !prev.uiState.showPassword, })); }; const toggleConfirmPassword = () => { setViewModel(prev => prev.withUIState({ ...prev.uiState, showConfirmPassword: !prev.uiState.showConfirmPassword, })); }; // Build viewData for template const templateViewData: SignupViewData = { ...viewData, formState: viewModel.formState, isSubmitting: viewModel.isSubmitting, submitError: viewModel.submitError, }; return ( ); }