From 442e906a798f6b9f964c2e75597d3c03443f9e99 Mon Sep 17 00:00:00 2001 From: Randall Stillwell Date: Fri, 1 Aug 2025 18:18:21 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20Implement=20Mobile-First=20Navig?= =?UTF-8?q?ation=20System?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ Features Implemented: • Mobile bottom navigation bar (Cards, Decks, Dashboard, Community, More) • Raised primary Dashboard button with gradient styling • Slide-out drawer menu from 'More' button • Responsive layout: mobile bottom nav + desktop sidebar • Backdrop blur effects and safe area support 🎯 Navigation Structure: • Cards - Browse trading cards • Decks - Manage decks • Dashboard - Primary home button (raised/prominent) • Community - Social features • More - Full menu drawer with all options 📱 Responsive Design: • Mobile (<768px): Bottom nav + drawer menu • Desktop (≥768px): Traditional left sidebar • Content padding adjustments for mobile nav • Touch-friendly sizing and animations 🔧 Technical Changes: • Created MobileNavigation.js component • Completely rewrote Layout.js with mobile-first approach • Added NavigationContent shared component • Enhanced CSS with mobile-specific styles • Proper accessibility and keyboard support Ready for mobile testing! 🔥📱✨ --- components/Layout.js | 771 ++++++++++++++++++--------------- components/Layout.js.backup | 709 ++++++++++++++++++++++++++++++ components/MobileNavigation.js | 171 ++++++++ styles/globals.css | 28 ++ 4 files changed, 1327 insertions(+), 352 deletions(-) create mode 100644 components/Layout.js.backup create mode 100644 components/MobileNavigation.js diff --git a/components/Layout.js b/components/Layout.js index 8d898fb..97db117 100644 --- a/components/Layout.js +++ b/components/Layout.js @@ -2,6 +2,7 @@ import { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import Link from 'next/link'; import { useTheme } from '../lib/theme-context'; +import MobileNavigation from './MobileNavigation'; // User Profile Dropdown Component function UserProfileDropdown({ user, onMobileMenuClose }) { @@ -122,11 +123,8 @@ function UserProfileDropdown({ user, onMobileMenuClose }) { ); } -export default function Layout({ children, user = { email: 'me@randallstillwell.com', role: 'user' }, showSearch = false }) { - const router = useRouter(); - const { theme, toggleTheme } = useTheme(); - const [searchQuery, setSearchQuery] = useState(''); - const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); +// Navigation Content Component - Shared between desktop and mobile +function NavigationContent({ user, router, onItemClick }) { const [isCommunityExpanded, setIsCommunityExpanded] = useState( router.pathname.startsWith('/community') ); @@ -146,10 +144,10 @@ export default function Layout({ children, user = { email: 'me@randallstillwell. // My Collection section (only for authenticated users) const myCollectionNavigation = user ? { name: 'My Collection', - href: '/dashboard', // My Collection itself links to dashboard + href: '/dashboard', icon: 'collection', active: router.pathname === '/dashboard' || router.pathname === '/collections' || router.pathname === '/my-cards' || router.pathname === '/decks' || router.pathname === '/analytics', - expanded: true, // Always expanded for now + expanded: true, items: [ { name: 'Collections', href: '/collections', active: router.pathname === '/collections' }, { name: 'Cards', href: '/my-cards', active: router.pathname === '/my-cards' }, @@ -182,12 +180,6 @@ export default function Layout({ children, user = { email: 'me@randallstillwell. ] }; - const bottomNavigation = [ - { name: 'Notifications', href: '/notifications', icon: 'notifications', active: router.pathname === '/notifications' }, - { name: 'Settings', href: '/settings', icon: 'settings', active: router.pathname === '/settings' }, - { name: 'Logout', href: '/logout', icon: 'logout', active: router.pathname === '/logout' } - ]; - const getIcon = (iconName) => { const icons = { grid: ( @@ -257,42 +249,346 @@ export default function Layout({ children, user = { email: 'me@randallstillwell. return icons[iconName] || icons.grid; }; + return ( + <> + {/* Authenticated User Navigation - Activity */} + {authenticatedNavigation.map((item) => ( +
+ {item.isPlaceholder ? ( +
+
+ + {item.name} +
+ + Coming Soon + +
+ ) : ( + +
+
+ + {item.name} +
+
+ + )} +
+ ))} + + {/* My Collection Section (only for authenticated users) */} + {myCollectionNavigation && ( +
+ {/* My Collection Header - Clickable */} + +
+
+ + {myCollectionNavigation.name} +
+
+ + + {/* My Collection Sub-items */} + {myCollectionNavigation.expanded && ( +
+ {myCollectionNavigation.items.map((subItem) => ( +
+ {subItem.isPlaceholder ? ( +
+ {subItem.name} + + Soon + +
+ ) : ( + +
+ {subItem.name} +
+ + )} +
+ ))} +
+ )} +
+ )} + + {/* Separator */} +
+ + {/* Public Navigation (always visible) */} + {publicNavigation.map((item) => ( +
+ {item.isPlaceholder ? ( +
+
+ + {item.name} +
+ + Coming Soon + +
+ ) : ( + +
+
+ + {item.name} +
+
+ + )} +
+ ))} + + {/* Community Section with Sub-items */} +
+
setIsCommunityExpanded(!isCommunityExpanded)} + role="menuitem" + aria-expanded={isCommunityExpanded} + aria-haspopup="menu" + tabIndex={0} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + setIsCommunityExpanded(!isCommunityExpanded); + } + }} + > +
+ + {communityNavigation.name} +
+ +
+ + {/* Community Sub-items */} + {isCommunityExpanded && ( +
+ {communityNavigation.items.map((subItem) => ( + +
{ + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + onItemClick(); + } + }} + > + {subItem.name} +
+ + ))} +
+ )} +
+ + {/* Admin Navigation (if admin user) */} + {adminNavigation.map((item) => ( + +
+
+ + {item.name} +
+ {item.badge && ( + + {item.badge} + + )} +
+ + ))} + + ); +} + +export default function Layout({ children, user = { email: 'me@randallstillwell.com', role: 'user' }, showSearch = false }) { + const router = useRouter(); + const { theme, toggleTheme } = useTheme(); + const [searchQuery, setSearchQuery] = useState(''); + const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); + return (
- {/* Mobile Menu Button */} - + {/* Mobile Navigation - Bottom bar for mobile */} + setIsMobileMenuOpen(true)} + /> {/* Mobile Overlay */} {isMobileMenuOpen && (
setIsMobileMenuOpen(false)} /> )} - {/* Left Sidebar */} + {/* Mobile Menu Drawer - Slides in from left when "More" is tapped */}
- {/* Mobile Close Button */} -
+ {/* Mobile Header with Close Button */} +
DH @@ -314,324 +610,18 @@ export default function Layout({ children, user = { email: 'me@randallstillwell.
- - {/* Desktop Header */} -
-
- DH -
-

Deck Hearth

-
-