mirror of
				https://github.com/massbug/judge4c.git
				synced 2025-11-04 10:46:46 +00:00 
			
		
		
		
	refactor(problemset): move components to separate files and improve structure
- Move ProblemsetHeader component from 'problemset-header' to 'header' - Extract problemset table logic into dedicated ProblemsetTable component - Add Suspense and skeleton loading for better UX - Update layout and page structure
This commit is contained in:
		
							parent
							
								
									0e3daefe48
								
							
						
					
					
						commit
						148ae677d7
					
				@ -1,4 +1,4 @@
 | 
				
			|||||||
import { ProblemsetHeader } from "@/features/problemset/components/problemset-header";
 | 
					import { ProblemsetHeader } from "@/features/problemset/components/header";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface ProblemsetLayoutProps {
 | 
					interface ProblemsetLayoutProps {
 | 
				
			||||||
  children: React.ReactNode;
 | 
					  children: React.ReactNode;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,73 +1,15 @@
 | 
				
			|||||||
import Link from "next/link";
 | 
					import { Suspense } from "react";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  Table,
 | 
					  ProblemsetTable,
 | 
				
			||||||
  TableBody,
 | 
					  ProblemsetTableSkeleton,
 | 
				
			||||||
  TableCell,
 | 
					} from "@/features/problemset/components/table";
 | 
				
			||||||
  TableHead,
 | 
					 | 
				
			||||||
  TableHeader,
 | 
					 | 
				
			||||||
  TableRow,
 | 
					 | 
				
			||||||
} from "@/components/ui/table";
 | 
					 | 
				
			||||||
import prisma from "@/lib/prisma";
 | 
					 | 
				
			||||||
import { auth } from "@/lib/auth";
 | 
					 | 
				
			||||||
import { getTranslations } from "next-intl/server";
 | 
					 | 
				
			||||||
import { getDifficultyColorClass } from "@/lib/utils";
 | 
					 | 
				
			||||||
import { CircleCheckBigIcon, CircleDotIcon } from "lucide-react";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default async function ProblemsetPage() {
 | 
					 | 
				
			||||||
  const problems = await prisma.problem.findMany({
 | 
					 | 
				
			||||||
    where: { published: true },
 | 
					 | 
				
			||||||
    orderBy: { id: "asc" },
 | 
					 | 
				
			||||||
    select: { id: true, title: true, difficulty: true },
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const session = await auth();
 | 
					 | 
				
			||||||
  const userId = session?.user?.id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const submissions = userId
 | 
					 | 
				
			||||||
    ? await prisma.submission.findMany({
 | 
					 | 
				
			||||||
      where: { userId },
 | 
					 | 
				
			||||||
      select: { problemId: true, status: true },
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    : [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const t = await getTranslations();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function ProblemsetPage() {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Table>
 | 
					    <div className="h-full container mx-auto p-4">
 | 
				
			||||||
      <TableHeader className="bg-transparent">
 | 
					      <Suspense fallback={<ProblemsetTableSkeleton />}>
 | 
				
			||||||
        <TableRow className="hover:bg-transparent">
 | 
					        <ProblemsetTable />
 | 
				
			||||||
          <TableHead className="w-1/3">{t("ProblemsetPage.Status")}</TableHead>
 | 
					      </Suspense>
 | 
				
			||||||
          <TableHead className="w-1/3">{t("ProblemsetPage.Title")}</TableHead>
 | 
					    </div>
 | 
				
			||||||
          <TableHead className="w-1/3">{t("ProblemsetPage.Difficulty")}</TableHead>
 | 
					 | 
				
			||||||
        </TableRow>
 | 
					 | 
				
			||||||
      </TableHeader>
 | 
					 | 
				
			||||||
      <TableBody className="[&_td:first-child]:rounded-l-lg [&_td:last-child]:rounded-r-lg">
 | 
					 | 
				
			||||||
        {problems.map((problem, index) => (
 | 
					 | 
				
			||||||
          <TableRow
 | 
					 | 
				
			||||||
            key={problem.id}
 | 
					 | 
				
			||||||
            className="h-10 border-b-0 odd:bg-muted/50 hover:text-blue-500 hover:bg-muted"
 | 
					 | 
				
			||||||
          >
 | 
					 | 
				
			||||||
            <TableCell className="py-2.5">
 | 
					 | 
				
			||||||
              {userId && (completedProblems.has(problem.id) ? (
 | 
					 | 
				
			||||||
                <CircleCheckBigIcon className="text-green-500" size={18} aria-hidden="true" />
 | 
					 | 
				
			||||||
              ) : attemptedProblems.has(problem.id) ? (
 | 
					 | 
				
			||||||
                <CircleDotIcon className="text-yellow-500" size={18} aria-hidden="true" />
 | 
					 | 
				
			||||||
              ) : null)}
 | 
					 | 
				
			||||||
            </TableCell>
 | 
					 | 
				
			||||||
            <TableCell className="py-2.5">
 | 
					 | 
				
			||||||
              <Link href={`/problems/${problem.id}`} className="hover:text-blue-500" prefetch>
 | 
					 | 
				
			||||||
                {index + 1}. {problem.title}
 | 
					 | 
				
			||||||
              </Link>
 | 
					 | 
				
			||||||
            </TableCell>
 | 
					 | 
				
			||||||
            <TableCell className={`py-2.5 ${getDifficultyColorClass(problem.difficulty)}`}>
 | 
					 | 
				
			||||||
              {t(`Difficulty.${problem.difficulty}`)}
 | 
					 | 
				
			||||||
            </TableCell>
 | 
					 | 
				
			||||||
          </TableRow>
 | 
					 | 
				
			||||||
        ))}
 | 
					 | 
				
			||||||
      </TableBody>
 | 
					 | 
				
			||||||
    </Table>
 | 
					 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user