-
-
-
-
-
- {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 (
<>
-
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