82 lines
2.3 KiB
TypeScript
82 lines
2.3 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((data) => {
|
|
setIsVerifying(false);
|
|
// Check if user is registered
|
|
if (data.token) {
|
|
navigate(`/register?email=${data.email}&token=${data.token}`, {
|
|
replace: true,
|
|
});
|
|
} else {
|
|
navigate("/", {
|
|
replace: true,
|
|
})
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
setOtpError(
|
|
error instanceof Error
|
|
? error.message
|
|
: "Code de vérification invalide"
|
|
)
|
|
setIsVerifying(false)
|
|
});
|
|
};
|
|
|
|
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>
|
|
);
|
|
}
|