turash/bugulma/frontend/pages/SignupPage.tsx

187 lines
6.0 KiB
TypeScript

import React, { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { MainLayout } from '@/components/layout/MainLayout';
import PageHeader from '@/components/layout/PageHeader';
import Button from '@/components/ui/Button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card';
import Input from '@/components/ui/Input';
import { FormField } from '@/components/ui/FormField';
import { RadioGroup } from '@/components/ui/RadioGroup';
import { Alert } from '@/components/ui/Alert';
import { Stack } from '@/components/ui/layout';
import { useAuth } from '@/contexts/AuthContext';
import { useTranslation } from '@/hooks/useI18n';
import { useNavigation } from '@/hooks/useNavigation';
import type { UserRole } from '@/contexts/AuthContext';
const SignupPage = () => {
const { t } = useTranslation();
const { signup, isLoading } = useAuth();
const { handleFooterNavigate } = useNavigation();
const navigate = useNavigate();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [name, setName] = useState('');
const [role, setRole] = useState<UserRole>('user');
const [error, setError] = useState('');
const roleOptions = [
{
value: 'user',
label: t('signupPage.roleUser'),
description: t('signupPage.roleUserDesc'),
},
{
value: 'admin',
label: t('signupPage.roleAdmin'),
description: t('signupPage.roleAdminDesc'),
},
];
const validateForm = (): string | null => {
if (!email || !email.includes('@')) {
return t('signupPage.errorInvalidEmail');
}
if (!name || name.length < 2) {
return t('signupPage.errorInvalidName');
}
if (!password || password.length < 8) {
return t('signupPage.errorPasswordLength');
}
if (password !== confirmPassword) {
return t('signupPage.errorPasswordMismatch');
}
return null;
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
const validationError = validateForm();
if (validationError) {
setError(validationError);
return;
}
try {
await signup(email, password, name, role);
// Navigate based on role
if (role === 'admin') {
navigate('/admin');
} else {
navigate('/dashboard');
}
} catch (err) {
setError(err instanceof Error ? err.message : t('signupPage.errorSignupFailed'));
}
};
return (
<MainLayout onNavigate={handleFooterNavigate}>
<div className="mx-auto max-w-md px-4 py-8 sm:py-12">
<PageHeader title={t('signupPage.title')} />
<Card>
<CardHeader>
<CardTitle>{t('signupPage.subtitle')}</CardTitle>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit}>
<Stack spacing="lg">
{error && (
<Alert variant="error" description={error} />
)}
<FormField
label={t('signupPage.name')}
required
>
<Input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
required
placeholder={t('signupPage.namePlaceholder')}
disabled={isLoading}
/>
</FormField>
<FormField
label={t('signupPage.email')}
required
>
<Input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
placeholder={t('signupPage.emailPlaceholder')}
disabled={isLoading}
/>
</FormField>
<FormField
label={t('signupPage.password')}
description={t('signupPage.passwordDesc')}
required
>
<Input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
placeholder={t('signupPage.passwordPlaceholder')}
disabled={isLoading}
/>
</FormField>
<FormField
label={t('signupPage.confirmPassword')}
required
>
<Input
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
required
placeholder={t('signupPage.confirmPasswordPlaceholder')}
disabled={isLoading}
/>
</FormField>
<FormField
label={t('signupPage.role')}
description={t('signupPage.roleDesc')}
required
>
<RadioGroup
name="role"
options={roleOptions}
value={role}
onChange={(value) => setRole(value as UserRole)}
/>
</FormField>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? t('signupPage.loading') : t('signupPage.signup')}
</Button>
<div className="text-sm text-muted-foreground text-center">
{t('signupPage.alreadyHaveAccount')}{' '}
<Link to="/login" className="text-primary hover:underline font-medium">
{t('signupPage.loginLink')}
</Link>
</div>
</Stack>
</form>
</CardContent>
</Card>
</div>
</MainLayout>
);
};
export default SignupPage;