"use client"; import { useState, useEffect, useTransition, useCallback } from "react"; import { useSession } from "next-auth/react"; import { formatBytes } from "@/lib/format"; interface Mailbox { username: string; name: string; local_part: string; domain: string; quota: number; quota_used: number; active: string; // "1" | "0" } interface Domain { domain_name: string; } export default function MailboxesPage() { const { data: session } = useSession(); const [domains, setDomains] = useState([]); const [selectedDomain, setSelectedDomain] = useState(""); const [mailboxes, setMailboxes] = useState([]); const [loading, setLoading] = useState(false); const [showCreateModal, setShowCreateModal] = useState(false); const [showPasswordModal, setShowPasswordModal] = useState(null); const [showInfoModal, setShowInfoModal] = useState(null); const [isPending, startTransition] = useTransition(); const [search, setSearch] = useState(""); const [createForm, setCreateForm] = useState({ local_part: "", name: "", password: "", quota: 3072 }); const [newPassword, setNewPassword] = useState(""); const [formError, setFormError] = useState(""); useEffect(() => { fetch("/api/domains") .then((r) => r.json()) .then((data: Domain[]) => { if (Array.isArray(data) && data.length > 0) { setDomains(data); setSelectedDomain(data[0].domain_name); } }); }, []); const fetchMailboxes = useCallback(async (domain: string) => { if (!domain) return; setLoading(true); const res = await fetch(`/api/mailboxes?domain=${encodeURIComponent(domain)}`); const data = await res.json(); setMailboxes(Array.isArray(data) ? data : []); setLoading(false); }, []); useEffect(() => { if (selectedDomain) fetchMailboxes(selectedDomain); }, [selectedDomain, fetchMailboxes]); const handleCreate = (e: React.FormEvent) => { e.preventDefault(); setFormError(""); startTransition(async () => { const res = await fetch("/api/mailboxes", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ...createForm, domain: selectedDomain }), }); const data = await res.json(); if (res.ok) { setShowCreateModal(false); setCreateForm({ local_part: "", name: "", password: "", quota: 3072 }); fetchMailboxes(selectedDomain); } else { const msg = Array.isArray(data) ? data.map((d: { msg?: unknown }) => JSON.stringify(d.msg)).join(", ") : (data?.error ?? "Mailcow bağlantısını kontrol edin"); setFormError(String(msg)); } }); }; const handleDelete = (username: string) => { if (!confirm(`"${username}" hesabını silmek istediğinizden emin misiniz?`)) return; startTransition(async () => { await fetch(`/api/mailboxes/${encodeURIComponent(username)}`, { method: "DELETE" }); setMailboxes((prev) => prev.filter((m) => m.username !== username)); }); }; const handleToggle = (username: string, active: string) => { const newActive = String(active) === "1" ? 0 : 1; startTransition(async () => { await fetch(`/api/mailboxes/${encodeURIComponent(username)}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ active: newActive }), }); setMailboxes((prev) => prev.map((m) => m.username === username ? { ...m, active: String(newActive) } : m) ); }); }; const handlePasswordChange = (e: React.FormEvent) => { e.preventDefault(); if (!showPasswordModal) return; startTransition(async () => { await fetch(`/api/mailboxes/${encodeURIComponent(showPasswordModal)}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ password: newPassword }), }); setShowPasswordModal(null); setNewPassword(""); }); }; const filtered = mailboxes.filter( (m) => m.username.toLowerCase().includes(search.toLowerCase()) || m.name.toLowerCase().includes(search.toLowerCase()) ); const isSuperAdmin = session?.user?.role === "SUPER_ADMIN"; return ( <>

Mail Hesapları

{selectedDomain ? `${selectedDomain} — ${mailboxes.length} hesap` : "Domain seçin"}

setSearch(e.target.value)} />
{loading ? (
) : filtered.length === 0 ? (
{selectedDomain ? "Bu domainde mail hesabı yok" : "Domain seçin"}
{selectedDomain ? '"Hesap Ekle" butonuna tıklayın' : "Sol üstteki listeden domain seçin"}
) : ( {filtered.map((m) => { const usedPct = m.quota > 0 ? Math.min((m.quota_used / m.quota) * 100, 100) : 0; return ( ); })}
E-posta Ad Soyad Kota Durum İşlemler
{m.local_part[0]?.toUpperCase()}
{m.username}
{m.name}
{formatBytes(m.quota_used)} / {formatBytes(m.quota)}
80 ? "danger" : ""}`} style={{ width: `${usedPct}%` }} />
{Math.round(usedPct)}%
{String(m.active) === "1" ? "● Aktif" : "● Pasif"}
)}
{/* Create Modal */} {showCreateModal && (
e.target === e.currentTarget && setShowCreateModal(false)}>

Yeni Mail Hesabı

{formError &&
{formError}
}
setCreateForm({ ...createForm, local_part: e.target.value })} required /> @{selectedDomain}
setCreateForm({ ...createForm, name: e.target.value })} required />
setCreateForm({ ...createForm, password: e.target.value })} required />
setCreateForm({ ...createForm, quota: parseInt(e.target.value) || 3072 })} />
)} {/* Password Modal */} {showPasswordModal && (
e.target === e.currentTarget && setShowPasswordModal(null)}>

Şifre Değiştir

{showPasswordModal} için yeni şifre
setNewPassword(e.target.value)} required autoFocus />
)} {/* Info Modal */} {showInfoModal && (
e.target === e.currentTarget && setShowInfoModal(null)}>

İstemci Bağlantı Bilgileri

{showInfoModal} hesabını Apple Mail, Outlook veya telefonunuza kurmak için aşağıdaki bilgileri kullanın:
IMAP (Gelen Sunucu)
Sunucu: mail.{showInfoModal.split("@")[1]} Port: 993 (SSL/TLS)
SMTP (Giden Sunucu)
Sunucu: mail.{showInfoModal.split("@")[1]} Port: 587 (STARTTLS) veya 465 (SSL)
Kimlik Doğrulama
Kullanıcı Adı: {showInfoModal}
Şifre: Hesap oluştururken belirlediğiniz şifre
)} ); } // Icons function PlusIcon() { return ; } function SearchIcon() { return ; } function RefreshIcon() { return ; } function MailIcon({ size = 13 }: { size?: number }) { return ; } function TrashIcon() { return ; } function KeyIcon() { return ; } function PauseIcon() { return ; } function PlayIcon() { return ; } function XIcon() { return ; } function InfoIcon() { return ; }