"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 }[]; evChargingAvailable: boolean; evChargingOnSite: boolean; wheelchairAccessible: boolean; }; export default function PendingAdminPage() { const { t } = useI18n(); const [pendingUsers, setPendingUsers] = useState([]); const [pendingListings, setPendingListings] = useState([]); const [role, setRole] = useState(null); 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; } setRole(data.role ?? null); 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) => { setRole(data.user?.role ?? null); if (!data.user?.role) { setError(t("adminRequired")); return; } if ( ["ADMIN", "USER_MODERATOR", "LISTING_MODERATOR"].includes( data.user.role, ) ) { loadPending(); return; } 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}
    {l.evChargingOnSite ? ( {t("amenityEvOnSite")} ) : null} {l.evChargingAvailable && !l.evChargingOnSite ? ( {t("amenityEvNearby")} ) : null} {l.wheelchairAccessible ? ( {t("amenityWheelchairAccessible")} ) : null}
    {t("slugsLabel")}:{" "} {l.translations .map((t) => `${t.slug} (${t.locale})`) .join(", ")}
  • ))}
)}
{message ? (

{message}

) : null} {error ?

{error}

: null}
); }