frontend/app/components/input-otp.tsx
Nathan Lamy 938ed8a4df
Some checks failed
Deploy to Netlify / Deploy to Netlify (push) Failing after 1m10s
ui: add register page
2025-07-28 23:29:27 +02:00

75 lines
2.1 KiB
TypeScript

import { AlertCircleIcon, LoaderIcon } from "lucide-react";
import { useState } from "react";
import { Alert, AlertDescription } from "./ui/alert";
import { InputOTP, InputOTPGroup, InputOTPSlot } from "./ui/input-otp";
import { verifyOtp } from "~/lib/api";
import { useNavigate } from "react-router";
export default function OtpInput({
email,
setOtpError,
otpError,
}: {
email: string;
setOtpError: (error: string | null) => void;
otpError: string | null;
}) {
const navigate = useNavigate();
const [isVerifying, setIsVerifying] = useState(false);
// Handle OTP verification
const handleVerifyOtp = (otpCode: string) => {
setIsVerifying(true);
setOtpError(null);
verifyOtp({ otpCode, email })
.then(() => {
setIsVerifying(false);
// TODO: Check if new user ??
navigate("/success?email=" + encodeURIComponent(email), {
replace: true,
});
})
.catch((error) =>
setOtpError(
error instanceof Error
? error.message
: "Code de vérification invalide"
)
);
};
return (
<div className="space-y-4">
<div className="flex-1 flex items-center justify-center">
<InputOTP
maxLength={6}
onComplete={(value) => handleVerifyOtp(value)}
disabled={isVerifying}
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
</div>
{isVerifying && (
<div className="flex justify-center items-center py-2">
<LoaderIcon className="h-5 w-5 animate-spin text-primary mr-2" />
<span className="text-sm">Vérification en cours...</span>
</div>
)}
{otpError && (
<Alert variant="destructive" className="mt-2 pb-2">
<AlertCircleIcon className="h-4 w-4" />
<AlertDescription>{otpError}</AlertDescription>
</Alert>
)}
</div>
);
}