'use client'; import { useCallback, useEffect, useState } from 'react'; import Link from 'next/link'; import style from '@/styles/admin.module.scss'; type UserRow = { id: number; email: string; is_approved: number | boolean; is_admin: number | boolean; created_at: string; }; export function UsersAdminClient() { const [users, setUsers] = useState([]); const [error, setError] = useState(''); const [loading, setLoading] = useState(true); const load = useCallback(async () => { setError(''); const res = await fetch('/api/admin/users', { credentials: 'include' }); const data = await res.json().catch(() => ({})); if (!res.ok) { setError((data as { error?: string }).error ?? 'Failed to load'); setLoading(false); return; } setUsers((data as { users: UserRow[] }).users ?? []); setLoading(false); }, []); useEffect(() => { load(); }, [load]); async function patch(id: number, body: { is_approved?: boolean; is_admin?: boolean }) { setError(''); const res = await fetch(`/api/admin/users/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify(body), }); const data = await res.json().catch(() => ({})); if (!res.ok) { setError((data as { error?: string }).error ?? 'Update failed'); return; } await load(); } return (

← Dashboard

Users

Approve new accounts and grant admin role.

{error ?

{error}

: null} {loading ?

Loading…

: null} {!loading && ( {users.map((u) => ( ))}
Email Approved Admin Created
{u.email} patch(u.id, { is_approved: e.target.checked })} /> patch(u.id, { is_admin: e.target.checked })} /> {String(u.created_at)}
)}
); }