Spaces:
Running
Running
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> | |
); | |
} | |