church-website/src/components/Gallery/Gallery.tsx
2024-12-11 10:17:37 +01:00

93 lines
No EOL
2.1 KiB
TypeScript

'use client'
import styles from './styles.module.scss'
import Image, { StaticImageData } from 'next/image'
import { useCallback, useEffect, useRef, useState } from 'react'
import { AutoScroll } from '@/components/Gallery/AutoScroll'
import { Fullscreen } from '@/components/Gallery/Fullscreen'
type ImageType = {
src: string,
width: number,
height: number
} | StaticImageData
export type GalleryItem = {
id: string;
thumbnail: ImageType ;
image: ImageType;
alt: string;
}
type GalleryItemProps = {
thumbnail: ImageType,
alt: string,
onClick?: () => void
}
type GalleryProps = {
items: GalleryItem[];
}
const GalleryItem = ({ thumbnail, alt, onClick }: GalleryItemProps) => {
return (
<Image
onClick={onClick}
className={styles.item}
src={thumbnail.src}
height={thumbnail.height}
width={thumbnail.width}
alt={alt}
unoptimized={true}
/>
)
}
export const Gallery = ({ items }: GalleryProps) => {
const [displayFullscreen, setDisplayFullscreen] = useState(false)
const [idx, setIdx] = useState(0)
const [isScrolling, setIsScrolling] = useState(true)
const displayImage = useCallback((n: number) => {
setIdx(n);
setDisplayFullscreen(true);
setIsScrolling(false)
}, [setDisplayFullscreen, setIdx, setIsScrolling]);
const next = useCallback(() => {
setIdx((idx + 1) % items.length)
}, [idx, setIdx, items])
if(items.length == 0) {
return null;
}
const { image, alt } = items[idx]
return (
<>
<AutoScroll
isScrolling={isScrolling}
onTouch={() => setIsScrolling(false)}
>
<div className={styles.container}>
{items.map((item, index) =>
<GalleryItem
onClick={() => displayImage(index)}
key={item.id}
thumbnail={item.thumbnail}
alt={item.alt}
/>)}
</div>
</AutoScroll>
<Fullscreen
display={displayFullscreen}
image={image}
closeClicked={() => setDisplayFullscreen(false)}
nextClicked={next}
/>
</>
)
}