feat: add active modal image state and thumbnail update logic to product display
This commit is contained in:
parent
530d2cbbcb
commit
b7f3953a56
@ -10,6 +10,13 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
const [allProducts, setAllProducts] = useState<any[]>(bestSellers.data);
|
const [allProducts, setAllProducts] = useState<any[]>(bestSellers.data);
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const [selectedCategorySlug, setSelectedCategorySlug] = useState('');
|
const [selectedCategorySlug, setSelectedCategorySlug] = useState('');
|
||||||
|
const [activeModalImage, setActiveModalImage] = useState<string | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedProduct) {
|
||||||
|
setActiveModalImage(selectedProduct?.thumbnail_url);
|
||||||
|
}
|
||||||
|
}, [selectedProduct]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
@ -160,13 +167,11 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
setSelectedCategorySlug(cat.slug);
|
setSelectedCategorySlug(cat.slug);
|
||||||
scrollToSection(e, '#product');
|
scrollToSection(e, '#product');
|
||||||
}}
|
}}
|
||||||
className={`group flex items-center justify-between border-b border-[#1e4a6d]/10 px-4 py-4 text-left text-xs font-bold uppercase tracking-wider transition-all hover:bg-[#1e4a6d] hover:text-white last:border-0 ${
|
className={`group flex items-center justify-between border-b border-[#1e4a6d]/10 px-4 py-4 text-left text-xs font-bold uppercase tracking-wider transition-all hover:bg-[#1e4a6d] hover:text-white last:border-0 ${selectedCategorySlug === cat.slug ? 'bg-[#1e4a6d] text-white' : ''
|
||||||
selectedCategorySlug === cat.slug ? 'bg-[#1e4a6d] text-white' : ''
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{cat.name}
|
{cat.name}
|
||||||
<ArrowRight size={14} className={`transition-all group-hover:translate-x-1 group-hover:opacity-100 ${
|
<ArrowRight size={14} className={`transition-all group-hover:translate-x-1 group-hover:opacity-100 ${selectedCategorySlug === cat.slug ? 'opacity-100 translate-x-1' : 'opacity-0'
|
||||||
selectedCategorySlug === cat.slug ? 'opacity-100 translate-x-1' : 'opacity-0'
|
|
||||||
}`} />
|
}`} />
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
@ -219,7 +224,7 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
onClick={() => setSelectedProduct(product)}
|
onClick={() => setSelectedProduct(product)}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={product.thumbnail_url || 'https://images.unsplash.com/photo-1719947348940-7aa339028cbc?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDgzfHx8ZW58MHx8fHx8'}
|
src={product?.thumbnail_url || 'https://images.unsplash.com/photo-1719947348940-7aa339028cbc?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDgzfHx8ZW58MHx8fHx8'}
|
||||||
alt={product.name}
|
alt={product.name}
|
||||||
className="h-full w-full object-cover"
|
className="h-full w-full object-cover"
|
||||||
/>
|
/>
|
||||||
@ -288,7 +293,7 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
onClick={() => setSelectedProduct(item)}
|
onClick={() => setSelectedProduct(item)}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={item.thumbnail_url || 'https://images.unsplash.com/photo-1719947348940-7aa339028cbc?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDgzfHx8ZW58MHx8fHx8'}
|
src={item?.thumbnail_url || 'https://images.unsplash.com/photo-1719947348940-7aa339028cbc?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDgzfHx8ZW58MHx8fHx8'}
|
||||||
alt={item.name}
|
alt={item.name}
|
||||||
className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-110"
|
className="h-full w-full object-cover transition-transform duration-500 group-hover:scale-110"
|
||||||
/>
|
/>
|
||||||
@ -501,24 +506,47 @@ export default function Homepage({ categories = [], bestSellers, topSellingProdu
|
|||||||
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2">
|
<div className="grid grid-cols-1 md:grid-cols-2">
|
||||||
{/* Product Images */}
|
{/* Product Images */}
|
||||||
<div className="border-b border-[#1e4a6d]/10 md:border-b-0 md:border-r overflow-hidden bg-white">
|
<div className="border-b border-[#1e4a6d]/10 md:border-b-0 md:border-r overflow-hidden bg-[#fdfcf9]">
|
||||||
<div className="aspect-[4/5] overflow-hidden">
|
<div className="aspect-[4/5] overflow-hidden relative group/hero">
|
||||||
<img
|
<img
|
||||||
src={selectedProduct?.thumbnail_url || 'https://images.unsplash.com/photo-1719947348940-7aa339028cbc?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDgzfHx8ZW58MHx8fHx8'}
|
src={activeModalImage || selectedProduct?.thumbnail_url || 'https://images.unsplash.com/photo-1719947348940-7aa339028cbc?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1yZWxhdGVkfDgzfHx8ZW58MHx8fHx8'}
|
||||||
alt={selectedProduct?.name}
|
alt={selectedProduct?.name}
|
||||||
className="h-full w-full object-cover"
|
className="h-full w-full object-cover transition-transform duration-700 hover:scale-105"
|
||||||
/>
|
/>
|
||||||
|
{/* Blueprint overlay decoration */}
|
||||||
|
<div className="absolute top-4 left-4 text-[8px] font-mono opacity-20 pointer-events-none">DET_V.1.0</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Image Gallery if exists */}
|
|
||||||
{selectedProduct?.images_data?.length > 0 && (
|
{/* Refined Image Gallery List */}
|
||||||
<div className="flex border-t border-[#1e4a6d]/10">
|
<div className="p-4 border-t border-[#1e4a6d]/10">
|
||||||
{selectedProduct.images_data.map((img: any, i: number) => (
|
<p className="text-[8px] font-bold uppercase tracking-[0.2em] mb-3 opacity-40">Galeri Foto</p>
|
||||||
<div key={i} className="aspect-square w-20 border-r border-[#1e4a6d]/10 overflow-hidden">
|
<div className="flex flex-wrap gap-3">
|
||||||
<img src={img.url} alt="detail" className="h-full w-full object-cover opacity-60 hover:opacity-100 transition-opacity cursor-pointer" />
|
{/* Thumbnail (Main Image) */}
|
||||||
|
<div
|
||||||
|
onClick={() => setActiveModalImage(selectedProduct?.thumbnail_url)}
|
||||||
|
className={`relative aspect-square w-14 cursor-pointer overflow-hidden transition-all duration-300 ${activeModalImage === selectedProduct?.thumbnail_url
|
||||||
|
? 'ring-1 ring-[#1e4a6d] ring-offset-2'
|
||||||
|
: 'opacity-40 hover:opacity-100'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<img src={selectedProduct?.thumbnail_url} className="h-full w-full object-cover" alt="main" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Additional Images */}
|
||||||
|
{selectedProduct?.images_data?.map((img: any, i: number) => (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
onClick={() => setActiveModalImage(img.url)}
|
||||||
|
className={`relative aspect-square w-14 cursor-pointer overflow-hidden transition-all duration-300 ${activeModalImage === img.url
|
||||||
|
? 'ring-1 ring-[#1e4a6d] ring-offset-2'
|
||||||
|
: 'opacity-40 hover:opacity-100'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<img src={img.url} className="h-full w-full object-cover" alt={`view ${i + 1}`} />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Product Info */}
|
{/* Product Info */}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user