Featured products as carousel

Converted FeaturedProducts from grid to a looping carousel using the existing carousel components. Displayed 8 featured items with badge styling, added Add to Quote action, and preserved View All Products CTA. Removed ProductCard grid usage.

X-Lovable-Edit-ID: edt-3345101d-8a05-4d9c-8266-0674e521ac5f
This commit is contained in:
gpt-engineer-app[bot] 2026-01-29 22:48:58 +00:00
commit e4caa0337a

View file

@ -1,21 +1,85 @@
import { products } from '@/data/products';
import { ProductCard } from '@/components/ProductCard';
import { Button } from '@/components/ui/button';
import { Link } from 'react-router-dom';
import { ArrowRight } from 'lucide-react';
import { ArrowRight, ChevronLeft, ChevronRight } from 'lucide-react';
import { useCart } from '@/context/CartContext';
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from '@/components/ui/carousel';
// Get featured products (those with badges or first 6)
// Get featured products (those with badges or first 8)
const featuredProducts = products
.filter(p => p.badge === 'hot' || p.badge === 'new')
.slice(0, 6);
.slice(0, 8);
export function FeaturedProducts() {
const { addItem } = useCart();
return (
<div>
<div className="grid grid-cols-2 lg:grid-cols-3 gap-4">
{featuredProducts.map((product) => (
<ProductCard key={product.id} product={product} />
))}
<Carousel
opts={{
align: 'start',
loop: true,
}}
className="w-full"
>
<CarouselContent className="-ml-2 md:-ml-4">
{featuredProducts.map((product) => (
<CarouselItem key={product.id} className="pl-2 md:pl-4 basis-1/2 md:basis-1/3 lg:basis-1/4">
<div className="group relative bg-card rounded-xl overflow-hidden shadow-industrial hover:shadow-industrial-lg transition-all duration-300">
{/* Badge */}
{product.badge && (
<div className={`absolute top-3 left-3 z-10 px-2 py-1 rounded-full text-xs font-semibold uppercase tracking-wide ${
product.badge === 'hot'
? 'bg-brand-red text-brand-red-foreground'
: 'bg-brand-blue text-brand-blue-foreground'
}`}>
{product.badge}
</div>
)}
{/* Image */}
<div className="aspect-square bg-muted overflow-hidden">
<img
src={product.image}
alt={product.name}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
/>
</div>
{/* Content */}
<div className="p-4">
<p className="text-xs text-brand-yellow font-medium uppercase tracking-wide mb-1">
{product.brand}
</p>
<h3 className="font-display font-semibold text-foreground text-sm md:text-base line-clamp-2 mb-3 min-h-[2.5rem]">
{product.name}
</h3>
<Button
onClick={() => addItem(product)}
size="sm"
className="w-full bg-brand-yellow text-brand-yellow-foreground hover:bg-brand-yellow/90"
>
Add to Quote
</Button>
</div>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious className="hidden md:flex -left-4 bg-card border-border hover:bg-muted" />
<CarouselNext className="hidden md:flex -right-4 bg-card border-border hover:bg-muted" />
</Carousel>
{/* Mobile scroll indicator */}
<div className="flex justify-center gap-1 mt-4 md:hidden">
<span className="text-xs text-muted-foreground">← Swipe to see more →</span>
</div>
<div className="text-center mt-8">