@@ -12,7 +12,7 @@ function MobileTabBar({ tabs, activeId, onChange, className = 'mb-6' }) {
role="tab"
aria-selected={activeId === tab.id}
onClick={() => onChange(tab.id)}
- className={`flex items-center gap-2 px-4 py-2 rounded-full whitespace-nowrap text-sm font-medium transition-colors flex-shrink-0 ${
+ className={`flex items-center gap-2 px-4 py-2.5 min-h-[44px] rounded-full whitespace-nowrap text-sm font-medium transition-colors flex-shrink-0 ${
activeId === tab.id
? 'bg-primary-500/10 text-primary ring-1 ring-primary-500/25'
: 'text-secondary hover:text-primary hover:bg-surface-hover'
diff --git a/frontend/src/components/Navbar.jsx b/frontend/src/components/Navbar.jsx
index 5eeadd7..2777147 100644
--- a/frontend/src/components/Navbar.jsx
+++ b/frontend/src/components/Navbar.jsx
@@ -7,6 +7,7 @@ import { ICON_STROKE } from './IconTile'
import { dashboardNavItems } from './DashboardSidebar'
import ThemeToggle from './ThemeToggle'
import { useTheme } from '../context/ThemeContext'
+import { useDashboardNavBridge } from '../context/DashboardNavBridge'
import { getUserButtonAppearance } from '../utils/clerkAppearance'
import BrandLogo from './BrandLogo'
import { BRAND_NAME_DISPLAY } from '../constants/brand'
@@ -58,20 +59,39 @@ function Navbar() {
const { theme } = useTheme()
const location = useLocation()
const menuButtonRef = useRef(null)
+ const dashboardNav = useDashboardNavBridge()
+ const openDashboardSidebar = dashboardNav?.openSidebar
+ const closeDashboardSidebar = dashboardNav?.closeSidebar
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
const [scrolled, setScrolled] = useState(false)
const onDashboard = isDashboardPath(location.pathname)
const userButtonAppearance = getUserButtonAppearance(theme)
- const showMobileMenu = !onDashboard
+ const usesDashboardDrawer = onDashboard && Boolean(dashboardNav)
+ const drawerOpen = usesDashboardDrawer && dashboardNav.sidebarOpen
+ const showMobileMenuButton = !onDashboard
+ const menuOpen = usesDashboardDrawer ? drawerOpen : mobileMenuOpen
const closeMobileMenu = () => setMobileMenuOpen(false)
- const toggleMobileMenu = () => setMobileMenuOpen((open) => !open)
+
+ const toggleMobileMenu = () => {
+ if (usesDashboardDrawer) {
+ if (dashboardNav.sidebarOpen) {
+ closeDashboardSidebar?.()
+ } else {
+ openDashboardSidebar?.()
+ }
+ return
+ }
+
+ setMobileMenuOpen((open) => !open)
+ }
useLayoutEffect(() => {
closeMobileMenu()
+ closeDashboardSidebar?.()
setScrolled(window.scrollY > 8)
- }, [location.pathname])
+ }, [location.pathname, closeDashboardSidebar])
useEffect(() => {
const handleScroll = () => setScrolled(window.scrollY > 8)
@@ -80,7 +100,7 @@ function Navbar() {
}, [])
useEffect(() => {
- if (!mobileMenuOpen) return
+ if (!mobileMenuOpen || usesDashboardDrawer) return
const previousOverflow = document.body.style.overflow
document.body.style.overflow = 'hidden'
@@ -97,7 +117,7 @@ function Navbar() {
document.body.style.overflow = previousOverflow
document.removeEventListener('keydown', handleKeyDown)
}
- }, [mobileMenuOpen])
+ }, [mobileMenuOpen, usesDashboardDrawer])
return (
@@ -107,18 +127,22 @@ function Navbar() {
scrolled ? 'navbar-scrolled' : ''
}`}
>
-
-
+
+
-
+
{/* Desktop */}
-
+
@@ -144,40 +168,66 @@ function Navbar() {
- {/* Mobile — fixed-width action slots prevent layout shift on route change */}
-
-
+ {/* Mobile */}
+
+
-
+ {!onDashboard && (
+
+
+ Dashboard
+
+ )}
+
+
+
+
- {showMobileMenu ? (
+ {showMobileMenuButton ? (
+
+
+
+ ) : (
- ) : (
-
)}
- {showMobileMenu && mobileMenuOpen && (
+ {showMobileMenuButton && mobileMenuOpen && (