100 lines
3.8 KiB
TypeScript
100 lines
3.8 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import { useSuperAdmin } from '../../_lib/super-admin-context';
|
|
import { useRouter } from 'next/navigation';
|
|
import Link from 'next/link';
|
|
|
|
export default function TenantsPage() {
|
|
const { admin, loading } = useSuperAdmin();
|
|
const router = useRouter();
|
|
const [tenants, setTenants] = useState<any[]>([]);
|
|
|
|
async function load() {
|
|
const res = await fetch('/api/admin/tenants');
|
|
if (res.ok) setTenants(await res.json());
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (loading) return;
|
|
if (!admin) { router.replace('/admin/login'); return; }
|
|
void load();
|
|
}, [admin, loading, router]);
|
|
|
|
async function toggleActive(id: string, current: boolean) {
|
|
await fetch(`/api/admin/tenants/${id}`, {
|
|
method: 'PATCH',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ isActive: !current }),
|
|
});
|
|
void load();
|
|
}
|
|
|
|
async function togglePaused(id: string, current: boolean) {
|
|
await fetch(`/api/admin/tenants/${id}`, {
|
|
method: 'PATCH',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ isForwardingPaused: !current }),
|
|
});
|
|
void load();
|
|
}
|
|
|
|
if (loading) return <p className="text-gray-500">Loading...</p>;
|
|
if (!admin) return null;
|
|
|
|
return (
|
|
<div>
|
|
<h1 className="text-2xl font-bold mb-6">Tenants</h1>
|
|
<div className="bg-white rounded-xl border overflow-hidden">
|
|
<table className="w-full text-sm">
|
|
<thead className="bg-gray-50 text-left">
|
|
<tr>
|
|
<th className="px-4 py-3 font-medium">Name</th>
|
|
<th className="px-4 py-3 font-medium">Slug</th>
|
|
<th className="px-4 py-3 font-medium">Bot</th>
|
|
<th className="px-4 py-3 font-medium">Groups</th>
|
|
<th className="px-4 py-3 font-medium">Messages</th>
|
|
<th className="px-4 py-3 font-medium">Active</th>
|
|
<th className="px-4 py-3 font-medium">Paused</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y">
|
|
{tenants.map((t: any) => (
|
|
<tr key={t.id} className="hover:bg-gray-50">
|
|
<td className="px-4 py-3">
|
|
<Link href={`/admin/tenants/${t.id}`} className="text-blue-600 hover:underline font-medium">
|
|
{t.name}
|
|
</Link>
|
|
</td>
|
|
<td className="px-4 py-3 text-gray-500">{t.slug}</td>
|
|
<td className="px-4 py-3 text-xs">
|
|
{t.bot ? <span className="font-mono">{t.bot.jid?.slice(0, 20)}...</span> : <span className="text-gray-400">—</span>}
|
|
</td>
|
|
<td className="px-4 py-3">{t.stats.groups}</td>
|
|
<td className="px-4 py-3">{t.stats.messages}</td>
|
|
<td className="px-4 py-3">
|
|
<button
|
|
onClick={() => toggleActive(t.id, t.isActive)}
|
|
className={`text-xs font-medium px-2 py-1 rounded-full ${t.isActive ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'}`}
|
|
>
|
|
{t.isActive ? 'Active' : 'Inactive'}
|
|
</button>
|
|
</td>
|
|
<td className="px-4 py-3">
|
|
<button
|
|
onClick={() => togglePaused(t.id, t.isForwardingPaused)}
|
|
className={`text-xs font-medium px-2 py-1 rounded-full ${t.isForwardingPaused ? 'bg-yellow-100 text-yellow-700' : 'bg-gray-100 text-gray-500'}`}
|
|
>
|
|
{t.isForwardingPaused ? 'Paused' : 'Active'}
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
{tenants.length === 0 && <p className="p-4 text-gray-400">No tenants yet.</p>}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|