import { useEffect, useState } from "react"; import { API_BASE } from "../../config"; const inputStyle = { padding: "0.6rem", background: "#222", color: "#eee", border: "1px solid #333", borderRadius: "8px", width: "100%", boxSizing: "border-box" }; const btn = (bg) => ({ padding: "0.5rem 1rem", background: bg, color: "#fff", border: "none", borderRadius: "8px", cursor: "pointer" }); const labelStyle = { display: "block", fontSize: "0.72rem", color: "#888", marginBottom: "0.3rem", textTransform: "uppercase", letterSpacing: "0.05em" }; const BLANK = { label: "", username: "", password: "", from_addr: "", from_name: "", imap_host: "imap.mail.me.com", imap_port: 993, smtp_host: "smtp.mail.me.com", smtp_port: 587, }; // macOS-Mail-style "Internet Accounts" window: accounts on the left, the // selected account's config on the right. Lets you manage several mailboxes // that happen to share the same IMAP/SMTP server. export function MailAccounts({ onClose, onChanged }) { const [accounts, setAccounts] = useState(null); // null = loading const [selectedId, setSelectedId] = useState(null); // null = "add account" form const [form, setForm] = useState(BLANK); const [busy, setBusy] = useState(false); const [note, setNote] = useState(""); const selectAccount = (id, list = accounts) => { setNote(""); setSelectedId(id); if (id === null) { setForm(BLANK); return; } const a = (list || []).find(x => x.id === id); if (a) setForm({ ...a, password: "" }); }; const load = async (selectAfter) => { const r = await fetch(`${API_BASE}/mail/accounts`); const list = r.ok ? (await r.json()).accounts || [] : []; setAccounts(list); onChanged && onChanged(list); if (selectAfter !== undefined) selectAccount(selectAfter, list); return list; }; useEffect(() => { load().then(list => { if (list.length) selectAccount(list[0].id, list); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const save = async () => { setBusy(true); setNote("Saving…"); try { const url = selectedId ? `${API_BASE}/mail/accounts/${selectedId}` : `${API_BASE}/mail/accounts`; const r = await fetch(url, { method: selectedId ? "PUT" : "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(form), }); if (!r.ok) { setNote("Save failed."); return; } const saved = await r.json(); setNote("Saved."); await load(saved.id); } finally { setBusy(false); } }; const test = async () => { if (!selectedId) { setNote("Save the account first."); return; } setBusy(true); setNote("Testing…"); try { const r = await fetch(`${API_BASE}/mail/accounts/${selectedId}/test`, { method: "POST" }); const d = await r.json().catch(() => ({})); setNote(d.ok ? `Connected — ${d.folders} folders.` : `Connection failed: ${d.error || "check credentials"}`); } finally { setBusy(false); } }; const remove = async () => { if (!selectedId) return; if (!window.confirm(`Delete account "${form.label || form.from_addr || form.username}"?`)) return; setBusy(true); try { await fetch(`${API_BASE}/mail/accounts/${selectedId}`, { method: "DELETE" }); const list = await load(); selectAccount(list.length ? list[0].id : null, list); } finally { setBusy(false); } }; const update = (k, v) => setForm(f => ({ ...f, [k]: v })); return (