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 (
e.stopPropagation()} style={{ background: "#1a1a1a", border: "1px solid #333", borderRadius: "12px", width: "720px", maxWidth: "100%", height: "520px", maxHeight: "100%", display: "flex", flexDirection: "column", overflow: "hidden" }}>
Mail Accounts
{/* Left: accounts bar */}
{accounts === null ? (
Loading…
) : accounts.length === 0 ? (
No accounts yet.
) : accounts.map(a => (
selectAccount(a.id)} style={{ padding: "0.5rem 0.6rem", borderRadius: "6px", cursor: "pointer", marginBottom: "0.2rem", background: selectedId === a.id ? "#1c2a3a" : "transparent", color: selectedId === a.id ? "#fff" : "#ccc", }}>
{a.label || a.from_addr || a.username || "(unnamed)"}
{a.configured ? (a.from_addr || a.username) : "needs password"}
))}
{/* Right: selected account form */}

{selectedId ? "Edit account" : "New account"}

update("label", e.target.value)} placeholder="e.g. Personal, Work" style={inputStyle} />
update("username", e.target.value)} placeholder="you@icloud.com" style={inputStyle} />
update("password", e.target.value)} style={inputStyle} />
update("from_addr", e.target.value)} placeholder="nexus@enderofwings.com" style={inputStyle} />
update("from_name", e.target.value)} style={inputStyle} />
update("imap_host", e.target.value)} style={inputStyle} />
update("imap_port", parseInt(e.target.value) || 0)} style={inputStyle} />
update("smtp_host", e.target.value)} style={inputStyle} />
update("smtp_port", parseInt(e.target.value) || 0)} style={inputStyle} />
{selectedId && } {selectedId && }
{note}
); }