160 lines
5.2 KiB
TypeScript
160 lines
5.2 KiB
TypeScript
import { getQuestions, getCategories, getPatterns } from "@/lib/api";
|
|
import { QuestionCard } from "@/components/questions/question-card";
|
|
import Link from "next/link";
|
|
|
|
interface SearchParams {
|
|
difficulty?: string;
|
|
category?: string;
|
|
pattern?: string;
|
|
search?: string;
|
|
page?: string;
|
|
}
|
|
|
|
export default async function QuestionsPage({
|
|
searchParams,
|
|
}: {
|
|
searchParams: Promise<SearchParams>;
|
|
}) {
|
|
const params = await searchParams;
|
|
const [questionsResponse, categoriesResponse, patternsResponse] =
|
|
await Promise.all([
|
|
getQuestions({
|
|
difficulty: params.difficulty,
|
|
category: params.category,
|
|
pattern: params.pattern,
|
|
search: params.search,
|
|
page: params.page ? parseInt(params.page) : 1,
|
|
}),
|
|
getCategories(),
|
|
getPatterns(),
|
|
]);
|
|
|
|
const difficulties = ["easy", "medium", "hard"];
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<h1 className="text-3xl font-bold">Questions</h1>
|
|
|
|
<div className="flex flex-wrap gap-4 p-4 rounded-lg bg-[var(--secondary)]">
|
|
<div className="space-y-1">
|
|
<label className="text-sm text-[var(--muted-foreground)]">
|
|
Difficulty
|
|
</label>
|
|
<div className="flex gap-2">
|
|
<Link
|
|
href="/questions"
|
|
className={`px-3 py-1 rounded text-sm ${
|
|
!params.difficulty
|
|
? "bg-[var(--primary)] text-[var(--primary-foreground)]"
|
|
: "bg-[var(--card)] hover:bg-[var(--muted)]"
|
|
}`}
|
|
>
|
|
All
|
|
</Link>
|
|
{difficulties.map((d) => (
|
|
<Link
|
|
key={d}
|
|
href={`/questions?difficulty=${d}`}
|
|
className={`px-3 py-1 rounded text-sm capitalize ${
|
|
params.difficulty === d
|
|
? "bg-[var(--primary)] text-[var(--primary-foreground)]"
|
|
: "bg-[var(--card)] hover:bg-[var(--muted)]"
|
|
}`}
|
|
>
|
|
{d}
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-1">
|
|
<label className="text-sm text-[var(--muted-foreground)]">
|
|
Category
|
|
</label>
|
|
<select
|
|
defaultValue={params.category || ""}
|
|
className="px-3 py-1 rounded text-sm bg-[var(--card)] border border-[var(--border)]"
|
|
onChange={(e) => {
|
|
const url = new URL(window.location.href);
|
|
if (e.target.value) {
|
|
url.searchParams.set("category", e.target.value);
|
|
} else {
|
|
url.searchParams.delete("category");
|
|
}
|
|
window.location.href = url.toString();
|
|
}}
|
|
>
|
|
<option value="">All Categories</option>
|
|
{categoriesResponse.items.map((cat) => (
|
|
<option key={cat.id} value={cat.slug}>
|
|
{cat.name} ({cat.question_count})
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
|
|
<div className="space-y-1">
|
|
<label className="text-sm text-[var(--muted-foreground)]">
|
|
Pattern
|
|
</label>
|
|
<select
|
|
defaultValue={params.pattern || ""}
|
|
className="px-3 py-1 rounded text-sm bg-[var(--card)] border border-[var(--border)]"
|
|
onChange={(e) => {
|
|
const url = new URL(window.location.href);
|
|
if (e.target.value) {
|
|
url.searchParams.set("pattern", e.target.value);
|
|
} else {
|
|
url.searchParams.delete("pattern");
|
|
}
|
|
window.location.href = url.toString();
|
|
}}
|
|
>
|
|
<option value="">All Patterns</option>
|
|
{patternsResponse.items.map((pat) => (
|
|
<option key={pat.id} value={pat.slug}>
|
|
{pat.name} ({pat.question_count})
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="text-sm text-[var(--muted-foreground)]">
|
|
Showing {questionsResponse.items.length} of {questionsResponse.total}{" "}
|
|
questions
|
|
</div>
|
|
|
|
<div className="grid gap-4">
|
|
{questionsResponse.items.map((question) => (
|
|
<QuestionCard key={question.id} question={question} />
|
|
))}
|
|
</div>
|
|
|
|
{questionsResponse.pages > 1 && (
|
|
<div className="flex justify-center gap-2">
|
|
{Array.from({ length: questionsResponse.pages }, (_, i) => i + 1).map(
|
|
(page) => (
|
|
<Link
|
|
key={page}
|
|
href={`/questions?page=${page}${
|
|
params.difficulty ? `&difficulty=${params.difficulty}` : ""
|
|
}${params.category ? `&category=${params.category}` : ""}${
|
|
params.pattern ? `&pattern=${params.pattern}` : ""
|
|
}`}
|
|
className={`px-3 py-1 rounded ${
|
|
page === questionsResponse.page
|
|
? "bg-[var(--primary)] text-[var(--primary-foreground)]"
|
|
: "bg-[var(--secondary)] hover:bg-[var(--muted)]"
|
|
}`}
|
|
>
|
|
{page}
|
|
</Link>
|
|
)
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|