111 lines
4.5 KiB
TypeScript
111 lines
4.5 KiB
TypeScript
/**
|
|
* @component RecentlyLaunched
|
|
* @purpose Section matching Electronics05 demo dynamically loaded from live DB 2 catalog products.
|
|
* @dependencies catalogService, lucide-react
|
|
*/
|
|
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import Link from 'next/link';
|
|
import Image from 'next/image';
|
|
import { ArrowRight, Star } from 'lucide-react';
|
|
import { catalogService, ProductResponse } from '@/services/api/catalogService';
|
|
import { formatCurrency, getCatalogPriceInfo, getImageUrl } from '@/lib/utils';
|
|
|
|
export function RecentlyLaunched() {
|
|
const [products, setProducts] = useState<ProductResponse[]>([]);
|
|
|
|
useEffect(() => {
|
|
catalogService.getProducts().then((res) => {
|
|
if (res && res.length > 0) {
|
|
setProducts(res.slice(0, 4));
|
|
}
|
|
});
|
|
}, []);
|
|
|
|
if (products.length === 0) return null;
|
|
|
|
return (
|
|
<section className="w-full py-6">
|
|
<div className="max-w-7xl mx-auto px-4 grid grid-cols-1 lg:grid-cols-4 gap-6 items-stretch">
|
|
{/* Left Promo Card (1/4 col) */}
|
|
<div className="lg:col-span-1 bg-linear-to-br from-slate-950 via-slate-900 to-slate-950 rounded-2xl p-6 text-white flex flex-col justify-between shadow-lg relative overflow-hidden group border border-slate-800 min-h-[320px]">
|
|
<div>
|
|
<span className="inline-block px-3 py-1 bg-red-600/30 text-red-400 border border-red-500/30 rounded-full text-xs font-bold uppercase mb-3 backdrop-blur-xs">
|
|
Recently Launched
|
|
</span>
|
|
<h3 className="text-xl font-extrabold leading-tight mb-2 tracking-tight">
|
|
Electronics Prodigy Collection
|
|
</h3>
|
|
<p className="text-xs text-gray-400 mb-4 line-clamp-2">
|
|
Next-generation high performance tech gadgets and flagship repairs
|
|
</p>
|
|
|
|
<Link
|
|
href="/products"
|
|
className="inline-flex items-center gap-2 px-4 py-2 bg-red-600 hover:bg-red-700 text-white font-bold rounded-xl text-xs transition-all shadow-md group-hover:gap-3"
|
|
>
|
|
Shop All
|
|
<ArrowRight className="w-3.5 h-3.5" />
|
|
</Link>
|
|
</div>
|
|
|
|
<div className="relative h-36 w-full mt-4 opacity-80 group-hover:scale-105 transition-transform duration-500">
|
|
</div>
|
|
</div>
|
|
|
|
{/* Right Product Grid (3/4 col -> 4 Cards) */}
|
|
<div className="lg:col-span-3 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4">
|
|
{products.map((prod) => {
|
|
const image = getImageUrl(prod.images && prod.images[0] ? prod.images[0].image_url : '');
|
|
return (
|
|
<div
|
|
key={prod.product_id}
|
|
className="bg-white border border-gray-200 rounded-2xl p-4 flex flex-col justify-between shadow-2xs hover:shadow-md hover:border-gray-300 transition-all group relative"
|
|
>
|
|
{/* Image Box */}
|
|
<div className="relative h-44 w-full mb-3 rounded-xl overflow-hidden bg-gray-50">
|
|
<Image
|
|
src={image}
|
|
alt={prod.name}
|
|
fill
|
|
className="object-cover group-hover:scale-105 transition-transform duration-300"
|
|
/>
|
|
</div>
|
|
|
|
{/* Info */}
|
|
<div>
|
|
<h4 className="text-xs font-extrabold text-[#1877f2] line-clamp-2 leading-snug mb-2 group-hover:underline">
|
|
<Link href={`/products/${prod.slug}`}>{prod.name}</Link>
|
|
</h4>
|
|
|
|
<div className="flex items-center gap-1 mb-2 text-amber-400 text-xs">
|
|
{'★'.repeat(5)}
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2">
|
|
{(() => {
|
|
const { price, oldPrice } = getCatalogPriceInfo(prod);
|
|
return (
|
|
<>
|
|
<span className="text-sm font-extrabold text-gray-900">
|
|
{formatCurrency(price)}
|
|
</span>
|
|
{oldPrice != null && oldPrice > price && (
|
|
<span className="text-xs text-gray-400 line-through">
|
|
{formatCurrency(oldPrice)}
|
|
</span>
|
|
)}
|
|
</>
|
|
);
|
|
})()}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|