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

126 lines
4.1 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 {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
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";
import { verifyOtpAction } from "@/actions/auth/verify-otp";
import { useSearchParams } from "next/navigation";
import { Input } from "../../../_components/ui/input";
const FormSchema = z.object({
token: z.string().min(6, {
message: "Your one-time password must be 6 characters.",
}),
});
interface InputOTPFormProps {
className?: string;
[key: string]: any;
}
export function VerifyOtpForm({ className, ...props }: InputOTPFormProps) {
const searchParams = useSearchParams();
const email = searchParams.get("email") || "";
const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
defaultValues: {
token: "",
},
});
async function onSubmit(data: z.infer<typeof FormSchema>) {
try {
} catch (error) {
toast({
variant: "destructive",
title: "Error",
description: "Failed to verify OTP. Please try again.",
});
}
}
return (
<div className={cn("flex flex-col gap-6", className)} {...props}>
<Card className="bg-[#171717] border-gray-800 text-white border-none">
<CardHeader className="text-center">
<CardTitle className="text-2xl font-bold">
One-Time Password
</CardTitle>
<CardDescription className="text-gray-400">
One time password is a security feature that helps protect your data
</CardDescription>
</CardHeader>
<CardContent>
<Form {...form}>
<form className="space-y-6">
<input type="hidden" name="email" value={email} />
<FormField
control={form.control}
name="token"
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 border-gray-700 bg-[#1C1C1C] text-white rounded-md focus:border-emerald-600 focus:ring-emerald-600"
/>
))}
</InputOTPGroup>
</InputOTP>
</FormControl>
<FormDescription className="flex w-full justify-center items-center text-gray-400">
Please enter the one-time password sent to {email}.
</FormDescription>
<FormMessage className="text-red-400" />
</FormItem>
)}
/>
<div className="flex justify-center">
<SubmitButton
className="w-full bg-emerald-600 hover:bg-emerald-700 text-white"
pendingText="Verifying..."
formAction={verifyOtpAction}
>
Submit
</SubmitButton>
</div>
</form>
</Form>
</CardContent>
</Card>
<div className="text-balance text-center text-xs text-gray-400 [&_a]:text-emerald-500 [&_a]:underline [&_a]:underline-offset-4 [&_a]:hover:text-emerald-400">
By clicking continue, you agree to our <a href="#">Terms of Service</a>{" "}
and <a href="#">Privacy Policy</a>.
</div>
</div>
);
}