feat(playground): add Description and Workspace layouts with tabs for better organization

This commit is contained in:
cfngc4594 2025-02-23 19:17:03 +08:00
parent d5cda08a3e
commit e06f286815
5 changed files with 81 additions and 12 deletions

View File

@ -0,0 +1,33 @@
import { FileTextIcon } from "lucide-react";
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
interface DescriptionLayoutProps {
children: React.ReactNode;
}
export default function DescriptionLayout({ children }: DescriptionLayoutProps) {
return (
<Tabs defaultValue="description" className="h-full">
<ScrollArea className="h-11 flex items-center pt-1 px-1">
<TabsList className="gap-1 bg-transparent">
<TabsTrigger
value="description"
className="data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none"
>
<FileTextIcon
className="-ms-0.5 me-1.5 opacity-60"
size={16}
aria-hidden="true"
/>
Description
</TabsTrigger>
</TabsList>
<ScrollBar orientation="horizontal" />
</ScrollArea>
<TabsContent value="description" className="h-full mt-0 border-t">
{children}
</TabsContent>
</Tabs>
);
}

View File

@ -1,6 +1,6 @@
import MdxPreview from "@/components/mdx-preview"; import MdxPreview from "@/components/mdx-preview";
import { DEFAULT_PROBLEM } from "@/config/problem"; import { DEFAULT_PROBLEM } from "@/config/problem";
export default function ProblemDescriptionPage() { export default function DescriptionPage() {
return <MdxPreview source={DEFAULT_PROBLEM} />; return <MdxPreview source={DEFAULT_PROBLEM} />;
} }

View File

@ -0,0 +1,33 @@
import { CodeXmlIcon } from "lucide-react";
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
interface WorkspaceLayoutProps {
children: React.ReactNode;
}
export default function WorkspaceLayout({ children }: WorkspaceLayoutProps) {
return (
<Tabs defaultValue="code" className="h-full">
<ScrollArea className="h-11 flex items-center pt-1 px-1">
<TabsList className="gap-1 bg-transparent">
<TabsTrigger
value="code"
className="data-[state=active]:bg-primary data-[state=active]:text-primary-foreground rounded-full data-[state=active]:shadow-none"
>
<CodeXmlIcon
className="-ms-0.5 me-1.5 opacity-60"
size={16}
aria-hidden="true"
/>
Code
</TabsTrigger>
</TabsList>
<ScrollBar orientation="horizontal" />
</ScrollArea>
<TabsContent value="code" className="h-full mt-0 border-t">
{children}
</TabsContent>
</Tabs>
);
}

View File

@ -1,5 +1,5 @@
import CodeEditor from "@/components/code-editor"; import CodeEditor from "@/components/code-editor";
export default function PlaygroundPage() { export default function WorkspacePage() {
return <CodeEditor />; return <CodeEditor />;
} }

View File

@ -5,22 +5,25 @@ import {
} from "@/components/ui/resizable"; } from "@/components/ui/resizable";
interface PlaygroundLayoutProps { interface PlaygroundLayoutProps {
children: React.ReactNode; description: React.ReactNode;
problemDescription: React.ReactNode; workspace: React.ReactNode;
} }
export default function PlaygroundLayout({ export default function PlaygroundLayout({
children, description,
problemDescription, workspace,
}: PlaygroundLayoutProps) { }: PlaygroundLayoutProps) {
return ( return (
<ResizablePanelGroup direction="horizontal"> <ResizablePanelGroup direction="horizontal" className="p-2.5">
<ResizablePanel defaultSize={50}> <ResizablePanel defaultSize={50} className="border border-muted rounded-2xl">
{problemDescription} {description}
</ResizablePanel> </ResizablePanel>
<ResizableHandle withHandle className="w-0.5 hover:bg-blue-500" /> <ResizableHandle
<ResizablePanel defaultSize={50}> withHandle
{children} className="w-0.5 bg-transparent hover:bg-blue-500 mx-0.5"
/>
<ResizablePanel defaultSize={50} className="border border-muted rounded-2xl">
{workspace}
</ResizablePanel> </ResizablePanel>
</ResizablePanelGroup> </ResizablePanelGroup>
); );