✨ Update bottom navigation with raised scanner button
- Change Dashboard to Home in navigation - Add raised purple scanner button in center - Implement new nav layout: Home | Cards | Scanner | Collections | More - Scanner button features elevated design with purple gradient - Add proper active/inactive states for all nav items - Remove unused navigationItems array to fix linting warning - Perfect spacing with justify-around layout
This commit is contained in:
parent
0a03f0ed14
commit
708c68fb07
1 changed files with 100 additions and 92 deletions
|
|
@ -3,13 +3,6 @@ import { Link, useLocation, useNavigate } from 'react-router-dom';
|
|||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
|
||||
interface NavigationItem {
|
||||
name: string;
|
||||
href: string;
|
||||
icon: React.ReactNode;
|
||||
activeIcon?: React.ReactNode;
|
||||
}
|
||||
|
||||
const MobileNavbar: React.FC = () => {
|
||||
const { user, logout, isAdmin } = useAuth();
|
||||
const { toggleTheme, effectiveTheme } = useTheme();
|
||||
|
|
@ -17,70 +10,6 @@ const MobileNavbar: React.FC = () => {
|
|||
const navigate = useNavigate();
|
||||
const [showUserMenu, setShowUserMenu] = useState(false);
|
||||
|
||||
const navigationItems: NavigationItem[] = [
|
||||
{
|
||||
name: 'Dashboard',
|
||||
href: '/dashboard',
|
||||
icon: (
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
|
||||
</svg>
|
||||
),
|
||||
activeIcon: (
|
||||
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'Cards',
|
||||
href: '/cards',
|
||||
icon: (
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||
</svg>
|
||||
),
|
||||
activeIcon: (
|
||||
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'Scanner',
|
||||
href: '/scanner',
|
||||
icon: (
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
),
|
||||
activeIcon: (
|
||||
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path fillRule="evenodd" d="M1.5 6a2.25 2.25 0 012.25-2.25h1.386c.17 0 .318.114.362.278l.558 2.047c.25.895 1.03 1.425 1.944 1.425H19.5a2.25 2.25 0 012.25 2.25v6.75a2.25 2.25 0 01-2.25 2.25H4.5A2.25 2.25 0 012.25 18V9.75a2.25 2.25 0 012.25-2.25H1.5V6zM12 15a3 3 0 100-6 3 3 0 000 6z" clipRule="evenodd" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'Collections',
|
||||
href: '/collections',
|
||||
icon: (
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'More',
|
||||
href: '/menu',
|
||||
icon: (
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const handleLogout = () => {
|
||||
logout();
|
||||
setShowUserMenu(false);
|
||||
|
|
@ -143,27 +72,106 @@ const MobileNavbar: React.FC = () => {
|
|||
|
||||
{/* Bottom Navigation */}
|
||||
<nav className="fixed bottom-0 left-0 right-0 z-50 bg-white dark:bg-surface-900 border-t border-surface-200 dark:border-surface-700 safe-area-inset-bottom">
|
||||
<div className="grid grid-cols-5 px-2 py-2">
|
||||
{navigationItems.map((item) => (
|
||||
<div className="relative flex items-end justify-around px-4 py-2">
|
||||
{/* Home */}
|
||||
<Link
|
||||
key={item.name}
|
||||
to={item.href === '/menu' ? '#' : item.href}
|
||||
onClick={item.href === '/menu' ? (e) => {
|
||||
e.preventDefault();
|
||||
setShowUserMenu(true);
|
||||
} : undefined}
|
||||
to="/dashboard"
|
||||
className={`flex flex-col items-center justify-center p-2 rounded-xl transition-all duration-200 ${
|
||||
isActive(item.href) && item.href !== '/menu'
|
||||
? 'text-primary-600 dark:text-primary-400 bg-primary-50 dark:bg-primary-900/30'
|
||||
: 'text-surface-600 dark:text-surface-400 hover:text-surface-900 dark:hover:text-white hover:bg-surface-100 dark:hover:bg-surface-800'
|
||||
isActive('/dashboard')
|
||||
? 'text-primary-600 dark:text-primary-400'
|
||||
: 'text-surface-600 dark:text-surface-400 hover:text-surface-900 dark:hover:text-white'
|
||||
}`}
|
||||
>
|
||||
<div className="mb-1">
|
||||
{isActive(item.href) && item.activeIcon ? item.activeIcon : item.icon}
|
||||
{isActive('/dashboard') ? (
|
||||
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
|
||||
</svg>
|
||||
) : (
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
<span className="text-xs font-medium">{item.name}</span>
|
||||
<span className="text-xs font-medium">Home</span>
|
||||
</Link>
|
||||
))}
|
||||
|
||||
{/* Cards */}
|
||||
<Link
|
||||
to="/cards"
|
||||
className={`flex flex-col items-center justify-center p-2 rounded-xl transition-all duration-200 ${
|
||||
isActive('/cards')
|
||||
? 'text-primary-600 dark:text-primary-400'
|
||||
: 'text-surface-600 dark:text-surface-400 hover:text-surface-900 dark:hover:text-white'
|
||||
}`}
|
||||
>
|
||||
<div className="mb-1">
|
||||
{isActive('/cards') ? (
|
||||
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||
</svg>
|
||||
) : (
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
<span className="text-xs font-medium">Cards</span>
|
||||
</Link>
|
||||
|
||||
{/* Scanner - Special Raised Button */}
|
||||
<Link
|
||||
to="/scanner"
|
||||
className="relative flex flex-col items-center justify-center -mt-6 mb-2"
|
||||
>
|
||||
<div className={`w-14 h-14 rounded-full shadow-lg transition-all duration-200 flex items-center justify-center ${
|
||||
isActive('/scanner')
|
||||
? 'bg-gradient-to-r from-primary-600 to-accent-600 shadow-primary-500/25 shadow-xl'
|
||||
: 'bg-gradient-to-r from-primary-500 to-accent-500 hover:from-primary-600 hover:to-accent-600 shadow-primary-500/20 hover:shadow-xl'
|
||||
}`}>
|
||||
<svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<span className="text-xs font-medium text-primary-600 dark:text-primary-400 mt-1">Scanner</span>
|
||||
</Link>
|
||||
|
||||
{/* Collections */}
|
||||
<Link
|
||||
to="/collections"
|
||||
className={`flex flex-col items-center justify-center p-2 rounded-xl transition-all duration-200 ${
|
||||
isActive('/collections')
|
||||
? 'text-primary-600 dark:text-primary-400'
|
||||
: 'text-surface-600 dark:text-surface-400 hover:text-surface-900 dark:hover:text-white'
|
||||
}`}
|
||||
>
|
||||
<div className="mb-1">
|
||||
{isActive('/collections') ? (
|
||||
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M7 4V2a1 1 0 011-1h8a1 1 0 011 1v2h3a1 1 0 110 2h-1v10a2 2 0 01-2 2H7a2 2 0 01-2-2V6H4a1 1 0 010-2h3zM9 4h6V3H9v1zm8 2H7v10h10V6z"/>
|
||||
</svg>
|
||||
) : (
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
<span className="text-xs font-medium">Collections</span>
|
||||
</Link>
|
||||
|
||||
{/* More */}
|
||||
<button
|
||||
onClick={() => setShowUserMenu(true)}
|
||||
className="flex flex-col items-center justify-center p-2 rounded-xl transition-all duration-200 text-surface-600 dark:text-surface-400 hover:text-surface-900 dark:hover:text-white"
|
||||
>
|
||||
<div className="mb-1">
|
||||
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
||||
</svg>
|
||||
</div>
|
||||
<span className="text-xs font-medium">More</span>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue