website refactor
This commit is contained in:
123
apps/website/app/auth/signup/SignupClient.tsx
Normal file
123
apps/website/app/auth/signup/SignupClient.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* 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/SignupViewDataBuilder';
|
||||
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<SignupViewModel>(() =>
|
||||
SignupViewModelBuilder.build(viewData)
|
||||
);
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
password: '',
|
||||
confirmPassword: ''
|
||||
});
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
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 (
|
||||
<SignupTemplate
|
||||
viewData={templateViewData}
|
||||
formActions={{
|
||||
setFormData,
|
||||
handleSubmit,
|
||||
setShowPassword: togglePassword,
|
||||
setShowConfirmPassword: toggleConfirmPassword,
|
||||
}}
|
||||
uiState={{
|
||||
showPassword: viewModel.uiState.showPassword,
|
||||
showConfirmPassword: viewModel.uiState.showConfirmPassword,
|
||||
}}
|
||||
mutationState={{
|
||||
isPending: viewModel.mutationPending,
|
||||
error: viewModel.mutationError,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user