feat(playground): add session management and folder open icon in PlaygroundSidebar component
This commit is contained in:
parent
08831481b8
commit
20d790c5e0
@ -22,6 +22,7 @@
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"cross-fetch": "^4.0.0",
|
||||
"devicons-react": "^1.4.0",
|
||||
"gitea-js": "^1.22.0",
|
||||
"jotai": "^2.10.3",
|
||||
"lucide-react": "^0.468.0",
|
||||
|
@ -1,3 +1,5 @@
|
||||
"use server";
|
||||
|
||||
import api from "@/lib/gitea";
|
||||
import { GitEntry, APIError } from "gitea-js";
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { auth } from "@/auth";
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import {
|
||||
Sidebar,
|
||||
@ -18,8 +19,10 @@ import {
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from "@/components/ui/collapsible";
|
||||
import { retrieveTreeStructure } from "@/app/actions";
|
||||
import { ChevronRight, File, Folder } from "lucide-react";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { retrieveTreeStructure } from "@/actions";
|
||||
import { COriginal, JavaOriginal } from "devicons-react";
|
||||
import { ChevronRight, File, Folder, FolderOpen } from "lucide-react";
|
||||
|
||||
interface FileTree {
|
||||
name: string;
|
||||
@ -69,20 +72,32 @@ export function buildFileTree(tree: GitEntry[]): FileTree {
|
||||
return root;
|
||||
}
|
||||
|
||||
export async function PlaygroundSidebar({
|
||||
export function PlaygroundSidebar({
|
||||
...props
|
||||
}: React.ComponentProps<typeof Sidebar>) {
|
||||
const session = await auth();
|
||||
const { data: session } = useSession();
|
||||
const [fileTree, setFileTree] = React.useState<FileTree>({
|
||||
name: "",
|
||||
type: "tree",
|
||||
children: {},
|
||||
});
|
||||
|
||||
const username = session?.user?.name ?? "";
|
||||
let fileTree: FileTree = { name: "", type: "tree", children: {} };
|
||||
|
||||
React.useEffect(() => {
|
||||
async function fetchFileTree() {
|
||||
if (username) {
|
||||
const tree: GitEntry[] = await retrieveTreeStructure(
|
||||
username,
|
||||
"playground",
|
||||
"main"
|
||||
);
|
||||
fileTree = buildFileTree(tree);
|
||||
const newFileTree = buildFileTree(tree);
|
||||
setFileTree(newFileTree);
|
||||
}
|
||||
}
|
||||
fetchFileTree();
|
||||
}, [username]);
|
||||
|
||||
return (
|
||||
<Sidebar {...props}>
|
||||
@ -106,10 +121,22 @@ export async function PlaygroundSidebar({
|
||||
|
||||
function Tree({ item }: { item: FileTree }) {
|
||||
const { name, type, children } = item;
|
||||
const fileExtension = name.split(".").pop();
|
||||
|
||||
let fileIcon = <File />;
|
||||
|
||||
if (fileExtension === "c") {
|
||||
fileIcon = <COriginal />;
|
||||
} else if (fileExtension === "java") {
|
||||
fileIcon = <JavaOriginal />;
|
||||
}
|
||||
|
||||
const [isOpen, setIsOpen] = React.useState(false);
|
||||
|
||||
if (type === "blob") {
|
||||
return (
|
||||
<SidebarMenuButton className="data-[active=true]:bg-transparent">
|
||||
<File />
|
||||
{fileIcon}
|
||||
{name}
|
||||
</SidebarMenuButton>
|
||||
);
|
||||
@ -117,11 +144,15 @@ function Tree({ item }: { item: FileTree }) {
|
||||
|
||||
return (
|
||||
<SidebarMenuItem>
|
||||
<Collapsible className="group/collapsible [&[data-state=open]>button>svg:first-child]:rotate-90">
|
||||
<Collapsible
|
||||
open={isOpen}
|
||||
onOpenChange={setIsOpen}
|
||||
className="group/collapsible [&[data-state=open]>button>svg:first-child]:rotate-90"
|
||||
>
|
||||
<CollapsibleTrigger asChild>
|
||||
<SidebarMenuButton>
|
||||
<ChevronRight className="transition-transform" />
|
||||
<Folder />
|
||||
{isOpen ? <FolderOpen /> : <Folder />}
|
||||
{name}
|
||||
</SidebarMenuButton>
|
||||
</CollapsibleTrigger>
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
} from "@/components/ui/breadcrumb";
|
||||
import { SessionProvider } from "next-auth/react";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { ModeSwitcher } from "@/components/mode-switcher";
|
||||
import LanguageSwitcher from "@/components/language-switcher";
|
||||
@ -18,6 +19,7 @@ export default function PlaygroundLayout({
|
||||
children,
|
||||
}: Readonly<{ children: React.ReactNode }>) {
|
||||
return (
|
||||
<SessionProvider>
|
||||
<SidebarProvider>
|
||||
<PlaygroundSidebar />
|
||||
<SidebarInset>
|
||||
@ -43,5 +45,6 @@ export default function PlaygroundLayout({
|
||||
{children}
|
||||
</SidebarInset>
|
||||
</SidebarProvider>
|
||||
</SessionProvider>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user