ecom / client /src /components /category /category-nav.tsx
shashwatIDR's picture
Upload 106 files
1684141 verified
import { Category } from "@/types";
import { Button } from "@/components/ui/button";
import {
Laptop,
Shirt,
Home,
Dumbbell,
Book,
Gamepad2,
Smartphone,
Camera,
Headphones,
Watch
} from "lucide-react";
interface CategoryNavProps {
categories: Category[];
selectedCategory: string;
onCategorySelect: (categoryId: string) => void;
}
const getCategoryIcon = (iconName?: string) => {
const iconMap: { [key: string]: React.ComponentType<any> } = {
'fa-laptop': Laptop,
'fa-tshirt': Shirt,
'fa-home': Home,
'fa-dumbbell': Dumbbell,
'fa-book': Book,
'fa-gamepad': Gamepad2,
'fa-mobile': Smartphone,
'fa-camera': Camera,
'fa-headphones': Headphones,
'fa-clock': Watch,
};
const IconComponent = iconName ? iconMap[iconName] || Laptop : Laptop;
return IconComponent;
};
const getDefaultIcon = (categoryName: string) => {
const name = categoryName.toLowerCase();
if (name.includes('electronics') || name.includes('tech')) return Laptop;
if (name.includes('fashion') || name.includes('clothing')) return Shirt;
if (name.includes('home') || name.includes('furniture')) return Home;
if (name.includes('sports') || name.includes('fitness')) return Dumbbell;
if (name.includes('books') || name.includes('education')) return Book;
if (name.includes('gaming') || name.includes('games')) return Gamepad2;
if (name.includes('mobile') || name.includes('phone')) return Smartphone;
if (name.includes('camera') || name.includes('photo')) return Camera;
if (name.includes('audio') || name.includes('music')) return Headphones;
if (name.includes('watch') || name.includes('time')) return Watch;
return Laptop;
};
export default function CategoryNav({ categories, selectedCategory, onCategorySelect }: CategoryNavProps) {
// Ensure categories is an array
const categoryList = Array.isArray(categories) ? categories : [];
return (
<div className="w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8" data-testid="category-nav">
{/* Modern Pill Chips Layout */}
<div className="flex gap-3 overflow-x-auto scrollbar-hide pb-4">
{/* All Categories Chip */}
<button
className={`flex items-center gap-2 px-6 py-3 rounded-full transition-all duration-200 whitespace-nowrap ${
selectedCategory === ''
? 'bg-gradient-to-r from-orange-500 to-red-500 text-white shadow-lg ring-2 ring-orange-200'
: 'bg-white text-gray-700 hover:text-orange-600 shadow-sm hover:shadow-md border border-gray-200 hover:border-orange-200'
}`}
onClick={() => onCategorySelect('')}
data-testid="category-all"
>
<Laptop className={`h-4 w-4 ${selectedCategory === '' ? 'text-white' : 'text-gray-500'}`} />
<span className="text-sm font-semibold">All Products</span>
</button>
{/* Category Chips */}
{categoryList.map((category) => {
const IconComponent = category.icon ? getCategoryIcon(category.icon) : getDefaultIcon(category.name);
const isSelected = selectedCategory === category.id;
return (
<button
key={category.id}
className={`flex items-center gap-2 px-6 py-3 rounded-full transition-all duration-200 whitespace-nowrap ${
isSelected
? 'bg-gradient-to-r from-orange-500 to-red-500 text-white shadow-lg ring-2 ring-orange-200'
: 'bg-white text-gray-700 hover:text-orange-600 shadow-sm hover:shadow-md border border-gray-200 hover:border-orange-200'
}`}
onClick={() => onCategorySelect(category.id)}
data-testid={`category-${category.id}`}
>
<IconComponent className={`h-4 w-4 ${isSelected ? 'text-white' : 'text-gray-500'}`} />
<span className="text-sm font-semibold">{category.name}</span>
</button>
);
})}
</div>
</div>
);
}