ecom / client /src /components /layout /mobile-bottom-nav.tsx
shashwatIDR's picture
Upload 106 files
1684141 verified
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>
);
}