'use client'; //=========================================== // THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY UNLESS YOU ALSO EDIT THE CORRESPONDING FILE IN packages/template //=========================================== import { yupResolver } from "@hookform/resolvers/yup"; import { KnownErrors } from "@hexclave/shared"; import { strictEmailSchema, yupObject } from "@hexclave/shared/dist/schema-fields"; import { runAsynchronouslyWithAlert } from "@hexclave/shared/dist/utils/promises"; import { Button, Input, InputOTP, InputOTPGroup, InputOTPSlot, Label, Typography } from "@hexclave/ui"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import * as yup from "yup"; import { useStackApp } from "../lib/hooks"; import { useTranslation } from "../lib/translations"; import { FormWarningText } from "./elements/form-warning"; function OTP(props: { onBack: () => void, nonce: string, }) { const { t } = useTranslation(); const [otp, setOtp] = useState(''); const [submitting, setSubmitting] = useState(false); const hexclaveApp = useStackApp(); const [error, setError] = useState(null); useEffect(() => { if (otp.length === 6 && !submitting) { setSubmitting(true); // eslint-disable-next-line no-restricted-syntax hexclaveApp.signInWithMagicLink(otp + props.nonce) .then(result => { if (result.status === 'error') { if (KnownErrors.VerificationCodeError.isInstance(result.error)) { setError(t("Invalid code")); } else if (KnownErrors.InvalidTotpCode.isInstance(result.error)) { setError(t("Invalid TOTP code")); } else { throw result.error; } } }) .catch(e => console.error(e)) .finally(() => { setSubmitting(false); setOtp(''); }); } if (otp.length !== 0 && otp.length !== 6) { setError(null); } }, [otp, submitting]); return (
{t('Enter the code from your email')} setOtp(value.toUpperCase())} disabled={submitting} > {[0, 1, 2, 3, 4, 5].map((index) => ( ))} {error && }
); } export function MagicLinkSignIn() { const { t } = useTranslation(); const app = useStackApp(); const [loading, setLoading] = useState(false); const [nonce, setNonce] = useState(null); const schema = yupObject({ email: strictEmailSchema(t('Please enter a valid email')).defined().nonEmpty(t('Please enter your email')) }); const { register, handleSubmit, setError, formState: { errors } } = useForm({ resolver: yupResolver(schema) }); const onSubmit = async (data: yup.InferType) => { setLoading(true); try { const { email } = data; const result = await app.sendMagicLinkEmail(email); if (result.status === 'error') { setError('email', { type: 'manual', message: result.error.message }); return; } else { setNonce(result.data.nonce); } } catch (e) { if (KnownErrors.SignUpNotEnabled.isInstance(e)) { setError('email', { type: 'manual', message: t('New account registration is not allowed') }); } else { throw e; } } finally { setLoading(false); } }; if (nonce) { return setNonce(null)} />; } else { return (
runAsynchronouslyWithAlert(handleSubmit(onSubmit)(e))} noValidate > ); } }