"use client"; import * as React from "react"; import Link from "next/link"; import { KeyRound, MailCheck } from "lucide-react"; import { authClient } from "@/lib/auth-client"; import { Button } from "@/components/ui/button"; import { Field, Input } from "@/components/ui/input"; import { toast } from "@/components/ui/toast"; import { AuthCard, FormError } from "./auth-card"; import { isValidEmail, type AuthClientError } from "./auth-errors"; import { useCooldown, RESEND_COOLDOWN_S } from "./resend-verification"; export function ForgotForm({ initialEmail = "" }: { initialEmail?: string }) { const [email, setEmail] = React.useState(initialEmail); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(null); const [sent, setSent] = React.useState(false); const { left, start } = useCooldown(0); async function request() { setError(null); if (!isValidEmail(email)) { setError("Enter a valid email address."); return; } setLoading(true); try { const { error: err } = await authClient.requestPasswordReset({ email: email.trim(), redirectTo: "/reset-password" }); if (err && (err as AuthClientError).status === 429) { setError("Too many requests. Please wait a minute and try again."); start(60); return; } // Whether or not an account exists, respond identically to avoid leaking who has an account. setSent(true); start(RESEND_COOLDOWN_S); toast.success("Reset link sent", "If an account exists for this email, the link is on its way."); } catch { setError("We couldn't reach the server. Check your connection and try again."); } finally { setLoading(false); } } if (sent) { return ( } title="Check your inbox" description={ <> If an account exists for {email.trim()}, we've sent a link to reset your password. It expires in 60 minutes. } footer={ Back to sign in } >
{error}
); } return ( } title="Reset your password" description="Enter the email you signed up with and we'll send you a link to choose a new password." footer={ <> Remembered it?{" "} Back to sign in } >
{ e.preventDefault(); void request(); }} noValidate className="space-y-4" > {error} setEmail(e.target.value)} placeholder="you@company.com" aria-invalid={!!error || undefined} aria-describedby={error ? "forgot-error" : undefined} autoFocus />
); }