import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; import { useNavigate } from "react-router-dom"; import { useT } from "../../i18n"; import { api, ApiError } from "../../lib/api"; import type { ServerConfig, SyncWindow } from "../../lib/types"; const PALETTE = ["#2563eb", "#16a34a", "#d4762a", "#9333ea", "#dc2626", "#0891b2"]; const EMPTY: ServerConfig = { host: "", port: 993, tls: "ssl", auth: "password" }; export function AccountWizard() { const t = useT(); const navigate = useNavigate(); const queryClient = useQueryClient(); const [step, setStep] = useState<1 | 2 | 3>(1); const [email, setEmail] = useState(""); const [displayName, setDisplayName] = useState(""); const [password, setPassword] = useState(""); const [color, setColor] = useState(PALETTE[0]); const [imap, setImap] = useState(EMPTY); const [smtp, setSmtp] = useState({ ...EMPTY, port: 465 }); const [source, setSource] = useState(""); const [syncWindow, setSyncWindow] = useState("all"); const [busy, setBusy] = useState(false); const [tested, setTested] = useState(false); const [error, setError] = useState(""); const discover = async () => { setBusy(true); setError(""); try { const res = await api.discover(email); const cand = res.candidates[0]; if (cand) { setImap({ ...cand.imap }); setSmtp({ ...cand.smtp }); setSource(cand.source); } else { setSource("manual"); } setStep(2); } catch (e) { setError(e instanceof ApiError ? e.message : String(e)); } finally { setBusy(false); } }; const test = async () => { setBusy(true); setError(""); setTested(false); try { await api.testAccount({ imap, smtp, email, password }); setTested(true); } catch (e) { setError(e instanceof ApiError ? e.message : String(e)); } finally { setBusy(false); } }; const create = async () => { setBusy(true); setError(""); try { await api.createAccount({ email, display_name: displayName || email, color, imap, smtp, password, sync_window: syncWindow, }); await queryClient.invalidateQueries({ queryKey: ["accounts"] }); setStep(3); } catch (e) { setError(e instanceof ApiError ? e.message : String(e)); } finally { setBusy(false); } }; const serverFields = ( cfg: ServerConfig, set: (c: ServerConfig) => void, label: string, ) => (
{label}
set({ ...cfg, host: e.target.value })} /> set({ ...cfg, port: Number(e.target.value) })} />
); return (

{t("wizard.title")}

{step === 1 && (
{ e.preventDefault(); discover(); }} > setEmail(e.target.value)} autoFocus />
)} {step === 2 && (
{source && source !== "manual" && (

{t("wizard.foundVia", { source })}

)} {serverFields(imap, setImap, t("wizard.imapServer"))} {serverFields(smtp, setSmtp, t("wizard.smtpServer"))} setDisplayName(e.target.value)} /> { setPassword(e.target.value); setTested(false); }} />

{t("wizard.appPasswordHint")}

Color {PALETTE.map((c) => (
{t("wizard.syncWindow")}
{(["all", "3months", "new"] as const).map((w) => ( ))}
{tested &&

{t("wizard.testOk")}

}
{!tested ? ( ) : ( )}
)} {step === 3 && (

{t("wizard.created")}

)} {error &&

{error}

}
); }