"use client"; import { useEffect, useRef, useState } from "react"; import { usePathname } from "next/navigation"; import { Copy, KeyRound } from "lucide-react"; import { useI18n } from "./I18nProvider"; import { api } from "@/lib/client-api"; import { generateInitialPassword } from "@/shared/initial-password"; export function LegacyPasswordNotice({ enabled }: { enabled: boolean }) { const { t } = useI18n(); const pathname = usePathname(); const dialog = useRef(null); const [needed, setNeeded] = useState(false); const [password, setPassword] = useState(""); const [busy, setBusy] = useState(false); const [saved, setSaved] = useState(false); const [copied, setCopied] = useState(false); const [error, setError] = useState(""); useEffect(() => { if (!enabled || pathname?.startsWith("/auth/") || password) return; let active = true; api<{ needed: boolean }>("auth/initial-password") .then((data) => { if (active) setNeeded(data.needed); }) .catch(() => {}); return () => { active = false; }; }, [enabled, pathname, password]); useEffect(() => { if (!needed) return; const element = dialog.current; element?.showModal(); return () => { element?.close(); }; }, [needed]); async function generate() { if (busy) return; setBusy(true); setError(""); const generated = generateInitialPassword(); try { await api("auth/initial-password", { password: generated }); // Only keep the confirmed password in this mounted dialog's memory. setPassword(generated); } catch (e) { setError((e as Error).message); } finally { setBusy(false); } } function dismiss() { setNeeded(false); setPassword(""); setSaved(false); setCopied(false); setError(""); } async function copy() { try { await navigator.clipboard.writeText(password); setCopied(true); } catch { setError("Select the password and copy it manually."); } } if (!needed) return null; return ( { if (password || busy) event.preventDefault(); else dismiss(); }} > ); }