123 lines
4.0 KiB
TypeScript
123 lines
4.0 KiB
TypeScript
"use client";
|
|
|
|
// import { useSignIn } from "@clerk/nextjs";
|
|
// import { OTPInput, SlotProps } from "input-otp";
|
|
import { useRouter } from "next/navigation";
|
|
import * as React from "react";
|
|
|
|
import { Loading } from "@/components/ui/loading";
|
|
import { toast } from "@/components/ui/toaster";
|
|
import { cn } from "@/lib/utils";
|
|
import { useTranslation } from "react-i18next";
|
|
// import { Minus } from "lucide-react";
|
|
|
|
type Props = {
|
|
setError: (s: string) => void;
|
|
};
|
|
|
|
export const EmailCode: React.FC<Props> = ({ setError }) => {
|
|
const router = useRouter();
|
|
const { t } = useTranslation();
|
|
// const { signIn, isLoaded: signInLoaded, setActive } = useSignIn();
|
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
|
|
const verifyCode = async (otp: string) => {
|
|
console.log("verifying", otp);
|
|
|
|
setIsLoading(true);
|
|
|
|
setIsLoading(false);
|
|
};
|
|
|
|
const resendCode = async () => {
|
|
// try {
|
|
// const firstFactor = signIn?.supportedFirstFactors.find((f) => f.strategy === "email_code") as
|
|
// | { emailAddressId: string }
|
|
// | undefined;
|
|
// if (!firstFactor) {
|
|
// return null;
|
|
// }
|
|
// const p = signIn!.prepareFirstFactor({
|
|
// strategy: "email_code",
|
|
// emailAddressId: firstFactor.emailAddressId,
|
|
// });
|
|
// toast.promise(p, {
|
|
// loading: "Sending new code ...",
|
|
// success: "A new code has been sent to your email",
|
|
// });
|
|
// await p;
|
|
// } catch (error) {
|
|
// setIsLoading(false);
|
|
// setError((error as Error).message);
|
|
// console.error(error);
|
|
// }
|
|
};
|
|
|
|
const [otp, setOtp] = React.useState("");
|
|
|
|
return (
|
|
<div className="flex flex-col max-w-sm mx-auto text-left">
|
|
<h1 className="text-4xl text-transparent bg-clip-text bg-gradient-to-r from-white to-white/30">
|
|
{t("auth.security_code_sent")}
|
|
</h1>
|
|
<p className="mt-4 text-sm text-white/40">
|
|
{t("auth.to_continue_text")}
|
|
</p>
|
|
|
|
<p className="mt-2 text-sm text-white/40">
|
|
{t("auth.receive_code")}{" "}
|
|
<button type="button" className="text-white" onClick={resendCode}>
|
|
{t("auth.resend")}
|
|
</button>
|
|
</p>
|
|
<form className="flex flex-col gap-12 mt-10" onSubmit={() => verifyCode(otp)}>
|
|
{/* <OTPInput
|
|
data-1p-ignore
|
|
value={otp}
|
|
onChange={setOtp}
|
|
onComplete={() => verifyCode(otp)}
|
|
maxLength={6}
|
|
render={({ slots }) => (
|
|
<div className="flex items-center justify-between">
|
|
{slots.slice(0, 3).map((slot, idx) => (
|
|
// biome-ignore lint/suspicious/noArrayIndexKey: I have nothing better
|
|
<Slot key={idx} {...slot} />
|
|
))}
|
|
<Minus className="w-6 h-6 text-white/15" />
|
|
{slots.slice(3).map((slot, idx) => (
|
|
// biome-ignore lint/suspicious/noArrayIndexKey: I have nothing better
|
|
<Slot key={idx} {...slot} />
|
|
))}
|
|
</div>
|
|
)}
|
|
/>*/}
|
|
|
|
<button
|
|
type="submit"
|
|
className="flex items-center justify-center h-10 gap-2 px-4 text-sm font-semibold text-black duration-200 bg-white border border-white rounded-lg hover:border-white/30 hover:bg-black hover:text-white"
|
|
disabled={isLoading}
|
|
onClick={() => verifyCode(otp)}
|
|
>
|
|
{isLoading ? <Loading className="w-4 h-4 mr-2 animate-spin" /> : null}
|
|
{t("auth.continue")}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
// const Slot: React.FC<SlotProps> = (props) => (
|
|
// <div
|
|
// className={cn(
|
|
// "relative w-10 h-12 text-[2rem] border border-white/20 rounded-lg text-white font-light text-base",
|
|
// "flex items-center justify-center",
|
|
// "transition-all duration-300",
|
|
// "group-hover:border-white/50 group-focus-within:border-white/50",
|
|
// "outline outline-0 outline-white",
|
|
// { "outline-1 ": props.isActive },
|
|
// )}
|
|
// >
|
|
// {props.char !== null && <div>{props.char}</div>}
|
|
// </div>
|
|
// );
|