import React, { useState, useMemo } from 'react'; import { Building2, Users, MessageSquare, Plus, Search, Edit, Trash2, ChevronDown, ChevronUp, ChevronsUpDown, X } from 'lucide-react'; import { getTenants, createTenant } from '../services/dataService'; import { Tenant } from '../types'; import { DateRangePicker } from '../components/DateRangePicker'; import { KPICard } from '../components/KPICard'; export const SuperAdmin: React.FC = () => { const [dateRange, setDateRange] = useState({ start: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000), end: new Date() }); const [selectedTenantId, setSelectedTenantId] = useState('all'); const [searchQuery, setSearchQuery] = useState(''); const [tenants, setTenants] = useState([]); const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [editingTenant, setEditingTenant] = useState(null); const [sortKey, setSortKey] = useState('created_at'); const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc'); const loadTenants = async () => { setLoading(true); const data = await getTenants(); setTenants(data); setLoading(false); }; React.useEffect(() => { loadTenants(); }, []); const totalTenants = tenants.length; const totalUsersGlobal = tenants.reduce((acc, t) => acc + (t.user_count || 0), 0); const totalAttendancesGlobal = tenants.reduce((acc, t) => acc + (t.attendance_count || 0), 0); const filteredTenants = useMemo(() => { let data = tenants; if (searchQuery) { const q = searchQuery.toLowerCase(); data = data.filter(t => t.name.toLowerCase().includes(q) || t.admin_email?.toLowerCase().includes(q) || t.slug?.toLowerCase().includes(q) ); } if (selectedTenantId !== 'all') { data = data.filter(t => t.id === selectedTenantId); } return [...data].sort((a, b) => { const aVal = a[sortKey]; const bVal = b[sortKey]; if (aVal === undefined) return 1; if (bVal === undefined) return -1; if (aVal < bVal) return sortDirection === 'asc' ? -1 : 1; if (aVal > bVal) return sortDirection === 'asc' ? 1 : -1; return 0; }); }, [tenants, searchQuery, selectedTenantId, sortKey, sortDirection]); const handleSort = (key: keyof Tenant) => { if (sortKey === key) { setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc'); } else { setSortKey(key); setSortDirection('asc'); } }; const handleEdit = (tenant: Tenant) => { setEditingTenant(tenant); setIsModalOpen(true); }; const handleDelete = (id: string) => { if (confirm('Tem certeza que deseja excluir esta organização? Esta ação não pode ser desfeita.')) { setTenants(prev => prev.filter(t => t.id !== id)); } }; const handleSaveTenant = async (e: React.FormEvent) => { e.preventDefault(); const form = e.target as HTMLFormElement; const name = (form.elements.namedItem('name') as HTMLInputElement).value; const slug = (form.elements.namedItem('slug') as HTMLInputElement).value; const admin_email = (form.elements.namedItem('admin_email') as HTMLInputElement).value; const status = (form.elements.namedItem('status') as HTMLSelectElement).value; const success = await createTenant({ name, slug, admin_email, status }); if (success) { setIsModalOpen(false); setEditingTenant(null); loadTenants(); alert('Organização salva com sucesso!'); } else { alert('Erro ao salvar organização.'); } }; const SortIcon = ({ column }: { column: keyof Tenant }) => { if (sortKey !== column) return ; return sortDirection === 'asc' ? : ; }; const StatusBadge = ({ status }: { status?: string }) => { const styles = { active: 'bg-green-100 text-green-700 border-green-200 dark:bg-green-900/30 dark:text-green-400 dark:border-green-800', inactive: 'bg-zinc-100 text-zinc-700 border-zinc-200 dark:bg-dark-input dark:text-dark-muted dark:border-dark-border', trial: 'bg-purple-100 text-purple-700 border-purple-200 dark:bg-purple-900/30 dark:text-purple-400 dark:border-purple-800', }; const style = styles[status as keyof typeof styles] || styles.inactive; let label = status === 'active' ? 'Ativo' : status === 'inactive' ? 'Inativo' : status === 'trial' ? 'Teste' : 'Desconhecido'; return {label}; }; return (

Painel Super Admin

Gerencie organizações e visualize estatísticas globais.

{/* KPI Cards */}
setSearchQuery(e.target.value)} className="w-full pl-9 pr-4 py-2 bg-zinc-50 dark:bg-dark-bg border border-zinc-200 dark:border-dark-border rounded-lg text-sm text-zinc-900 dark:text-zinc-100 outline-none focus:ring-2 focus:ring-brand-yellow/20 transition-all" />
{filteredTenants.map((tenant) => ( ))}
handleSort('name')}>
Organização
Slug handleSort('status')}>
Status
handleSort('user_count')}>
Usuários
handleSort('attendance_count')}>
Atendimentos
Ações
{tenant.logo_url ? : }
{tenant.name}
{tenant.admin_email}
{tenant.slug} {tenant.user_count} {tenant.attendance_count?.toLocaleString()}
Mostrando {filteredTenants.length} de {tenants.length} organizações
{isModalOpen && (

{editingTenant ? 'Editar Organização' : 'Adicionar Nova Organização'}

)}
); };