diff --git a/api/admin/foundation/achievements.ts b/api/admin/foundation/achievements.ts index cc0e1bc1..912b08d5 100644 --- a/api/admin/foundation/achievements.ts +++ b/api/admin/foundation/achievements.ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.VITE_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE! + process.env.SUPABASE_SERVICE_ROLE!, ); export default async function handler(req: any, res: any) { @@ -18,11 +18,9 @@ export default async function handler(req: any, res: any) { res.status(200).json(achievements || []); } catch (error: any) { - res - .status(500) - .json({ - error: error.message || "Failed to fetch achievements", - }); + res.status(500).json({ + error: error.message || "Failed to fetch achievements", + }); } } else { res.status(405).json({ error: "Method not allowed" }); diff --git a/api/admin/foundation/courses.ts b/api/admin/foundation/courses.ts index cec7ce51..ff85ef33 100644 --- a/api/admin/foundation/courses.ts +++ b/api/admin/foundation/courses.ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.VITE_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE! + process.env.SUPABASE_SERVICE_ROLE!, ); export default async function handler(req: any, res: any) { @@ -26,7 +26,7 @@ export default async function handler(req: any, res: any) { id, full_name ) - ` + `, ) .order("created_at", { ascending: false }); diff --git a/api/admin/foundation/courses/[id].ts b/api/admin/foundation/courses/[id].ts index 245aaf18..300695d4 100644 --- a/api/admin/foundation/courses/[id].ts +++ b/api/admin/foundation/courses/[id].ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.VITE_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE! + process.env.SUPABASE_SERVICE_ROLE!, ); export default async function handler(req: any, res: any) { diff --git a/api/admin/foundation/mentors.ts b/api/admin/foundation/mentors.ts index 3a843c8b..90fa45d3 100644 --- a/api/admin/foundation/mentors.ts +++ b/api/admin/foundation/mentors.ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.VITE_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE! + process.env.SUPABASE_SERVICE_ROLE!, ); export default async function handler(req: any, res: any) { @@ -25,7 +25,7 @@ export default async function handler(req: any, res: any) { full_name, email ) - ` + `, ) .order("created_at", { ascending: false }); diff --git a/api/admin/foundation/mentors/[id].ts b/api/admin/foundation/mentors/[id].ts index e0fc7613..9b711a1d 100644 --- a/api/admin/foundation/mentors/[id].ts +++ b/api/admin/foundation/mentors/[id].ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.VITE_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE! + process.env.SUPABASE_SERVICE_ROLE!, ); export default async function handler(req: any, res: any) { @@ -21,7 +21,8 @@ export default async function handler(req: any, res: any) { .update({ approval_status, approved_by: req.user?.id, // Assumes middleware sets req.user - approved_at: approval_status === "approved" ? new Date().toISOString() : null, + approved_at: + approval_status === "approved" ? new Date().toISOString() : null, }) .eq("user_id", id) .select(); diff --git a/api/admin/nexus/commissions.ts b/api/admin/nexus/commissions.ts index 28f8c197..9a713148 100644 --- a/api/admin/nexus/commissions.ts +++ b/api/admin/nexus/commissions.ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.VITE_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE! + process.env.SUPABASE_SERVICE_ROLE!, ); export default async function handler(req: any, res: any) { diff --git a/api/admin/nexus/disputes.ts b/api/admin/nexus/disputes.ts index 597e1e5c..3d76d6a3 100644 --- a/api/admin/nexus/disputes.ts +++ b/api/admin/nexus/disputes.ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.VITE_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE! + process.env.SUPABASE_SERVICE_ROLE!, ); export default async function handler(req: any, res: any) { @@ -22,7 +22,7 @@ export default async function handler(req: any, res: any) { id, email ) - ` + `, ) .order("created_at", { ascending: false }); diff --git a/api/admin/nexus/disputes/[id].ts b/api/admin/nexus/disputes/[id].ts index ce968b51..c54d847e 100644 --- a/api/admin/nexus/disputes/[id].ts +++ b/api/admin/nexus/disputes/[id].ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.VITE_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE! + process.env.SUPABASE_SERVICE_ROLE!, ); export default async function handler(req: any, res: any) { diff --git a/api/admin/nexus/opportunities.ts b/api/admin/nexus/opportunities.ts index 1a73672b..d1b73604 100644 --- a/api/admin/nexus/opportunities.ts +++ b/api/admin/nexus/opportunities.ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.VITE_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE! + process.env.SUPABASE_SERVICE_ROLE!, ); export default async function handler(req: any, res: any) { @@ -25,7 +25,7 @@ export default async function handler(req: any, res: any) { id, email ) - ` + `, ) .order("created_at", { ascending: false }); @@ -46,11 +46,9 @@ export default async function handler(req: any, res: any) { res.status(200).json(formattedOpp); } catch (error: any) { - res - .status(500) - .json({ - error: error.message || "Failed to fetch opportunities", - }); + res.status(500).json({ + error: error.message || "Failed to fetch opportunities", + }); } } else { res.status(405).json({ error: "Method not allowed" }); diff --git a/api/admin/nexus/opportunities/[id].ts b/api/admin/nexus/opportunities/[id].ts index 35b43d05..dc5ff067 100644 --- a/api/admin/nexus/opportunities/[id].ts +++ b/api/admin/nexus/opportunities/[id].ts @@ -2,7 +2,7 @@ import { createClient } from "@supabase/supabase-js"; const supabase = createClient( process.env.VITE_SUPABASE_URL!, - process.env.SUPABASE_SERVICE_ROLE! + process.env.SUPABASE_SERVICE_ROLE!, ); export default async function handler(req: any, res: any) { @@ -14,7 +14,11 @@ export default async function handler(req: any, res: any) { const updateData: any = {}; if (status) { - if (!["open", "in_progress", "filled", "closed", "cancelled"].includes(status)) { + if ( + !["open", "in_progress", "filled", "closed", "cancelled"].includes( + status, + ) + ) { return res.status(400).json({ error: "Invalid status" }); } updateData.status = status; @@ -37,11 +41,9 @@ export default async function handler(req: any, res: any) { res.status(200).json(data); } catch (error: any) { - res - .status(500) - .json({ - error: error.message || "Failed to update opportunity", - }); + res.status(500).json({ + error: error.message || "Failed to update opportunity", + }); } } else { res.status(405).json({ error: "Method not allowed" }); diff --git a/api/gameforge/builds.ts b/api/gameforge/builds.ts index 004df518..01cbd3ca 100644 --- a/api/gameforge/builds.ts +++ b/api/gameforge/builds.ts @@ -11,13 +11,7 @@ export default async function handler(req: any, res: any) { try { if (method === "GET") { - const { - id, - project_id, - build_type, - limit = 50, - offset = 0, - } = query; + const { id, project_id, build_type, limit = 50, offset = 0 } = query; if (id) { // Get single build diff --git a/api/gameforge/projects.ts b/api/gameforge/projects.ts index 28e8ce4c..376ca0f1 100644 --- a/api/gameforge/projects.ts +++ b/api/gameforge/projects.ts @@ -34,10 +34,8 @@ export default async function handler(req: any, res: any) { } // List all projects with filters - let dbQuery = supabase - .from("gameforge_projects") - .select( - ` + let dbQuery = supabase.from("gameforge_projects").select( + ` id, name, description, @@ -52,8 +50,8 @@ export default async function handler(req: any, res: any) { created_at, user_profiles!lead_id(id, full_name, avatar_url) `, - { count: "exact" }, - ); + { count: "exact" }, + ); if (status) dbQuery = dbQuery.eq("status", status); if (platform) dbQuery = dbQuery.eq("platform", platform); @@ -140,9 +138,7 @@ export default async function handler(req: any, res: any) { .single(); if (project?.lead_id !== userId) { - return res - .status(403) - .json({ error: "Only project lead can update" }); + return res.status(403).json({ error: "Only project lead can update" }); } const updateData: any = {}; @@ -157,7 +153,8 @@ export default async function handler(req: any, res: any) { updateData.actual_release_date = actual_release_date; if (budget !== undefined) updateData.budget = budget; if (current_spend !== undefined) updateData.current_spend = current_spend; - if (repository_url !== undefined) updateData.repository_url = repository_url; + if (repository_url !== undefined) + updateData.repository_url = repository_url; if (documentation_url !== undefined) updateData.documentation_url = documentation_url; diff --git a/api/gameforge/team.ts b/api/gameforge/team.ts index 77a16740..4e310f3c 100644 --- a/api/gameforge/team.ts +++ b/api/gameforge/team.ts @@ -13,15 +13,13 @@ export default async function handler(req: any, res: any) { if (method === "GET") { const { user_id, project_id, role, limit = 50, offset = 0 } = query; - let dbQuery = supabase - .from("gameforge_team_members") - .select( - ` + let dbQuery = supabase.from("gameforge_team_members").select( + ` *, user_profiles(id, full_name, avatar_url, email) `, - { count: "exact" }, - ); + { count: "exact" }, + ); if (user_id) dbQuery = dbQuery.eq("user_id", user_id).single(); if (project_id) dbQuery = dbQuery.contains("project_ids", [project_id]); diff --git a/client/components/admin/AdminFoundationManager.tsx b/client/components/admin/AdminFoundationManager.tsx index 8f97f5ce..40df2c90 100644 --- a/client/components/admin/AdminFoundationManager.tsx +++ b/client/components/admin/AdminFoundationManager.tsx @@ -82,7 +82,7 @@ export default function AdminFoundationManager() { const [selectedMentor, setSelectedMentor] = useState(null); const [approvalDialogOpen, setApprovalDialogOpen] = useState(false); const [approvalAction, setApprovalAction] = useState<"approve" | "reject">( - "approve" + "approve", ); useEffect(() => { @@ -146,12 +146,12 @@ export default function AdminFoundationManager() { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ approval_status: approvalAction }), - } + }, ); if (!response.ok) throw new Error("Failed to update mentor"); aethexToast.success( - `Mentor ${approvalAction === "approve" ? "approved" : "rejected"}` + `Mentor ${approvalAction === "approve" ? "approved" : "rejected"}`, ); setApprovalDialogOpen(false); setSelectedMentor(null); @@ -164,16 +164,17 @@ export default function AdminFoundationManager() { const handlePublishCourse = async (courseId: string, publish: boolean) => { try { - const response = await fetch(`/api/admin/foundation/courses/${courseId}`, { - method: "PUT", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ is_published: publish }), - }); + const response = await fetch( + `/api/admin/foundation/courses/${courseId}`, + { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ is_published: publish }), + }, + ); if (!response.ok) throw new Error("Failed to update course"); - aethexToast.success( - `Course ${publish ? "published" : "unpublished"}` - ); + aethexToast.success(`Course ${publish ? "published" : "unpublished"}`); fetchCourses(); } catch (error) { aethexToast.error("Failed to update course"); @@ -183,9 +184,12 @@ export default function AdminFoundationManager() { const handleDeleteCourse = async (courseId: string) => { try { - const response = await fetch(`/api/admin/foundation/courses/${courseId}`, { - method: "DELETE", - }); + const response = await fetch( + `/api/admin/foundation/courses/${courseId}`, + { + method: "DELETE", + }, + ); if (!response.ok) throw new Error("Failed to delete course"); aethexToast.success("Course deleted"); @@ -197,20 +201,18 @@ export default function AdminFoundationManager() { }; const filteredMentors = mentors.filter((m) => - (m.user_name || "") - .toLowerCase() - .includes(searchMentor.toLowerCase()) + (m.user_name || "").toLowerCase().includes(searchMentor.toLowerCase()), ); const filteredCourses = courses.filter((c) => - c.title.toLowerCase().includes(searchCourse.toLowerCase()) + c.title.toLowerCase().includes(searchCourse.toLowerCase()), ); const pendingMentors = filteredMentors.filter( - (m) => m.approval_status === "pending" + (m) => m.approval_status === "pending", ); const approvedMentors = filteredMentors.filter( - (m) => m.approval_status === "approved" + (m) => m.approval_status === "approved", ); const publishedCourses = courses.filter((c) => c.is_published).length; @@ -484,7 +486,7 @@ export default function AdminFoundationManager() { onClick={() => handlePublishCourse( course.id, - !course.is_published + !course.is_published, ) } > @@ -534,10 +536,7 @@ export default function AdminFoundationManager() { {achievement.description}

- + {achievement.requirement_type} @@ -555,10 +554,15 @@ export default function AdminFoundationManager() { {/* Approval Dialog */} - + - {approvalAction === "approve" ? "Approve Mentor?" : "Reject Mentor?"} + {approvalAction === "approve" + ? "Approve Mentor?" + : "Reject Mentor?"} {approvalAction === "approve" ? ( diff --git a/client/components/admin/AdminGameForgeStudio.tsx b/client/components/admin/AdminGameForgeStudio.tsx index 74233366..b3732f9a 100644 --- a/client/components/admin/AdminGameForgeStudio.tsx +++ b/client/components/admin/AdminGameForgeStudio.tsx @@ -116,7 +116,7 @@ export default function AdminGameForgeStudio() { // Fetch builds and metrics if project selected if (selectedProject) { const buildsRes = await fetch( - `/api/gameforge/builds?project_id=${selectedProject}` + `/api/gameforge/builds?project_id=${selectedProject}`, ); if (buildsRes.ok) { const { data } = await buildsRes.json(); @@ -124,7 +124,7 @@ export default function AdminGameForgeStudio() { } const metricsRes = await fetch( - `/api/gameforge/metrics?project_id=${selectedProject}` + `/api/gameforge/metrics?project_id=${selectedProject}`, ); if (metricsRes.ok) { const { data } = await metricsRes.json(); @@ -142,8 +142,9 @@ export default function AdminGameForgeStudio() { // Calculate KPIs const totalTeamSize = teamMembers.filter((m) => m.is_active).length; - const activeProjects = projects.filter((p) => p.status === "in_development") - .length; + const activeProjects = projects.filter( + (p) => p.status === "in_development", + ).length; const totalBudget = projects.reduce((sum, p) => sum + (p.budget || 0), 0); const totalSpent = projects.reduce( (sum, p) => sum + (p.current_spend || 0), @@ -194,7 +195,9 @@ export default function AdminGameForgeStudio() { -
{activeProjects}
+
+ {activeProjects} +

in development

@@ -302,16 +305,16 @@ export default function AdminGameForgeStudio() { return (
-

- {project.name} -

+

{project.name}

{project.status}

{isOnSchedule ? "On Time" : "Delayed"} diff --git a/client/components/admin/AdminNexusManager.tsx b/client/components/admin/AdminNexusManager.tsx index 9b84fc83..1c70b150 100644 --- a/client/components/admin/AdminNexusManager.tsx +++ b/client/components/admin/AdminNexusManager.tsx @@ -79,12 +79,14 @@ export default function AdminNexusManager() { const [loadingDisputes, setLoadingDisputes] = useState(true); const [loadingCommissions, setLoadingCommissions] = useState(true); const [searchOpp, setSearchOpp] = useState(""); - const [disputeFilter, setDisputeFilter] = useState<"all" | "open" | "resolved">("all"); + 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" + "resolve", ); useEffect(() => { @@ -140,7 +142,7 @@ export default function AdminNexusManager() { const handleModerateOpportunity = async ( opportunityId: string, - status: "open" | "filled" | "closed" | "cancelled" + status: "open" | "filled" | "closed" | "cancelled", ) => { try { const response = await fetch( @@ -149,7 +151,7 @@ export default function AdminNexusManager() { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status }), - } + }, ); if (!response.ok) throw new Error("Failed to update opportunity"); @@ -163,7 +165,7 @@ export default function AdminNexusManager() { const handleFeatureOpportunity = async ( opportunityId: string, - featured: boolean + featured: boolean, ) => { try { const response = await fetch( @@ -172,12 +174,12 @@ export default function AdminNexusManager() { 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"}` + `Opportunity ${featured ? "featured" : "unfeatured"}`, ); fetchOpportunities(); } catch (error) { @@ -199,12 +201,12 @@ export default function AdminNexusManager() { 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"}` + `Dispute ${disputeAction === "resolve" ? "resolved" : "escalated"}`, ); setDisputeDialogOpen(false); setSelectedDispute(null); @@ -217,7 +219,7 @@ export default function AdminNexusManager() { }; const filteredOpportunities = opportunities.filter((o) => - o.title.toLowerCase().includes(searchOpp.toLowerCase()) + o.title.toLowerCase().includes(searchOpp.toLowerCase()), ); const filteredDisputes = disputes.filter((d) => { @@ -228,12 +230,12 @@ export default function AdminNexusManager() { }); const openOpportunities = opportunities.filter( - (o) => o.status === "open" + (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 + 0, ); return ( @@ -261,7 +263,9 @@ export default function AdminNexusManager() { -
{openDisputes}
+
+ {openDisputes} +

Requires attention

@@ -302,7 +306,10 @@ export default function AdminNexusManager() { {/* Tabs */} - + Opportunities @@ -333,7 +340,9 @@ export default function AdminNexusManager() { {loadingOpp ? ( -

Loading opportunities...

+

+ Loading opportunities... +

) : filteredOpportunities.length === 0 ? ( @@ -360,8 +369,8 @@ export default function AdminNexusManager() { opp.status === "open" ? "bg-green-50" : opp.status === "filled" - ? "bg-blue-50" - : "bg-gray-50" + ? "bg-blue-50" + : "bg-gray-50" } > {opp.status} @@ -386,7 +395,7 @@ export default function AdminNexusManager() { onClick={() => handleFeatureOpportunity( opp.id, - !opp.is_featured + !opp.is_featured, ) } > @@ -408,10 +417,7 @@ export default function AdminNexusManager() { size="sm" variant="destructive" onClick={() => - handleModerateOpportunity( - opp.id, - "cancelled" - ) + handleModerateOpportunity(opp.id, "cancelled") } > @@ -429,7 +435,10 @@ export default function AdminNexusManager() { {/* DISPUTES TAB */}
- setDisputeFilter(v)} + > @@ -458,9 +467,7 @@ export default function AdminNexusManager() { {filteredDisputes.map((dispute) => (
@@ -474,8 +481,8 @@ export default function AdminNexusManager() { dispute.status === "open" ? "bg-red-50" : dispute.status === "escalated" - ? "bg-orange-50" - : "bg-green-50" + ? "bg-orange-50" + : "bg-green-50" } > {dispute.status} @@ -536,7 +543,7 @@ export default function AdminNexusManager() {

Period

{new Date( - commission.period_start + commission.period_start, ).toLocaleDateString()}{" "} -{" "} {new Date(commission.period_end).toLocaleDateString()} @@ -566,8 +573,8 @@ export default function AdminNexusManager() { commission.status === "settled" ? "bg-green-50" : commission.status === "disputed" - ? "bg-red-50" - : "bg-yellow-50" + ? "bg-red-50" + : "bg-yellow-50" } > {commission.status} @@ -598,13 +605,18 @@ export default function AdminNexusManager() {

- setDisputeAction(v)} + > Resolve & Close - Escalate to Senior Team + + Escalate to Senior Team +