import React, { useEffect, useMemo, useState } from "react"; import Layout from "@/components/Layout"; import { useAuth } from "@/contexts/AuthContext"; import { useNavigate } from "react-router-dom"; import { aethexToast } from "@/lib/aethex-toast"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; function useHasStaffAccess(roles: string[]) { return useMemo( () => roles.some((r) => ["owner", "admin", "founder", "staff", "employee"].includes( r.toLowerCase(), ), ), [roles], ); } export default function Staff() { const { user, roles, loading } = useAuth(); const navigate = useNavigate(); const hasAccess = useHasStaffAccess(roles); useEffect(() => { if (loading) return; if (!user) { aethexToast.info({ title: "Sign in required", description: "Staff area requires authentication", }); navigate("/login"); return; } if (!hasAccess) { aethexToast.error({ title: "Access denied", description: "You don't have staff permissions", }); navigate("/dashboard"); } }, [user, roles, hasAccess, loading, navigate]); const [activeTab, setActiveTab] = useState("overview"); const [openReports, setOpenReports] = useState([]); const [mentorshipAll, setMentorshipAll] = useState([]); const [loadingData, setLoadingData] = useState(false); const refresh = async () => { setLoadingData(true); try { const [r1, r2] = await Promise.all([ fetch("/api/moderation/reports?status=open&limit=100"), fetch("/api/mentorship/requests/all?limit=50&status=pending"), ]); const reports = r1.ok ? await r1.json() : []; const m = r2.ok ? await r2.json() : []; setOpenReports(Array.isArray(reports) ? reports : []); setMentorshipAll(Array.isArray(m) ? m : []); } catch (e) { /* ignore */ } finally { setLoadingData(false); } }; useEffect(() => { if (user && hasAccess) refresh(); }, [user, hasAccess]); const updateReportStatus = async ( id: string, status: "resolved" | "ignored" | "open", ) => { try { const resp = await fetch( `/api/moderation/reports/${encodeURIComponent(id)}/status`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status }), }, ); if (resp.ok) { aethexToast.success({ title: "Updated", description: `Report marked ${status}`, }); refresh(); } } catch {} }; return (
Internal

Operations Command

Staff dashboards, moderation, and internal tools.

Overview Moderation Mentorship Users
Community Health Quick pulse across posts and reports
Open reports
{openReports.length}
Mentorship requests
{mentorshipAll.length}
Service Status APIs and queues
Admin API
OK
Notifications
OK
Shortcuts Common operational links
Moderation Queue Flagged content and actions {loadingData && (

Loading…

)} {!loadingData && openReports.length === 0 && (

No items in queue.

)}
{openReports.map((r) => (
{r.reason}
{r.details}
))}
Mentorship Requests Review recent mentor/mentee activity {loadingData && (

Loading…

)} {!loadingData && mentorshipAll.length === 0 && (

No requests to review.

)}
{mentorshipAll.map((req) => (
{req.mentee?.full_name || req.mentee?.username} →{" "} {req.mentor?.full_name || req.mentor?.username}
{req.message || "No message"}
{req.status}
))}
Users Search, roles, and quick actions

User tools coming soon.

); }