L1f/src/pages/auth/LoginPage.tsx

108 lines
3.7 KiB
TypeScript

import { Link as RouterLink } from 'react-router-dom';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import TextField from '@mui/material/TextField';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import Divider from '@mui/material/Divider';
import GoogleIcon from '@mui/icons-material/Google';
import AppleIcon from '@mui/icons-material/Apple';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useTranslation } from 'react-i18next';
import { LuxeButton } from '@/components/ui';
import { loginSchema, type LoginFormData } from '@/validators/auth';
import { ROUTES } from '@/constants';
export function LoginPage() {
const { t } = useTranslation();
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<LoginFormData>({
resolver: zodResolver(loginSchema),
defaultValues: { rememberMe: false },
});
const onSubmit = async (_data: LoginFormData) => {
await new Promise((r) => setTimeout(r, 800));
};
return (
<Box>
<Typography variant="h4" sx={{ mb: 1, fontFamily: '"Playfair Display", serif' }}>
{t('auth.welcomeBack')}
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 4 }}>
Sign in to access your dashboard and saved profiles.
</Typography>
<Box component="form" onSubmit={handleSubmit(onSubmit)} noValidate>
<TextField
{...register('email')}
label={t('auth.email')}
type="email"
fullWidth
margin="normal"
autoComplete="email"
error={!!errors.email}
helperText={errors.email?.message}
/>
<TextField
{...register('password')}
label={t('auth.password')}
type="password"
fullWidth
margin="normal"
autoComplete="current-password"
error={!!errors.password}
helperText={errors.password?.message}
/>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mt: 1 }}>
<FormControlLabel
control={<Checkbox {...register('rememberMe')} size="small" />}
label={<Typography variant="body2">Remember me</Typography>}
/>
<Typography
component={RouterLink}
to={ROUTES.AUTH.FORGOT_PASSWORD}
variant="body2"
sx={{ color: 'gold.main', textDecoration: 'none' }}
>
{t('auth.forgotPassword')}
</Typography>
</Box>
<LuxeButton type="submit" variant="contained" fullWidth sx={{ mt: 3, py: 1.5 }} disabled={isSubmitting}>
{isSubmitting ? t('common.loading') : t('common.login')}
</LuxeButton>
</Box>
<Divider sx={{ my: 3 }}>
<Typography variant="caption" color="text.secondary">
{t('auth.orContinueWith')}
</Typography>
</Divider>
<Box sx={{ display: 'flex', gap: 2 }}>
<LuxeButton variant="outlined" fullWidth startIcon={<GoogleIcon />} aria-label="Sign in with Google">
Google
</LuxeButton>
<LuxeButton variant="outlined" fullWidth startIcon={<AppleIcon />} aria-label="Sign in with Apple">
Apple
</LuxeButton>
</Box>
<Typography variant="body2" color="text.secondary" sx={{ mt: 4, textAlign: 'center' }}>
{t('auth.noAccount')}{' '}
<Typography component={RouterLink} to={ROUTES.AUTH.REGISTER} variant="body2" sx={{ color: 'gold.main', fontWeight: 600 }}>
{t('common.register')}
</Typography>
</Typography>
</Box>
);
}
export default LoginPage;