diff --git a/src/app/leaderboards/page.tsx b/src/app/leaderboards/page.tsx
index 8eada98..fd07be5 100644
--- a/src/app/leaderboards/page.tsx
+++ b/src/app/leaderboards/page.tsx
@@ -5,154 +5,301 @@ import LeaderboardRow from "@/components/app/LeaderboardRow";
import { useState } from "react";
const Leaderboards = () => {
- const [activeTab, setActiveTab] = useState<"global" | "weekly">("global");
+ const [activeTab, setActiveTab] = useState<"global" | "weekly">("global");
- const globalLeaderboard = [
- { rank: 1, username: "speedmaster_x", pb: "2:34.21", runsCount: 2341, category: "Any%" },
- { rank: 2, username: "algo_ninja", pb: "2:38.54", runsCount: 1876, category: "Any%" },
- { rank: 3, username: "clockwork", pb: "2:41.02", runsCount: 3102, category: "Any%" },
- { rank: 4, username: "fastfingers99", pb: "2:45.33", runsCount: 987, category: "Any%" },
- { rank: 5, username: "recursion_queen", pb: "2:47.89", runsCount: 1543, category: "Any%" },
- { rank: 6, username: "bitshifter", pb: "2:52.11", runsCount: 2109, category: "Any%" },
- { rank: 7, username: "nullpointer", pb: "2:54.67", runsCount: 876, category: "Any%" },
- { rank: 8, username: "stackattack", pb: "2:58.23", runsCount: 1234, category: "Any%" },
- { rank: 9, username: "looplegend", pb: "3:01.45", runsCount: 654, category: "Any%" },
- { rank: 10, username: "coderunner", pb: "3:05.78", runsCount: 1098, category: "Any%" },
- ];
+ const globalLeaderboard = [
+ {
+ rank: 1,
+ username: "speedmaster_x",
+ pb: "2:34.21",
+ runsCount: 2341,
+ category: "Any%",
+ },
+ {
+ rank: 2,
+ username: "algo_ninja",
+ pb: "2:38.54",
+ runsCount: 1876,
+ category: "Any%",
+ },
+ {
+ rank: 3,
+ username: "clockwork",
+ pb: "2:41.02",
+ runsCount: 3102,
+ category: "Any%",
+ },
+ {
+ rank: 4,
+ username: "fastfingers99",
+ pb: "2:45.33",
+ runsCount: 987,
+ category: "Any%",
+ },
+ {
+ rank: 5,
+ username: "recursion_queen",
+ pb: "2:47.89",
+ runsCount: 1543,
+ category: "Any%",
+ },
+ {
+ rank: 6,
+ username: "bitshifter",
+ pb: "2:52.11",
+ runsCount: 2109,
+ category: "Any%",
+ },
+ {
+ rank: 7,
+ username: "nullpointer",
+ pb: "2:54.67",
+ runsCount: 876,
+ category: "Any%",
+ },
+ {
+ rank: 8,
+ username: "stackattack",
+ pb: "2:58.23",
+ runsCount: 1234,
+ category: "Any%",
+ },
+ {
+ rank: 9,
+ username: "looplegend",
+ pb: "3:01.45",
+ runsCount: 654,
+ category: "Any%",
+ },
+ {
+ rank: 10,
+ username: "coderunner",
+ pb: "3:05.78",
+ runsCount: 1098,
+ category: "Any%",
+ },
+ ];
- const weeklyLeaderboard = [
- { rank: 1, username: "weekly_warrior", pb: "2:51.33", runsCount: 156, category: "Any%" },
- { rank: 2, username: "speedmaster_x", pb: "2:53.12", runsCount: 89, category: "Any%" },
- { rank: 3, username: "newbie_grinder", pb: "2:58.67", runsCount: 234, category: "Any%" },
- { rank: 4, username: "algo_ninja", pb: "3:02.45", runsCount: 67, category: "Any%" },
- { rank: 5, username: "fresh_runner", pb: "3:05.89", runsCount: 45, category: "Any%" },
- { rank: 6, username: "practice_makes", pb: "3:08.12", runsCount: 112, category: "Any%" },
- { rank: 7, username: "splitmaster", pb: "3:12.34", runsCount: 78, category: "Any%" },
- { rank: 8, username: "grindtime", pb: "3:15.56", runsCount: 92, category: "Any%" },
- { rank: 9, username: "pb_hunter", pb: "3:18.90", runsCount: 56, category: "Any%" },
- { rank: 10, username: "reset_king", pb: "3:22.11", runsCount: 187, category: "Any%" },
- ];
+ const weeklyLeaderboard = [
+ {
+ rank: 1,
+ username: "weekly_warrior",
+ pb: "2:51.33",
+ runsCount: 156,
+ category: "Any%",
+ },
+ {
+ rank: 2,
+ username: "speedmaster_x",
+ pb: "2:53.12",
+ runsCount: 89,
+ category: "Any%",
+ },
+ {
+ rank: 3,
+ username: "newbie_grinder",
+ pb: "2:58.67",
+ runsCount: 234,
+ category: "Any%",
+ },
+ {
+ rank: 4,
+ username: "algo_ninja",
+ pb: "3:02.45",
+ runsCount: 67,
+ category: "Any%",
+ },
+ {
+ rank: 5,
+ username: "fresh_runner",
+ pb: "3:05.89",
+ runsCount: 45,
+ category: "Any%",
+ },
+ {
+ rank: 6,
+ username: "practice_makes",
+ pb: "3:08.12",
+ runsCount: 112,
+ category: "Any%",
+ },
+ {
+ rank: 7,
+ username: "splitmaster",
+ pb: "3:12.34",
+ runsCount: 78,
+ category: "Any%",
+ },
+ {
+ rank: 8,
+ username: "grindtime",
+ pb: "3:15.56",
+ runsCount: 92,
+ category: "Any%",
+ },
+ {
+ rank: 9,
+ username: "pb_hunter",
+ pb: "3:18.90",
+ runsCount: 56,
+ category: "Any%",
+ },
+ {
+ rank: 10,
+ username: "reset_king",
+ pb: "3:22.11",
+ runsCount: 187,
+ category: "Any%",
+ },
+ ];
- const categories = ["Any%", "100%", "Easy Only", "No DP", "Blind"];
+ const categories = ["Any%", "100%", "Easy Only", "No DP", "Blind"];
- return (
-
-
- {/* Header */}
-
-
Leaderboards
-
The fastest runners in the game. Will you claim a spot?
-
-
- {/* Stats Row */}
-
-
-
-
12,453
-
Total Runners
-
-
-
-
2:34.21
-
World Record
-
-
-
-
847K
-
Runs This Week
-
-
-
-
5d 12h
-
Until Reset
-
-
-
- {/* Tabs and Filters */}
-
- {/* Global/Weekly Toggle */}
-
-
-
-
-
- {/* Category Filter */}
-
- {categories.map((cat, i) => (
-
- ))}
-
-
-
- {/* Leaderboard Table */}
-
-
-
-
- | Rank |
- Runner |
- PB |
- Runs |
- Category |
-
-
-
- {(activeTab === "global" ? globalLeaderboard : weeklyLeaderboard).map((entry, i) => (
-
- ))}
-
-
-
-
- {/* Pagination */}
-
-
- {[1, 2, 3, '...', 50].map((page, i) => (
-
- ))}
-
-
-
+ return (
+
+
+ {/* Header */}
+
+
+ Leaderboards
+
+
+ The fastest runners in the game. Will you claim a spot?
+
- );
+
+ {/* Stats Row */}
+
+
+
+
+ 12,453
+
+
Total Runners
+
+
+
+
+ 2:34.21
+
+
World Record
+
+
+
+
847K
+
Runs This Week
+
+
+
+
+ 5d 12h
+
+
Until Reset
+
+
+
+ {/* Tabs and Filters */}
+
+ {/* Global/Weekly Toggle */}
+
+
+
+
+
+ {/* Category Filter */}
+
+ {categories.map((cat, i) => (
+
+ ))}
+
+
+
+ {/* Leaderboard Table */}
+
+
+
+
+ |
+ Rank
+ |
+
+ Runner
+ |
+
+ PB
+ |
+
+ Runs
+ |
+
+ Category
+ |
+
+
+
+ {(activeTab === "global"
+ ? globalLeaderboard
+ : weeklyLeaderboard
+ ).map((entry, i) => (
+
+ ))}
+
+
+
+
+ {/* Pagination */}
+
+
+ {[1, 2, 3, "...", 50].map((page, i) => (
+
+ ))}
+
+
+
+
+ );
};
export default Leaderboards;
diff --git a/src/app/problems/page.tsx b/src/app/problems/page.tsx
index cb39d4b..db441a9 100644
--- a/src/app/problems/page.tsx
+++ b/src/app/problems/page.tsx
@@ -5,115 +5,200 @@ import ProblemCard from "@/components/app/ProblemCard";
import { useState } from "react";
const Problems = () => {
- const [viewMode, setViewMode] = useState<"grid" | "list">("grid");
+ const [viewMode, setViewMode] = useState<"grid" | "list">("grid");
- const problems = [
- { name: "Two Sum Dash", difficulty: "easy" as const, tags: ["arrays", "hash-map"], bestTime: "0:42", attempts: 12453 },
- { name: "Binary Sprint", difficulty: "easy" as const, tags: ["binary-search"], bestTime: "0:38", attempts: 8921 },
- { name: "Linked List Rush", difficulty: "medium" as const, tags: ["linked-list", "pointers"], bestTime: "1:24", attempts: 6234 },
- { name: "Tree Traverse Blitz", difficulty: "medium" as const, tags: ["trees", "recursion"], bestTime: "2:01", attempts: 5102 },
- { name: "DP Gauntlet", difficulty: "hard" as const, tags: ["dynamic-programming"], bestTime: "4:32", attempts: 2341 },
- { name: "Graph Navigator", difficulty: "hard" as const, tags: ["graphs", "bfs", "dfs"], bestTime: "3:45", attempts: 3456 },
- { name: "String Scramble", difficulty: "easy" as const, tags: ["strings", "manipulation"], bestTime: "0:55", attempts: 9876 },
- { name: "Stack Overflow", difficulty: "medium" as const, tags: ["stacks", "queues"], bestTime: "1:42", attempts: 4567 },
- { name: "Heap Hero", difficulty: "hard" as const, tags: ["heaps", "priority-queue"], bestTime: "3:21", attempts: 1890 },
- { name: "Sliding Window Slam", difficulty: "medium" as const, tags: ["sliding-window", "arrays"], bestTime: "1:56", attempts: 5678 },
- { name: "Trie Triumph", difficulty: "hard" as const, tags: ["trie", "strings"], bestTime: "4:12", attempts: 1234 },
- { name: "Backtrack Blaster", difficulty: "hard" as const, tags: ["backtracking", "recursion"], bestTime: "5:01", attempts: 987 },
- ];
+ const problems = [
+ {
+ name: "Two Sum Dash",
+ difficulty: "easy" as const,
+ tags: ["arrays", "hash-map"],
+ bestTime: "0:42",
+ attempts: 12453,
+ },
+ {
+ name: "Binary Sprint",
+ difficulty: "easy" as const,
+ tags: ["binary-search"],
+ bestTime: "0:38",
+ attempts: 8921,
+ },
+ {
+ name: "Linked List Rush",
+ difficulty: "medium" as const,
+ tags: ["linked-list", "pointers"],
+ bestTime: "1:24",
+ attempts: 6234,
+ },
+ {
+ name: "Tree Traverse Blitz",
+ difficulty: "medium" as const,
+ tags: ["trees", "recursion"],
+ bestTime: "2:01",
+ attempts: 5102,
+ },
+ {
+ name: "DP Gauntlet",
+ difficulty: "hard" as const,
+ tags: ["dynamic-programming"],
+ bestTime: "4:32",
+ attempts: 2341,
+ },
+ {
+ name: "Graph Navigator",
+ difficulty: "hard" as const,
+ tags: ["graphs", "bfs", "dfs"],
+ bestTime: "3:45",
+ attempts: 3456,
+ },
+ {
+ name: "String Scramble",
+ difficulty: "easy" as const,
+ tags: ["strings", "manipulation"],
+ bestTime: "0:55",
+ attempts: 9876,
+ },
+ {
+ name: "Stack Overflow",
+ difficulty: "medium" as const,
+ tags: ["stacks", "queues"],
+ bestTime: "1:42",
+ attempts: 4567,
+ },
+ {
+ name: "Heap Hero",
+ difficulty: "hard" as const,
+ tags: ["heaps", "priority-queue"],
+ bestTime: "3:21",
+ attempts: 1890,
+ },
+ {
+ name: "Sliding Window Slam",
+ difficulty: "medium" as const,
+ tags: ["sliding-window", "arrays"],
+ bestTime: "1:56",
+ attempts: 5678,
+ },
+ {
+ name: "Trie Triumph",
+ difficulty: "hard" as const,
+ tags: ["trie", "strings"],
+ bestTime: "4:12",
+ attempts: 1234,
+ },
+ {
+ name: "Backtrack Blaster",
+ difficulty: "hard" as const,
+ tags: ["backtracking", "recursion"],
+ bestTime: "5:01",
+ attempts: 987,
+ },
+ ];
- const categories = ["All", "Arrays", "Trees", "Graphs", "DP", "Strings"];
- const difficulties = ["All", "Easy", "Medium", "Hard"];
+ const categories = ["All", "Arrays", "Trees", "Graphs", "DP", "Strings"];
+ const difficulties = ["All", "Easy", "Medium", "Hard"];
- return (
-
-
- {/* Header */}
-
-
Problems
-
Choose your battleground. Each run brings you closer to your PB.
-
-
- {/* Filters */}
-
- {/* Search */}
-
-
-
-
-
- {/* Category Filter */}
-
- {categories.map((cat) => (
-
- ))}
-
-
- {/* Difficulty Filter */}
-
- {difficulties.map((diff) => (
-
- ))}
-
-
- {/* View Toggle */}
-
-
-
-
-
-
- {/* Problem Grid */}
-
- {problems.map((problem, i) => (
-
- ))}
-
-
- {/* Load More */}
-
-
-
-
+ return (
+
+
+ {/* Header */}
+
+
Problems
+
+ Choose your battleground. Each run brings you closer to your PB.
+
- );
+
+ {/* Filters */}
+
+ {/* Search */}
+
+
+
+
+
+ {/* Category Filter */}
+
+ {categories.map((cat) => (
+
+ ))}
+
+
+ {/* Difficulty Filter */}
+
+ {difficulties.map((diff) => (
+
+ ))}
+
+
+ {/* View Toggle */}
+
+
+
+
+
+
+ {/* Problem Grid */}
+
+ {problems.map((problem, i) => (
+
+ ))}
+
+
+ {/* Load More */}
+
+
+
+
+
+ );
};
export default Problems;
diff --git a/src/app/profile/page.tsx b/src/app/profile/page.tsx
index 114ac1f..3038877 100644
--- a/src/app/profile/page.tsx
+++ b/src/app/profile/page.tsx
@@ -1,190 +1,350 @@
-import { Trophy, Timer, Zap, Target, Calendar, TrendingUp, Award } from "lucide-react";
+import {
+ Trophy,
+ Timer,
+ Zap,
+ Target,
+ Calendar,
+ TrendingUp,
+ Award,
+} from "lucide-react";
import StatCard from "@/components/app/StatCard";
const Profile = () => {
- const user = {
- username: "speedmaster_x",
- joinDate: "Jan 2024",
- rank: 1,
- totalRuns: 2341,
- pb: "2:34.21",
- cleanRuns: 892,
- avgTime: "3:12.45",
- favoriteCategory: "Any%",
- };
+ const user = {
+ username: "speedmaster_x",
+ joinDate: "Jan 2024",
+ rank: 1,
+ totalRuns: 2341,
+ pb: "2:34.21",
+ cleanRuns: 892,
+ avgTime: "3:12.45",
+ favoriteCategory: "Any%",
+ };
- const recentRuns = [
- { id: 1, category: "Any%", time: "2:38.54", date: "2 hours ago", status: "clean" },
- { id: 2, category: "Any%", time: "2:45.12", date: "3 hours ago", status: "clean" },
- { id: 3, category: "Easy Only", time: "1:23.45", date: "5 hours ago", status: "clean" },
- { id: 4, category: "Any%", time: "--:--", date: "5 hours ago", status: "reset" },
- { id: 5, category: "Any%", time: "2:51.33", date: "Yesterday", status: "clean" },
- { id: 6, category: "No DP", time: "3:45.67", date: "Yesterday", status: "clean" },
- ];
+ const recentRuns = [
+ {
+ id: 1,
+ category: "Any%",
+ time: "2:38.54",
+ date: "2 hours ago",
+ status: "clean",
+ },
+ {
+ id: 2,
+ category: "Any%",
+ time: "2:45.12",
+ date: "3 hours ago",
+ status: "clean",
+ },
+ {
+ id: 3,
+ category: "Easy Only",
+ time: "1:23.45",
+ date: "5 hours ago",
+ status: "clean",
+ },
+ {
+ id: 4,
+ category: "Any%",
+ time: "--:--",
+ date: "5 hours ago",
+ status: "reset",
+ },
+ {
+ id: 5,
+ category: "Any%",
+ time: "2:51.33",
+ date: "Yesterday",
+ status: "clean",
+ },
+ {
+ id: 6,
+ category: "No DP",
+ time: "3:45.67",
+ date: "Yesterday",
+ status: "clean",
+ },
+ ];
- const achievements = [
- { name: "First Blood", description: "Complete your first run", icon: Zap, unlocked: true },
- { name: "Sub-3 Club", description: "Finish a run under 3 minutes", icon: Timer, unlocked: true },
- { name: "World Record", description: "Hold a world record", icon: Trophy, unlocked: true },
- { name: "Century", description: "Complete 100 runs", icon: Target, unlocked: true },
- { name: "Perfectionist", description: "100 clean runs", icon: Award, unlocked: false },
- { name: "Marathon", description: "10 hours of running", icon: Calendar, unlocked: true },
- ];
+ const achievements = [
+ {
+ name: "First Blood",
+ description: "Complete your first run",
+ icon: Zap,
+ unlocked: true,
+ },
+ {
+ name: "Sub-3 Club",
+ description: "Finish a run under 3 minutes",
+ icon: Timer,
+ unlocked: true,
+ },
+ {
+ name: "World Record",
+ description: "Hold a world record",
+ icon: Trophy,
+ unlocked: true,
+ },
+ {
+ name: "Century",
+ description: "Complete 100 runs",
+ icon: Target,
+ unlocked: true,
+ },
+ {
+ name: "Perfectionist",
+ description: "100 clean runs",
+ icon: Award,
+ unlocked: false,
+ },
+ {
+ name: "Marathon",
+ description: "10 hours of running",
+ icon: Calendar,
+ unlocked: true,
+ },
+ ];
- return (
-
-
- {/* Profile Header */}
-
- {/* Background gradient */}
-
+ return (
+
+
+ {/* Profile Header */}
+
+ {/* Background gradient */}
+
-
- {/* Avatar */}
-
-
- {user.username.charAt(0).toUpperCase()}
-
-
- #1
-
-
-
- {/* User Info */}
-
-
{user.username}
-
Runner since {user.joinDate}
-
-
- World Record Holder
-
-
- {user.favoriteCategory} Main
-
-
-
-
- {/* Quick Stats */}
-
-
{user.pb}
-
Personal Best
-
-
-
-
- {/* Stats Grid */}
-
-
-
-
-
-
-
-
- {/* Recent Runs */}
-
-
-
-
Recent Runs
-
-
-
-
- {recentRuns.map((run, i) => (
-
-
-
-
-
{run.category}
-
{run.date}
-
-
-
-
- {run.time}
-
-
{run.status}
-
-
- ))}
-
-
-
-
- {/* Achievements */}
-
-
-
-
Achievements
- 5/6
-
-
-
- {achievements.map((achievement, i) => (
-
-
-
-
- {achievement.name}
-
-
{achievement.description}
-
- {achievement.unlocked && (
-
- )}
-
- ))}
-
-
-
- {/* PB History */}
-
-
PB History
-
-
- 2:34.21
- Today
-
-
- 2:38.54
- 3 days ago
-
-
- 2:45.12
- 1 week ago
-
-
- 2:52.33
- 2 weeks ago
-
-
-
-
-
+
+ {/* Avatar */}
+
+
+ {user.username.charAt(0).toUpperCase()}
+
+
+ #1
+
+
+ {/* User Info */}
+
+
+ {user.username}
+
+
+ Runner since {user.joinDate}
+
+
+
+ World Record Holder
+
+
+ {user.favoriteCategory} Main
+
+
+
+
+ {/* Quick Stats */}
+
+
+ {user.pb}
+
+
Personal Best
+
+
- );
+
+ {/* Stats Grid */}
+
+
+
+
+
+
+
+
+ {/* Recent Runs */}
+
+
+
+
+ Recent Runs
+
+
+
+
+
+ {recentRuns.map((run, i) => (
+
+
+
+
+
+ {run.category}
+
+
+ {run.date}
+
+
+
+
+
+ {run.time}
+
+
+ {run.status}
+
+
+
+ ))}
+
+
+
+
+ {/* Achievements */}
+
+
+
+
+ Achievements
+
+ 5/6
+
+
+
+ {achievements.map((achievement, i) => (
+
+
+
+
+ {achievement.name}
+
+
+ {achievement.description}
+
+
+ {achievement.unlocked && (
+
+ )}
+
+ ))}
+
+
+
+ {/* PB History */}
+
+
+ PB History
+
+
+
+ 2:34.21
+ Today
+
+
+ 2:38.54
+
+ 3 days ago
+
+
+
+ 2:45.12
+
+ 1 week ago
+
+
+
+ 2:52.33
+
+ 2 weeks ago
+
+
+
+
+
+
+
+
+ );
};
export default Profile;
diff --git a/src/app/run/page.tsx b/src/app/run/page.tsx
index d17a98a..c78f88d 100644
--- a/src/app/run/page.tsx
+++ b/src/app/run/page.tsx
@@ -3,166 +3,233 @@ import SplitRow from "@/components/app/SplitRow";
import { Button } from "@/components/ui/button";
const Run = () => {
- const splits = [
- { problemName: "Two Sum Dash", splitTime: "0:38", delta: "-0:04", isCompleted: true, pbTime: "0:42" },
- { problemName: "Binary Sprint", splitTime: "1:12", delta: "+0:02", isCompleted: true, pbTime: "0:32" },
- { problemName: "String Scramble", splitTime: "--:--", delta: undefined, isCompleted: false, isCurrent: true, pbTime: "0:55" },
- { problemName: "Linked List Rush", splitTime: "--:--", delta: undefined, isCompleted: false, pbTime: "1:24" },
- { problemName: "Stack Overflow", splitTime: "--:--", delta: undefined, isCompleted: false, pbTime: "1:42" },
- ];
+ const splits = [
+ {
+ problemName: "Two Sum Dash",
+ splitTime: "0:38",
+ delta: "-0:04",
+ isCompleted: true,
+ pbTime: "0:42",
+ },
+ {
+ problemName: "Binary Sprint",
+ splitTime: "1:12",
+ delta: "+0:02",
+ isCompleted: true,
+ pbTime: "0:32",
+ },
+ {
+ problemName: "String Scramble",
+ splitTime: "--:--",
+ delta: undefined,
+ isCompleted: false,
+ isCurrent: true,
+ pbTime: "0:55",
+ },
+ {
+ problemName: "Linked List Rush",
+ splitTime: "--:--",
+ delta: undefined,
+ isCompleted: false,
+ pbTime: "1:24",
+ },
+ {
+ problemName: "Stack Overflow",
+ splitTime: "--:--",
+ delta: undefined,
+ isCompleted: false,
+ pbTime: "1:42",
+ },
+ ];
- const runInfo = {
- category: "Any% Easy",
- problems: 5,
- pbTime: "4:35",
- worldRecord: "3:58",
- currentAttempt: 47,
- };
+ const runInfo = {
+ category: "Any% Easy",
+ problems: 5,
+ pbTime: "4:35",
+ worldRecord: "3:58",
+ currentAttempt: 47,
+ };
- return (
-
-
-
- {/* Main Timer Area */}
-
- {/* Category Header */}
-
-
-
- Category
-
- {runInfo.category}
-
-
Current Run
-
-
-
Attempt #{runInfo.currentAttempt}
-
WR: {runInfo.worldRecord}
-
-
-
- {/* Timer Display */}
-
- {/* Background glow */}
-
-
-
- {/* Timer */}
-
-
1:52.34
-
- PB: {runInfo.pbTime} | Diff: +0:12
-
-
-
- {/* Progress bar */}
-
-
- {/* Controls */}
-
-
-
-
-
-
-
-
- {/* Current Problem */}
-
-
-
-
Problem 3 of 5
-
String Scramble
-
-
Easy
-
-
-
- strings
- manipulation
-
-
-
- PB Split: 0:55
- |
- Best: 0:38
-
-
-
-
-
-
- {/* Splits Sidebar */}
-
-
-
-
Splits
- 2/5 Complete
-
-
-
- {splits.map((split) => (
-
- ))}
-
-
- {/* Sum of Best */}
-
-
- Sum of Best
- 3:51
-
-
- Personal Best
- {runInfo.pbTime}
-
-
-
-
- {/* Quick Stats */}
-
-
Session Stats
-
-
- Runs Today
- 12
-
-
- Clean Runs
- 3
-
-
- Resets
- 9
-
-
- Time Played
- 1:42:31
-
-
-
-
+ return (
+
+
+
+ {/* Main Timer Area */}
+
+ {/* Category Header */}
+
+
+
+ Category
+
+ {runInfo.category}
+
+ Current Run
+
+
+
+
+ Attempt #{runInfo.currentAttempt}
+
+
+ WR:{" "}
+
+ {runInfo.worldRecord}
+
+
+
+
+ {/* Timer Display */}
+
+ {/* Background glow */}
+
+
+
+ {/* Timer */}
+
+
1:52.34
+
+ PB: {runInfo.pbTime} | Diff:{" "}
+ +0:12
+
+
+
+ {/* Progress bar */}
+
+
+ {/* Controls */}
+
+
+
+
+
+
+
+
+ {/* Current Problem */}
+
+
+
+
+ Problem 3 of 5
+
+
+ String Scramble
+
+
+
+ Easy
+
+
+
+
+
+ strings
+
+
+ manipulation
+
+
+
+
+
+ PB Split: 0:55
+
+ |
+
+ Best: 0:38
+
+
+
+
+
+
+
+ {/* Splits Sidebar */}
+
+
+
+
Splits
+
+ 2/5 Complete
+
+
+
+
+ {splits.map((split) => (
+
+ ))}
+
+
+ {/* Sum of Best */}
+
+
+ Sum of Best
+ 3:51
+
+
+ Personal Best
+
+ {runInfo.pbTime}
+
+
+
+
+
+ {/* Quick Stats */}
+
+
+ Session Stats
+
+
+
+
+ Runs Today
+
+ 12
+
+
+
+ Clean Runs
+
+ 3
+
+
+ Resets
+ 9
+
+
+
+ Time Played
+
+ 1:42:31
+
+
+
+
- );
+
+
+ );
};
export default Run;
diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx
deleted file mode 100644
index 1e7878c..0000000
--- a/src/components/ui/accordion.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import * as React from "react";
-import * as AccordionPrimitive from "@radix-ui/react-accordion";
-import { ChevronDown } from "lucide-react";
-
-import { cn } from "@/lib/utils";
-
-const Accordion = AccordionPrimitive.Root;
-
-const AccordionItem = React.forwardRef<
- React.ElementRef
,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-AccordionItem.displayName = "AccordionItem";
-
-const AccordionTrigger = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
- svg]:rotate-180",
- className,
- )}
- {...props}
- >
- {children}
-
-
-
-));
-AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
-
-const AccordionContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
- {children}
-
-));
-
-AccordionContent.displayName = AccordionPrimitive.Content.displayName;
-
-export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
diff --git a/src/components/ui/alert-dialog.tsx b/src/components/ui/alert-dialog.tsx
deleted file mode 100644
index 6dfbfb4..0000000
--- a/src/components/ui/alert-dialog.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import * as React from "react";
-import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
-
-import { cn } from "@/lib/utils";
-import { buttonVariants } from "@/components/ui/button";
-
-const AlertDialog = AlertDialogPrimitive.Root;
-
-const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
-
-const AlertDialogPortal = AlertDialogPrimitive.Portal;
-
-const AlertDialogOverlay = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
-
-const AlertDialogContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-
-
-
-));
-AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
-
-const AlertDialogHeader = ({ className, ...props }: React.HTMLAttributes) => (
-
-);
-AlertDialogHeader.displayName = "AlertDialogHeader";
-
-const AlertDialogFooter = ({ className, ...props }: React.HTMLAttributes) => (
-
-);
-AlertDialogFooter.displayName = "AlertDialogFooter";
-
-const AlertDialogTitle = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
-
-const AlertDialogDescription = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
-
-const AlertDialogAction = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
-
-const AlertDialogCancel = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
-
-export {
- AlertDialog,
- AlertDialogPortal,
- AlertDialogOverlay,
- AlertDialogTrigger,
- AlertDialogContent,
- AlertDialogHeader,
- AlertDialogFooter,
- AlertDialogTitle,
- AlertDialogDescription,
- AlertDialogAction,
- AlertDialogCancel,
-};
diff --git a/src/components/ui/alert.tsx b/src/components/ui/alert.tsx
deleted file mode 100644
index 2efc3c8..0000000
--- a/src/components/ui/alert.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import * as React from "react";
-import { cva, type VariantProps } from "class-variance-authority";
-
-import { cn } from "@/lib/utils";
-
-const alertVariants = cva(
- "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
- {
- variants: {
- variant: {
- default: "bg-background text-foreground",
- destructive: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- },
-);
-
-const Alert = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes & VariantProps
->(({ className, variant, ...props }, ref) => (
-
-));
-Alert.displayName = "Alert";
-
-const AlertTitle = React.forwardRef>(
- ({ className, ...props }, ref) => (
-
- ),
-);
-AlertTitle.displayName = "AlertTitle";
-
-const AlertDescription = React.forwardRef>(
- ({ className, ...props }, ref) => (
-
- ),
-);
-AlertDescription.displayName = "AlertDescription";
-
-export { Alert, AlertTitle, AlertDescription };
diff --git a/src/components/ui/aspect-ratio.tsx b/src/components/ui/aspect-ratio.tsx
deleted file mode 100644
index c9e6f4b..0000000
--- a/src/components/ui/aspect-ratio.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
-
-const AspectRatio = AspectRatioPrimitive.Root;
-
-export { AspectRatio };
diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx
deleted file mode 100644
index 68d21bb..0000000
--- a/src/components/ui/avatar.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import * as React from "react";
-import * as AvatarPrimitive from "@radix-ui/react-avatar";
-
-import { cn } from "@/lib/utils";
-
-const Avatar = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-Avatar.displayName = AvatarPrimitive.Root.displayName;
-
-const AvatarImage = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-AvatarImage.displayName = AvatarPrimitive.Image.displayName;
-
-const AvatarFallback = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
-
-export { Avatar, AvatarImage, AvatarFallback };
diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx
deleted file mode 100644
index 0853c44..0000000
--- a/src/components/ui/badge.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as React from "react";
-import { cva, type VariantProps } from "class-variance-authority";
-
-import { cn } from "@/lib/utils";
-
-const badgeVariants = cva(
- "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
- {
- variants: {
- variant: {
- default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
- secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
- destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
- outline: "text-foreground",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- },
-);
-
-export interface BadgeProps extends React.HTMLAttributes, VariantProps {}
-
-function Badge({ className, variant, ...props }: BadgeProps) {
- return ;
-}
-
-export { Badge, badgeVariants };
diff --git a/src/components/ui/breadcrumb.tsx b/src/components/ui/breadcrumb.tsx
deleted file mode 100644
index ca91ff5..0000000
--- a/src/components/ui/breadcrumb.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import * as React from "react";
-import { Slot } from "@radix-ui/react-slot";
-import { ChevronRight, MoreHorizontal } from "lucide-react";
-
-import { cn } from "@/lib/utils";
-
-const Breadcrumb = React.forwardRef<
- HTMLElement,
- React.ComponentPropsWithoutRef<"nav"> & {
- separator?: React.ReactNode;
- }
->(({ ...props }, ref) => );
-Breadcrumb.displayName = "Breadcrumb";
-
-const BreadcrumbList = React.forwardRef>(
- ({ className, ...props }, ref) => (
-
- ),
-);
-BreadcrumbList.displayName = "BreadcrumbList";
-
-const BreadcrumbItem = React.forwardRef>(
- ({ className, ...props }, ref) => (
-
- ),
-);
-BreadcrumbItem.displayName = "BreadcrumbItem";
-
-const BreadcrumbLink = React.forwardRef<
- HTMLAnchorElement,
- React.ComponentPropsWithoutRef<"a"> & {
- asChild?: boolean;
- }
->(({ asChild, className, ...props }, ref) => {
- const Comp = asChild ? Slot : "a";
-
- return ;
-});
-BreadcrumbLink.displayName = "BreadcrumbLink";
-
-const BreadcrumbPage = React.forwardRef>(
- ({ className, ...props }, ref) => (
-
- ),
-);
-BreadcrumbPage.displayName = "BreadcrumbPage";
-
-const BreadcrumbSeparator = ({ children, className, ...props }: React.ComponentProps<"li">) => (
- svg]:size-3.5", className)} {...props}>
- {children ?? }
-
-);
-BreadcrumbSeparator.displayName = "BreadcrumbSeparator";
-
-const BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<"span">) => (
-
-
- More
-
-);
-BreadcrumbEllipsis.displayName = "BreadcrumbElipssis";
-
-export {
- Breadcrumb,
- BreadcrumbList,
- BreadcrumbItem,
- BreadcrumbLink,
- BreadcrumbPage,
- BreadcrumbSeparator,
- BreadcrumbEllipsis,
-};
diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx
deleted file mode 100644
index 9fb18ca..0000000
--- a/src/components/ui/calendar.tsx
+++ /dev/null
@@ -1,220 +0,0 @@
-"use client"
-
-import * as React from "react"
-import {
- ChevronDownIcon,
- ChevronLeftIcon,
- ChevronRightIcon,
-} from "lucide-react"
-import {
- DayPicker,
- getDefaultClassNames,
- type DayButton,
-} from "react-day-picker"
-
-import { cn } from "@/lib/utils"
-import { Button, buttonVariants } from "@/components/ui/button"
-
-function Calendar({
- className,
- classNames,
- showOutsideDays = true,
- captionLayout = "label",
- buttonVariant = "ghost",
- formatters,
- components,
- ...props
-}: React.ComponentProps & {
- buttonVariant?: React.ComponentProps["variant"]
-}) {
- const defaultClassNames = getDefaultClassNames()
-
- return (
- svg]:rotate-180`,
- String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
- className
- )}
- captionLayout={captionLayout}
- formatters={{
- formatMonthDropdown: (date) =>
- date.toLocaleString("default", { month: "short" }),
- ...formatters,
- }}
- classNames={{
- root: cn("w-fit", defaultClassNames.root),
- months: cn(
- "flex gap-4 flex-col md:flex-row relative",
- defaultClassNames.months
- ),
- month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
- nav: cn(
- "flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
- defaultClassNames.nav
- ),
- button_previous: cn(
- buttonVariants({ variant: buttonVariant }),
- "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
- defaultClassNames.button_previous
- ),
- button_next: cn(
- buttonVariants({ variant: buttonVariant }),
- "size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
- defaultClassNames.button_next
- ),
- month_caption: cn(
- "flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
- defaultClassNames.month_caption
- ),
- dropdowns: cn(
- "w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
- defaultClassNames.dropdowns
- ),
- dropdown_root: cn(
- "relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
- defaultClassNames.dropdown_root
- ),
- dropdown: cn(
- "absolute bg-popover inset-0 opacity-0",
- defaultClassNames.dropdown
- ),
- caption_label: cn(
- "select-none font-medium",
- captionLayout === "label"
- ? "text-sm"
- : "rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5",
- defaultClassNames.caption_label
- ),
- table: "w-full border-collapse",
- weekdays: cn("flex", defaultClassNames.weekdays),
- weekday: cn(
- "text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none",
- defaultClassNames.weekday
- ),
- week: cn("flex w-full mt-2", defaultClassNames.week),
- week_number_header: cn(
- "select-none w-(--cell-size)",
- defaultClassNames.week_number_header
- ),
- week_number: cn(
- "text-[0.8rem] select-none text-muted-foreground",
- defaultClassNames.week_number
- ),
- day: cn(
- "relative w-full h-full p-0 text-center [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none",
- props.showWeekNumber
- ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md"
- : "[&:first-child[data-selected=true]_button]:rounded-l-md",
- defaultClassNames.day
- ),
- range_start: cn(
- "rounded-l-md bg-accent",
- defaultClassNames.range_start
- ),
- range_middle: cn("rounded-none", defaultClassNames.range_middle),
- range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
- today: cn(
- "bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
- defaultClassNames.today
- ),
- outside: cn(
- "text-muted-foreground aria-selected:text-muted-foreground",
- defaultClassNames.outside
- ),
- disabled: cn(
- "text-muted-foreground opacity-50",
- defaultClassNames.disabled
- ),
- hidden: cn("invisible", defaultClassNames.hidden),
- ...classNames,
- }}
- components={{
- Root: ({ className, rootRef, ...props }) => {
- return (
-
- )
- },
- Chevron: ({ className, orientation, ...props }) => {
- if (orientation === "left") {
- return (
-
- )
- }
-
- if (orientation === "right") {
- return (
-
- )
- }
-
- return (
-
- )
- },
- DayButton: CalendarDayButton,
- WeekNumber: ({ children, ...props }) => {
- return (
-
-
- {children}
-
- |
- )
- },
- ...components,
- }}
- {...props}
- />
- )
-}
-
-function CalendarDayButton({
- className,
- day,
- modifiers,
- ...props
-}: React.ComponentProps) {
- const defaultClassNames = getDefaultClassNames()
-
- const ref = React.useRef(null)
- React.useEffect(() => {
- if (modifiers.focused) ref.current?.focus()
- }, [modifiers.focused])
-
- return (
-