From eea16a82241e4eaff6db2c3fe83e48215f7a8aa0 Mon Sep 17 00:00:00 2001 From: cfngc4594 Date: Tue, 13 May 2025 15:36:07 +0800 Subject: [PATCH] feat(problems): add localization support for problem descriptions and solutions - Replace cached problem data with direct Prisma queries for localized content - Implement locale-based content selection for both descriptions and solutions - Refactor skeleton loading components structure - Change all exports from named to default exports --- .../description/components/content.tsx | 89 ++++++++++++------- .../problems/description/components/panel.tsx | 4 +- .../problems/solution/components/content.tsx | 87 +++++++++++------- .../problems/solution/components/panel.tsx | 4 +- 4 files changed, 116 insertions(+), 68 deletions(-) diff --git a/src/features/problems/description/components/content.tsx b/src/features/problems/description/components/content.tsx index fd2885f..cd20dde 100644 --- a/src/features/problems/description/components/content.tsx +++ b/src/features/problems/description/components/content.tsx @@ -1,56 +1,83 @@ -import { getCachedProblem } from "@/lib/prisma"; +import prisma from "@/lib/prisma"; +import { getLocale } from "next-intl/server"; import { Skeleton } from "@/components/ui/skeleton"; import { MdxRenderer } from "@/components/content/mdx-renderer"; import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; +import type { Locale, ProblemLocalization } from "@/generated/client"; + +const getLocalizedDescription = ( + localizations: ProblemLocalization[], + locale: Locale +) => { + if (!localizations || localizations.length === 0) { + return "Unknown Description"; + } + + const localization = localizations.find( + (localization) => localization.locale === locale + ); + + return ( + localization?.content ?? localizations[0].content ?? "Unknown Description" + ); +}; interface DescriptionContentProps { problemId: string; } -const DescriptionContent = async ({ problemId }: DescriptionContentProps) => { - const problem = await getCachedProblem(problemId); +export const DescriptionContent = async ({ + problemId, +}: DescriptionContentProps) => { + const locale = await getLocale(); + + const descriptions = await prisma.problemLocalization.findMany({ + where: { + problemId, + type: "DESCRIPTION", + }, + }); + + const description = getLocalizedDescription(descriptions, locale as Locale); return ( - + ); }; -const DescriptionContentSkeleton = () => { +export const DescriptionContentSkeleton = () => { return ( -
- {/* Title skeleton */} - +
+
+ {/* Title skeleton */} + - {/* Content skeletons */} - - - - - + {/* Content skeletons */} + + + + + - {/* Example section heading */} - + {/* Example section heading */} + - {/* Example content */} - - + {/* Example content */} + + - {/* Code block skeleton */} -
- + {/* Code block skeleton */} +
+ +
+ + {/* More content */} + +
- - {/* More content */} - -
); }; - -export { DescriptionContent, DescriptionContentSkeleton }; diff --git a/src/features/problems/description/components/panel.tsx b/src/features/problems/description/components/panel.tsx index 8cdf4aa..c8a936f 100644 --- a/src/features/problems/description/components/panel.tsx +++ b/src/features/problems/description/components/panel.tsx @@ -8,7 +8,7 @@ interface DescriptionPanelProps { problemId: string; } -const DescriptionPanel = ({ problemId }: DescriptionPanelProps) => { +export const DescriptionPanel = ({ problemId }: DescriptionPanelProps) => { return (
@@ -21,5 +21,3 @@ const DescriptionPanel = ({ problemId }: DescriptionPanelProps) => {
); }; - -export { DescriptionPanel }; diff --git a/src/features/problems/solution/components/content.tsx b/src/features/problems/solution/components/content.tsx index 8c053f5..70f2970 100644 --- a/src/features/problems/solution/components/content.tsx +++ b/src/features/problems/solution/components/content.tsx @@ -1,56 +1,81 @@ -import { getCachedProblem } from "@/lib/prisma"; +import prisma from "@/lib/prisma"; +import { getLocale } from "next-intl/server"; import { Skeleton } from "@/components/ui/skeleton"; import { MdxRenderer } from "@/components/content/mdx-renderer"; import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; +import type { Locale, ProblemLocalization } from "@/generated/client"; + +const getLocalizedSolution = ( + localizations: ProblemLocalization[], + locale: Locale +) => { + if (!localizations || localizations.length === 0) { + return "Unknown Solution"; + } + + const localization = localizations.find( + (localization) => localization.locale === locale + ); + + return ( + localization?.content ?? localizations[0].content ?? "Unknown Solution" + ); +}; interface SolutionContentProps { problemId: string; } -const SolutionContent = async ({ problemId }: SolutionContentProps) => { - const problem = await getCachedProblem(problemId); +export const SolutionContent = async ({ problemId }: SolutionContentProps) => { + const locale = await getLocale(); + + const solutions = await prisma.problemLocalization.findMany({ + where: { + problemId, + type: "SOLUTION", + }, + }); + + const solution = getLocalizedSolution(solutions, locale as Locale); return ( - + ); }; -const SolutionContentSkeleton = () => { +export const SolutionContentSkeleton = () => { return ( -
- {/* Title skeleton */} - +
+
+ {/* Title skeleton */} + - {/* Content skeletons */} - - - - - + {/* Content skeletons */} + + + + + - {/* Example section heading */} - + {/* Example section heading */} + - {/* Example content */} - - + {/* Example content */} + + - {/* Code block skeleton */} -
- + {/* Code block skeleton */} +
+ +
+ + {/* More content */} + +
- - {/* More content */} - -
); }; - -export { SolutionContent, SolutionContentSkeleton }; diff --git a/src/features/problems/solution/components/panel.tsx b/src/features/problems/solution/components/panel.tsx index a503f13..2b74243 100644 --- a/src/features/problems/solution/components/panel.tsx +++ b/src/features/problems/solution/components/panel.tsx @@ -8,7 +8,7 @@ interface SolutionPanelProps { problemId: string; } -const SolutionPanel = ({ problemId }: SolutionPanelProps) => { +export const SolutionPanel = ({ problemId }: SolutionPanelProps) => { return (
@@ -21,5 +21,3 @@ const SolutionPanel = ({ problemId }: SolutionPanelProps) => {
); }; - -export { SolutionPanel };