diff --git a/src/app/leaderboards/components/LeaderboardRow.tsx b/src/app/leaderboards/components/LeaderboardRow.tsx
index 884bc1b..fde8889 100644
--- a/src/app/leaderboards/components/LeaderboardRow.tsx
+++ b/src/app/leaderboards/components/LeaderboardRow.tsx
@@ -1,25 +1,33 @@
-import { LeaderboardRank } from "@/modules/leaderboard/types";
import { LinkIcon, Trophy } from "lucide-react";
import Link from "next/link";
+interface GlobalLeaderboardUser {
+ rank: number;
+ user_id: string;
+ username: string;
+ wins: number;
+ podiums: number;
+ problems_completed: number;
+}
+
const LeaderboardRow = ({
index = 0,
run,
}: {
index?: number;
- run: LeaderboardRank;
+ run: GlobalLeaderboardUser;
}) => {
const getRankStyle = (rank: number) => {
- if (run.rank === 1) return "rank-gold";
- if (run.rank === 2) return "rank-silver";
- if (run.rank === 3) return "rank-bronze";
+ if (rank === 1) return "rank-gold";
+ if (rank === 2) return "rank-silver";
+ if (rank === 3) return "rank-bronze";
return "bg-secondary text-muted-foreground";
};
const getRankGlow = (rank: number) => {
- if (run.rank === 1) return "glow-gold";
- if (run.rank === 2) return "glow-silver";
- if (run.rank === 3) return "glow-bronze";
+ if (rank === 1) return "glow-gold";
+ if (rank === 2) return "glow-silver";
+ if (rank === 3) return "glow-bronze";
return "";
};
@@ -27,7 +35,9 @@ const LeaderboardRow = ({
return (
{isTopThree ? : run.rank}
@@ -46,41 +58,37 @@ const LeaderboardRow = ({
{run.username}
|
- {/* Time */}
-
-
- {run.pb}
-
+ {/* Wins */}
+ |
+ {run.wins}
|
- {/* Category */}
-
-
- {run.category}
-
+ {/* Podiums */}
+ |
+ {run.podiums}
|
- {/* Assisted */}
-
-
- {run.assisted ? "Assisted" : "Unassisted"}
-
+ {/* Problems Completed */}
+ |
+ {run.problems_completed}
|
- {/* Runs */}
- {run.runsCount} |
-
- {/* Problem */}
+ {/* Profile Link */}
-
- {run.problem}
+
+ View Profile
|
diff --git a/src/app/leaderboards/page.tsx b/src/app/leaderboards/page.tsx
index 8487913..51e704a 100644
--- a/src/app/leaderboards/page.tsx
+++ b/src/app/leaderboards/page.tsx
@@ -3,8 +3,7 @@
import { Trophy, Calendar, Globe, TrendingUp } from "lucide-react";
import { useState } from "react";
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
-import { Button } from "@/components/ui/button";
+import { Card } from "@/components/ui/card";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
Table,
@@ -13,7 +12,6 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
-import { Badge } from "@/components/ui/badge";
import {
Pagination,
PaginationContent,
@@ -30,11 +28,10 @@ import {
getGlobalLeaderboard,
getWeeklyLeaderboard,
} from "@/modules/leaderboard/actions";
-import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
export default function Leaderboards() {
- const [global, globalLoaded, globalError] = useAction(getGlobalLeaderboard);
- const [weekly, weeklyLoaded, weeklyError] = useAction(getWeeklyLeaderboard);
+ const [global] = useAction(getGlobalLeaderboard);
+ const [weekly] = useAction(getWeeklyLeaderboard);
const [activeTab, setActiveTab] = useState<"global" | "weekly">("global");
const data = (activeTab === "global" ? global : weekly) || [];
@@ -95,26 +92,6 @@ export default function Leaderboards() {
-
-
-
-
- any%
-
-
- 100%
-
-
-
-
-
- Assisted
-
-
- Unassisted
-
-
-
{/* Table */}
@@ -122,28 +99,38 @@ export default function Leaderboards() {
-
- Rank
+ {/* Rank */}
+
+ Rank
-
- Runner
+
+ {/* Runner / Username */}
+ Runner
+
+ {/* Wins */}
+
+ Wins
-
- Time
+
+ {/* Podiums */}
+
+ Podiums
-
- Category
+
+ {/* Problems Completed */}
+
+ Problems Completed
-
- Assisted
+
+ {/* User ID (optional) */}
+
+ User ID
- Runs
- Problem
{data.map((entry, i) => (
-
+
))}
diff --git a/src/modules/leaderboard/actions.ts b/src/modules/leaderboard/actions.ts
index c62bab4..4e395f6 100644
--- a/src/modules/leaderboard/actions.ts
+++ b/src/modules/leaderboard/actions.ts
@@ -1,194 +1,17 @@
"use server";
+import { createClient } from "@/lib/supabase/server";
import * as Core from "./core";
-import { LeaderboardRank } from "./types"; // updated interface
+import { LeaderboardUser } from "./types"; // updated interface
-export async function getGlobalLeaderboard(): Promise {
- return [
- {
- rank: 1,
- username: "speedmaster_x",
- pb: "2:34.21",
- runsCount: 2341,
- problem: "Fix broken login flow",
- category: "any%",
- assisted: false,
- },
- {
- rank: 2,
- username: "algo_ninja",
- pb: "2:38.54",
- runsCount: 1876,
- problem: "Refactor legacy API endpoints",
- category: "any%",
- assisted: false,
- },
- {
- rank: 3,
- username: "clockwork",
- pb: "2:41.02",
- runsCount: 3102,
- problem: "Optimize image upload pipeline",
- category: "any%",
- assisted: false,
- },
- {
- rank: 4,
- username: "fastfingers99",
- pb: "2:45.33",
- runsCount: 987,
- problem: "Build a mini chat server",
- category: "any%",
- assisted: false,
- },
- {
- rank: 5,
- username: "recursion_queen",
- pb: "2:47.89",
- runsCount: 1543,
- problem: "Fix CSS layout bug in dashboard",
- category: "any%",
- assisted: false,
- },
- {
- rank: 6,
- username: "bitshifter",
- pb: "2:52.11",
- runsCount: 2109,
- problem: "Implement JWT authentication",
- category: "any%",
- assisted: false,
- },
- {
- rank: 7,
- username: "nullpointer",
- pb: "2:54.67",
- runsCount: 876,
- problem: "Create REST endpoint for user data",
- category: "any%",
- assisted: false,
- },
- {
- rank: 8,
- username: "stackattack",
- pb: "2:58.23",
- runsCount: 1234,
- problem: "Fix off-by-one bug in sorting function",
- category: "any%",
- assisted: false,
- },
- {
- rank: 9,
- username: "looplegend",
- pb: "3:01.45",
- runsCount: 654,
- problem: "Optimize SQL query for reports",
- category: "any%",
- assisted: false,
- },
- {
- rank: 10,
- username: "coderunner",
- pb: "3:05.78",
- runsCount: 1098,
- problem: "Add file upload validation",
- category: "any%",
- assisted: false,
- },
- ];
+export async function getGlobalLeaderboard(): Promise {
+ const supabase = await createClient();
+
+ return await Core.getGlobalLeaderboard(supabase);
}
-export async function getWeeklyLeaderboard(): Promise {
- return [
- {
- rank: 1,
- username: "weekly_warrior",
- pb: "2:51.33",
- runsCount: 156,
- problem: "Build notifications API",
- category: "any%",
- assisted: false,
- },
- {
- rank: 2,
- username: "speedmaster_x",
- pb: "2:53.12",
- runsCount: 89,
- problem: "Build notifications API",
- category: "any%",
- assisted: false,
- },
- {
- rank: 3,
- username: "newbie_grinder",
- pb: "2:58.67",
- runsCount: 234,
- problem: "Build notifications API",
- category: "any%",
- assisted: false,
- },
- {
- rank: 4,
- username: "algo_ninja",
- pb: "3:02.45",
- runsCount: 67,
- problem: "Build notifications API",
- category: "any%",
- assisted: false,
- },
- {
- rank: 5,
- username: "fresh_runner",
- pb: "3:05.89",
- runsCount: 45,
- problem: "Build notifications API",
- category: "any%",
- assisted: false,
- },
- {
- rank: 6,
- username: "practice_makes",
- pb: "3:08.12",
- runsCount: 112,
- problem: "Build notifications API",
- category: "any%",
- assisted: false,
- },
- {
- rank: 7,
- username: "splitmaster",
- pb: "3:12.34",
- runsCount: 78,
- problem: "Build notifications API",
- category: "any%",
- assisted: false,
- },
- {
- rank: 8,
- username: "grindtime",
- pb: "3:15.56",
- runsCount: 92,
- problem: "Build notifications API",
- category: "any%",
- assisted: false,
- },
- {
- rank: 9,
- username: "pb_hunter",
- pb: "3:18.90",
- runsCount: 56,
- problem: "Build notifications API",
- category: "any%",
- assisted: false,
- },
- {
- rank: 10,
- username: "reset_king",
- pb: "3:22.11",
- runsCount: 187,
- problem: "Build notifications API",
- category: "any%",
- assisted: false,
- },
- ];
+export async function getWeeklyLeaderboard(): Promise {
+ const supabase = await createClient();
+
+ return await Core.getWeeklyLeaderboard(supabase);
}
diff --git a/src/modules/leaderboard/core.ts b/src/modules/leaderboard/core.ts
index a59f71d..d981b6c 100644
--- a/src/modules/leaderboard/core.ts
+++ b/src/modules/leaderboard/core.ts
@@ -1,3 +1,21 @@
"use server";
+import { SupabaseClient } from "@supabase/supabase-js";
import "server-only";
+import { LeaderboardUser } from "./types";
+
+export async function getGlobalLeaderboard(
+ supabase: SupabaseClient,
+): Promise {
+ const { data, error } = await supabase.rpc("get_global_leaderboard");
+ if (error) throw error;
+ return data;
+}
+
+export async function getWeeklyLeaderboard(
+ supabase: SupabaseClient,
+): Promise {
+ const { data, error } = await supabase.rpc("get_weekly_leaderboard");
+ if (error) throw error;
+ return data;
+}
diff --git a/src/modules/leaderboard/types.ts b/src/modules/leaderboard/types.ts
index 0f1cc51..c5edd3e 100644
--- a/src/modules/leaderboard/types.ts
+++ b/src/modules/leaderboard/types.ts
@@ -1,11 +1,8 @@
-export type Leaderboard = LeaderboardRank[];
-
-export interface LeaderboardRank {
+export interface LeaderboardUser {
rank: number;
+ user_id: string;
username: string;
- pb: string;
- runsCount: number;
- problem: string;
- category: "any%" | "100%";
- assisted: boolean;
+ wins: number;
+ podiums: number;
+ problems_completed: number;
}