uchill/front_minimal/src/sections/auth/jwt/jwt-sign-in-view.jsx

159 lines
4.3 KiB
JavaScript

import { z as zod } from 'zod';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import Link from '@mui/material/Link';
import Alert from '@mui/material/Alert';
import Stack from '@mui/material/Stack';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import LoadingButton from '@mui/lab/LoadingButton';
import InputAdornment from '@mui/material/InputAdornment';
import { paths } from 'src/routes/paths';
import { useRouter, useSearchParams } from 'src/routes/hooks';
import { RouterLink } from 'src/routes/components';
import { useBoolean } from 'src/hooks/use-boolean';
import { Iconify } from 'src/components/iconify';
import { Form, Field } from 'src/components/hook-form';
import { useAuthContext } from 'src/auth/hooks';
import { signInWithPassword } from 'src/auth/context/jwt';
// ----------------------------------------------------------------------
export const SignInSchema = zod.object({
email: zod
.string()
.min(1, { message: 'Введите email!' })
.email({ message: 'Введите корректный email адрес!' }),
password: zod
.string()
.min(1, { message: 'Введите пароль!' })
.min(8, { message: 'Пароль должен содержать не менее 8 символов!' }),
});
// ----------------------------------------------------------------------
export function JwtSignInView() {
const router = useRouter();
const searchParams = useSearchParams();
const { checkUserSession } = useAuthContext();
const [errorMsg, setErrorMsg] = useState('');
const password = useBoolean();
const returnTo = searchParams.get('returnTo') || paths.dashboard.root;
const defaultValues = {
email: '',
password: '',
};
const methods = useForm({
resolver: zodResolver(SignInSchema),
defaultValues,
});
const {
handleSubmit,
formState: { isSubmitting },
} = methods;
const onSubmit = handleSubmit(async (data) => {
try {
await signInWithPassword({ email: data.email, password: data.password });
await checkUserSession?.();
router.replace(returnTo);
} catch (error) {
console.error(error);
setErrorMsg(error instanceof Error ? error.message : error);
}
});
const renderHead = (
<Stack spacing={1.5} sx={{ mb: 5 }}>
<Typography variant="h5">Войти в аккаунт</Typography>
<Stack direction="row" spacing={0.5}>
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
Нет аккаунта?
</Typography>
<Link component={RouterLink} href={paths.auth.jwt.signUp} variant="subtitle2">
Зарегистрироваться
</Link>
</Stack>
</Stack>
);
const renderForm = (
<Stack spacing={3}>
<Field.Text name="email" label="Email" InputLabelProps={{ shrink: true }} />
<Stack spacing={1.5}>
<Link
component={RouterLink}
href={paths.auth.jwt.forgotPassword}
variant="body2"
color="inherit"
sx={{ alignSelf: 'flex-end' }}
>
Забыли пароль?
</Link>
<Field.Text
name="password"
label="Пароль"
placeholder="8+ символов"
type={password.value ? 'text' : 'password'}
InputLabelProps={{ shrink: true }}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={password.onToggle} edge="end">
<Iconify icon={password.value ? 'solar:eye-bold' : 'solar:eye-closed-bold'} />
</IconButton>
</InputAdornment>
),
}}
/>
</Stack>
<LoadingButton
fullWidth
color="inherit"
size="large"
type="submit"
variant="contained"
loading={isSubmitting}
loadingIndicator="Вход..."
>
Войти
</LoadingButton>
</Stack>
);
return (
<>
{renderHead}
{!!errorMsg && (
<Alert severity="error" sx={{ mb: 3 }}>
{errorMsg}
</Alert>
)}
<Form methods={methods} onSubmit={onSubmit}>
{renderForm}
</Form>
</>
);
}