mirror of
https://litchi.icu/ngc2207/judge4c-latest.git
synced 2025-07-13 11:34:35 +00:00
refactor: improve problems layout
This commit is contained in:
parent
c1f870651f
commit
52b38caa62
@ -1,12 +0,0 @@
|
|||||||
export default async function AnswerPage({
|
|
||||||
params,
|
|
||||||
}: {
|
|
||||||
params: Promise<{ slug: string }>;
|
|
||||||
}) {
|
|
||||||
const slug = (await params).slug;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h1>Answer Page: {slug}</h1>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
export default async function ConsolePage({
|
|
||||||
params,
|
|
||||||
}: {
|
|
||||||
params: Promise<{ slug: string }>;
|
|
||||||
}) {
|
|
||||||
const slug = (await params).slug;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h1>Console Page: {slug}</h1>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
export default async function DescriptionPage({
|
|
||||||
params,
|
|
||||||
}: {
|
|
||||||
params: Promise<{ slug: string }>;
|
|
||||||
}) {
|
|
||||||
const slug = (await params).slug;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h1>Description Page: {slug}</h1>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
41
src/app/(main)/problems/[slug]/components/tabs-card.tsx
Normal file
41
src/app/(main)/problems/[slug]/components/tabs-card.tsx
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { LucideIcon } from "lucide-react";
|
||||||
|
import { Tabs } from "@radix-ui/react-tabs";
|
||||||
|
import { TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
|
|
||||||
|
interface TabsItem {
|
||||||
|
icon: LucideIcon;
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
content: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TabsCardProps {
|
||||||
|
tabsItems: TabsItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TabsCard({ tabsItems }: TabsCardProps) {
|
||||||
|
return (
|
||||||
|
<Tabs
|
||||||
|
defaultValue={tabsItems[0].value}
|
||||||
|
className="h-full w-full flex flex-col"
|
||||||
|
>
|
||||||
|
<TabsList className="h-9 w-full flex flex-row items-center justify-start rounded-t-lg rounded-b-none">
|
||||||
|
{tabsItems.map((tabsItem) => (
|
||||||
|
<TabsTrigger
|
||||||
|
value={tabsItem.value}
|
||||||
|
key={tabsItem.value}
|
||||||
|
className="gap-x-1 px-2"
|
||||||
|
>
|
||||||
|
<tabsItem.icon className="h-6 w-auto text-cyan-500" />
|
||||||
|
<span>{tabsItem.label}</span>
|
||||||
|
</TabsTrigger>
|
||||||
|
))}
|
||||||
|
</TabsList>
|
||||||
|
{tabsItems.map((tabsItem) => (
|
||||||
|
<TabsContent value={tabsItem.value} key={tabsItem.value}>
|
||||||
|
{tabsItem.content}
|
||||||
|
</TabsContent>
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
|
);
|
||||||
|
}
|
@ -1,20 +1,50 @@
|
|||||||
|
import {
|
||||||
|
CodeXmlIcon,
|
||||||
|
FileChartColumnIcon,
|
||||||
|
SquareChevronRightIcon,
|
||||||
|
} from "lucide-react";
|
||||||
import {
|
import {
|
||||||
ResizableHandle,
|
ResizableHandle,
|
||||||
ResizablePanel,
|
ResizablePanel,
|
||||||
ResizablePanelGroup,
|
ResizablePanelGroup,
|
||||||
} from "@/components/ui/resizable";
|
} from "@/components/ui/resizable";
|
||||||
|
import AnswerPage from "./views/answer-page";
|
||||||
|
import ConsolePage from "./views/console-page";
|
||||||
|
import { TabsCard } from "./components/tabs-card";
|
||||||
|
import DescriptionPage from "./views/description-page";
|
||||||
|
|
||||||
export default async function ProblemLayout({
|
export default async function ProblemLayout({
|
||||||
|
params,
|
||||||
children,
|
children,
|
||||||
description,
|
|
||||||
answer,
|
|
||||||
console,
|
|
||||||
}: {
|
}: {
|
||||||
|
params: Promise<{ slug: string }>;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
description: React.ReactNode;
|
|
||||||
answer: React.ReactNode;
|
|
||||||
console: React.ReactNode;
|
|
||||||
}) {
|
}) {
|
||||||
|
const slug = (await params).slug;
|
||||||
|
const descriptionTabsItems = [
|
||||||
|
{
|
||||||
|
icon: FileChartColumnIcon,
|
||||||
|
label: "题目描述",
|
||||||
|
value: "description",
|
||||||
|
content: <DescriptionPage slug={slug} />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const answerTabsItems = [
|
||||||
|
{
|
||||||
|
icon: CodeXmlIcon,
|
||||||
|
label: "代码",
|
||||||
|
value: "code",
|
||||||
|
content: <AnswerPage slug={slug} />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const consoleTabsItems = [
|
||||||
|
{
|
||||||
|
icon: SquareChevronRightIcon,
|
||||||
|
label: "控制台",
|
||||||
|
value: "console",
|
||||||
|
content: <ConsolePage slug={slug} />,
|
||||||
|
},
|
||||||
|
];
|
||||||
return (
|
return (
|
||||||
<div className="h-full rounded-b-xl">
|
<div className="h-full rounded-b-xl">
|
||||||
{children}
|
{children}
|
||||||
@ -23,18 +53,18 @@ export default async function ProblemLayout({
|
|||||||
defaultSize={25}
|
defaultSize={25}
|
||||||
className="hidden lg:block border rounded-lg"
|
className="hidden lg:block border rounded-lg"
|
||||||
>
|
>
|
||||||
{description}
|
<TabsCard tabsItems={descriptionTabsItems} />
|
||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
<ResizableHandle className="hidden lg:block bg-transparent hover:bg-cyan-500" />
|
<ResizableHandle className="hidden lg:block bg-transparent hover:bg-cyan-500" />
|
||||||
<ResizablePanel defaultSize={50} className="border rounded-lg">
|
<ResizablePanel defaultSize={50} className="border rounded-lg">
|
||||||
{answer}
|
<TabsCard tabsItems={answerTabsItems} />
|
||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
<ResizableHandle className="hidden xl:block bg-transparent hover:bg-cyan-500" />
|
<ResizableHandle className="hidden xl:block bg-transparent hover:bg-cyan-500" />
|
||||||
<ResizablePanel
|
<ResizablePanel
|
||||||
defaultSize={25}
|
defaultSize={25}
|
||||||
className="hidden xl:block border rounded-lg"
|
className="hidden xl:block border rounded-lg"
|
||||||
>
|
>
|
||||||
{console}
|
<TabsCard tabsItems={consoleTabsItems} />
|
||||||
</ResizablePanel>
|
</ResizablePanel>
|
||||||
</ResizablePanelGroup>
|
</ResizablePanelGroup>
|
||||||
</div>
|
</div>
|
||||||
|
7
src/app/(main)/problems/[slug]/views/answer-page.tsx
Normal file
7
src/app/(main)/problems/[slug]/views/answer-page.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default function AnswerPage({ slug }: { slug: string }) {
|
||||||
|
return (
|
||||||
|
<div className="p-4">
|
||||||
|
<h1>Answer Page: {slug}</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
7
src/app/(main)/problems/[slug]/views/console-page.tsx
Normal file
7
src/app/(main)/problems/[slug]/views/console-page.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default function ConsolePage({ slug }: { slug: string }) {
|
||||||
|
return (
|
||||||
|
<div className="p-4">
|
||||||
|
<h1>Console Page: {slug}</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
export default function DescriptionPage({ slug }: { slug: string }) {
|
||||||
|
return (
|
||||||
|
<div className="p-4">
|
||||||
|
<h1>Description Page: {slug}</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user