feat(problemset): add status icons for problem set page, support completed and attempted states

This commit is contained in:
cfngc4594 2025-04-14 17:35:31 +08:00
parent 0694e4dea0
commit c540a04c36

View File

@ -9,38 +9,28 @@ import {
} from "@/components/ui/table"; } from "@/components/ui/table";
import prisma from "@/lib/prisma"; import prisma from "@/lib/prisma";
import { auth } from "@/lib/auth"; import { auth } from "@/lib/auth";
import { CircleCheckBigIcon } from "lucide-react";
import { getDifficultyColorClass } from "@/lib/utils"; import { getDifficultyColorClass } from "@/lib/utils";
import { CircleCheckBigIcon, CircleDotIcon } from "lucide-react";
export default async function ProblemsetPage() { export default async function ProblemsetPage() {
const problems = await prisma.problem.findMany({ const problems = await prisma.problem.findMany({
where: { published: true }, where: { published: true },
orderBy: { orderBy: { id: "asc" },
id: "asc", select: { id: true, title: true, difficulty: true },
},
select: {
id: true,
title: true,
difficulty: true,
},
}); });
const session = await auth(); const session = await auth();
const userId = session?.user?.id;
let completedProblems: string[] = []; const submissions = userId
if (session?.user) { ? await prisma.submission.findMany({
const submissions = await prisma.submission.findMany({ where: { userId },
where: { select: { problemId: true, status: true },
userId: session.user.id, })
status: "AC", : [];
},
select: {
problemId: true,
},
});
completedProblems = submissions.map(sub => sub.problemId); const completedProblems = new Set(submissions.filter(s => s.status === "AC").map(s => s.problemId));
} const attemptedProblems = new Set(submissions.filter(s => s.status !== "AC").map(s => s.problemId));
return ( return (
<Table> <Table>
@ -51,7 +41,6 @@ export default async function ProblemsetPage() {
<TableHead className="w-1/3">Difficulty</TableHead> <TableHead className="w-1/3">Difficulty</TableHead>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<tbody aria-hidden="true" className="table-row h-2"></tbody>
<TableBody className="[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg"> <TableBody className="[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg">
{problems.map((problem, index) => ( {problems.map((problem, index) => (
<TableRow <TableRow
@ -59,19 +48,14 @@ export default async function ProblemsetPage() {
className="h-10 border-b-0 odd:bg-muted/50 hover:text-blue-500 hover:bg-muted" className="h-10 border-b-0 odd:bg-muted/50 hover:text-blue-500 hover:bg-muted"
> >
<TableCell className="py-2.5"> <TableCell className="py-2.5">
{session?.user && completedProblems.includes(problem.id) && ( {userId && (completedProblems.has(problem.id) ? (
<CircleCheckBigIcon <CircleCheckBigIcon className="text-green-500" size={18} aria-hidden="true" />
className="text-green-500" ) : attemptedProblems.has(problem.id) ? (
size={16} <CircleDotIcon className="text-yellow-500" size={18} aria-hidden="true" />
aria-hidden="true" ) : null)}
/>
)}
</TableCell> </TableCell>
<TableCell className="py-2.5"> <TableCell className="py-2.5">
<Link <Link href={`/problems/${problem.id}`} className="hover:text-blue-500">
href={`/problems/${problem.id}`}
className="hover:text-blue-500"
>
{index + 1}. {problem.title} {index + 1}. {problem.title}
</Link> </Link>
</TableCell> </TableCell>