diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index b104cc6c0..94dd902f7 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -103,18 +103,22 @@ export default function RootLayout({
- -
-
-
- - {children} - - + + + + +
+
+
+ {children} + +
+
+
-
-
-
+ + +
diff --git a/frontend/src/app/scripts/_components/script-accordion.tsx b/frontend/src/app/scripts/_components/script-accordion.tsx index 8432c89c7..bce44c761 100644 --- a/frontend/src/app/scripts/_components/script-accordion.tsx +++ b/frontend/src/app/scripts/_components/script-accordion.tsx @@ -27,12 +27,14 @@ export default function ScriptAccordion({ setSelectedScript, selectedCategory, setSelectedCategory, + onItemSelect, }: { items: Category[]; selectedScript: string | null; setSelectedScript: (script: string | null) => void; selectedCategory: string | null; setSelectedCategory: (category: string | null) => void; + onItemSelect?: () => void; }) { const [expandedItem, setExpandedItem] = useState(undefined); const linkRefs = useRef<{ [key: string]: HTMLAnchorElement | null }>({}); @@ -77,7 +79,7 @@ export default function ScriptAccordion({ value={expandedItem} onValueChange={handleAccordionChange} collapsible - className="overflow-y-scroll max-h-[calc(100vh-225px)] overflow-x-hidden p-2" + className="overflow-y-scroll sm:max-h-[calc(100vh-209px)] overflow-x-hidden p-1" > {items.map(category => ( { handleSelected(script.slug); setSelectedCategory(category.name); + onItemSelect?.(); }} ref={(el) => { linkRefs.current[script.slug] = el; diff --git a/frontend/src/app/scripts/_components/sidebar.tsx b/frontend/src/app/scripts/_components/sidebar.tsx index aefff1493..2f0d69e01 100644 --- a/frontend/src/app/scripts/_components/sidebar.tsx +++ b/frontend/src/app/scripts/_components/sidebar.tsx @@ -2,21 +2,29 @@ import type { Category, Script } from "@/lib/types"; +import { cn } from "@/lib/utils"; + import ScriptAccordion from "./script-accordion"; +type SidebarProps = { + items: Category[]; + selectedScript: string | null; + setSelectedScript: (script: string | null) => void; + selectedCategory: string | null; + setSelectedCategory: (category: string | null) => void; + onItemSelect?: () => void; + className?: string; +}; + function Sidebar({ items, selectedScript, setSelectedScript, selectedCategory, setSelectedCategory, -}: { - items: Category[]; - selectedScript: string | null; - setSelectedScript: (script: string | null) => void; - selectedCategory: string | null; - setSelectedCategory: (category: string | null) => void; -}) { + onItemSelect, + className, +}: SidebarProps) { const uniqueScripts = items.reduce((acc, category) => { for (const script of category.scripts) { if (!acc.some(s => s.name === script.name)) { @@ -27,7 +35,7 @@ function Sidebar({ }, [] as Script[]); return ( -
+

Categories

@@ -43,6 +51,7 @@ function Sidebar({ setSelectedScript={setSelectedScript} selectedCategory={selectedCategory} setSelectedCategory={setSelectedCategory} + onItemSelect={onItemSelect} />

diff --git a/frontend/src/components/navbar.tsx b/frontend/src/components/navbar.tsx index 0d769d28c..3e51fcbe8 100644 --- a/frontend/src/components/navbar.tsx +++ b/frontend/src/components/navbar.tsx @@ -8,6 +8,7 @@ import { navbarLinks } from "@/config/site-config"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip"; import { GitHubStarsButton } from "./animate-ui/components/buttons/github-stars"; import { Button } from "./animate-ui/components/buttons/button"; +import MobileSidebar from "./navigation/mobile-sidebar"; import { ThemeToggle } from "./ui/theme-toggle"; import CommandMenu from "./command-menu"; @@ -30,21 +31,23 @@ function Navbar() { return ( <>
logo - Proxmox VE Helper-Scripts + Proxmox VE Helper-Scripts -
+
+
+ +
- + {navbarLinks.map(({ href, event, icon, text, mobileHidden }) => ( diff --git a/frontend/src/components/navigation/mobile-sidebar.tsx b/frontend/src/components/navigation/mobile-sidebar.tsx new file mode 100644 index 000000000..b4fcd9e0f --- /dev/null +++ b/frontend/src/components/navigation/mobile-sidebar.tsx @@ -0,0 +1,116 @@ +"use client"; + +import { useCallback, useEffect, useState } from "react"; +import { useQueryState } from "nuqs"; +import { Menu } from "lucide-react"; + +import type { Category, Script } from "@/lib/types"; + +import { ScriptItem } from "@/app/scripts/_components/script-item"; +import Sidebar from "@/app/scripts/_components/sidebar"; +import { fetchCategories } from "@/lib/data"; + +import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "../ui/sheet"; +import { Button } from "../ui/button"; + +function MobileSidebar() { + const [isOpen, setIsOpen] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [categories, setCategories] = useState([]); + const [lastViewedScript, setLastViewedScript] = useState