grand commit
This commit is contained in:
116
components/pages/product/carousel.tsx
Normal file
116
components/pages/product/carousel.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
'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 w-full'>
|
||||
<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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user