"use client" import { useEffect, useState } from "react" import { useRouter, useSearchParams } from "next/navigation" import { MoreHorizontal, Pencil, Trash2 } from "lucide-react" import { Button } from "@/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card" import { AddMailAccountForm } from "@/components/gmail/settings/add-mail-account-form" import { EditMailAccountForm } from "@/components/gmail/settings/edit-mail-account-form" import { useMailAccounts } from "@/lib/api/hooks/use-mail-queries" import { useCreateMailAccount, useDeleteMailAccount, useResanitizeBodies, useSyncMailAccount, } from "@/lib/api/hooks/use-mail-account-mutations" import { useIdentities } from "@/lib/api/hooks/use-folder-label-queries" import { useCreateIdentity, useUpdateIdentity, useDeleteIdentity, } from "@/lib/api/hooks/use-identity-mutations" import { SettingsSectionHeader } from "@/components/gmail/settings/settings-section-header" import { SettingsSyncBanner } from "@/components/gmail/settings/settings-sync-banner" import { useAuthReady } from "@/lib/api/use-auth-ready" import type { ApiMailAccount } from "@/lib/api/types" export function AccountsSettingsSection() { const router = useRouter() const searchParams = useSearchParams() const oauthStatus = searchParams.get("oauth") const { ready, authenticated } = useAuthReady() const { data: accounts = [], isFetching, isError, refetch, isPending } = useMailAccounts() const createAccount = useCreateMailAccount() const showInitialLoad = ready && authenticated && isPending && accounts.length === 0 useEffect(() => { if (oauthStatus === "success") { void refetch() router.replace("/mail/settings/accounts") } }, [oauthStatus, refetch, router]) return ( <> {oauthStatus === "success" ? (

Compte mail connecté via OAuth.

) : null} {oauthStatus === "error" ? (

Échec de la connexion OAuth {searchParams.get("code") ? ` (${searchParams.get("code")})` : ""}.

) : null} refetch()} />
createAccount.mutate(payload)} /> {showInitialLoad ? null : accounts.length === 0 ? (

Aucun compte mail configuré. Ajoutez votre adresse e-mail ci-dessus pour commencer.

) : ( accounts.map((account) => ) )}
) } function AccountCard({ account }: { account: ApiMailAccount }) { const deleteAccount = useDeleteMailAccount() const resanitizeBodies = useResanitizeBodies(account.id) const syncAccount = useSyncMailAccount(account.id) const { data: identities = [] } = useIdentities(account.id) const [editing, setEditing] = useState(false) const [maintenanceMessage, setMaintenanceMessage] = useState(null) async function runResanitize() { setMaintenanceMessage(null) try { const result = await resanitizeBodies.mutateAsync() setMaintenanceMessage( `Corps réimportés depuis IMAP : ${result.updated} message(s) mis à jour sur ${result.scanned} analysé(s).` ) } catch { setMaintenanceMessage("Échec de la réimportation des corps depuis IMAP.") } } async function runSync(force = false) { setMaintenanceMessage(null) try { await syncAccount.mutateAsync({ force }) setMaintenanceMessage( force ? "Re-synchronisation complète IMAP terminée." : "Synchronisation IMAP terminée." ) } catch { setMaintenanceMessage("Échec de la synchronisation IMAP.") } } const maintenancePending = resanitizeBodies.isPending || syncAccount.isPending return (
{account.name} {account.email}

IMAP {account.imap_host} · SMTP {account.smtp_host} {account.last_sync_at ? ` · Dernière sync : ${new Date(account.last_sync_at).toLocaleString("fr-FR")}` : null}

void runResanitize()} > {resanitizeBodies.isPending ? "Réimportation IMAP…" : "Réimporter les corps depuis IMAP"} void runSync()} > {syncAccount.isPending ? "Synchronisation…" : "Synchroniser IMAP"} void runSync(true)} > Forcer re-sync complet
{maintenanceMessage ? (

{maintenanceMessage}

) : null} {editing ? ( setEditing(false)} /> ) : null}
) } function IdentitiesBlock({ accountId, accountEmail, identities, }: { accountId: string accountEmail: string identities: Array<{ id: string email: string name: string is_default: boolean signature_html?: string default_signature_id?: string reply_to_addrs?: string[] }> }) { const createIdentity = useCreateIdentity(accountId) const updateIdentity = useUpdateIdentity(accountId) const deleteIdentity = useDeleteIdentity(accountId) const [showAddForm, setShowAddForm] = useState(false) const [newIdentity, setNewIdentity] = useState({ email: accountEmail, name: "" }) useEffect(() => { if (!showAddForm) { setNewIdentity({ email: accountEmail, name: "" }) } }, [accountEmail, showAddForm]) function identityPayload( identity: (typeof identities)[number], patch: Partial<{ email: string name: string is_default: boolean }> = {} ) { return { identityId: identity.id, email: patch.email ?? identity.email, name: patch.name ?? identity.name, is_default: patch.is_default ?? identity.is_default, signature_html: identity.signature_html ?? "", default_signature_id: identity.default_signature_id ?? "", reply_to_addrs: identity.reply_to_addrs, } } function handleCreateIdentity() { const email = newIdentity.email.trim() const name = newIdentity.name.trim() if (!email) return createIdentity.mutate( { email, name: name || email.split("@")[0] || "Identité", is_default: identities.length === 0, }, { onSuccess: () => { setShowAddForm(false) setNewIdentity({ email: accountEmail, name: "" }) }, } ) } return (

Identités d'envoi

{identities.length === 0 ? (

Aucune identité configurée.

) : (
    {identities.map((identity) => (
  • { const next = e.target.value.trim() if (!next || next === identity.name) return updateIdentity.mutate(identityPayload(identity, { name: next })) }} />
    { const next = e.target.value.trim() if (!next || next === identity.email) return updateIdentity.mutate(identityPayload(identity, { email: next })) }} />
    {identity.is_default ? (

    Identité par défaut

    ) : null}
  • ))}
)} {showAddForm ? (
setNewIdentity({ ...newIdentity, name: e.target.value })} />
setNewIdentity({ ...newIdentity, email: e.target.value })} />
) : ( )}
) }