From e37e698d29d4d020d0968fd16379e633019e288e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A1muel=20Fekete?= Date: Mon, 29 Jan 2024 22:51:39 +0100 Subject: [PATCH] getting there --- package.json | 1 + src/app/page.tsx | 4 +- src/components/image-carousel.tsx | 45 ------------ src/components/image-carousel/carousel.tsx | 72 +++++++++++++++++++ .../image-carousel/image-carousel-section.tsx | 51 +++++++++++++ yarn.lock | 5 ++ 6 files changed, 131 insertions(+), 47 deletions(-) delete mode 100644 src/components/image-carousel.tsx create mode 100644 src/components/image-carousel/carousel.tsx create mode 100644 src/components/image-carousel/image-carousel-section.tsx diff --git a/package.json b/package.json index ed36ebe..b9f9b4b 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "react-dom": "^18", "react-icons": "^4.12.0", "react-markdown": "^9.0.1", + "react-snap-carousel": "^0.4.0", "remark-gfm": "^4.0.0", "yet-another-react-lightbox": "^3.16.0" }, diff --git a/src/app/page.tsx b/src/app/page.tsx index 8368da5..de1132c 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,7 +1,7 @@ import Image from 'next/image'; import { metadata } from '@/app/layout'; -import { ImageCarousel } from '@/components/image-carousel'; +import { ImageCarouselSection } from '@/components/image-carousel/image-carousel-section'; import { SponsorSection } from '@/components/sponsors/sponsor-section'; import { CountdownTile } from '@/components/tiles/countdown-tile'; import { GiveawayTile } from '@/components/tiles/giveaway-tile'; @@ -49,7 +49,7 @@ export default async function Landing() { Vörös bolygó - {data.previousConferences.conferences.length > 0 && } + {data.previousConferences.conferences.length > 0 && } Fehér bolygó diff --git a/src/components/image-carousel.tsx b/src/components/image-carousel.tsx deleted file mode 100644 index 2d36d87..0000000 --- a/src/components/image-carousel.tsx +++ /dev/null @@ -1,45 +0,0 @@ -'use client'; - -import 'yet-another-react-lightbox/styles.css'; - -import Image from 'next/image'; -import { useState } from 'react'; -import Lightbox from 'yet-another-react-lightbox'; - -import { PrevConfData } from '@/models/models'; - -import NextJsImage from './next-js-image'; - -type Props = { - data: PrevConfData; -}; - -export function ImageCarousel({ data: { conferences, sectionTitle } }: Props) { - const [index, setIndex] = useState(-1); - const images = conferences[0].imageUrls; - return ( -
-

{sectionTitle}

-
- {images.map((imageUrl, idx) => ( - setIndex(idx)} - src={imageUrl} - key={imageUrl} - alt='Kép korábbi konferenciáról' - className='h-full cursor-pointer' - height={225} - width={300} - /> - ))} -
- -1} - index={index} - close={() => setIndex(-1)} - slides={images.map((i) => ({ src: i }))} - render={{ slide: NextJsImage }} - /> -
- ); -} diff --git a/src/components/image-carousel/carousel.tsx b/src/components/image-carousel/carousel.tsx new file mode 100644 index 0000000..88339b0 --- /dev/null +++ b/src/components/image-carousel/carousel.tsx @@ -0,0 +1,72 @@ +import React, { CSSProperties } from 'react'; +import { FaArrowLeft, FaArrowRight } from 'react-icons/fa'; +import { useSnapCarousel } from 'react-snap-carousel'; + +const styles = { + root: {}, + scroll: { + scrollSnapType: 'x mandatory', + }, + item: { + flexShrink: 0, + }, + itemSnapPoint: { + scrollSnapAlign: 'start', + }, + nextPrevButton: {}, + nextPrevButtonDisabled: { opacity: 0.3 }, +} satisfies Record; + +interface CarouselProps { + readonly items: T[]; + readonly renderItem: (props: CarouselRenderItemProps) => React.ReactElement; +} + +interface CarouselRenderItemProps { + readonly item: T; + readonly isSnapPoint: boolean; + readonly index: number; +} + +export const Carousel = ({ items, renderItem }: CarouselProps) => { + const { scrollRef, pages, activePageIndex, prev, next, snapPointIndexes } = useSnapCarousel(); + return ( +
+
+ prev()} + /> + next()} + /> +
+
    + {items.map((item, i) => + renderItem({ + item, + isSnapPoint: snapPointIndexes.has(i), + index: i, + }) + )} +
+
+ ); +}; + +interface CarouselItemProps { + readonly isSnapPoint: boolean; + readonly children?: React.ReactNode; +} + +export const CarouselItem = ({ isSnapPoint, children }: CarouselItemProps) => ( +
  • + {children} +
  • +); diff --git a/src/components/image-carousel/image-carousel-section.tsx b/src/components/image-carousel/image-carousel-section.tsx new file mode 100644 index 0000000..57de45e --- /dev/null +++ b/src/components/image-carousel/image-carousel-section.tsx @@ -0,0 +1,51 @@ +'use client'; + +import 'yet-another-react-lightbox/styles.css'; + +import Image from 'next/image'; +import { useState } from 'react'; +import Lightbox from 'yet-another-react-lightbox'; + +import { PrevConfData } from '@/models/models'; + +import NextJsImage from '../next-js-image'; +import { Carousel, CarouselItem } from './carousel'; + +type Props = { + data: PrevConfData; +}; + +export function ImageCarouselSection({ data: { conferences, sectionTitle } }: Props) { + const [index, setIndex] = useState(-1); + const images = conferences[0].imageUrls; + return ( +
    +

    {sectionTitle}

    +
    + ( + + setIndex(i)} + src={item} + key={item} + alt='Kép korábbi konferenciáról' + className='h-full cursor-pointer rounded-[30px]' + height={225} + width={300} + /> + + )} + /> +
    + -1} + index={index} + close={() => setIndex(-1)} + slides={images.map((i) => ({ src: i }))} + render={{ slide: NextJsImage }} + /> +
    + ); +} diff --git a/yarn.lock b/yarn.lock index 9d7d618..8dc27cf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3077,6 +3077,11 @@ react-markdown@^9.0.1: unist-util-visit "^5.0.0" vfile "^6.0.0" +react-snap-carousel@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/react-snap-carousel/-/react-snap-carousel-0.4.0.tgz#526626f980edf1b37a8bc99310086cd39cf0078d" + integrity sha512-uPrXbH2BxJnPodQ+GwEYnbygGZ368RpnAJkNYyiOfko3i0D5cIAuSA4mz+pv9r/O5WhIMo5WOuP4DU56sO7QeA== + react@^18: version "18.2.0" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"