import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useAuth } from '@/lib/auth'; import { api } from '@/lib/api'; import { useToast } from '@/hooks/useToast'; import { Search, Plus, Pencil, Ban, Check, X, Trash2 } from 'lucide-react'; const PLAN_COLORS: Record = { STARTER: 'bg-slate-700 text-slate-300', GROWTH: 'bg-blue-900/60 text-blue-300', SCALE: 'bg-violet-900/60 text-violet-300', ENTERPRISE: 'bg-amber-900/60 text-amber-300', }; function StatusBadge({ isHardStopped, status }: { isHardStopped: boolean; status: string }) { const { t } = useTranslation(); if (isHardStopped) return {t('super_admin.status_suspended')}; if (status === 'TRIAL') return {t('super_admin.status_trial')}; return {t('super_admin.status_active')}; } export default function OrganizationsManager() { const { t } = useTranslation(); const { token } = useAuth(); const toast = useToast(); const [orgs, setOrgs] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [search, setSearch] = useState(''); const [loading, setLoading] = useState(true); const [editOrg, setEditOrg] = useState(null); const [showCreate, setShowCreate] = useState(false); const [newOrgName, setNewOrgName] = useState(''); const [saving, setSaving] = useState(false); const LIMIT = 20; async function load() { if (!token) return; setLoading(true); try { const params = new URLSearchParams({ page: String(page), limit: String(LIMIT) }); if (search) params.set('search', search); const data = await api.get(`/v1/super-admin/organizations?${params}`, token); setOrgs(data.data ?? []); setTotal(data.total ?? 0); } catch { toast.error(t('super_admin.err_load_orgs')); } finally { setLoading(false); } } useEffect(() => { load(); }, [page, token, search]); async function handleSearch(e: React.FormEvent) { e.preventDefault(); setPage(1); } async function handleSuspend(org: any) { try { await api.post(`/v1/super-admin/organizations/${org.id}/suspend`, { suspend: !org.isHardStopped }, token); toast.success(org.isHardStopped ? t('super_admin.org_reactivated') : t('super_admin.org_suspended')); load(); } catch { toast.error(t('super_admin.err_suspend')); } } async function handleDelete(org: any) { if (!confirm(t('super_admin.org_delete_confirm', { name: org.name }))) return; try { await api.delete(`/v1/super-admin/organizations/${org.id}`, token); toast.success(t('super_admin.org_deleted', { name: org.name })); load(); } catch { toast.error(t('super_admin.err_delete')); } } async function handleSaveEdit() { if (!editOrg) return; setSaving(true); try { await api.patch(`/v1/super-admin/organizations/${editOrg.id}`, { subscriptionPlan: editOrg.subscriptionPlan, aiCreditsLimit: editOrg.aiCreditsLimit, isCrmActive: editOrg.isCrmActive, isEdTechActive: editOrg.isEdTechActive, }, token); toast.success(t('super_admin.org_updated')); setEditOrg(null); load(); } catch { toast.error(t('super_admin.err_update')); } finally { setSaving(false); } } async function handleCreate() { if (!newOrgName.trim()) return; setSaving(true); try { await api.post('/v1/super-admin/organizations', { name: newOrgName }, token); toast.success(t('super_admin.org_created')); setShowCreate(false); setNewOrgName(''); load(); } catch { toast.error(t('super_admin.err_create')); } finally { setSaving(false); } } return (

{t('super_admin.orgs_title')}

{t('super_admin.orgs_total', { count: total })}

setSearch(e.target.value)} placeholder={t('super_admin.org_search_placeholder')} className="w-full pl-9 pr-4 py-2 bg-slate-900 border border-slate-700 rounded-lg text-sm text-white placeholder-slate-500 focus:outline-none focus:border-violet-500" />
{loading ? (
{t('super_admin.org_loading')}
) : orgs.length === 0 ? (
{t('super_admin.org_empty')}
) : (
{orgs.map(org => ( ))}
{t('super_admin.col_name')} {t('super_admin.col_plan')} {t('super_admin.col_status')} {t('super_admin.col_users')} {t('super_admin.col_credits')}
{org.name}
{(org.id ?? '').slice(0, 8)}…
{org.subscriptionPlan} {org.userCount} {org.walletBalance?.toLocaleString()}
)}
{total > LIMIT && (
{t('super_admin.pagination_info', { from: ((page - 1) * LIMIT) + 1, to: Math.min(page * LIMIT, total), total })}
)} {editOrg && (

{editOrg.name}

setEditOrg({ ...editOrg, aiCreditsLimit: parseInt(e.target.value) })} className="mt-1.5 w-full bg-slate-800 border border-slate-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:border-violet-500" />
{t('super_admin.label_crm_active')}
{t('super_admin.label_edtech_active')}
)} {showCreate && (

{t('super_admin.modal_new_org')}

setNewOrgName(e.target.value)} placeholder={t('super_admin.org_name_placeholder')} className="w-full bg-slate-800 border border-slate-700 rounded-lg px-3 py-2 text-sm text-white placeholder-slate-500 focus:outline-none focus:border-violet-500" />
)}
); }