From 5f3eb72d0088c8852bbdf55a80369df4009ab733 Mon Sep 17 00:00:00 2001 From: cfngc4594 Date: Tue, 6 May 2025 19:38:50 +0800 Subject: [PATCH] refactor(problems): migrate description and solution to feature-based structure - Remove old parallel route implementations (@Description and @Solutions) - Add new feature-based components for problem description and solution - Create content and panel components for both features - Implement skeleton loading states - Use cached data fetching - Update MDX rendering and scroll area implementations --- .../problems/[id]/@Description/layout.tsx | 16 ------ .../(app)/problems/[id]/@Description/page.tsx | 42 -------------- .../(app)/problems/[id]/@Solutions/layout.tsx | 16 ------ .../(app)/problems/[id]/@Solutions/page.tsx | 43 -------------- .../description/components/content.tsx | 56 +++++++++++++++++++ .../problems/description/components/panel.tsx | 25 +++++++++ .../problems/solution/components/content.tsx | 56 +++++++++++++++++++ .../problems/solution/components/panel.tsx | 25 +++++++++ 8 files changed, 162 insertions(+), 117 deletions(-) delete mode 100644 src/app/(app)/problems/[id]/@Description/layout.tsx delete mode 100644 src/app/(app)/problems/[id]/@Description/page.tsx delete mode 100644 src/app/(app)/problems/[id]/@Solutions/layout.tsx delete mode 100644 src/app/(app)/problems/[id]/@Solutions/page.tsx create mode 100644 src/features/problems/description/components/content.tsx create mode 100644 src/features/problems/description/components/panel.tsx create mode 100644 src/features/problems/solution/components/content.tsx create mode 100644 src/features/problems/solution/components/panel.tsx diff --git a/src/app/(app)/problems/[id]/@Description/layout.tsx b/src/app/(app)/problems/[id]/@Description/layout.tsx deleted file mode 100644 index 0bef527..0000000 --- a/src/app/(app)/problems/[id]/@Description/layout.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Suspense } from "react"; -import { Loading } from "@/components/loading"; - -interface DescriptionLayoutProps { - children: React.ReactNode; -} - -export default function DescriptionLayout({ children }: DescriptionLayoutProps) { - return ( -
- }> - {children} - -
- ); -} diff --git a/src/app/(app)/problems/[id]/@Description/page.tsx b/src/app/(app)/problems/[id]/@Description/page.tsx deleted file mode 100644 index ad9c28a..0000000 --- a/src/app/(app)/problems/[id]/@Description/page.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import prisma from "@/lib/prisma"; -import { notFound } from "next/navigation"; -import MdxPreview from "@/components/mdx-preview"; -import { ScrollArea } from "@/components/ui/scroll-area"; -import ProblemDescriptionFooter from "@/components/features/playground/problem/description/footer"; - -interface DescriptionPageProps { - params: Promise<{ id: string }>; -} - -export default async function DescriptionPage({ params }: DescriptionPageProps) { - const { id } = await params; - - if (!id) { - return notFound(); - } - - const problem = await prisma.problem.findUnique({ - where: { id }, - select: { - title: true, - description: true, - }, - }); - - if (!problem) { - return notFound(); - } - - return ( - <> -
-
- - - -
-
- - - ); -} diff --git a/src/app/(app)/problems/[id]/@Solutions/layout.tsx b/src/app/(app)/problems/[id]/@Solutions/layout.tsx deleted file mode 100644 index 90bcbeb..0000000 --- a/src/app/(app)/problems/[id]/@Solutions/layout.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Suspense } from "react"; -import { Loading } from "@/components/loading"; - -interface SolutionsLayoutProps { - children: React.ReactNode; -} - -export default async function SolutionsLayout({ children }: SolutionsLayoutProps) { - return ( -
- }> - {children} - -
- ); -} diff --git a/src/app/(app)/problems/[id]/@Solutions/page.tsx b/src/app/(app)/problems/[id]/@Solutions/page.tsx deleted file mode 100644 index e9c8e10..0000000 --- a/src/app/(app)/problems/[id]/@Solutions/page.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import prisma from "@/lib/prisma"; -import { notFound } from "next/navigation"; -import MdxPreview from "@/components/mdx-preview"; -import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; -import ProblemSolutionFooter from "@/components/features/playground/problem/solution/footer"; - -interface SolutionsPageProps { - params: Promise<{ id: string }>; -} - -export default async function SolutionsPage({ params }: SolutionsPageProps) { - const { id } = await params; - - if (!id) { - return notFound(); - } - - const problem = await prisma.problem.findUnique({ - where: { id }, - select: { - title: true, - solution: true, - }, - }); - - if (!problem) { - return notFound(); - } - - return ( - <> -
-
- - - - -
-
- - - ); -} diff --git a/src/features/problems/description/components/content.tsx b/src/features/problems/description/components/content.tsx new file mode 100644 index 0000000..2a090ee --- /dev/null +++ b/src/features/problems/description/components/content.tsx @@ -0,0 +1,56 @@ +import { getCachedProblem } from "@/lib/prisma"; +import { Skeleton } from "@/components/ui/skeleton"; +import { MdxRenderer } from "@/components/content/mdx-renderer"; +import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; + +interface DescriptionContentProps { + id: string; +} + +const DescriptionContent = async ({ id }: DescriptionContentProps) => { + const problem = await getCachedProblem(id); + + return ( + + + + + ); +}; + +const DescriptionContentSkeleton = () => { + return ( +
+ {/* Title skeleton */} + + + {/* Content skeletons */} + + + + + + + {/* Example section heading */} + + + {/* Example content */} + + + + {/* Code block skeleton */} +
+ +
+ + {/* More content */} + + +
+ ); +}; + +export { DescriptionContent, DescriptionContentSkeleton }; diff --git a/src/features/problems/description/components/panel.tsx b/src/features/problems/description/components/panel.tsx new file mode 100644 index 0000000..9ffd4dc --- /dev/null +++ b/src/features/problems/description/components/panel.tsx @@ -0,0 +1,25 @@ +import { Suspense } from "react"; +import { + DescriptionContent, + DescriptionContentSkeleton, +} from "@/features/problems/description/components/content"; + +interface DescriptionPanelProps { + id: string; +} + +const DescriptionPanel = ({ id }: DescriptionPanelProps) => { + return ( +
+
+
+ }> + + +
+
+
+ ); +}; + +export { DescriptionPanel }; diff --git a/src/features/problems/solution/components/content.tsx b/src/features/problems/solution/components/content.tsx new file mode 100644 index 0000000..4a62da2 --- /dev/null +++ b/src/features/problems/solution/components/content.tsx @@ -0,0 +1,56 @@ +import { getCachedProblem } from "@/lib/prisma"; +import { Skeleton } from "@/components/ui/skeleton"; +import { MdxRenderer } from "@/components/content/mdx-renderer"; +import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; + +interface SolutionContentProps { + id: string; +} + +const SolutionContent = async ({ id }: SolutionContentProps) => { + const problem = await getCachedProblem(id); + + return ( + + + + + ); +}; + +const SolutionContentSkeleton = () => { + return ( +
+ {/* Title skeleton */} + + + {/* Content skeletons */} + + + + + + + {/* Example section heading */} + + + {/* Example content */} + + + + {/* Code block skeleton */} +
+ +
+ + {/* More content */} + + +
+ ); +}; + +export { SolutionContent, SolutionContentSkeleton }; diff --git a/src/features/problems/solution/components/panel.tsx b/src/features/problems/solution/components/panel.tsx new file mode 100644 index 0000000..eba0fcc --- /dev/null +++ b/src/features/problems/solution/components/panel.tsx @@ -0,0 +1,25 @@ +import { Suspense } from "react"; +import { + SolutionContent, + SolutionContentSkeleton, +} from "@/features/problems/solution/components/content"; + +interface SolutionPanelProps { + id: string; +} + +const SolutionPanel = ({ id }: SolutionPanelProps) => { + return ( +
+
+
+ }> + + +
+
+
+ ); +}; + +export { SolutionPanel };