update design
This commit is contained in:
73
components/shopify/product-detail/product-detail-gallery.tsx
Normal file
73
components/shopify/product-detail/product-detail-gallery.tsx
Normal 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;
|
||||
Reference in New Issue
Block a user