import React, { useState, useEffect } from "react"; const API_BASE = import.meta.env.VITE_API_BASE || ""; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Briefcase, AlertTriangle, TrendingUp, XCircle, CheckCircle, Search, Eye, Flag, } from "lucide-react"; import { aethexToast } from "@/lib/aethex-toast"; interface Opportunity { id: string; title: string; category: string; budget_min?: number; budget_max?: number; status: "open" | "in_progress" | "filled" | "closed" | "cancelled"; application_count: number; posted_by_email?: string; created_at: string; is_featured: boolean; } interface Dispute { id: string; contract_id: string; reported_by_email?: string; reason: string; status: "open" | "reviewing" | "resolved" | "escalated"; created_at: string; resolution_notes?: string; } interface Commission { period_start: string; period_end: string; total_volume: number; total_commission: number; creator_payouts: number; aethex_revenue: number; status: "pending" | "settled" | "disputed"; } export default function AdminNexusManager() { const [opportunities, setOpportunities] = useState([]); const [disputes, setDisputes] = useState([]); const [commissions, setCommissions] = useState([]); const [loadingOpp, setLoadingOpp] = useState(true); const [loadingDisputes, setLoadingDisputes] = useState(true); const [loadingCommissions, setLoadingCommissions] = useState(true); const [searchOpp, setSearchOpp] = useState(""); const [disputeFilter, setDisputeFilter] = useState< "all" | "open" | "resolved" >("all"); const [selectedDispute, setSelectedDispute] = useState(null); const [disputeDialogOpen, setDisputeDialogOpen] = useState(false); const [disputeResolution, setDisputeResolution] = useState(""); const [disputeAction, setDisputeAction] = useState<"resolve" | "escalate">( "resolve", ); useEffect(() => { fetchOpportunities(); fetchDisputes(); fetchCommissions(); }, []); const fetchOpportunities = async () => { try { setLoadingOpp(true); const response = await fetch(`${API_BASE}/api/admin/nexus/opportunities`); if (!response.ok) throw new Error("Failed to fetch opportunities"); const data = await response.json(); setOpportunities(data || []); } catch (error) { aethexToast.error("Failed to load opportunities"); console.error(error); } finally { setLoadingOpp(false); } }; const fetchDisputes = async () => { try { setLoadingDisputes(true); const response = await fetch(`${API_BASE}/api/admin/nexus/disputes`); if (!response.ok) throw new Error("Failed to fetch disputes"); const data = await response.json(); setDisputes(data || []); } catch (error) { aethexToast.error("Failed to load disputes"); console.error(error); } finally { setLoadingDisputes(false); } }; const fetchCommissions = async () => { try { setLoadingCommissions(true); const response = await fetch(`${API_BASE}/api/admin/nexus/commissions`); if (!response.ok) throw new Error("Failed to fetch commissions"); const data = await response.json(); setCommissions(data || []); } catch (error) { aethexToast.error("Failed to load commissions"); console.error(error); } finally { setLoadingCommissions(false); } }; const handleModerateOpportunity = async ( opportunityId: string, status: "open" | "filled" | "closed" | "cancelled", ) => { try { const response = await fetch( `/api/admin/nexus/opportunities/${opportunityId}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status }), }, ); if (!response.ok) throw new Error("Failed to update opportunity"); aethexToast.success(`Opportunity marked as ${status}`); fetchOpportunities(); } catch (error) { aethexToast.error("Failed to update opportunity"); console.error(error); } }; const handleFeatureOpportunity = async ( opportunityId: string, featured: boolean, ) => { try { const response = await fetch( `/api/admin/nexus/opportunities/${opportunityId}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ is_featured: featured }), }, ); if (!response.ok) throw new Error("Failed to update opportunity"); aethexToast.success( `Opportunity ${featured ? "featured" : "unfeatured"}`, ); fetchOpportunities(); } catch (error) { aethexToast.error("Failed to update opportunity"); console.error(error); } }; const handleDisputeResolution = async () => { if (!selectedDispute) return; try { const response = await fetch( `/api/admin/nexus/disputes/${selectedDispute.id}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status: disputeAction === "resolve" ? "resolved" : "escalated", resolution_notes: disputeResolution, }), }, ); if (!response.ok) throw new Error("Failed to update dispute"); aethexToast.success( `Dispute ${disputeAction === "resolve" ? "resolved" : "escalated"}`, ); setDisputeDialogOpen(false); setSelectedDispute(null); setDisputeResolution(""); fetchDisputes(); } catch (error) { aethexToast.error("Failed to update dispute"); console.error(error); } }; const filteredOpportunities = opportunities.filter((o) => o.title.toLowerCase().includes(searchOpp.toLowerCase()), ); const filteredDisputes = disputes.filter((d) => { if (disputeFilter === "all") return true; if (disputeFilter === "open") return d.status === "open"; if (disputeFilter === "resolved") return d.status === "resolved"; return true; }); const openOpportunities = opportunities.filter( (o) => o.status === "open", ).length; const openDisputes = disputes.filter((d) => d.status === "open").length; const totalCommissionsRevenue = commissions.reduce( (sum, c) => sum + c.aethex_revenue, 0, ); return (
{/* Overview Cards */}
Total Opportunities
{opportunities.length}

{openOpportunities} open

Open Disputes
{openDisputes}

Requires attention

Commission Revenue
${totalCommissionsRevenue.toFixed(0)}

20% of marketplace

Ledger Periods
{commissions.length}

Commission records

{/* Tabs */} Opportunities Disputes Commissions {/* OPPORTUNITIES TAB */}
setSearchOpp(e.target.value)} className="pl-10" />
{loadingOpp ? (

Loading opportunities...

) : filteredOpportunities.length === 0 ? (

No opportunities found

) : (
{filteredOpportunities.map((opp) => (

{opp.title}

{opp.is_featured && ( Featured )} {opp.status}

Category: {opp.category} • {opp.application_count}{" "} applications

{opp.budget_min && opp.budget_max && (

${opp.budget_min} - ${opp.budget_max}

)}
{opp.status === "open" && ( <> )} {opp.status !== "cancelled" && ( )}
))}
)}
{/* DISPUTES TAB */}
{loadingDisputes ? (

Loading disputes...

) : filteredDisputes.length === 0 ? (

No disputes found

) : (
{filteredDisputes.map((dispute) => (

{dispute.reason}

{dispute.status}

Reported by: {dispute.reported_by_email}

{dispute.resolution_notes && (

Resolution: {dispute.resolution_notes}

)}
{dispute.status === "open" && ( )}
))}
)}
{/* COMMISSIONS TAB */} {loadingCommissions ? (

Loading commissions...

) : commissions.length === 0 ? (

No commission records

) : (
{commissions.map((commission, idx) => (

Period

{new Date( commission.period_start, ).toLocaleDateString()}{" "} -{" "} {new Date(commission.period_end).toLocaleDateString()}

Total Volume

${commission.total_volume.toFixed(2)}

AeThex Revenue (20%)

${commission.aethex_revenue.toFixed(2)}

Status

{commission.status}
))}
)}
{/* Dispute Resolution Dialog */} Resolve Dispute