import { Box, Container, Flex, Heading } from '@radix-ui/themes'; import { useMutation } from '@tanstack/react-query'; import { useNavigate } from 'react-router'; import { Slide, toast, ToastContainer } from 'react-toastify'; import * as v from 'valibot'; import { useResponseErrorHandler } from '../../hooks/ResponseHelper'; import { useApi } from '../../providers/ApiProvider'; import { formHook } from '../../providers/FormProvider'; import type { Route } from './+types/login'; const loginFormSchema = v.object({ username: v.pipe(v.string(), v.trim(), v.minLength(1, 'Username is required')), password: v.pipe(v.string(), v.minLength(1, 'Password is required')), }); // eslint-disable-next-line no-empty-pattern export function meta({}: Route.MetaArgs): Route.MetaDescriptors { return [{ title: 'Login | YANPM' }]; } export default function LoginRoute() { const navigate = useNavigate(); const { tanstackApiClient } = useApi(); const { defaultResponseErrorHandler } = useResponseErrorHandler(); const { mutateAsync: login, isPending } = useMutation({ ...tanstackApiClient.mutation('post', '/api/auth/login').mutationOptions, onSuccess: async () => { navigate('/'); }, onError: (error) => { if (defaultResponseErrorHandler(error)) return; console.error('Login failed:', error); }, }); const form = formHook.useAppForm({ defaultValues: { username: '', password: '', }, validators: { onBlur: loginFormSchema, onSubmit: loginFormSchema, }, onSubmit: async ({ value }) => { toast.dismiss(); return await login({ body: { password: value.password, username: value.username } }); }, }); return ( <> Sign In
{ e.preventDefault(); form.handleSubmit(); }} > ( <> field.handleChange(e.target.value)} /> )} /> ( <> field.handleChange(e.target.value)} showPasswordToggle /> )} />
); }