MIF_E31221222/sigap-website/app/(auth-pages)/_components/auth/otp-form.tsx

116 lines
3.6 KiB
TypeScript

"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { toast } from "@/app/_hooks/use-toast";
import { Button } from "@/app/_components/ui/button";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/app/_components/ui/form";
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
} from "@/app/_components/ui/input-otp";
import { SubmitButton } from "../../../_components/submit-button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "../../../_components/ui/card";
import { cn } from "@/lib/utils";
const FormSchema = z.object({
pin: z.string().min(6, {
message: "Your one-time password must be 6 characters.",
}),
});
interface InputOTPFormProps {
className?: string;
[key: string]: any;
}
export function InputOTPForm({ className, ...props }: InputOTPFormProps) {
const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
defaultValues: {
pin: "",
},
});
function onSubmit(data: z.infer<typeof FormSchema>) {
toast({
title: "You submitted the following values:",
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
</pre>
),
});
}
return (
<div className={cn("flex flex-col gap-6", className)} {...props}>
<Card>
<CardHeader className="text-center">
<CardTitle className="text-xl">One-Time Password</CardTitle>
<CardDescription>
One time password is a security feature that helps protect your data
</CardDescription>
</CardHeader>
<CardContent>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<FormField
control={form.control}
name="pin"
render={({ field }) => (
<FormItem>
<FormControl>
<InputOTP maxLength={6} {...field}>
<InputOTPGroup className="flex w-full items-center justify-center space-x-2">
{[...Array(6)].map((_, index) => (
<InputOTPSlot
key={index}
index={index}
className="w-12 h-12 text-xl border-2 dark:border-gray-50/10 rounded-md"
/>
))}
</InputOTPGroup>
</InputOTP>
</FormControl>
<FormDescription className="flex w-full justify-center items-center">
Please enter the one-time password sent to your phone.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-center ">
<SubmitButton pendingText="verifying..." className="w-full">
Submit
</SubmitButton>
</div>
</form>
</Form>
</CardContent>
</Card>
<div className="text-balance text-center text-xs text-muted-foreground [&_a]:underline [&_a]:underline-offset-4 [&_a]:hover:text-primary ">
By clicking continue, you agree to our <a href="#">Terms of Service</a>{" "}
and <a href="#">Privacy Policy</a>.
</div>
</div>
);
}