refactor: extract panel layout and simplify bot content structure

This commit is contained in:
cfngc4594 2025-06-20 23:03:23 +08:00
parent c372856c3a
commit ecaba8f48b
9 changed files with 56 additions and 64 deletions

View File

@ -37,13 +37,7 @@ export const BotContent = async ({ problemId }: BotContentProps) => {
const description = getLocalizedDescription(descriptions, locale as Locale); const description = getLocalizedDescription(descriptions, locale as Locale);
return ( return <BotForm description={description} />;
<div className="relative flex-1">
<div className="absolute h-full w-full">
<BotForm description={description} />
</div>
</div>
);
}; };
export const BotContentSkeleton = () => { export const BotContentSkeleton = () => {

View File

@ -3,6 +3,7 @@ import {
BotContent, BotContent,
BotContentSkeleton, BotContentSkeleton,
} from "@/features/problems/bot/components/content"; } from "@/features/problems/bot/components/content";
import { PanelLayout } from "@/features/problems/layouts/panel-layout";
interface BotPanelProps { interface BotPanelProps {
problemId: string; problemId: string;
@ -10,10 +11,10 @@ interface BotPanelProps {
export const BotPanel = ({ problemId }: BotPanelProps) => { export const BotPanel = ({ problemId }: BotPanelProps) => {
return ( return (
<div className="h-full flex flex-col border border-t-0 border-muted rounded-b-lg bg-background overflow-hidden"> <PanelLayout>
<Suspense fallback={<BotContentSkeleton />}> <Suspense fallback={<BotContentSkeleton />}>
<BotContent problemId={problemId} /> <BotContent problemId={problemId} />
</Suspense> </Suspense>
</div> </PanelLayout>
); );
}; };

View File

@ -3,6 +3,7 @@ import {
CodeContent, CodeContent,
CodeContentSkeleton, CodeContentSkeleton,
} from "@/features/problems/code/components/content"; } from "@/features/problems/code/components/content";
import { PanelLayout } from "@/features/problems/layouts/panel-layout";
import { CodeFooter } from "@/features/problems/code/components/footer"; import { CodeFooter } from "@/features/problems/code/components/footer";
import { CodeToolbar } from "@/features/problems/code/components/toolbar/code-toolbar"; import { CodeToolbar } from "@/features/problems/code/components/toolbar/code-toolbar";
@ -12,16 +13,14 @@ interface CodePanelProps {
export const CodePanel = ({ problemId }: CodePanelProps) => { export const CodePanel = ({ problemId }: CodePanelProps) => {
return ( return (
<div className="h-full flex flex-col border border-t-0 border-muted rounded-b-lg bg-background overflow-hidden"> <PanelLayout>
<CodeToolbar className="border-b" /> <div className="h-full flex flex-col">
<div className="relative flex-1"> <CodeToolbar className="border-b" />
<div className="absolute h-full w-full"> <Suspense fallback={<CodeContentSkeleton />}>
<Suspense fallback={<CodeContentSkeleton />}> <CodeContent problemId={problemId} />
<CodeContent problemId={problemId} /> </Suspense>
</Suspense> <CodeFooter />
</div>
</div> </div>
<CodeFooter /> </PanelLayout>
</div>
); );
}; };

View File

@ -3,6 +3,7 @@ import {
DescriptionContent, DescriptionContent,
DescriptionContentSkeleton, DescriptionContentSkeleton,
} from "@/features/problems/description/components/content"; } from "@/features/problems/description/components/content";
import { PanelLayout } from "@/features/problems/layouts/panel-layout";
interface DescriptionPanelProps { interface DescriptionPanelProps {
problemId: string; problemId: string;
@ -10,14 +11,10 @@ interface DescriptionPanelProps {
export const DescriptionPanel = ({ problemId }: DescriptionPanelProps) => { export const DescriptionPanel = ({ problemId }: DescriptionPanelProps) => {
return ( return (
<div className="h-full flex flex-col border border-t-0 border-muted rounded-b-lg bg-background overflow-hidden"> <PanelLayout>
<div className="relative flex-1"> <Suspense fallback={<DescriptionContentSkeleton />}>
<div className="absolute h-full w-full"> <DescriptionContent problemId={problemId} />
<Suspense fallback={<DescriptionContentSkeleton />}> </Suspense>
<DescriptionContent problemId={problemId} /> </PanelLayout>
</Suspense>
</div>
</div>
</div>
); );
}; };

View File

@ -3,6 +3,7 @@ import {
DetailContent, DetailContent,
DetailContentSkeleton, DetailContentSkeleton,
} from "@/features/problems/detail/components/content"; } from "@/features/problems/detail/components/content";
import { PanelLayout } from "@/features/problems/layouts/panel-layout";
import { DetailHeader } from "@/features/problems/detail/components/header"; import { DetailHeader } from "@/features/problems/detail/components/header";
interface DetailPanelProps { interface DetailPanelProps {
@ -15,15 +16,11 @@ export const DetailPanel = ({ submissionId }: DetailPanelProps) => {
} }
return ( return (
<div className="h-full flex flex-col border border-t-0 border-muted rounded-b-lg bg-background overflow-hidden"> <PanelLayout>
<DetailHeader /> <DetailHeader />
<div className="relative flex-1"> <Suspense fallback={<DetailContentSkeleton />}>
<div className="absolute h-full w-full"> <DetailContent submissionId={submissionId} />
<Suspense fallback={<DetailContentSkeleton />}> </Suspense>
<DetailContent submissionId={submissionId} /> </PanelLayout>
</Suspense>
</div>
</div>
</div>
); );
}; };

View File

@ -0,0 +1,13 @@
interface PanelLayoutProps {
children: React.ReactNode;
}
export const PanelLayout = ({ children }: PanelLayoutProps) => {
return (
<div className="h-full flex flex-col border border-t-0 border-muted rounded-b-lg bg-background overflow-hidden">
<div className="relative flex-1">
<div className="absolute h-full w-full">{children}</div>
</div>
</div>
);
};

View File

@ -3,6 +3,7 @@ import {
SolutionContent, SolutionContent,
SolutionContentSkeleton, SolutionContentSkeleton,
} from "@/features/problems/solution/components/content"; } from "@/features/problems/solution/components/content";
import { PanelLayout } from "@/features/problems/layouts/panel-layout";
interface SolutionPanelProps { interface SolutionPanelProps {
problemId: string; problemId: string;
@ -10,14 +11,10 @@ interface SolutionPanelProps {
export const SolutionPanel = ({ problemId }: SolutionPanelProps) => { export const SolutionPanel = ({ problemId }: SolutionPanelProps) => {
return ( return (
<div className="h-full flex flex-col border border-t-0 border-muted rounded-b-lg bg-background overflow-hidden"> <PanelLayout>
<div className="relative flex-1"> <Suspense fallback={<SolutionContentSkeleton />}>
<div className="absolute h-full w-full"> <SolutionContent problemId={problemId} />
<Suspense fallback={<SolutionContentSkeleton />}> </Suspense>
<SolutionContent problemId={problemId} /> </PanelLayout>
</Suspense>
</div>
</div>
</div>
); );
}; };

View File

@ -3,6 +3,7 @@ import {
SubmissionContent, SubmissionContent,
SubmissionContentSkeleton, SubmissionContentSkeleton,
} from "@/features/problems/submission/components/content"; } from "@/features/problems/submission/components/content";
import { PanelLayout } from "@/features/problems/layouts/panel-layout";
interface SubmissionPanelProps { interface SubmissionPanelProps {
problemId: string; problemId: string;
@ -10,14 +11,10 @@ interface SubmissionPanelProps {
export const SubmissionPanel = ({ problemId }: SubmissionPanelProps) => { export const SubmissionPanel = ({ problemId }: SubmissionPanelProps) => {
return ( return (
<div className="h-full flex flex-col border border-t-0 border-muted rounded-b-lg bg-background overflow-hidden"> <PanelLayout>
<div className="relative flex-1"> <Suspense fallback={<SubmissionContentSkeleton />}>
<div className="absolute h-full w-full"> <SubmissionContent problemId={problemId} />
<Suspense fallback={<SubmissionContentSkeleton />}> </Suspense>
<SubmissionContent problemId={problemId} /> </PanelLayout>
</Suspense>
</div>
</div>
</div>
); );
}; };

View File

@ -3,6 +3,7 @@ import {
TestcaseContent, TestcaseContent,
TestcaseContentSkeleton, TestcaseContentSkeleton,
} from "@/features/problems/testcase/content"; } from "@/features/problems/testcase/content";
import { PanelLayout } from "@/features/problems/layouts/panel-layout";
interface TestcasePanelProps { interface TestcasePanelProps {
problemId: string; problemId: string;
@ -10,14 +11,10 @@ interface TestcasePanelProps {
export const TestcasePanel = ({ problemId }: TestcasePanelProps) => { export const TestcasePanel = ({ problemId }: TestcasePanelProps) => {
return ( return (
<div className="h-full flex flex-col border border-t-0 border-muted rounded-b-lg bg-background overflow-hidden"> <PanelLayout>
<div className="relative flex-1"> <Suspense fallback={<TestcaseContentSkeleton />}>
<div className="absolute h-full w-full"> <TestcaseContent problemId={problemId} />
<Suspense fallback={<TestcaseContentSkeleton />}> </Suspense>
<TestcaseContent problemId={problemId} /> </PanelLayout>
</Suspense>
</div>
</div>
</div>
); );
}; };