Skip to content

Instantly share code, notes, and snippets.

@allipiopereira
Created February 26, 2025 01:27
Show Gist options
  • Save allipiopereira/2672a826c5409aa38e1d799164d7b38d to your computer and use it in GitHub Desktop.
Save allipiopereira/2672a826c5409aa38e1d799164d7b38d to your computer and use it in GitHub Desktop.
//login-form
"use client";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useState } from "react";
import { EbdoLogo } from "@/components/icons";
import { Spinner } from "@/components/ui/spinner";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
const emailSchema = z.object({
email: z
.string()
.email("Digite um email válido.")
.nonempty("*Campo obrigatório."),
});
const otpSchema = z.object({
otp: z
.string()
.min(6, "O código deve ter 6 dígitos.")
.max(6, "O código deve ter 6 dígitos.")
.nonempty("*Campo obrigatório."),
});
type EmailFormData = z.infer<typeof emailSchema>;
type OtpFormData = z.infer<typeof otpSchema>;
export function LoginForm() {
const [step, setStep] = useState<"email" | "otp">("email");
const [email, setEmail] = useState("");
const [isLoading, setIsLoading] = useState(false);
const emailForm = useForm<EmailFormData>({
resolver: zodResolver(emailSchema),
defaultValues: {
email: "",
},
});
const otpForm = useForm<OtpFormData>({
resolver: zodResolver(otpSchema),
defaultValues: {
otp: "",
},
});
const onSubmit = async (data: EmailFormData | OtpFormData) => {
setIsLoading(true);
try {
if (step === "email") {
const emailFormData = data as EmailFormData;
console.log("Enviando código para:", emailFormData.email);
setEmail(emailFormData.email);
setStep("otp");
} else {
const otpFormData = data as OtpFormData;
console.log(
"Verificando código:",
otpFormData.otp,
"para o email:",
email,
);
}
} catch (error) {
console.error(error);
} finally {
setIsLoading(false);
}
};
return (
<div className="flex h-screen flex-col items-center justify-center">
<div className="flex w-72 flex-col items-center">
<EbdoLogo className="h-24 w-24 fill-white" />
<h2 className="text-2xl font-semibold">Command Center</h2>
{step === "email" ? (
<Form {...emailForm}>
<form
onSubmit={emailForm.handleSubmit(onSubmit)}
className="mt-10 w-full space-y-6"
>
<FormField
control={emailForm.control}
name="email"
render={({ field }) => (
<FormItem>
<FormControl>
<Input placeholder="Email" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? <Spinner className="mr-2" /> : null}
Continue
</Button>
</form>
</Form>
) : (
<Form {...otpForm}>
<form
onSubmit={otpForm.handleSubmit(onSubmit)}
className="mt-10 w-72 space-y-6"
>
<div>
<span>Enviamos um código para seu email.</span>
<span>{email}</span>
</div>
<FormField
control={otpForm.control}
name="otp"
render={({ field }) => (
<FormItem>
<FormControl>
<Input
placeholder="Código de verificação"
maxLength={6}
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" className="w-full" disabled={isLoading}>
{isLoading ? <Spinner className="mr-2" /> : null}
Continue
</Button>
</form>
</Form>
)}
</div>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment