'use client' import { useEffect, useState } from 'react' import { toast } from 'sonner' import { Eye, Shield } from 'lucide-react' import { Button } from '@/components/ui/button' import { resetReferenceCache } from '@/lib/reference-data' type U = { id: string; name: string | null; email: string; role: string; _count?: { bookmarks: number; pages: number; tags: number } } export function AdminClient({ currentUserId }: { currentUserId: string }) { const [users, setUsers] = useState([]) const load = () => fetch('/api/admin/users') .then((r) => (r.ok ? r.json() : [])) .then((d) => setUsers(Array.isArray(d) ? d : d?.users ?? [])) .catch((e) => console.error('Failed to load users', e)) useEffect(() => { load() }, []) const viewAs = async (userId: string) => { const res = await fetch('/api/admin/view-as', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId }) }) if (!res.ok) return toast.error('Could not switch account') // Review L-6: entering view-as changes the effective identity. resetReferenceCache() window.location.href = '/pages' } const toggleRole = async (u: U) => { const res = await fetch('/api/admin/users', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: u.id, role: u.role === 'ADMIN' ? 'USER' : 'ADMIN' }) }) if (!res.ok) return toast.error((await res.json().catch(() => null))?.error ?? 'Could not change role') load() } return (

Admin

All accounts in the group. “View as” opens an account with a visible banner; exit any time.

{users.map((u) => (

{u.name || u.email} {u.role === 'ADMIN' && }

{u.email} · {u._count?.bookmarks ?? 0} bookmarks · {u._count?.pages ?? 0} pages

))} {users.length === 0 &&

No users found.

}
) }