From d17bb63e23c34af99d00b0a8f63ff93a9142cbad Mon Sep 17 00:00:00 2001 From: Meik Date: Wed, 5 Aug 2026 19:46:34 +0200 Subject: [PATCH] feat: move mobile slot tools into menu Brand the mobile header as Foodsharing Manager and move refresh and notification actions from the dashboard into the contextual navigation menu. --- .commitmessage | 6 ++-- public/index.html | 2 +- src/App.js | 4 +++ src/components/DashboardView.js | 23 ++---------- src/components/MobileConfigList.css | 52 --------------------------- src/components/NavigationTabs.css | 50 ++++++++++++++++++++++++-- src/components/NavigationTabs.js | 48 ++++++++++++++++++++++--- src/components/NavigationTabs.test.js | 16 +++++++++ src/components/RangePickerModal.js | 4 +-- 9 files changed, 120 insertions(+), 85 deletions(-) diff --git a/.commitmessage b/.commitmessage index 228bed0..f97276e 100644 --- a/.commitmessage +++ b/.commitmessage @@ -1,4 +1,4 @@ -feat: combine mobile navigation and account menu +feat: move mobile slot tools into menu -Replace the mobile profile card with a compact page header, account menu, and -contextual dashboard toolbar while preserving desktop behavior. +Brand the mobile header as Foodsharing Manager and move refresh and notification +actions from the dashboard into the contextual navigation menu. diff --git a/public/index.html b/public/index.html index 028cb4b..d0b59a0 100644 --- a/public/index.html +++ b/public/index.html @@ -25,7 +25,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - Foodsharing Abholung-Konfiguration + Foodsharing Manager diff --git a/src/App.js b/src/App.js index e088dcf..9dde4a5 100644 --- a/src/App.js +++ b/src/App.js @@ -873,6 +873,10 @@ function App() { onProtectedNavigate={requestNavigation} profileName={session?.profile?.name} onLogout={handleLogout} + onRefresh={() => handleRefreshStoresAndPickups({ block: false })} + onToggleNotifications={() => setNotificationPanelOpen((prev) => !prev)} + notificationPanelOpen={notificationPanelOpen} + notificationLoading={notificationLoading} /> diff --git a/src/components/DashboardView.js b/src/components/DashboardView.js index 02f13b2..5bec4de 100644 --- a/src/components/DashboardView.js +++ b/src/components/DashboardView.js @@ -760,7 +760,7 @@ const DashboardView = ({ return (
-

Foodsharing Pickup Manager

+

Foodsharing Manager

@@ -803,25 +803,6 @@ const DashboardView = ({
-
- - - {notificationLoading && Lade...} -
- {notificationPanelOpen && ( {plannedPickupEntries.length}
{plannedPickupEntries.length === 0 ? ( -

Keine aktiven Planungen im Pickup Manager.

+

Keine aktiven Planungen im Foodsharing Manager.

) : (
    {plannedPickupEntries.slice(0, 8).map((entry) => ( diff --git a/src/components/MobileConfigList.css b/src/components/MobileConfigList.css index 636402b..6452175 100644 --- a/src/components/MobileConfigList.css +++ b/src/components/MobileConfigList.css @@ -2,10 +2,6 @@ display: none; } -.dashboard-mobile-toolbar { - display: none; -} - @media (max-width: 767px) { .dashboard-session { display: none; @@ -15,54 +11,6 @@ display: none; } - .dashboard-mobile-toolbar { - display: grid; - grid-template-columns: minmax(0, 1fr) auto auto; - gap: 0.45rem; - align-items: center; - margin: 0.75rem 0 1rem; - } - - .dashboard-mobile-toolbar__refresh, - .dashboard-mobile-toolbar__notifications { - box-sizing: border-box; - min-height: 2.35rem; - border-radius: 5px; - font-size: 0.8125rem; - } - - .dashboard-mobile-toolbar__refresh { - width: 100%; - border: 1px solid #2563eb; - background: #2563eb; - color: #fff; - } - - .dashboard-mobile-toolbar__notifications { - width: 2.35rem; - height: 2.35rem; - padding: 0; - border: 1px solid #cbd5e1; - background: #fff; - color: #475569; - } - - .dashboard-mobile-toolbar__notifications svg { - width: 1rem; - height: 1rem; - } - - .dashboard-mobile-toolbar__notifications.is-active { - border-color: #2563eb; - background: #eff6ff; - color: #1d4ed8; - } - - .dashboard-mobile-toolbar__loading { - color: #64748b; - font-size: 0.75rem; - } - .mobile-config-list { display: block; padding-bottom: 5.5rem; diff --git a/src/components/NavigationTabs.css b/src/components/NavigationTabs.css index 7ce0651..a12816a 100644 --- a/src/components/NavigationTabs.css +++ b/src/components/NavigationTabs.css @@ -50,10 +50,10 @@ border-bottom: 1px solid #cbd5e1; } - .app-navigation__current-page { + .app-navigation__product-name { overflow: hidden; color: #1f2937; - font-size: 1rem; + font-size: 0.9375rem; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; @@ -117,6 +117,52 @@ border-top: 1px solid #dbe4ee; } + .app-navigation__tools { + display: grid; + gap: 0.35rem; + padding-top: 0.75rem; + border-top: 1px solid #dbe4ee; + } + + .app-navigation__tools > span { + color: #64748b; + font-size: 0.75rem; + font-weight: 500; + } + + .app-navigation__tool { + display: flex; + align-items: center; + gap: 0.6rem; + width: 100%; + min-height: 2.5rem; + border: 1px solid #dbe4ee; + border-radius: 5px; + padding: 0.55rem 0.7rem; + background: #fff; + color: #334155; + font-size: 0.875rem; + font-weight: 500; + text-align: left; + } + + .app-navigation__tool svg { + flex: 0 0 auto; + width: 1rem; + height: 1rem; + } + + .app-navigation__tool.is-active { + border-color: #2563eb; + background: #eff6ff; + color: #1d4ed8; + } + + .app-navigation__tools small { + color: #64748b; + font-size: 0.75rem; + } + .app-navigation__account div { display: grid; min-width: 0; diff --git a/src/components/NavigationTabs.js b/src/components/NavigationTabs.js index bcfd1f6..a234617 100644 --- a/src/components/NavigationTabs.js +++ b/src/components/NavigationTabs.js @@ -2,7 +2,16 @@ import { useEffect, useMemo, useState } from 'react'; import { Link, useLocation, useNavigate } from 'react-router-dom'; import './NavigationTabs.css'; -const NavigationTabs = ({ isAdmin, onProtectedNavigate, profileName, onLogout }) => { +const NavigationTabs = ({ + isAdmin, + onProtectedNavigate, + profileName, + onLogout, + onRefresh, + onToggleNotifications, + notificationPanelOpen, + notificationLoading +}) => { const location = useLocation(); const navigate = useNavigate(); const [mobileOpen, setMobileOpen] = useState(false); @@ -20,8 +29,6 @@ const NavigationTabs = ({ isAdmin, onProtectedNavigate, profileName, onLogout }) return items; }, [isAdmin]); - const activeTab = tabs.find((tab) => tab.to === location.pathname) || tabs[0]; - const handleClick = (event, to) => { event.preventDefault(); if (to === location.pathname) { @@ -40,6 +47,11 @@ const NavigationTabs = ({ isAdmin, onProtectedNavigate, profileName, onLogout }) setMobileOpen(false); }, [location.pathname]); + const handleToolAction = (action) => { + setMobileOpen(false); + action?.(); + }; + const renderLink = (tab, className) => { const isActive = location.pathname === tab.to; return ( @@ -58,7 +70,7 @@ const NavigationTabs = ({ isAdmin, onProtectedNavigate, profileName, onLogout }) return (