x
This commit is contained in:
1 parent
5d111b2866
commit
62dec90f82
2 files changed
+103
-17
No files matched your search
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useState, useRef, useEffect } from 'react'
|
||||
import Image from 'next/image'
|
||||
|
||||
interface Props {
|
||||
@@ -11,6 +11,29 @@ interface Props {
|
||||
|
||||
export default function ProductGallery({ productName, categoryName, images }: Props) {
|
||||
const [activeIndex, setActiveIndex] = useState(0)
|
||||
const scrollRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (scrollRef.current) {
|
||||
const container = scrollRef.current
|
||||
const child = container.children[activeIndex] as HTMLElement
|
||||
if (child) {
|
||||
container.scrollTo({ left: child.offsetLeft, behavior: 'smooth' })
|
||||
}
|
||||
}
|
||||
}, [activeIndex])
|
||||
|
||||
const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
|
||||
const container = e.currentTarget
|
||||
const scrollLeft = container.scrollLeft
|
||||
const width = container.clientWidth
|
||||
if (width > 0) {
|
||||
const newIndex = Math.round(scrollLeft / width)
|
||||
if (newIndex !== activeIndex && newIndex >= 0 && newIndex < images.length) {
|
||||
setActiveIndex(newIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (images.length === 0) return null
|
||||
|
||||
@@ -60,19 +83,39 @@ export default function ProductGallery({ productName, categoryName, images }: Pr
|
||||
|
||||
{/* Main Image */}
|
||||
<div className="relative aspect-square w-full flex-1 overflow-hidden rounded-3xl bg-surface-card shadow-card">
|
||||
<Image
|
||||
key={activeIndex}
|
||||
src={images[activeIndex]}
|
||||
alt={productName}
|
||||
fill
|
||||
priority={true}
|
||||
className="object-cover animate-fade-in"
|
||||
/>
|
||||
<div
|
||||
ref={scrollRef}
|
||||
onScroll={handleScroll}
|
||||
className="flex w-full h-full overflow-x-auto snap-x snap-mandatory hide-scrollbar"
|
||||
>
|
||||
{images.map((img, idx) => (
|
||||
<div key={idx} className="relative w-full h-full flex-none snap-center snap-always block">
|
||||
<Image
|
||||
src={img}
|
||||
alt={`${productName} ${idx + 1}`}
|
||||
fill
|
||||
priority={idx === 0}
|
||||
className="object-cover"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{categoryName && (
|
||||
<div className="absolute left-5 top-5 rounded-full bg-surface-card/90 px-4 py-2 text-xs font-bold uppercase tracking-widest text-text-main shadow-sm pointer-events-none z-10">
|
||||
{categoryName}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Mobile Dots */}
|
||||
<div className="md:hidden absolute bottom-4 left-0 right-0 flex justify-center gap-2 z-10 pointer-events-none">
|
||||
{images.map((_, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className={`w-1.5 h-1.5 rounded-full shadow-[0_1px_2px_rgba(0,0,0,0.3)] transition-all ${activeIndex === idx ? 'bg-white scale-125' : 'bg-white/50'}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in new issue
Block a user