|
| 1 | +"use client"; |
| 2 | +import { useEffect, useState } from "react"; |
| 3 | +import EventBox from "../../components/ui/EventBox"; |
| 4 | +import { getPublicUrl } from "@/lib/utils" |
| 5 | +function Page() { |
| 6 | + const [events, setEvents] = useState([]); |
| 7 | + const [nextPageEvents, setNextPageEvents] = useState([]); |
| 8 | + const [pageCount, setPageCount] = useState(1); |
| 9 | + const [hasMoreEvents, setHasMoreEvents] = useState(true); |
| 10 | + const [columnCount, setColumnCount] = useState(3); |
| 11 | + |
| 12 | + const fetchEvents = async (page) => { |
| 13 | + try { |
| 14 | + const response = await fetch(`/api/v1/get/events?page=${page}`); |
| 15 | + const data = await response.json(); |
| 16 | + return data; |
| 17 | + } catch (error) { |
| 18 | + console.error("Error fetching events:", error); |
| 19 | + return []; |
| 20 | + } |
| 21 | + }; |
| 22 | + |
| 23 | + const getMoreEvents = async () => { |
| 24 | + setEvents((prevEvents) => [...prevEvents, ...nextPageEvents]); |
| 25 | + setPageCount((prev) => prev + 1); |
| 26 | + |
| 27 | + const newEvents = await fetchEvents(pageCount + 2); |
| 28 | + if (newEvents.length === 0) { |
| 29 | + setHasMoreEvents(false); |
| 30 | + } else { |
| 31 | + setNextPageEvents(newEvents); |
| 32 | + } |
| 33 | + }; |
| 34 | + |
| 35 | + useEffect(() => { |
| 36 | + const loadInitialEvents = async () => { |
| 37 | + const firstPageEvents = await fetchEvents(pageCount); |
| 38 | + const secondPageEvents = await fetchEvents(pageCount + 1); |
| 39 | + |
| 40 | + setEvents(firstPageEvents); |
| 41 | + setNextPageEvents(secondPageEvents); |
| 42 | + |
| 43 | + if (secondPageEvents.length === 0) { |
| 44 | + setHasMoreEvents(false); |
| 45 | + } |
| 46 | + }; |
| 47 | + |
| 48 | + |
| 49 | + const handleResize = () => { |
| 50 | + if (window.innerWidth < 768) { |
| 51 | + setColumnCount(2); |
| 52 | + } else { |
| 53 | + setColumnCount(3); |
| 54 | + } |
| 55 | + }; |
| 56 | + |
| 57 | + window.addEventListener("resize", handleResize); |
| 58 | + handleResize(); |
| 59 | + loadInitialEvents(); |
| 60 | + |
| 61 | + return () => { |
| 62 | + window.removeEventListener("resize", handleResize); |
| 63 | + }; |
| 64 | + }, []); |
| 65 | + |
| 66 | + const columns = Array.from({ length: columnCount }, () => []); |
| 67 | + |
| 68 | + events.forEach((event, index) => { |
| 69 | + let posterUrl = getPublicUrl(`/events/${event.id}/poster`) |
| 70 | + |
| 71 | + columns[index % columnCount].push( |
| 72 | + <EventBox |
| 73 | + img={posterUrl} |
| 74 | + key={event.id} |
| 75 | + caption={event.description} |
| 76 | + time={event.date} |
| 77 | + category={event.name} |
| 78 | + hostLink={event.host_link} |
| 79 | + /> |
| 80 | + ); |
| 81 | + }); |
| 82 | + |
| 83 | + return ( |
| 84 | + <div className="flex flex-col w-full h-full"> |
| 85 | + <div className="self-center h-fit py-2 w-11/12 flex flex-col bg-[#201f31] mt-4"> |
| 86 | + <p className="md:pl-12 pt-5 text-2xl font-medium mb-7 ">Events Near</p> |
| 87 | + <div className="self-center w-full grid grid-flow-row grid-cols-2 md:grid-cols-3"> |
| 88 | + {columns.map((column, colIndex) => ( |
| 89 | + <section |
| 90 | + key={colIndex} |
| 91 | + className={`h-fit w-full gap-8 py-4 grid grid-flow-row md:pl-12 ${ |
| 92 | + colIndex === 1 && columnCount === 3 ? "mt-32" : "" |
| 93 | + } |
| 94 | + ${ |
| 95 | + colIndex === 1 && columnCount === 2 ? "mt-20" : "" |
| 96 | + }` |
| 97 | + } |
| 98 | + > |
| 99 | + {column} |
| 100 | + </section> |
| 101 | + ))} |
| 102 | + </div> |
| 103 | + {hasMoreEvents && ( |
| 104 | + <button |
| 105 | + onClick={getMoreEvents} |
| 106 | + className="text-sm md:text-xl hover:border-[#e890bd] text-[#FFBADE] border-[#FFBADE] border-[0.5vh] w-fit px-24 md:px-32 active:scale-95 transition-all duration-100 self-center rounded-3xl py-3" |
| 107 | + > |
| 108 | + Show More |
| 109 | + </button> |
| 110 | + )} |
| 111 | + </div> |
| 112 | + </div> |
| 113 | + ); |
| 114 | +} |
| 115 | + |
| 116 | +export default Page; |
0 commit comments