"use client" import { useEffect, useMemo, useState } from "react" import { Loader2, MailCheck, Server } from "lucide-react" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card" import { ApiRequestError } from "@/lib/api/client" import { useCheckMailAddress, useHostedMailStatus, useSetupHostedMailbox, } from "@/lib/api/hooks/use-hosted-mail" import { useAuthStore } from "@/lib/api/auth-store" function suggestLocalPart(platformEmail: string | undefined, domain: string): string { if (!platformEmail?.includes("@")) return "" const [local, emailDomain] = platformEmail.split("@") if (!local) return "" if (emailDomain?.toLowerCase() === domain.toLowerCase()) { return local.toLowerCase() } return local.toLowerCase().replace(/[^a-z0-9._+-]/g, "") } function setupErrorMessage(error: unknown): string { if (error instanceof ApiRequestError) { switch (error.code) { case "address_taken": return "Cette adresse est déjà utilisée." case "domain_not_active": return "Le domaine mail n'est pas encore actif." } return error.message } if (error instanceof Error) return error.message return "Échec de la configuration." } export function HostedMailSetupCard() { const platformEmail = useAuthStore((s) => s.user?.email) const { data: status, isPending } = useHostedMailStatus() const setup = useSetupHostedMailbox() const domain = status?.platform_domain ?? "" const alreadyConnected = Boolean( status?.hosted_mail_account_id || status?.mailbox?.mail_account_id ) const connectedEmail = status?.hosted_mail_account_email ?? status?.mailbox?.email ?? "" const [localPart, setLocalPart] = useState("") const [displayName, setDisplayName] = useState("") const [password, setPassword] = useState("") const [confirmPassword, setConfirmPassword] = useState("") useEffect(() => { if (!domain || localPart) return const suggested = suggestLocalPart(platformEmail, domain) if (suggested) setLocalPart(suggested) }, [domain, localPart, platformEmail]) const fullEmail = useMemo(() => { const local = localPart.trim().toLowerCase() return local && domain ? `${local}@${domain}` : "" }, [localPart, domain]) const addressCheck = useCheckMailAddress(localPart.trim(), domain) const addressTaken = addressCheck.data?.available === false && addressCheck.data.reason !== "hosted_mail_disabled" const passwordsMatch = password === confirmPassword const passwordOk = password.length >= 8 const canSubmit = !setup.isPending && localPart.trim().length > 0 && passwordOk && passwordsMatch && addressCheck.data?.available !== false if (isPending || !status?.enabled) return null const endpoints = status.endpoints async function handleSubmit() { if (!canSubmit) return try { await setup.mutateAsync({ local_part: localPart.trim().toLowerCase(), password, display_name: displayName.trim() || undefined, }) setPassword("") setConfirmPassword("") } catch { /* message below */ } } return (
Mail hébergé Ultimail (Stalwart) Créez ou connectez votre boîte @{domain} — IMAP/SMTP préconfigurés, sans saisie manuelle des serveurs.
{endpoints ? (

Serveurs : IMAP {endpoints.imap_host}:{endpoints.imap_port} {endpoints.imap_tls ? " (TLS)" : ""} · SMTP {endpoints.smtp_host}:{endpoints.smtp_port} {endpoints.smtp_tls ? " (TLS)" : ""}

) : null} {alreadyConnected ? (

Boîte hébergée connectée

{connectedEmail}

) : (
setLocalPart(e.target.value)} /> @{domain}
{fullEmail ? (

{fullEmail}

) : null} {addressCheck.isFetching ? (

Vérification de la disponibilité…

) : addressTaken ? (

Adresse déjà prise.

) : addressCheck.data?.available === true && localPart.trim() ? (

Adresse disponible.

) : null}
setDisplayName(e.target.value)} />
setPassword(e.target.value)} />
setConfirmPassword(e.target.value)} /> {password && !passwordOk ? (

8 caractères minimum.

) : null} {confirmPassword && !passwordsMatch ? (

Les mots de passe ne correspondent pas.

) : null}
{setup.isError ? (

{setupErrorMessage(setup.error)}

) : null} {setup.isSuccess ? (

Boîte configurée — synchronisation IMAP en cours.

) : null}
)}
) }