2025-03-15 11:15:46 +00:00

92 lines
3.2 KiB
TypeScript

"use client";
import { ArrowLeftIcon, ArrowRightIcon } from "@heroicons/react/24/outline";
import { GridTileImage } from "components/grid/tile";
import { useProduct } from "components/product/product-context";
import { Image } from "lib/store/types";
import { getImageUrl } from "lib/utils/image";
import NextImage from "next/image";
export function Gallery({ images }: { images: Image[] }) {
const { state, updateImage } = useProduct();
const imageIndex = state.image ? parseInt(state.image) : 0;
const nextImageIndex = imageIndex + 1 < images.length ? imageIndex + 1 : 0;
const previousImageIndex =
imageIndex === 0 ? images.length - 1 : imageIndex - 1;
const buttonClassName =
"h-full px-6 transition-all ease-in-out hover:scale-110 hover:text-black dark:hover:text-white flex items-center justify-center";
return (
<form>
<div className="relative aspect-square h-full max-h-[550px] w-full overflow-hidden">
{images[imageIndex] && (
<NextImage
className="h-full w-full object-contain"
fill
sizes="(min-width: 1024px) 66vw, 100vw"
alt={images[imageIndex]?.altText as string}
src={getImageUrl(images[imageIndex]?.source)}
priority={true}
/>
)}
{images.length > 1 ? (
<div className="absolute bottom-[15%] flex w-full justify-center">
<div className="mx-auto flex h-11 items-center rounded-full border border-white bg-neutral-50/80 text-neutral-500 backdrop-blur-sm dark:border-black dark:bg-neutral-900/80">
<button
formAction={() => {
updateImage(previousImageIndex.toString());
}}
aria-label="Previous product image"
className={buttonClassName}
>
<ArrowLeftIcon className="h-5" />
</button>
<div className="mx-1 h-6 w-px bg-neutral-500"></div>
<button
formAction={() => {
updateImage(nextImageIndex.toString());
}}
aria-label="Next product image"
className={buttonClassName}
>
<ArrowRightIcon className="h-5" />
</button>
</div>
</div>
) : null}
</div>
{images.length > 1 ? (
<ul className="my-12 flex items-center flex-wrap justify-center gap-2 overflow-auto py-1 lg:mb-0">
{images.map((image, index) => {
const isActive = index === imageIndex;
return (
<li key={getImageUrl(image.source)} className="h-20 w-20">
<button
formAction={() => {
updateImage(index.toString());
}}
aria-label="Select product image"
className="h-full w-full"
>
<GridTileImage
alt={image.altText}
src={getImageUrl(image.source)}
width={80}
height={80}
active={isActive}
/>
</button>
</li>
);
})}
</ul>
) : null}
</form>
);
}