Skip to content

Commit

Permalink
feat: wrapping register form
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcoEscaleira committed Feb 6, 2024
1 parent 0a90c3b commit 923e4eb
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 97 deletions.
18 changes: 11 additions & 7 deletions src/components/DatePicker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ import { FC, useState } from "react";
import { Input, Popover, PopoverHandler, PopoverContent } from "@material-tailwind/react";
import { format } from "date-fns";
import { ChevronRightIcon, ChevronLeftIcon } from "lucide-react";
import { DayPicker } from "react-day-picker";
import { DayPicker, DayPickerProps } from "react-day-picker";
import { useFormContext } from "react-hook-form";

interface DatePickerProps {
type DatePickerProps = {
name: string;
label?: string;
}
} & DayPickerProps;

export const DatePicker: FC<DatePickerProps> = ({ name, label }) => {
export const DatePicker: FC<DatePickerProps> = ({ name, label, ...props }) => {
const [date, setDate] = useState<Date>();

const { register } = useFormContext();
const { register, setValue } = useFormContext();

return (
<Popover placement="bottom">
Expand All @@ -24,8 +24,12 @@ export const DatePicker: FC<DatePickerProps> = ({ name, label }) => {
<DayPicker
mode="single"
selected={date}
onSelect={setDate}
showOutsideDays
// @ts-expect-error: due to the props spread below
onSelect={newDate => {
setDate(newDate);
setValue(name, newDate);
}}
{...props}
className="border-0"
classNames={{
caption: "flex justify-center py-2 mb-4 relative items-center",
Expand Down
182 changes: 92 additions & 90 deletions src/components/Register/RegisterForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { useMutation } from "@apollo/client";
import { zodResolver } from "@hookform/resolvers/zod";
import { Input, Typography, Button, Select, Option } from "@material-tailwind/react";
import { Info } from "lucide-react";
import { SubmitHandler, useForm } from "react-hook-form";
import { FormProvider, SubmitHandler, useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import { useCountries } from "use-react-countries";
import { z } from "zod";
// import { DatePicker } from "@components/DatePicker/DatePicker.tsx";
import { DatePicker } from "@components/DatePicker/DatePicker.tsx";
import { gql } from "@generated/gql.ts";

const REGISTER_USER = gql(/* GraphQL */ `
Expand All @@ -25,8 +25,8 @@ const formSchema = z
password: z.string().min(1, { message: "Enter a password." }),
passwordConfirm: z.string().min(1, { message: "Enter a confirm password." }),
firstName: z.string().min(1, { message: "Enter a first name." }),
lastName: z.string().min(1, { message: "Enter a last name." }),
dateOfBirth: z.string().datetime(),
lastName: z.string(),
dateOfBirth: z.string(),
country: z.string(),
})
.superRefine(({ password, passwordConfirm }, ctx) => {
Expand All @@ -43,12 +43,7 @@ export function RegisterForm() {
const navigate = useNavigate();
const { countries } = useCountries();

const {
register,
handleSubmit,
reset,
formState: { errors },
} = useForm<z.infer<typeof formSchema>>({
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
email: "",
Expand All @@ -60,6 +55,12 @@ export function RegisterForm() {
country: "",
},
});
const {
register,
handleSubmit,
reset,
formState: { errors },
} = form;

const [registerMutation, { loading: isLoadingRegister, error: mutationError }] = useMutation(REGISTER_USER, {
onCompleted: async () => {
Expand All @@ -70,7 +71,6 @@ export function RegisterForm() {
});

const onSubmit: SubmitHandler<z.infer<typeof formSchema>> = async (values, event) => {
console.log(values);
event?.preventDefault();
try {
await registerMutation({
Expand All @@ -84,96 +84,98 @@ export function RegisterForm() {
};

return (
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6 py-4">
<Input
{...register("email")}
name="email"
size="lg"
label="Email address"
placeholder="[email protected]"
error={!!errors.email}
/>
<FormProvider {...form}>
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6 py-4">
<Input
{...register("email")}
name="email"
size="lg"
label="Email address"
placeholder="[email protected]"
error={!!errors.email}
/>

<div>
<Input
{...register("password")}
name="password"
size="lg"
type="password"
label="Password"
placeholder="*******"
error={!!errors.password}
/>
<Typography variant="small" color="gray" className="mt-2 flex items-center gap-1 font-normal">
<Info className="w-7 md:w-5" />
Use at least 8 characters, one uppercase, one lowercase and one number and one special character.
</Typography>
</div>

<div>
<Input
{...register("password")}
name="password"
{...register("passwordConfirm")}
name="passwordConfirm"
size="lg"
type="password"
label="Password"
label="Password confirmation"
placeholder="*******"
error={!!errors.password}
error={!!errors.passwordConfirm}
/>
<Typography variant="small" color="gray" className="mt-2 flex items-center gap-1 font-normal">
<Info className="w-7 md:w-5" />
Use at least 8 characters, one uppercase, one lowercase and one number and one special character.
</Typography>
</div>

<Input
{...register("passwordConfirm")}
name="passwordConfirm"
size="lg"
type="password"
label="Password confirmation"
placeholder="*******"
error={!!errors.passwordConfirm}
/>

<Input
{...register("firstName")}
name="firstName"
size="lg"
label="First name"
placeholder=""
error={!!errors.firstName}
/>
<Input
{...register("firstName")}
name="firstName"
size="lg"
label="First name"
placeholder=""
error={!!errors.firstName}
/>

<Input
{...register("lastName")}
name="lastName"
size="lg"
label="Last name"
placeholder=""
error={!!errors.firstName}
/>
<Input
{...register("lastName")}
name="lastName"
size="lg"
label="Last name"
placeholder=""
error={!!errors.firstName}
/>

{/*<DatePicker name="dateOfBirth" label="Date of birth" />*/}
<DatePicker name="dateOfBirth" label="Date of birth" disabled={{ after: new Date() }} />

<Select
size="lg"
label="Select Country"
selected={element =>
element &&
cloneElement(element, {
disabled: true,
className: "flex items-center opacity-100 px-0 gap-2 pointer-events-none",
})
}
>
{countries.map(({ name, flags }: { name: string; flags: { svg: string } }) => (
<Option key={name} value={name} className="flex items-center gap-2">
<img src={flags.svg} alt={name} className="h-5 w-5 rounded-full object-cover" />
{name}
</Option>
))}
</Select>
<Select
size="lg"
label="Select Country"
selected={element =>
element &&
cloneElement(element, {
disabled: true,
className: "flex items-center opacity-100 px-0 gap-2 pointer-events-none",
})
}
>
{countries.map(({ name, flags }: { name: string; flags: { svg: string } }) => (
<Option key={name} value={name} className="flex items-center gap-2">
<img src={flags.svg} alt={name} className="h-5 w-5 rounded-full object-cover" />
{name}
</Option>
))}
</Select>

{mutationError?.message && (
<Typography variant="small" color="red">
{mutationError.message}
</Typography>
)}
{mutationError?.message && (
<Typography variant="small" color="red">
{mutationError.message}
</Typography>
)}

<Button
type="submit"
fullWidth
placeholder="Create account"
disabled={isLoadingRegister}
loading={isLoadingRegister}
>
Create
</Button>
</form>
<Button
type="submit"
fullWidth
placeholder="Create account"
disabled={isLoadingRegister}
loading={isLoadingRegister}
>
Create
</Button>
</form>
</FormProvider>
);
}

0 comments on commit 923e4eb

Please sign in to comment.