117 lines
3.2 KiB
TypeScript
117 lines
3.2 KiB
TypeScript
'use client'
|
|
|
|
import {ProductResource} from '@prisma/client'
|
|
import {EmblaOptionsType} from 'embla-carousel'
|
|
import useEmblaCarousel from 'embla-carousel-react'
|
|
import Image from 'next/image'
|
|
import React, {useCallback, useEffect, useState} from 'react'
|
|
|
|
import {Thumb} from './thumb'
|
|
import {Dialog, DialogContent, DialogTitle} from '@/ui/dialog'
|
|
|
|
type PropType = {
|
|
slides: number[]
|
|
options?: EmblaOptionsType
|
|
}
|
|
|
|
export default function ProductCarousel({
|
|
images,
|
|
title
|
|
}: {
|
|
images: ProductResource[] | null
|
|
title: string
|
|
}) {
|
|
//const {slides, options} = props
|
|
const [selectedIndex, setSelectedIndex] = useState(0)
|
|
const [emblaMainRef, emblaMainApi] = useEmblaCarousel({}) //options
|
|
const [emblaThumbsRef, emblaThumbsApi] = useEmblaCarousel({
|
|
containScroll: 'keepSnaps',
|
|
dragFree: true
|
|
})
|
|
|
|
const onThumbClick = useCallback(
|
|
(index: number) => {
|
|
if (!emblaMainApi || !emblaThumbsApi) return
|
|
emblaMainApi.scrollTo(index)
|
|
},
|
|
[emblaMainApi, emblaThumbsApi]
|
|
)
|
|
|
|
const onSelect = useCallback(() => {
|
|
if (!emblaMainApi || !emblaThumbsApi) return
|
|
setSelectedIndex(emblaMainApi.selectedScrollSnap())
|
|
emblaThumbsApi.scrollTo(emblaMainApi.selectedScrollSnap())
|
|
}, [emblaMainApi, emblaThumbsApi, setSelectedIndex])
|
|
|
|
useEffect(() => {
|
|
if (!emblaMainApi) return
|
|
onSelect()
|
|
|
|
emblaMainApi.on('select', onSelect).on('reInit', onSelect)
|
|
}, [emblaMainApi, onSelect])
|
|
//let featuredImage: ProductResource | null | undefined
|
|
/*if ((resources || []).length > 0) {
|
|
featuredImage = resources?.find(resource => resource.isFeature)
|
|
}*/
|
|
|
|
return (
|
|
<div className='embla my-8'>
|
|
<div className='embla__viewport' ref={emblaMainRef}>
|
|
<div className='embla__container'>
|
|
{images?.map((image: ProductResource, index: number) => (
|
|
<div className='embla__slide' key={index}>
|
|
<div className='embla__slide__number h-[480px] overflow-hidden'>
|
|
<Image
|
|
src={image.uri}
|
|
alt=''
|
|
width={image.width || 100}
|
|
height={image.height || 100}
|
|
sizes='100vw'
|
|
style={{
|
|
width: '100%',
|
|
height: 'auto',
|
|
maxHeight: '480px',
|
|
objectFit: 'contain'
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className='embla-thumbs mb-8 mt-6'>
|
|
<div className='embla-thumbs__viewport' ref={emblaThumbsRef}>
|
|
<div className='embla-thumbs__container flex items-center justify-center gap-x-6'>
|
|
{images?.map((image: ProductResource, index: number) => (
|
|
<Dialog key={index}>
|
|
<DialogTitle className='hidden'>{title}</DialogTitle>
|
|
<Thumb
|
|
image={image}
|
|
onClick={() => onThumbClick(index)}
|
|
selected={index === selectedIndex}
|
|
index={index}
|
|
/>
|
|
<DialogContent className='overflow max-w-screen rounded-0 h-screen p-0'>
|
|
<Image
|
|
src={image.uri}
|
|
alt=''
|
|
width={image.width || 100}
|
|
height={image.height || 100}
|
|
sizes='100vw'
|
|
style={{
|
|
width: '100%',
|
|
maxHeight: '100dvh',
|
|
objectFit: 'contain'
|
|
}}
|
|
/>
|
|
</DialogContent>
|
|
</Dialog>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|