import { useState, useEffect } from "react"; import { toast } from "sonner"; import { authClient } from "../../lib/auth-client"; type Tab = "login" | "register"; type AuthModalProps = { onClose: () => void; onSuccess: () => void }; type LoginFormProps = { onSuccess: () => void }; const LoginForm = ({ onSuccess }: LoginFormProps) => { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [isPending, setIsPending] = useState(false); const handleSubmit = async () => { setIsPending(true); await authClient.signIn.email( { email, password }, { onSuccess: () => { toast.success("Welcome back!"); onSuccess(); }, onError: (ctx) => { toast.error(ctx.error.message ?? "Something went wrong."); setIsPending(false); }, }, ); }; return (
{ e.preventDefault(); void handleSubmit(); }} className="flex flex-col gap-3" > setEmail(e.target.value)} required className="w-full rounded-2xl border border-(--color-primary-light) bg-white px-4 py-3 text-sm text-(--color-text) placeholder:text-(--color-text-muted) focus:outline-none focus:ring-2 focus:ring-(--color-primary)" /> setPassword(e.target.value)} required className="w-full rounded-2xl border border-(--color-primary-light) bg-white px-4 py-3 text-sm text-(--color-text) placeholder:text-(--color-text-muted) focus:outline-none focus:ring-2 focus:ring-(--color-primary)" />
Forgot password?
); }; type RegisterFormProps = { onSuccess: () => void }; const RegisterForm = ({ onSuccess }: RegisterFormProps) => { const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [isPending, setIsPending] = useState(false); const handleSubmit = async () => { setIsPending(true); await authClient.signUp.email( { name, email, password }, { onSuccess: () => { toast.success("Check your email to verify your account."); onSuccess(); }, onError: (ctx) => { toast.error(ctx.error.message ?? "Something went wrong."); setIsPending(false); }, }, ); }; return (
{ e.preventDefault(); void handleSubmit(); }} className="flex flex-col gap-3" > setName(e.target.value)} required className="w-full rounded-2xl border border-(--color-primary-light) bg-white px-4 py-3 text-sm text-(--color-text) placeholder:text-(--color-text-muted) focus:outline-none focus:ring-2 focus:ring-(--color-primary)" /> setEmail(e.target.value)} required className="w-full rounded-2xl border border-(--color-primary-light) bg-white px-4 py-3 text-sm text-(--color-text) placeholder:text-(--color-text-muted) focus:outline-none focus:ring-2 focus:ring-(--color-primary)" /> setPassword(e.target.value)} required minLength={8} className="w-full rounded-2xl border border-(--color-primary-light) bg-white px-4 py-3 text-sm text-(--color-text) placeholder:text-(--color-text-muted) focus:outline-none focus:ring-2 focus:ring-(--color-primary)" />
); }; type SocialButtonsProps = { onSuccess: () => void }; const SocialButtons = ({ onSuccess }: SocialButtonsProps) => { const handleSocial = (provider: "google" | "github") => { void authClient.signIn.social( { provider, callbackURL: window.location.origin }, { onSuccess, onError: (ctx) => { toast.error(ctx.error.message ?? "Something went wrong."); }, }, ); }; return (
or continue with
); }; export const AuthModal = ({ onClose, onSuccess }: AuthModalProps) => { const [tab, setTab] = useState("login"); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); }; document.addEventListener("keydown", handleKeyDown); return () => document.removeEventListener("keydown", handleKeyDown); }, [onClose]); return (
e.stopPropagation()} > {/* Close button */} {/* Header */}

lila

{/* Tabs */}
{(["login", "register"] as Tab[]).map((t) => ( ))}
{tab === "login" ? ( ) : ( )} {/* Social */}
); };