Spaces:
Running
Running
File size: 3,469 Bytes
b89a86e 1684141 b89a86e b091b61 b89a86e b091b61 b89a86e b091b61 b89a86e 1684141 b091b61 1684141 b091b61 1684141 b091b61 b89a86e b091b61 1684141 b89a86e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
import { Link, useLocation } from "wouter";
import { useAuth } from "@/hooks/use-auth";
import { useCart } from "@/hooks/use-cart";
import {
Home,
Search,
ShoppingCart,
User,
Package
} from "lucide-react";
export default function MobileBottomNav() {
const [location] = useLocation();
const { isAuthenticated, user, userType } = useAuth();
const { itemCount } = useCart();
// Hide navigation on admin pages since they have their own floating nav
if (location.startsWith('/admin-prospective')) {
return null;
}
const isActive = (path: string) => {
if (path === '/') {
return location === '/';
}
return location.startsWith(path);
};
const navItems = [
{
id: 'home',
label: 'Home',
path: '/',
icon: Home,
active: isActive('/'),
isLink: true
},
{
id: 'search',
label: 'Search',
path: '/search',
icon: Search,
active: isActive('/search'),
isLink: true
},
...(isAuthenticated && userType === 'user' ? [{
id: 'orders',
label: 'Track Orders',
path: '/orders',
icon: Package,
active: isActive('/orders'),
isLink: true
}] : []),
{
id: 'cart',
label: 'Cart',
path: '/cart',
icon: ShoppingCart,
active: isActive('/cart'),
badge: itemCount > 0 ? itemCount : undefined,
isLink: true
},
{
id: 'profile',
label: isAuthenticated ? 'Profile' : 'Sign In',
path: isAuthenticated ? '/profile' : '/auth',
icon: isAuthenticated ? (userType === 'seller' ? Package : User) : User,
active: isActive(isAuthenticated ? '/profile' : '/auth'),
isLink: true
}
];
return (
<div className="fixed bottom-6 left-1/2 transform -translate-x-1/2 z-50">
{/* Floating Navigation Card */}
<nav className="bg-white/80 backdrop-blur-xl border border-gray-200/30 rounded-2xl shadow-lg px-4 py-3 flex items-center space-x-2">
{navItems.map((item) => {
const IconComponent = item.icon;
return (
<a key={item.id} href={item.path} className="no-underline">
<button
className={`relative flex flex-col items-center justify-center p-3 rounded-xl transition-all duration-200 ${
item.active
? 'text-purple-600 bg-purple-50'
: 'text-gray-500 hover:text-purple-600 hover:bg-gray-50'
}`}
data-testid={`mobile-nav-${item.id}`}
>
{/* Icon with Badge */}
<div className="relative">
<IconComponent className="h-6 w-6" />
{item.badge && (
<span
className="absolute -top-2 -right-2 h-5 w-5 flex items-center justify-center text-xs bg-red-500 text-white rounded-full"
data-testid={`mobile-nav-badge-${item.id}`}
>
{item.badge > 99 ? '99+' : item.badge}
</span>
)}
</div>
{/* Active Indicator */}
{item.active && (
<div className="absolute top-1/2 left-0 transform -translate-y-1/2 w-1 h-6 bg-purple-600 rounded-r-full"></div>
)}
</button>
</a>
);
})}
</nav>
</div>
);
} |