From 42cdfdbd749cc1fa9a623bde03df4fff4f1e69fd Mon Sep 17 00:00:00 2001 From: maziggy Date: Tue, 9 Dec 2025 12:55:59 +0000 Subject: [PATCH] * Add comprehensive mobile support with responsive navigation - Add hamburger drawer navigation for mobile (< 768px) - Create useIsMobile hook for responsive breakpoint detection - Create useLongPress hook for touch gesture context menus - Update Button component with 44px min-height for WCAG touch compliance - Update Toggle component with larger mobile size (44x28px) - Add responsive padding (p-4 md:p-8) to all pages - Update ArchivesPage with mobile menu button and horizontal scroll filters - Update SettingsPage with stacked column layout on mobile - Increase drag handle sizes for touch-friendly reordering - Add CSS utilities for touch-manipulation and safe-area insets --- frontend/src/components/Button.tsx | 6 +- frontend/src/components/Dashboard.tsx | 2 +- .../src/components/ExternalLinksSettings.tsx | 2 +- frontend/src/components/Layout.tsx | 104 +- frontend/src/components/Toggle.tsx | 4 +- frontend/src/hooks/useIsMobile.ts | 26 + frontend/src/hooks/useLongPress.ts | 46 + frontend/src/index.css | 38 + frontend/src/pages/ArchivesPage.tsx | 53 +- frontend/src/pages/MaintenancePage.tsx | 4 +- frontend/src/pages/PrintersPage.tsx | 2 +- frontend/src/pages/ProfilesPage.tsx | 2 +- frontend/src/pages/QueuePage.tsx | 6 +- frontend/src/pages/SettingsPage.tsx | 12 +- frontend/src/pages/StatsPage.tsx | 4 +- static/assets/index-BDGCrNHI.css | 1 + static/assets/index-CcC-KyfM.css | 1 - static/assets/index-DHVVjLkT.js | 8611 ----------------- static/assets/index-iXqNZkoR.js | 8611 +++++++++++++++++ static/index.html | 4 +- 20 files changed, 8857 insertions(+), 8682 deletions(-) create mode 100644 frontend/src/hooks/useIsMobile.ts create mode 100644 frontend/src/hooks/useLongPress.ts create mode 100644 static/assets/index-BDGCrNHI.css delete mode 100644 static/assets/index-CcC-KyfM.css delete mode 100644 static/assets/index-DHVVjLkT.js create mode 100644 static/assets/index-iXqNZkoR.js diff --git a/frontend/src/components/Button.tsx b/frontend/src/components/Button.tsx index fe6f106e3..e4bcc04fd 100644 --- a/frontend/src/components/Button.tsx +++ b/frontend/src/components/Button.tsx @@ -26,9 +26,9 @@ export function Button({ }; const sizes = { - sm: 'px-3 py-1.5 text-sm gap-1.5', - md: 'px-4 py-2 text-sm gap-2', - lg: 'px-6 py-3 text-base gap-2', + sm: 'px-3 py-1.5 text-sm gap-1.5 min-h-[44px] md:min-h-0', + md: 'px-4 py-2 text-sm gap-2 min-h-[44px] md:min-h-0', + lg: 'px-6 py-3 text-base gap-2 min-h-[48px] md:min-h-0', }; return ( diff --git a/frontend/src/components/Dashboard.tsx b/frontend/src/components/Dashboard.tsx index 3cf38a658..28661cedd 100644 --- a/frontend/src/components/Dashboard.tsx +++ b/frontend/src/components/Dashboard.tsx @@ -93,7 +93,7 @@ function SortableWidget({ className="cursor-grab active:cursor-grabbing p-1 hover:bg-bambu-dark-tertiary rounded transition-colors" title="Drag to reorder" > - +

{title}

diff --git a/frontend/src/components/ExternalLinksSettings.tsx b/frontend/src/components/ExternalLinksSettings.tsx index 1aae299ff..d794480b6 100644 --- a/frontend/src/components/ExternalLinksSettings.tsx +++ b/frontend/src/components/ExternalLinksSettings.tsx @@ -117,7 +117,7 @@ export function ExternalLinksSettings() { draggedId === link.id ? 'opacity-50' : '' }`} > - +
diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx index 45b2c3f1c..1991affd7 100644 --- a/frontend/src/components/Layout.tsx +++ b/frontend/src/components/Layout.tsx @@ -1,12 +1,13 @@ import { useState, useEffect, useCallback, useRef } from 'react'; import { NavLink, Outlet, useNavigate, useLocation } from 'react-router-dom'; -import { Printer, Archive, Calendar, BarChart3, Cloud, Settings, Sun, Moon, ChevronLeft, ChevronRight, Keyboard, Github, GripVertical, ArrowUpCircle, Wrench, X, type LucideIcon } from 'lucide-react'; +import { Printer, Archive, Calendar, BarChart3, Cloud, Settings, Sun, Moon, ChevronLeft, ChevronRight, Keyboard, Github, GripVertical, ArrowUpCircle, Wrench, X, Menu, type LucideIcon } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { useTheme } from '../contexts/ThemeContext'; import { KeyboardShortcutsModal } from './KeyboardShortcutsModal'; import { useQuery } from '@tanstack/react-query'; import { api } from '../api/client'; import { getIconByName } from './IconPicker'; +import { useIsMobile } from '../hooks/useIsMobile'; interface NavItem { id: string; @@ -63,10 +64,12 @@ export function Layout() { const location = useLocation(); const { theme, toggleTheme } = useTheme(); const { t } = useTranslation(); + const isMobile = useIsMobile(); const [sidebarExpanded, setSidebarExpanded] = useState(() => { const stored = localStorage.getItem('sidebarExpanded'); return stored !== 'false'; }); + const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false); const [showShortcuts, setShowShortcuts] = useState(false); const [sidebarOrder, setSidebarOrder] = useState(getSidebarOrder); const [draggedId, setDraggedId] = useState(null); @@ -219,6 +222,13 @@ export function Layout() { localStorage.setItem('sidebarExpanded', String(sidebarExpanded)); }, [sidebarExpanded]); + // Close mobile drawer on navigation + useEffect(() => { + if (isMobile) { + setMobileDrawerOpen(false); + } + }, [location.pathname, isMobile]); + // Global keyboard shortcuts for navigation const handleKeyDown = useCallback((e: KeyboardEvent) => { const target = e.target as HTMLElement; @@ -259,16 +269,46 @@ export function Layout() { return (
- {/* Sidebar */} -