'use client'; import { useCallback, useEffect, useRef, useState } from 'react'; import { useSuperAdmin } from '../../_lib/super-admin-context'; import { useRouter } from 'next/navigation'; export default function BotsPage() { const { admin, loading } = useSuperAdmin(); const router = useRouter(); const [bots, setBots] = useState([]); const [initiating, setInitiating] = useState(false); const [pairingInfo, setPairingInfo] = useState<{ pairingToken: string; expiresAt: string } | null>(null); const [qrDataUrl, setQrDataUrl] = useState(null); const [qrStatus, setQrStatus] = useState('PAIRING'); const pollRef = useRef | null>(null); async function load() { const res = await fetch('/api/admin/bots'); if (res.ok) setBots(await res.json()); } useEffect(() => { if (loading) return; if (!admin) { router.replace('/admin/login'); return; } void load(); }, [admin, loading, router]); const pollQr = useCallback(async (token: string) => { const res = await fetch(`/api/admin/bots/qr/${token}`); if (!res.ok) { clearInterval(pollRef.current!); return; } const data = await res.json(); setQrStatus(data.status); if (data.qrDataUrl) { setQrDataUrl(data.qrDataUrl); clearInterval(pollRef.current!); } if (data.status === 'ACTIVE') { clearInterval(pollRef.current!); setPairingInfo(null); void load(); } }, []); useEffect(() => { return () => { if (pollRef.current) clearInterval(pollRef.current); }; }, []); async function initiateBot() { setInitiating(true); setQrDataUrl(null); setQrStatus('PAIRING'); try { const res = await fetch('/api/admin/bots', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}), }); if (res.ok) { const data = await res.json(); setPairingInfo(data); pollRef.current = setInterval(() => void pollQr(data.pairingToken), 2000); void pollQr(data.pairingToken); } } finally { setInitiating(false); void load(); } } async function removeBot(id: string) { if (!confirm('Remove this bot? Only possible if no tenants are assigned.')) return; const res = await fetch(`/api/admin/bots/${id}`, { method: 'DELETE' }); if (res.ok) { void load(); } else { const err = await res.json(); alert(err.message ?? 'Failed to remove bot'); } } if (loading) return

Loading...

; if (!admin) return null; return (

Bot Pool

{pairingInfo && (

{qrStatus === 'ACTIVE' ? 'Bot connected!' : 'New bot created — waiting for QR scan...'}

Status: {qrStatus}

Expires: {pairingInfo.expiresAt}

{qrDataUrl ? ( QR Code ) : (
{qrStatus === 'ACTIVE' ? 'Connected' : 'Waiting for QR...'}
)}
)}
{bots.map((b: any) => ( ))}
JID Name Status Tenants Created
{b.jid?.slice(0, 30) ?? 'pending...'} {b.displayName ?? '—'} {b.status} {b.tenantCount} {new Date(b.createdAt).toLocaleDateString()}
{bots.length === 0 &&

No bots in the pool.

}
); }