import { useEffect, useState } from 'react'; import { Building2, Check, Edit, Plus, Power, X, } from 'lucide-react'; import toast from 'react-hot-toast'; import { tenantsApi } from '../services/api'; import type { Tenant } from '../types'; import Modal from '../components/Modal'; import ConfirmDialog from '../components/ConfirmDialog'; import SearchBar from '../components/SearchBar'; import Pagination from '../components/Pagination'; import EmptyState from '../components/EmptyState'; export default function TenantList() { const [tenants, setTenants] = useState([]); const [search, setSearch] = useState(''); const [page, setPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [loading, setLoading] = useState(true); // Modal state const [modalOpen, setModalOpen] = useState(false); const [editingTenant, setEditingTenant] = useState(null); const [formName, setFormName] = useState(''); const [formSlug, setFormSlug] = useState(''); const [formActive, setFormActive] = useState(true); const [formSaving, setFormSaving] = useState(false); // Deactivate dialog const [deactivateTarget, setDeactivateTarget] = useState(null); const [deactivating, setDeactivating] = useState(false); useEffect(() => { loadTenants(); }, [search, page]); const loadTenants = async () => { setLoading(true); try { const res = await tenantsApi.list({ page, pageSize: 20, search: search || undefined, }); setTenants(res.data); setTotalPages(res.totalPages); } catch { toast.error('Mandanten konnten nicht geladen werden'); } finally { setLoading(false); } }; const openCreate = () => { setEditingTenant(null); setFormName(''); setFormSlug(''); setFormActive(true); setModalOpen(true); }; const openEdit = (tenant: Tenant) => { setEditingTenant(tenant); setFormName(tenant.name); setFormSlug(tenant.slug); setFormActive(tenant.active); setModalOpen(true); }; const handleSave = async () => { if (!formName.trim() || !formSlug.trim()) { toast.error('Name und Slug sind erforderlich'); return; } setFormSaving(true); try { if (editingTenant) { await tenantsApi.update(editingTenant.id, { name: formName, slug: formSlug, active: formActive, }); toast.success('Mandant aktualisiert'); } else { await tenantsApi.create({ name: formName, slug: formSlug, active: formActive, }); toast.success('Mandant erstellt'); } setModalOpen(false); loadTenants(); } catch { toast.error('Speichern fehlgeschlagen'); } finally { setFormSaving(false); } }; const handleDeactivate = async () => { if (!deactivateTarget) return; setDeactivating(true); try { await tenantsApi.update(deactivateTarget.id, { active: !deactivateTarget.active, }); toast.success( deactivateTarget.active ? 'Mandant deaktiviert' : 'Mandant aktiviert' ); setDeactivateTarget(null); loadTenants(); } catch { toast.error('Aktion fehlgeschlagen'); } finally { setDeactivating(false); } }; return (
{/* Header */}

Mandanten

Verwalten Sie die Mandanten des Portals.

{/* Search */}
{ setSearch(val); setPage(1); }} placeholder="Mandanten suchen..." />
{/* Table */} {loading ? (
) : tenants.length === 0 ? ( Neuer Mandant } /> ) : (
{tenants.map((tenant) => ( ))}
Name Slug Status Aktionen
{tenant.name[0]}
{tenant.name}
{tenant.slug} {tenant.active ? ( Aktiv ) : ( Inaktiv )}
)} {totalPages > 1 && ( )} {/* Create/Edit Modal */} setModalOpen(false)} title={editingTenant ? 'Mandant bearbeiten' : 'Neuer Mandant'} >
{ setFormName(e.target.value); if (!editingTenant) { setFormSlug( e.target.value .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/(^-|-$)/g, '') ); } }} placeholder="Firmenname GmbH" className="input-field" />
setFormSlug(e.target.value)} placeholder="firmenname-gmbh" className="input-field" />
{/* Deactivate Confirm */} setDeactivateTarget(null)} onConfirm={handleDeactivate} title={ deactivateTarget?.active ? 'Mandant deaktivieren?' : 'Mandant aktivieren?' } message={ deactivateTarget?.active ? `Der Mandant "${deactivateTarget?.name}" wird deaktiviert. Benutzer des Mandanten können sich nicht mehr anmelden.` : `Der Mandant "${deactivateTarget?.name}" wird wieder aktiviert.` } confirmLabel={deactivateTarget?.active ? 'Deaktivieren' : 'Aktivieren'} variant={deactivateTarget?.active ? 'danger' : 'warning'} loading={deactivating} />
); }