diff --git a/src/components/DesktopNavManager.tsx b/src/components/DesktopNavManager.tsx new file mode 100644 index 0000000..73c0416 --- /dev/null +++ b/src/components/DesktopNavManager.tsx @@ -0,0 +1,157 @@ +import { useDesktopNavPreferences, type NavTab } from '@/hooks/useNavPreferences'; +import { useTranslation } from '@/contexts/LanguageContext'; +import { Button } from '@/components/ui/button'; +import { cn } from '@/lib/utils'; +import { ArrowUp, ArrowDown, Eye, EyeOff, Lock, RotateCcw, Monitor } from 'lucide-react'; + +/** + * Desktop top-nav customizer (Settings). + * + * A lightweight list: reorder the primary top-nav tabs with up/down controls + * and toggle items shown/hidden. Map is the fixed first tab (locked). Hidden + * items still live in the header's "More" dropdown, so nothing is ever lost. + * Persists via useDesktopNavPreferences (localStorage). + */ +export function DesktopNavManager() { + const { primaryIds, hiddenIds, setPrimaryIds, reset, catalog, fixedMapTab } = + useDesktopNavPreferences(); + const { t } = useTranslation(); + + const label = (tab: NavTab) => (tab.labelKey ? t(tab.labelKey) : tab.label); + const byId = (id: string) => catalog.find((c) => c.id === id); + + const move = (id: string, dir: -1 | 1) => { + const idx = primaryIds.indexOf(id); + const next = idx + dir; + if (idx < 0 || next < 0 || next >= primaryIds.length) return; + const copy = [...primaryIds]; + [copy[idx], copy[next]] = [copy[next], copy[idx]]; + setPrimaryIds(copy); + }; + + const hide = (id: string) => setPrimaryIds(primaryIds.filter((x) => x !== id)); + const show = (id: string) => setPrimaryIds([...primaryIds, id]); + + return ( +
+
+
+ +
+
+

Desktop navigation

+

+ Choose which tabs appear in the top bar and their order. Hidden tabs + still live in the “More” menu. +

+
+
+ + {/* Fixed Map tab */} +
+ + {label(fixedMapTab)} + + Fixed + +
+ + {/* Shown (primary) tabs — reorderable */} +
+

+ Shown in top bar ({primaryIds.length}) +

+ {primaryIds.length === 0 && ( +

+ No extra tabs shown — everything is in the “More” menu. Add some below. +

+ )} + {primaryIds.map((id, i) => { + const tab = byId(id); + if (!tab) return null; + return ( +
+ + {label(tab)} + + + +
+ ); + })} +
+ + {/* Hidden tabs — available to add */} + {hiddenIds.length > 0 && ( +
+

+ In “More” menu ({hiddenIds.length}) +

+ {hiddenIds.map((id) => { + const tab = byId(id); + if (!tab) return null; + return ( +
+ + + {label(tab)} + + +
+ ); + })} +
+ )} + +
+ +
+
+ ); +} diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 4cb1955..a5af17c 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -2,7 +2,7 @@ import { useState, useRef } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { cn } from '@/lib/utils'; import { CustomizeNavSheet } from '@/components/CustomizeNavSheet'; -import { useNavPreferences, type NavTab } from '@/hooks/useNavPreferences'; +import { useNavPreferences, useDesktopNavPreferences, type NavTab } from '@/hooks/useNavPreferences'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Sheet, SheetContent, SheetTrigger, SheetTitle } from '@/components/ui/sheet'; @@ -394,6 +394,12 @@ export function Layout({ children, noPadding }: LayoutProps) { const displayName = author.data?.metadata?.name ?? genUserName(user?.pubkey); const userAvatar = author.data?.metadata?.picture; const { fixedMapTab, middleTabs } = useNavPreferences(); + const { + primaryTabs: desktopPrimaryTabs, + hiddenIds: desktopHiddenIds, + fixedMapTab: desktopMapTab, + catalog: desktopCatalog, + } = useDesktopNavPreferences(); const isActive = (path: string) => { // Both / and /map are the "spots" page @@ -418,9 +424,10 @@ export function Layout({ children, noPadding }: LayoutProps) {