import axios from "axios"; import { Form, Formik, FormikHelpers } from "formik"; import { useContext } from "react"; import { useLocation, useNavigate } from "react-router"; import * as yup from "yup"; import { AuthContext } from "../AuthContext"; import EmailField from "../components/EmailField"; import FormActions from "../components/FormActions"; import PasswordField from "../components/PasswordField"; import Title from "../components/Title"; import { ToastContext } from "../ToastContext"; import { useMutation } from "../query"; interface IForm { email: string; password: string; } const useLogin = () => { const location = useLocation(); const navigate = useNavigate(); const { addToast } = useContext(ToastContext); const { setAuthenticated } = useContext(AuthContext); const { mutateAsync: login } = useMutation( async (data: IForm) => await axios.post("/sessions/", data), ); return async (data: IForm, { setFieldError }: FormikHelpers) => { try { await login(data); setAuthenticated(true); navigate((location.state as any)?.from ?? "/"); } catch (error: any) { if (error.response?.status === 401) { setFieldError("email", "Invalid credentials"); setFieldError("password", "Invalid credentials"); } else { addToast("Try again", "error"); } } }; }; const validationSchema = yup.object({ email: yup.string().email("Email invalid").required("Required"), password: yup.string().required("Required"), }); const Login = () => { const onSubmit = useLogin(); const location = useLocation(); return ( <> <Formik<IForm> initialValues={{ email: (location.state as any)?.email ?? "", password: "", }} onSubmit={onSubmit} validationSchema={validationSchema} > {({ dirty, isSubmitting, values }) => ( <Form> <EmailField fullWidth label="Email" name="email" required /> <PasswordField autoComplete="password" fullWidth label="Password" name="password" required /> <FormActions disabled={!dirty} isSubmitting={isSubmitting} label="Login" links={[ { label: "Reset password", to: "/forgotten-password/", state: { email: values.email }, }, { label: "Register", to: "/register/", state: { email: values.email }, }, ]} /> </Form> )} </Formik> </> ); }; export default Login;