'use client'; import { useEffect, useState } from 'react'; import { useI18n } from '../../components/I18nProvider'; type PendingUser = { id: string; email: string; status: string; emailVerifiedAt: string | null; approvedAt: string | null; role: string }; type PendingListing = { id: string; status: string; createdAt: string; owner: { email: string }; translations: { title: string; slug: string; locale: string }[] }; export default function PendingAdminPage() { const { t } = useI18n(); const [pendingUsers, setPendingUsers] = useState([]); const [pendingListings, setPendingListings] = useState([]); const [message, setMessage] = useState(null); const [error, setError] = useState(null); async function loadPending() { setMessage(null); setError(null); try { const res = await fetch('/api/admin/pending', { cache: 'no-store' }); const data = await res.json(); if (!res.ok) { setError(data.error || 'Failed to load'); return; } setPendingUsers(data.users ?? []); setPendingListings(data.listings ?? []); } catch (e) { setError('Failed to load'); } } useEffect(() => { fetch('/api/auth/me', { cache: 'no-store' }) .then((res) => res.json()) .then((data) => { if (data.user?.role === 'ADMIN') { loadPending(); } else { setError(t('adminRequired')); } }) .catch(() => setError(t('adminRequired'))); }, [t]); async function approveUser(userId: string, makeAdmin: boolean) { setMessage(null); setError(null); const res = await fetch('/api/admin/users/approve', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId, makeAdmin }), }); const data = await res.json(); if (!res.ok) { setError(data.error || 'Failed to approve user'); } else { setMessage(t('userUpdated')); loadPending(); } } async function approveListing(listingId: string, action: 'approve' | 'reject' | 'remove') { setMessage(null); setError(null); const reason = action === 'reject' ? window.prompt(`${t('reject')}? (optional)`) : action === 'remove' ? window.prompt(`${t('remove')}? (optional)`) : null; const res = await fetch('/api/admin/listings/approve', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ listingId, action, reason }), }); const data = await res.json(); if (!res.ok) { setError(data.error || 'Failed to update listing'); } else { setMessage(t('approvalsMessage')); loadPending(); } } async function rejectUser(userId: string) { setMessage(null); setError(null); const reason = window.prompt(`${t('reject')}? (optional)`); const res = await fetch('/api/admin/users/reject', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId, reason }), }); const data = await res.json(); if (!res.ok) { setError(data.error || 'Failed to reject user'); } else { setMessage(t('userUpdated')); loadPending(); } } return (

{t('pendingAdminTitle')}

{t('pendingUsersTitle')}

{pendingUsers.length === 0 ? (

{t('noPendingUsers')}

) : (
    {pendingUsers.map((u) => (
  • {u.email} — {t('statusLabel')}: {u.status} — {t('verifiedLabel')}: {u.emailVerifiedAt ? t('yes') : t('no')}
  • ))}
)}

{t('pendingListingsTitle')}

{pendingListings.length === 0 ? (

{t('noPendingListings')}

) : (
    {pendingListings.map((l) => (
  • {l.translations[0]?.title ?? 'Listing'} — owner: {l.owner.email}
    {t('slugsLabel')}: {l.translations.map((t) => `${t.slug} (${t.locale})`).join(', ')}
  • ))}
)}
{message ?

{message}

: null} {error ?

{error}

: null}
); }