diff --git a/src/app/(frontend)/gallery/_components/Gallery.tsx b/src/app/(frontend)/gallery/_components/Gallery.tsx index 229868e..d069ac8 100644 --- a/src/app/(frontend)/gallery/_components/Gallery.tsx +++ b/src/app/(frontend)/gallery/_components/Gallery.tsx @@ -3,15 +3,18 @@ import Image from 'next/image'; import Polaroid from './Polaroid'; import { PolaroidProps } from './Polaroid'; -import { useEffect, useState } from 'react'; +import { ReactElement } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { ChevronLeft, ChevronRight } from 'lucide-react'; import { useGalleryImages } from '@/features/gallery/tanstack/useGalleryImages'; +import { useState } from 'react'; +import { useEffect } from 'react'; export default function Gallery() { const [currentPage, setCurrentPage] = useState(1); const [itemsPerPage, setItemsPerPage] = useState(9); const { data: polaroids, isLoading, error } = useGalleryImages(); + const [isMobile, setIsMobile] = useState(false); useEffect(() => { const handleResize = (): void => { @@ -20,9 +23,11 @@ export default function Gallery() { } else if (window.innerWidth >= 768) { setItemsPerPage(4); // md has 2x2 grid } else { - setItemsPerPage(2); //sm has 1x2 grid + setItemsPerPage(9); //sm has 1x2 grid } setCurrentPage(1); // Reset to first page on resize + + setIsMobile(window.innerWidth < 768); }; window.addEventListener('resize', handleResize); @@ -47,35 +52,61 @@ export default function Gallery() { }; const handlePrevPage = (): void => { - setCurrentPage((prev) => Math.max(1, prev - 1)); + setCurrentPage((prev: number) => Math.max(1, prev - 1)); }; const handleNextPage = (): void => { - setCurrentPage((prev) => Math.min(getTotalPages(), prev + 1)); + setCurrentPage((prev: number) => Math.min(getTotalPages(), prev + 1)); + }; + + const prevButton = (hidden: boolean = false): ReactElement => { + return ( +
+ +
+ ); + }; + + const nextButton = (hidden: boolean = false) => { + return ( +
+ +
+ ); }; return ( -
+
{/* Gallery Board */}
-
- -
- -
+ {prevButton(isMobile)} +
Gallery Board Background @@ -85,7 +116,7 @@ export default function Gallery() { initial={{ opacity: 1 }} animate={{ opacity: 1 }} exit={{ opacity: 1 }} - className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-[5vh] place-items-center relative z-10" + className="grid grid-cols-3 md:grid-cols-2 lg:grid-cols-3 grid-rows-3 md:grid-rows-2 lg:grid-rows-3 gap-x-[5vw] gap-y-[1vh] md:gap-y-[3vh] lg:gap-y-[2.5vh] place-items-center relative z-10" > {getCurrentItems().map((polaroid: PolaroidProps, index: number) => (
- -
- -
+ {nextButton(isMobile)}
{/* Page Indicator */} +
+ {prevButton(!isMobile)} {Array.from({ length: getTotalPages() }, (_, index) => (
setCurrentPage(index + 1)} /> ))} + {nextButton(!isMobile)}
); diff --git a/src/app/(frontend)/gallery/_components/Polaroid.tsx b/src/app/(frontend)/gallery/_components/Polaroid.tsx index 7acdd17..c7a3e7a 100644 --- a/src/app/(frontend)/gallery/_components/Polaroid.tsx +++ b/src/app/(frontend)/gallery/_components/Polaroid.tsx @@ -1,71 +1,69 @@ -import Image from "next/image"; -import Pin from "./Pin"; -import {PIN_COLOURS, VARIATIONS } from "@/types/GalleryImageData"; -import { GalleryImageData } from "@/types/GalleryImageData"; +'use client'; +import Image from 'next/image'; +import Pin from './Pin'; +import { PIN_COLOURS, VARIATIONS } from '@/types/GalleryImageData'; +import { GalleryImageData } from '@/types/GalleryImageData'; // To change options for pinColour and variation, edit src/types/GalleryImageData.ts export interface PolaroidProps extends GalleryImageData { // Add additional props here if needed } -const RANDOM_TRANSFORMS = [ - 'rotate-3 translate-x-1 translate-y-1', - '-rotate-2 -translate-x-1 translate-y-2', - 'rotate-1 translate-x-2 -translate-y-1', - '-rotate-3 -translate-x-2 -translate-y-2', - 'rotate-2 translate-x-1 -translate-y-1', - '-rotate-1 -translate-x-1 translate-y-1', - 'rotate-1 translate-x-2 translate-y-1', - '-rotate-2 translate-x-1 -translate-y-2', - 'rotate-3 -translate-x-1 translate-y-1', -] as const; - const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleDateString('en-GB', { day: '2-digit', month: '2-digit', - year: 'numeric' + year: 'numeric', }); }; -export default function Polaroid({ - image = "/images/aboutus/AboutUsImage.jpg", - eventDate = "12/20/2015", - eventName = "TestEvent", - pinColour = 'red', - variation = 'small' +const getRandomInt = (min: number = -3, max: number = 3): number => { + return Math.floor(Math.random() * (max - min)) + min; +}; + +export default function Polaroid({ + image = '/images/aboutus/AboutUsImage.jpg', + eventDate = '12/20/2015', + eventName = 'TestEvent', + pinColour = 'red', + variation = 'small', }: PolaroidProps) { - // Calculates transform based on event name. - // This allows for the "random" transforms without using math.random. This prevents hydration issues. - const shift = RANDOM_TRANSFORMS[ - eventName.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0) % RANDOM_TRANSFORMS.length - ]; + const variationCSS = // cannot create a new entry in GalleryImageData.ts in types because it creates a payload option for mobile size selection, which is not what we want this for. + window.innerWidth < 768 + ? 'min-w-[26.667vw] aspect-[1.213/1]' + : VARIATIONS[variation].dimensions; + + const getTransformValue = window.innerWidth < 768 ? () => 0 : getRandomInt; // This is much cleaner and simpler than using a predetermined array of transforms + const rotate = getTransformValue(); + const translateX = getTransformValue(); + const translateY = getTransformValue(); - return ( -
- -
+
{eventName}
-
-

{formatDate(eventDate)}

-

{eventName}

+
+ {/* Hide the event date in mobile layout */} + {formatDate(eventDate)} {eventName}
diff --git a/src/app/(frontend)/gallery/page.tsx b/src/app/(frontend)/gallery/page.tsx index 9965726..5fd8e23 100644 --- a/src/app/(frontend)/gallery/page.tsx +++ b/src/app/(frontend)/gallery/page.tsx @@ -3,16 +3,16 @@ import Image from 'next/image'; export default function GalleryPage() { return ( -
+

Gallery

-
+

View our event images here!

-
+
{/* Background star */} -
+
background star red
-
+
background star red ({ +export const PIN_COLOUR_OPTIONS = Object.keys(PIN_COLOURS).map((color) => ({ label: color.charAt(0).toUpperCase() + color.slice(1), - value: color + value: color, })); // Convert variations to Payload select options -export const VARIATION_OPTIONS = Object.keys(VARIATIONS).map(variation => ({ +export const VARIATION_OPTIONS = Object.keys(VARIATIONS).map((variation) => ({ label: variation.charAt(0).toUpperCase() + variation.slice(1), - value: variation -})); \ No newline at end of file + value: variation, +}));