Skip to content

Commit b52c252

Browse files
authored
fix sidebar loading issues and navbar on mobile (#7991)
* Refactor MobileSidebar to manage script and category selection based on current pathname. Introduced temporary state for non-scripts pages and updated logic for last viewed script handling. Improved accessibility by ensuring proper aria attributes and class management. * Update API endpoint paths in data.ts to include ProxmoxVE prefix for category and version fetching functions. * Refactor Navbar component layout for improved structure and responsiveness. Adjusted flex properties to ensure proper alignment of elements, enhancing the mobile and desktop user experience. Updated accessibility features and ensured consistent use of TailwindCSS classes.
1 parent be5ac71 commit b52c252

File tree

3 files changed

+52
-33
lines changed

3 files changed

+52
-33
lines changed

frontend/src/components/navbar.tsx

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,32 +42,34 @@ function Navbar() {
4242
<Image height={18} unoptimized width={18} alt="logo" src="/ProxmoxVE/logo.png" className="" />
4343
<span className="">Proxmox VE Helper-Scripts</span>
4444
</Link>
45-
<div className="flex items-center gap-2">
45+
<div className="flex items-center justify-between gap-2 w-full">
4646
<div className="flex sm:hidden">
4747
<Suspense>
4848
<MobileSidebar />
4949
</Suspense>
5050
</div>
51-
<CommandMenu />
52-
<GitHubStarsButton username="community-scripts" repo="ProxmoxVE" className="hidden md:flex" />
53-
{navbarLinks.map(({ href, event, icon, text, mobileHidden }) => (
54-
<TooltipProvider key={event}>
55-
<Tooltip delayDuration={100}>
56-
<TooltipTrigger className={mobileHidden ? "hidden lg:block" : ""}>
57-
<Button variant="ghost" size="icon" asChild>
58-
<Link target="_blank" href={href} data-umami-event={event}>
59-
{icon}
60-
<span className="sr-only">{text}</span>
61-
</Link>
62-
</Button>
63-
</TooltipTrigger>
64-
<TooltipContent side="bottom" className="text-xs">
65-
{text}
66-
</TooltipContent>
67-
</Tooltip>
68-
</TooltipProvider>
69-
))}
70-
<ThemeToggle />
51+
<div className="flex sm:gap-2">
52+
<CommandMenu />
53+
<GitHubStarsButton username="community-scripts" repo="ProxmoxVE" className="hidden md:flex" />
54+
{navbarLinks.map(({ href, event, icon, text, mobileHidden }) => (
55+
<TooltipProvider key={event}>
56+
<Tooltip delayDuration={100}>
57+
<TooltipTrigger className={mobileHidden ? "hidden lg:block" : ""}>
58+
<Button variant="ghost" size="icon" asChild>
59+
<Link target="_blank" href={href} data-umami-event={event}>
60+
{icon}
61+
<span className="sr-only">{text}</span>
62+
</Link>
63+
</Button>
64+
</TooltipTrigger>
65+
<TooltipContent side="bottom" className="text-xs">
66+
{text}
67+
</TooltipContent>
68+
</Tooltip>
69+
</TooltipProvider>
70+
))}
71+
<ThemeToggle />
72+
</div>
7173
</div>
7274
</div>
7375
</div>

frontend/src/components/navigation/mobile-sidebar.tsx

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22

33
import { useCallback, useEffect, useState } from "react";
4+
import { usePathname } from "next/navigation";
45
import { useQueryState } from "nuqs";
56
import { Menu } from "lucide-react";
67

@@ -18,9 +19,20 @@ function MobileSidebar() {
1819
const [isLoading, setIsLoading] = useState(false);
1920
const [categories, setCategories] = useState<Category[]>([]);
2021
const [lastViewedScript, setLastViewedScript] = useState<Script | undefined>(undefined);
22+
const pathname = usePathname();
23+
24+
// Always call the hooks (React hooks can't be conditional)
2125
const [selectedScript, setSelectedScript] = useQueryState("id");
2226
const [selectedCategory, setSelectedCategory] = useQueryState("category");
2327

28+
// For non-scripts pages, we'll manage state locally
29+
const [tempSelectedScript, setTempSelectedScript] = useState<string | null>(null);
30+
const [tempSelectedCategory, setTempSelectedCategory] = useState<string | null>(null);
31+
32+
const isOnScriptsPage = pathname === "/scripts";
33+
const currentSelectedScript = isOnScriptsPage ? selectedScript : tempSelectedScript;
34+
const currentSelectedCategory = isOnScriptsPage ? selectedCategory : tempSelectedCategory;
35+
2436
const loadCategories = useCallback(async () => {
2537
setIsLoading(true);
2638
try {
@@ -40,16 +52,16 @@ function MobileSidebar() {
4052
}, [loadCategories]);
4153

4254
useEffect(() => {
43-
if (!selectedScript || categories.length === 0) {
55+
if (!currentSelectedScript || categories.length === 0) {
4456
return;
4557
}
4658

4759
const scriptMatch = categories
4860
.flatMap(category => category.scripts)
49-
.find(script => script.slug === selectedScript);
61+
.find(script => script.slug === currentSelectedScript);
5062

5163
setLastViewedScript(scriptMatch);
52-
}, [selectedScript, categories]);
64+
}, [currentSelectedScript, categories]);
5365

5466
const handleOpenChange = (openState: boolean) => {
5567
setIsOpen(openState);
@@ -78,7 +90,9 @@ function MobileSidebar() {
7890
<Menu className="size-5" aria-hidden="true" />
7991
</Button>
8092
</SheetTrigger>
81-
<SheetHeader className="border-b border-border px-6 pb-4 pt-2"><SheetTitle className="sr-only">Categories</SheetTitle></SheetHeader>
93+
<SheetHeader className="border-b border-border px-6 pb-4 pt-2 sr-only">
94+
<SheetTitle className="sr-only">Categories</SheetTitle>
95+
</SheetHeader>
8296
<SheetContent side="left" className="flex w-full max-w-xs flex-col gap-4 overflow-hidden px-0 pb-6">
8397
<div className="flex h-full flex-col gap-4 overflow-y-auto">
8498
{isLoading && !hasLinks
@@ -91,19 +105,22 @@ function MobileSidebar() {
91105
<div className="flex flex-col gap-4 px-4">
92106
<Sidebar
93107
items={categories}
94-
selectedScript={selectedScript}
95-
setSelectedScript={setSelectedScript}
96-
selectedCategory={selectedCategory}
97-
setSelectedCategory={setSelectedCategory}
108+
selectedScript={currentSelectedScript}
109+
setSelectedScript={isOnScriptsPage ? setSelectedScript : setTempSelectedScript}
110+
selectedCategory={currentSelectedCategory}
111+
setSelectedCategory={isOnScriptsPage ? setSelectedCategory : setTempSelectedCategory}
98112
onItemSelect={handleItemSelect}
99113
/>
100114
</div>
101115
)}
102-
{selectedScript && lastViewedScript
116+
{currentSelectedScript && lastViewedScript
103117
? (
104118
<div className="flex flex-col gap-3 px-4">
105119
<p className="text-sm font-medium">Last Viewed</p>
106-
<ScriptItem item={lastViewedScript} setSelectedScript={setSelectedScript} />
120+
<ScriptItem
121+
item={lastViewedScript}
122+
setSelectedScript={isOnScriptsPage ? setSelectedScript : setTempSelectedScript}
123+
/>
107124
</div>
108125
)
109126
: null}

frontend/src/lib/data.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Category } from "./types";
22

33
export async function fetchCategories() {
4-
const response = await fetch("api/categories");
4+
const response = await fetch(`/ProxmoxVE/api/categories`);
55
if (!response.ok) {
66
throw new Error(`Failed to fetch categories: ${response.statusText}`);
77
}
@@ -10,7 +10,7 @@ export async function fetchCategories() {
1010
}
1111

1212
export async function fetchVersions() {
13-
const response = await fetch(`api/versions`);
13+
const response = await fetch(`/ProxmoxVE/api/versions`);
1414
if (!response.ok) {
1515
throw new Error(`Failed to fetch versions: ${response.statusText}`);
1616
}

0 commit comments

Comments
 (0)