Update shopify collection

This commit is contained in:
Rami Bitar
2026-06-10 13:48:13 -04:00
parent eeeafd36d3
commit fc42f2d114
95 changed files with 7228 additions and 6178 deletions

View File

@@ -0,0 +1,73 @@
'use client';
import React, { useState } from 'react';
import { RiImageLine } from '@remixicon/react';
import { cn } from '@/lib/utils';
import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog';
interface ProductImage {
url: string;
altText?: string;
}
interface ProductDetailGalleryProps {
images: ProductImage[];
}
const ProductDetailGallery: React.FC<ProductDetailGalleryProps> = ({ images }) => {
const [zoomedIndex, setZoomedIndex] = useState<number | null>(null);
if (images.length === 0) {
return (
<div className="aspect-square bg-gray-100 flex items-center justify-center text-gray-400">
<RiImageLine size={60} />
</div>
);
}
const zoomedImage = zoomedIndex !== null ? images[zoomedIndex] : null;
return (
<>
<div className="grid grid-cols-2 gap-4">
{images.map((image, index) => (
<button
key={index}
onClick={() => setZoomedIndex(index)}
className={cn(
'aspect-square bg-gray-100 overflow-hidden cursor-zoom-in group',
// A lone image (or the last of an odd count) spans both columns to avoid a gap
images.length % 2 === 1 && index === images.length - 1 && 'col-span-2'
)}
aria-label={`Zoom image ${index + 1}`}
>
<img
src={image.url}
alt={image.altText || `Product image ${index + 1}`}
className="w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
/>
</button>
))}
</div>
{/* Zoom Lightbox */}
<Dialog
open={zoomedIndex !== null}
onOpenChange={(open) => !open && setZoomedIndex(null)}
>
<DialogContent className="max-w-4xl p-0 gap-0 overflow-hidden">
<DialogTitle className="sr-only">Product image</DialogTitle>
{zoomedImage && (
<img
src={zoomedImage.url}
alt={zoomedImage.altText || 'Product image'}
className="w-full h-auto max-h-[85vh] object-contain bg-gray-100"
/>
)}
</DialogContent>
</Dialog>
</>
);
};
export default ProductDetailGallery;