committed by
GitHub
5 changed files with 213 additions and 8 deletions
@ -0,0 +1,163 @@ |
|||||
|
import { |
||||
|
Button, |
||||
|
Container, |
||||
|
Flex, |
||||
|
FormControl, |
||||
|
FormErrorMessage, |
||||
|
FormLabel, |
||||
|
Image, |
||||
|
Input, |
||||
|
Link, |
||||
|
Text, |
||||
|
} from "@chakra-ui/react" |
||||
|
import { |
||||
|
Link as RouterLink, |
||||
|
createFileRoute, |
||||
|
redirect, |
||||
|
} from "@tanstack/react-router" |
||||
|
import { type SubmitHandler, useForm } from "react-hook-form" |
||||
|
|
||||
|
import Logo from "/assets/images/fastapi-logo.svg" |
||||
|
import type { UserRegister } from "../client" |
||||
|
import useAuth, { isLoggedIn } from "../hooks/useAuth" |
||||
|
import { confirmPasswordRules, emailPattern, passwordRules } from "../utils" |
||||
|
|
||||
|
export const Route = createFileRoute("/signup")({ |
||||
|
component: SignUp, |
||||
|
beforeLoad: async () => { |
||||
|
if (isLoggedIn()) { |
||||
|
throw redirect({ |
||||
|
to: "/", |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
interface UserRegisterForm extends UserRegister { |
||||
|
confirm_password: string |
||||
|
} |
||||
|
|
||||
|
function SignUp() { |
||||
|
const { signUpMutation } = useAuth() |
||||
|
const { |
||||
|
register, |
||||
|
handleSubmit, |
||||
|
getValues, |
||||
|
formState: { errors, isSubmitting }, |
||||
|
} = useForm<UserRegisterForm>({ |
||||
|
mode: "onBlur", |
||||
|
criteriaMode: "all", |
||||
|
defaultValues: { |
||||
|
email: "", |
||||
|
full_name: "", |
||||
|
password: "", |
||||
|
confirm_password: "", |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
const onSubmit: SubmitHandler<UserRegisterForm> = (data) => { |
||||
|
signUpMutation.mutate(data) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<Flex flexDir={{ base: "column", md: "row" }} justify="center" h="100vh"> |
||||
|
<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} |
||||
|
/> |
||||
|
<FormControl id="full_name" isInvalid={!!errors.full_name}> |
||||
|
<FormLabel htmlFor="full_name" srOnly> |
||||
|
Full Name |
||||
|
</FormLabel> |
||||
|
<Input |
||||
|
id="full_name" |
||||
|
minLength={3} |
||||
|
{...register("full_name")} |
||||
|
placeholder="Full Name" |
||||
|
type="text" |
||||
|
/> |
||||
|
{errors.full_name && ( |
||||
|
<FormErrorMessage>{errors.full_name.message}</FormErrorMessage> |
||||
|
)} |
||||
|
</FormControl> |
||||
|
<FormControl id="email" isInvalid={!!errors.email}> |
||||
|
<FormLabel htmlFor="username" srOnly> |
||||
|
Email |
||||
|
</FormLabel> |
||||
|
<Input |
||||
|
id="email" |
||||
|
{...register("email", { |
||||
|
pattern: emailPattern, |
||||
|
})} |
||||
|
placeholder="Email" |
||||
|
type="email" |
||||
|
/> |
||||
|
{errors.email && ( |
||||
|
<FormErrorMessage>{errors.email.message}</FormErrorMessage> |
||||
|
)} |
||||
|
</FormControl> |
||||
|
<FormControl id="password" isInvalid={!!errors.password}> |
||||
|
<FormLabel htmlFor="password" srOnly> |
||||
|
Password |
||||
|
</FormLabel> |
||||
|
<Input |
||||
|
id="password" |
||||
|
{...register("password", passwordRules())} |
||||
|
placeholder="Password" |
||||
|
type="password" |
||||
|
/> |
||||
|
{errors.password && ( |
||||
|
<FormErrorMessage>{errors.password.message}</FormErrorMessage> |
||||
|
)} |
||||
|
</FormControl> |
||||
|
<FormControl |
||||
|
id="confirm_password" |
||||
|
isInvalid={!!errors.confirm_password} |
||||
|
> |
||||
|
<FormLabel htmlFor="confirm_password" srOnly> |
||||
|
Confirm Password |
||||
|
</FormLabel> |
||||
|
|
||||
|
<Input |
||||
|
id="confirm_password" |
||||
|
{...register("confirm_password", confirmPasswordRules(getValues))} |
||||
|
placeholder="Repeat Password" |
||||
|
type="password" |
||||
|
/> |
||||
|
{errors.confirm_password && ( |
||||
|
<FormErrorMessage> |
||||
|
{errors.confirm_password.message} |
||||
|
</FormErrorMessage> |
||||
|
)} |
||||
|
</FormControl> |
||||
|
<Button variant="primary" type="submit" isLoading={isSubmitting}> |
||||
|
Sign Up |
||||
|
</Button> |
||||
|
<Text> |
||||
|
Already have an account?{" "} |
||||
|
<Link as={RouterLink} to="/login" color="blue.500"> |
||||
|
Log In |
||||
|
</Link> |
||||
|
</Text> |
||||
|
</Container> |
||||
|
</Flex> |
||||
|
</> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default SignUp |
Loading…
Reference in new issue