UNPKG

@oberoncms/core

Version:

OberonCMS is a cloud deployable CMS written in typescript based on the Puck visual editor

147 lines (146 loc) 4.84 kB
"use client"; import { jsx, jsxs } from "react/jsx-runtime"; import { Form, FormField, FormItem, FormLabel, FormControl } from "@tohuhono/ui/form"; import { z } from "zod"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { Input } from "@tohuhono/ui/input"; import { Button } from "@tohuhono/ui/button"; import { InputOTP, InputOTPGroup, InputOTPSlot } from "@tohuhono/ui/input-otp"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { useDebouncedCallback } from "use-debounce"; import { cn } from "@tohuhono/utils"; import { useToast } from "@tohuhono/ui/toast"; import { useOberonActions } from "../hooks/use-oberon.js"; const LoginSchema = z.object({ email: z.string().email(), token: z.string().max(6).optional() }); function Login({ callbackUrl, email, token }) { const { signIn } = useOberonActions(); const router = useRouter(); const { toast } = useToast(); const form = useForm({ resolver: zodResolver(LoginSchema), defaultValues: { email, token } }); const [sending, setSending] = useState(false); const [submitting, setSubmitting] = useState(false); const [sent, setSent] = useState(!!email && !!token); const debouncedSetSending = useDebouncedCallback( (loading) => setSending(loading), 3e3 ); const sendOnCLick = form.handleSubmit(async ({ email: email2 }) => { setSending(true); try { await signIn({ email: typeof email2 === "string" ? email2 : "" }); form.resetField("token"); setSent(true); } catch (error) { setSending(false); throw error; } toast({ title: `Token sent to ${email2}`, description: "Please check your emails" }); debouncedSetSending(false); }); const tokenOnClick = form.handleSubmit(async ({ email: email2, token: token2 }) => { setSubmitting(true); const response = await fetch( `/cms/api/auth/callback/email?email=${email2}&token=${token2}` ); if (response.ok) { router.push(callbackUrl || "/cms/pages"); } if (!response.ok) { toast({ variant: "destructive", title: "Authentication failed", description: "Please check your credentials and try again" }); } form.resetField("token"); setSubmitting(false); }); return /* @__PURE__ */ jsx("div", { className: "grid h-screen place-content-center gap-3", children: /* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs("form", { className: "contents", children: [ /* @__PURE__ */ jsx( FormField, { control: form.control, name: "email", render: ({ field }) => { var _a; return /* @__PURE__ */ jsxs(FormItem, { children: [ /* @__PURE__ */ jsx(FormLabel, { children: ((_a = form.formState.errors.email) == null ? void 0 : _a.message) ?? "Email adress" }), /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(Input, { ...field }) }) ] }); } } ), /* @__PURE__ */ jsx( FormField, { control: form.control, name: "token", render: ({ field }) => /* @__PURE__ */ jsx( FormItem, { className: cn(sent ? "visible animate-fade-in" : "hidden"), children: /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(InputOTP, { maxLength: 6, ...field, children: /* @__PURE__ */ jsxs(InputOTPGroup, { children: [ /* @__PURE__ */ jsx(InputOTPSlot, { index: 0 }), /* @__PURE__ */ jsx(InputOTPSlot, { index: 1 }), /* @__PURE__ */ jsx(InputOTPSlot, { index: 2 }), /* @__PURE__ */ jsx(InputOTPSlot, { index: 3 }), /* @__PURE__ */ jsx(InputOTPSlot, { index: 4 }), /* @__PURE__ */ jsx(InputOTPSlot, { index: 5 }) ] }) }) }) } ) } ), !sent && /* @__PURE__ */ jsx(Button, { disabled: sending, variant: "default", onClick: sendOnCLick, children: "Sign in" }), /* @__PURE__ */ jsx( Button, { disabled: submitting, className: cn( "pt-2", sent ? "visible animate-fade-in" : "collapse", sending ? "transition-none" : "transition-opacity" ), onClick: tokenOnClick, children: "Complete Sign in" } ), /* @__PURE__ */ jsx( Button, { disabled: sending, className: cn( "animate-fade-in-half duration-1000", sent ? "visible" : "collapse", sending ? "transition-none" : "transition-opacity" ), variant: "secondary", onClick: sendOnCLick, children: "Resend OTP Token" } ) ] }) }) }); } export { Login };