import { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import Layout from "@/components/Layout"; import { Button } from "@/components/ui/button"; import { useAuth } from "@/contexts/AuthContext"; import { aethexToast } from "@/lib/aethex-toast"; import { supabase } from "@/lib/supabase"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import LoadingScreen from "@/components/LoadingScreen"; import { Briefcase, DollarSign, FileText, CheckCircle, AlertCircle, Clock, TrendingUp, Users, ArrowRight, Heart, Star, ExternalLink, ToggleLeft, ToggleRight, } from "lucide-react"; const API_BASE = import.meta.env.VITE_API_BASE || ""; type ViewMode = "creator" | "client"; export default function NexusDashboard() { const navigate = useNavigate(); const { user, loading: authLoading } = useAuth(); const [viewMode, setViewMode] = useState("creator"); const [activeTab, setActiveTab] = useState("overview"); const [creatorProfile, setCreatorProfile] = useState(null); const [applications, setApplications] = useState([]); const [contracts, setContracts] = useState([]); const [payoutInfo, setPayoutInfo] = useState(null); const [postedOpportunities, setPostedOpportunities] = useState([]); const [applicants, setApplicants] = useState([]); const [paymentHistory, setPaymentHistory] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { if (!authLoading && user) { loadDashboardData(); } }, [user, authLoading]); const loadDashboardData = async () => { try { setLoading(true); const { data: { session } } = await supabase.auth.getSession(); const token = session?.access_token; if (!token) throw new Error("No auth token"); // Load creator profile const profileRes = await fetch(`${API_BASE}/api/nexus/creator/profile`, { headers: { Authorization: `Bearer ${token}` }, }); if (profileRes.ok) { setCreatorProfile(await profileRes.json()); } // Load applications const appRes = await fetch(`${API_BASE}/api/nexus/creator/applications?limit=10`, { headers: { Authorization: `Bearer ${token}` }, }); if (appRes.ok) { const data = await appRes.json(); setApplications(data.applications || []); } // Load contracts const contractRes = await fetch(`${API_BASE}/api/nexus/creator/contracts?limit=10`, { headers: { Authorization: `Bearer ${token}` }, }); if (contractRes.ok) { const data = await contractRes.json(); setContracts(data.contracts || []); } // Load payout info const payoutRes = await fetch(`${API_BASE}/api/nexus/creator/payouts?limit=10`, { headers: { Authorization: `Bearer ${token}` }, }); if (payoutRes.ok) { const data = await payoutRes.json(); setPayoutInfo(data.summary); } // Load client data (posted opportunities) const oppRes = await fetch(`${API_BASE}/api/nexus/client/opportunities?limit=10`, { headers: { Authorization: `Bearer ${token}` }, }); if (oppRes.ok) { const data = await oppRes.json(); setPostedOpportunities(data.opportunities || []); } // Load applicants const appliRes = await fetch(`${API_BASE}/api/nexus/client/applicants?limit=50`, { headers: { Authorization: `Bearer ${token}` }, }); if (appliRes.ok) { const data = await appliRes.json(); setApplicants(data.applicants || []); } // Load payment history const payHistRes = await fetch(`${API_BASE}/api/nexus/client/payment-history?limit=10`, { headers: { Authorization: `Bearer ${token}` }, }); if (payHistRes.ok) { const data = await payHistRes.json(); setPaymentHistory(data.payments || []); } } catch (error: any) { aethexToast({ message: "Failed to load dashboard data", type: "error", }); } finally { setLoading(false); } }; if (authLoading || loading) { return ; } if (!user) { return (

Sign In to NEXUS

Access the marketplace and start earning

); } const isProfileComplete = creatorProfile?.verified || (creatorProfile?.headline && creatorProfile?.skills?.length > 0); const pendingApplications = applications.filter((a) => a.status === "submitted").length; const activeContracts = contracts.filter((c) => c.status === "active").length; const openOpportunities = postedOpportunities.filter((o) => o.status === "open").length; const applicantStats = { applied: applicants.filter((a) => a.status === "applied").length, interviewing: applicants.filter((a) => a.status === "interviewing").length, hired: applicants.filter((a) => a.status === "hired").length, }; return (
{/* Header with View Toggle */}

NEXUS Marketplace

{viewMode === "creator" ? "Showcase your skills and land paid opportunities" : "Hire talent and manage your team"}

{/* View Toggle */}
{/* Setup Banner (Creator View) */} {viewMode === "creator" && !isProfileComplete && (

Complete Your NEXUS Profile

Add a headline, skills, and hourly rate to attract clients and start bidding on opportunities

)}
{/* Creator View */} {viewMode === "creator" && ( <> {/* Tabs */} Overview Applications Contracts Profile {/* Overview Tab */}
{/* Stat: Total Earnings */}

Total Earnings

${(payoutInfo?.total_earnings || 0).toLocaleString('en-US', { minimumFractionDigits: 2 })}

{/* Stat: Pending Payouts */}

Pending Payouts

${(payoutInfo?.pending_payouts || 0).toLocaleString('en-US', { minimumFractionDigits: 2 })}

{/* Stat: Pending Applications */}

Pending Applications

{pendingApplications}

{/* Stat: Active Contracts */}

Active Contracts

{activeContracts}

{/* Recent Applications */} Recent Applications Your most recent bids {applications.length === 0 ? (

No applications yet. Browse opportunities to get started!

) : (
{applications.slice(0, 5).map((app: any) => (

{app.opportunity?.title}

{app.opportunity?.category}

{app.status}
))}
)}
{/* CTA Section */} {applications.length < 3 && (

Ready to Earn?

Browse thousands of opportunities from clients looking for talented creators

)}
{/* Applications Tab */} My Applications Track all your bids and applications {applications.length === 0 ? (

No applications submitted yet

) : (
{applications.map((app: any) => (

{app.opportunity?.title}

{app.opportunity?.description?.substring(0, 100)}...

{app.status}
Proposed: ${app.proposed_rate?.toLocaleString()}/hr Submitted {new Date(app.created_at).toLocaleDateString()}
))}
)}
{/* Contracts Tab */} Active Contracts Manage your ongoing work {contracts.length === 0 ? (

No active contracts

) : (
{contracts.map((contract: any) => (

{contract.title}

Total: ${contract.total_amount?.toLocaleString()}

{contract.status}
{/* Milestones */} {contract.milestones?.length > 0 && (

Progress

{contract.milestones.map((m: any) => (
{m.description} ${m.amount?.toLocaleString()}
))}
)}
))}
)}
{/* Profile Tab */} Your NEXUS Profile Your marketplace identity
{/* Verification Status */} {creatorProfile?.verified && (
Profile Verified ✓
)}

To edit your profile, go to Dashboard → Profile Settings

{/* Payout Setup */} Payout Information Manage how you receive payments

Connect your Stripe account to receive payouts for completed contracts

)} {/* Client View */} {viewMode === "client" && ( <> Overview Opportunities Applicants Contracts {/* Overview Tab */}
{/* Stat: Open Opportunities */}

Open Opportunities

{openOpportunities}

{/* Stat: Total Applicants */}

Total Applicants

{applicants.length}

{/* Stat: Active Contracts */}

Active Contracts

{contracts.filter(c => c.status === "active").length}

{/* Stat: Total Spent */}

Total Spent

${(paymentHistory.reduce((acc, p) => acc + (p.amount || 0), 0)).toLocaleString('en-US', { minimumFractionDigits: 2 })}

{/* Quick Stats */}

Reviewing

{applicantStats.applied}

Interviewing

{applicantStats.interviewing}

Hired

{applicantStats.hired}

{/* CTA Section */}

Hire Top Talent

Post opportunities and find the perfect creators for your projects

{/* Opportunities Tab */} My Posted Opportunities Manage your job postings {postedOpportunities.length === 0 ? (

No opportunities posted yet

) : (
{postedOpportunities.map((opp: any) => (

{opp.title}

{opp.description?.substring(0, 100)}...

{opp.status}
Budget: ${opp.budget?.toLocaleString()} {opp.applications_count || 0} applications
))}
)}
{/* Applicants Tab - Kanban Style */}
{/* Applied Column */} Applied ({applicantStats.applied}) {applicants.filter(a => a.status === "applied").length === 0 ? (

No applicants

) : ( applicants.filter(a => a.status === "applied").map((app: any) => (

{app.user?.name}

{app.opportunity?.title}

)) )}
{/* Interviewing Column */} Interviewing ({applicantStats.interviewing}) {applicants.filter(a => a.status === "interviewing").length === 0 ? (

No applicants

) : ( applicants.filter(a => a.status === "interviewing").map((app: any) => (

{app.user?.name}

{app.opportunity?.title}

)) )}
{/* Hired Column */} Hired ({applicantStats.hired}) {applicants.filter(a => a.status === "hired").length === 0 ? (

No applicants

) : ( applicants.filter(a => a.status === "hired").map((app: any) => (

{app.user?.name}

{app.opportunity?.title}

)) )}
{/* Contracts Tab */} My Active Contracts & Payment History Track your active work and payments {contracts.length === 0 ? (

No contracts yet

) : (
{contracts.map((contract: any) => (

{contract.title}

with {contract.creator?.name}

{contract.status}

Total Value

${contract.total_amount?.toLocaleString()}

Paid

${(contract.paid_amount || 0).toLocaleString()}

Remaining

${((contract.total_amount || 0) - (contract.paid_amount || 0)).toLocaleString()}

))}
)}
{/* Payment History */} {paymentHistory.length > 0 && ( Payment History Recent payments made
{paymentHistory.map((payment: any) => (

{payment.description}

{new Date(payment.created_at).toLocaleDateString()}

${payment.amount?.toLocaleString()}

))}
)}
)}
); }