Untitled

mail@pastecode.io avatar
unknown
tsx
17 days ago
3.7 kB
3
Indexable
Never
import utils from '@helpers/utils';
import Pagination from '@layouts/placedetail/Pagination';
import SubPage, { SubPageProps, getSubPageProps } from '@layouts/placedetail/SubPage';
import LightGallery from 'lightgallery/react';
import lgZoom from 'lightgallery/plugins/zoom';
import { GetServerSideProps } from 'next';
import Image from 'next/image';
import { FC, MutableRefObject, memo, useEffect, useRef, useState } from 'react';
import 'lightgallery/css/lg-zoom.css';
import 'lightgallery/css/lightgallery.css';
import { InitDetail } from 'lightgallery/lg-events';
import { startCase } from 'lodash';

export const getServerSideProps: GetServerSideProps<SubPageProps> = async context => {
  const result = await getSubPageProps(context);
  if ('redirect' in result || 'notFound' in result) {
    return result;
  }
  const props = await result.props;

  return {
    props,
  };
};

const PlaceDetailPhotos: FC<SubPageProps> = props => {
  const [page, setPage] = useState(1);
  const [imageSize, setImageSize] = useState(120);
  const container = useRef<HTMLDivElement | null>(null);
  const lightGallery = useRef(null) as MutableRefObject<InitDetail['instance'] | null>;
  const { placeDetail } = props;
  const { name, images, urbanVillage } = placeDetail.outlet;
  const limit = 15;
  const offset = (page - 1) * limit;
  const pageCount = Math.ceil(images.length / limit);
  const photos = images.slice(offset, page * limit);

  useEffect(() => {
    const listener = () => {
      if (container.current) {
        const gridCount = 3;
        const space = 16;
        const totalSpace = (gridCount + 1) * space;
        const size = (container.current.clientWidth - totalSpace) / gridCount;
        setImageSize(size);
      }
    };
    listener();
    window.addEventListener('resize', listener);
    return () => {
      window.removeEventListener('resize', listener);
    };
  }, []);

  useEffect(() => {
    if (container.current) {
      const offsetTop = container.current.offsetTop || 0;
      const space = 4;
      window.scrollTo({
        top: offsetTop - 92 + space,
      });
    }
    lightGallery.current?.refresh();
  }, [page]);

  const place = startCase(urbanVillage.toLowerCase());
  const metaTitle = `Foto ${name}, ${place} | Horego`;
  const metaDescription = `Lihat foto makanan minuman dan suasana ${name}, ${place}`;

  return (
    <>
      <SubPage {...props} metaTitle={metaTitle} metaDescription={metaDescription}>
        <div className="pt-4 px-4" ref={container}>
          <h2 className="font-14 font-bold mb-4">
            Photos
          </h2>
          <LightGallery
            plugins={[lgZoom]}
            mode="lg-fade"
            elementClassNames="grid grid-cols-3 gap-4"
            onInit={detail => lightGallery.current = detail.instance}
          >
            {photos.map(photo => (
              <div
                key={photo.thumbnail}
                data-src={photo.thumbnail}
                style={{ width: imageSize, height: imageSize }}
                className="hover:cursor-pointer rounded-lg overflow-hidden"
              >
                <Image
                  src={photo.thumbnail}
                  width={imageSize}
                  height={imageSize}
                  alt={`Photo's ${name}`}
                  objectFit="cover"
                  blurDataURL={utils.blurDataURL(224, 224, 224)}
                  placeholder="blur"
                />
              </div>
            ))}
          </LightGallery>
          {images.length > limit && (
            <Pagination currentPage={page} pageCount={pageCount} onClick={setPage} />
          )}
        </div>
      </SubPage>
    </>
  );
};

export default memo(PlaceDetailPhotos);
Leave a Comment