Files
score/frontend/src/routes/login.tsx
Alejandra 55df823739 🛂 Migrate to Chakra UI v3 (#1496)
Co-authored-by: github-actions <github-actions@github.com>
2025-02-17 20:33:00 +01:00

116 lines
2.9 KiB
TypeScript

import { Container, Image, Input, Text } from "@chakra-ui/react"
import {
Link as RouterLink,
createFileRoute,
redirect,
} from "@tanstack/react-router"
import { type SubmitHandler, useForm } from "react-hook-form"
import { FiLock, FiMail } from "react-icons/fi"
import Logo from "/assets/images/fastapi-logo.svg"
import type { Body_login_login_access_token as AccessToken } from "../client"
import { Button } from "../components/ui/button"
import { Field } from "../components/ui/field"
import { InputGroup } from "../components/ui/input-group"
import { PasswordInput } from "../components/ui/password-input"
import useAuth, { isLoggedIn } from "../hooks/useAuth"
import { emailPattern, passwordRules } from "../utils"
export const Route = createFileRoute("/login")({
component: Login,
beforeLoad: async () => {
if (isLoggedIn()) {
throw redirect({
to: "/",
})
}
},
})
function Login() {
const { loginMutation, error, resetError } = useAuth()
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<AccessToken>({
mode: "onBlur",
criteriaMode: "all",
defaultValues: {
username: "",
password: "",
},
})
const onSubmit: SubmitHandler<AccessToken> = async (data) => {
if (isSubmitting) return
resetError()
try {
await loginMutation.mutateAsync(data)
} catch {
// error is handled by useAuth hook
}
}
return (
<>
<Container
as="form"
onSubmit={handleSubmit(onSubmit)}
h="100vh"
maxW="sm"
alignItems="stretch"
justifyContent="center"
gap={4}
centerContent
>
<Image
src={Logo}
alt="FastAPI logo"
height="auto"
maxW="2xs"
alignSelf="center"
mb={4}
/>
<Field
invalid={!!errors.username}
errorText={errors.username?.message || !!error}
>
<InputGroup w="100%" startElement={<FiMail />}>
<Input
id="username"
{...register("username", {
required: "Username is required",
pattern: emailPattern,
})}
placeholder="Email"
type="email"
/>
</InputGroup>
</Field>
<PasswordInput
type="password"
startElement={<FiLock />}
{...register("password", passwordRules())}
placeholder="Password"
errors={errors}
/>
<RouterLink to="/recover-password" className="main-link">
Forgot Password?
</RouterLink>
<Button variant="solid" type="submit" loading={isSubmitting} size="md">
Log In
</Button>
<Text>
Don't have an account?{" "}
<RouterLink to="/signup" className="main-link">
Sign Up
</RouterLink>
</Text>
</Container>
</>
)
}