working Problems
This commit is contained in:
@@ -1,23 +1,18 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Clock, Zap, Users } from "lucide-react";
|
||||
|
||||
interface ProblemCardProps {
|
||||
name: string;
|
||||
difficulty: "easy" | "medium" | "hard";
|
||||
tags: string[];
|
||||
bestTime?: string;
|
||||
attempts: number;
|
||||
index?: number;
|
||||
}
|
||||
import { Problem } from "@/modules/problems/types";
|
||||
import { Clock, Zap, Users, Code } from "lucide-react";
|
||||
|
||||
const ProblemCard = ({
|
||||
name,
|
||||
difficulty,
|
||||
tags,
|
||||
bestTime,
|
||||
attempts,
|
||||
problem,
|
||||
index = 0,
|
||||
}: ProblemCardProps) => {
|
||||
bestTime,
|
||||
attempts = 0,
|
||||
}: {
|
||||
problem: Problem;
|
||||
index?: number;
|
||||
bestTime?: string;
|
||||
attempts?: number;
|
||||
}) => {
|
||||
const difficultyStyles = {
|
||||
easy: "diff-easy",
|
||||
medium: "diff-medium",
|
||||
@@ -46,29 +41,30 @@ const ProblemCard = ({
|
||||
{/* Header */}
|
||||
<div className="flex items-start justify-between mb-3">
|
||||
<h3 className="font-semibold text-foreground group-hover:text-primary transition-colors">
|
||||
{name}
|
||||
{problem.title}
|
||||
</h3>
|
||||
<span
|
||||
className={`px-2 py-1 rounded-md text-xs font-medium ${difficultyStyles[difficulty]}`}
|
||||
className={`px-2 py-1 rounded-md text-xs font-medium ${
|
||||
difficultyStyles[problem.difficulty]
|
||||
}`}
|
||||
>
|
||||
{difficultyLabels[difficulty]}
|
||||
{difficultyLabels[problem.difficulty]}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Tags */}
|
||||
<div className="flex flex-wrap gap-2 mb-4">
|
||||
{tags.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="px-2 py-1 rounded-md bg-secondary text-muted-foreground text-xs"
|
||||
>
|
||||
{tag}
|
||||
{/* Tags / Meta */}
|
||||
<div className="flex flex-wrap gap-2 mb-4 text-xs text-muted-foreground">
|
||||
{problem.language && (
|
||||
<span className="px-2 py-1 rounded-md bg-secondary">
|
||||
<Code className="w-3 h-3 inline-block mr-1" /> {problem.language}
|
||||
</span>
|
||||
))}
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Spacer */}
|
||||
<div className="flex-1" />
|
||||
{/* Description */}
|
||||
<p className="text-sm text-muted-foreground flex-1">
|
||||
{problem.description}
|
||||
</p>
|
||||
|
||||
{/* Stats + Action */}
|
||||
<div className="flex items-center justify-between mt-4 text-sm text-muted-foreground">
|
||||
|
||||
@@ -14,6 +14,8 @@ import { getProblems } from "@/modules/problems/actions";
|
||||
export default function Problems() {
|
||||
const [problems, problemsLoaded, problemsError] = useAction(getProblems);
|
||||
|
||||
console.log(problems);
|
||||
|
||||
const [viewMode, setViewMode] = useState<"grid" | "list">("grid");
|
||||
|
||||
const difficulties = ["All", "Easy", "Medium", "Hard"];
|
||||
@@ -84,7 +86,7 @@ export default function Problems() {
|
||||
>
|
||||
{problems &&
|
||||
problems.map((problem, i) => (
|
||||
<ProblemCard key={problem.name} {...problem} index={i} />
|
||||
<ProblemCard key={problem.title} index={i} problem={problem} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -45,11 +45,15 @@ export default function Run() {
|
||||
|
||||
<div className="flex-1">
|
||||
<ProblemCard
|
||||
name="Idk"
|
||||
difficulty="hard"
|
||||
tags={[]}
|
||||
attempts={0}
|
||||
index={4}
|
||||
problem={{
|
||||
id: "fix-auth-callback",
|
||||
title: "Fix the Broken Auth Callback",
|
||||
description:
|
||||
"Users can log in with OAuth, but sessions aren't persisted. Fix it.",
|
||||
language: "typescript",
|
||||
difficulty: "easy",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,90 +4,5 @@ import * as Core from "./core";
|
||||
import { Problem } from "./types";
|
||||
|
||||
export async function getProblems(): Promise<Problem[]> {
|
||||
return [
|
||||
{
|
||||
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,
|
||||
},
|
||||
];
|
||||
return await Core.getProblems();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,46 @@
|
||||
"use server";
|
||||
|
||||
import "server-only";
|
||||
import { ProblemDefinition } from "./types";
|
||||
|
||||
const problems: ProblemDefinition[] = [
|
||||
{
|
||||
id: "fix-auth-callback",
|
||||
title: "Fix the Broken Auth Callback",
|
||||
description:
|
||||
"Users can log in with OAuth, but sessions aren't persisted. Fix it.",
|
||||
language: "typescript",
|
||||
difficulty: "easy",
|
||||
validate100: () => true,
|
||||
validateAny: () => true,
|
||||
},
|
||||
{
|
||||
id: "fix-prod-build",
|
||||
title: "Patch a Failing Production Build",
|
||||
description:
|
||||
"Production build fails while development works. Fix the build.",
|
||||
language: "javascript",
|
||||
difficulty: "easy",
|
||||
validate100: () => true,
|
||||
validateAny: () => true,
|
||||
},
|
||||
{
|
||||
id: "add-user-profile-endpoint",
|
||||
title: "Implement Missing API Endpoint",
|
||||
description: "The frontend expects `/api/me`. Implement it correctly.",
|
||||
language: "go",
|
||||
difficulty: "easy",
|
||||
validate100: () => true,
|
||||
validateAny: () => true,
|
||||
},
|
||||
];
|
||||
|
||||
export async function getProblems() {
|
||||
return problems.map((def) => ({
|
||||
id: def.id,
|
||||
title: def.title,
|
||||
description: def.description,
|
||||
difficulty: def.difficulty,
|
||||
language: def.language,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,24 @@
|
||||
export type ProblemValidator = (submission: any) => boolean;
|
||||
|
||||
export interface Problem {
|
||||
name: string;
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
difficulty: "easy" | "medium" | "hard";
|
||||
tags: string[];
|
||||
bestTime?: string;
|
||||
attempts: number;
|
||||
language:
|
||||
| "rust"
|
||||
| "go"
|
||||
| "java"
|
||||
| "javascript"
|
||||
| "typescript"
|
||||
| "python"
|
||||
| null;
|
||||
}
|
||||
|
||||
export interface ProblemDefinition extends Problem {
|
||||
/* Any% validator */
|
||||
validateAny: ProblemValidator;
|
||||
/* 100% validator */
|
||||
validate100: ProblemValidator;
|
||||
metadata?: Record<string, any>; // optional extra info like time limits, refs
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user