TypeScript 97.4%
SQL 1%
JavaScript 0.9%
CSS 0.6%
1"use client";2import * as React from "react";3import { authClient } from "@/lib/auth-client";4import { Button } from "@/components/ui/button";5import { toast } from "@/components/ui/toast";6import { humanAuthError, type AuthClientError } from "./auth-errors";78export const RESEND_COOLDOWN_S = 30;910/** Ticks a cooldown down to zero. `start(seconds)` resets it. */11export function useCooldown(initial = 0) {12 const [left, setLeft] = React.useState(initial);13 React.useEffect(() => {14 if (left <= 0) return;15 const t = setTimeout(() => setLeft((v) => Math.max(0, v - 1)), 1000);16 return () => clearTimeout(t);17 }, [left]);18 return { left, start: (s: number) => setLeft(s) };19}2021export function ResendVerification({ email, initialCooldown = 0, variant = "outline", className }: { email: string; initialCooldown?: number; variant?: "outline" | "ghost" | "primary" | "link"; className?: string }) {22 const { left, start } = useCooldown(initialCooldown);23 const [loading, setLoading] = React.useState(false);2425 async function resend() {26 if (!email || loading || left > 0) return;27 setLoading(true);28 try {29 const { error } = await authClient.sendVerificationEmail({ email, callbackURL: "/verify-email" });30 if (error) {31 const e = error as AuthClientError;32 if (e.status === 429) {33 toast.error("Slow down", "Too many emails requested. Please wait a minute before trying again.");34 start(60);35 } else {36 toast.error("Couldn't send the email", humanAuthError(e, "verify"));37 }38 return;39 }40 toast.success("Verification email sent", `Check ${email} — the link is valid for 24 hours.`);41 start(RESEND_COOLDOWN_S);42 } catch {43 toast.error("Couldn't send the email", "Check your connection and try again.");44 } finally {45 setLoading(false);46 }47 }4849 return (50 <Button type="button" variant={variant} onClick={resend} loading={loading} disabled={left > 0 || !email} className={className} aria-live="polite">51 {left > 0 ? `Resend available in ${left}s` : "Resend verification email"}52 </Button>53 );54}55