From ba56fb50ea1e599547999070b817813ee4f401dc Mon Sep 17 00:00:00 2001 From: deveshsawant05 <146441689+deveshsawant05@users.noreply.github.com> Date: Mon, 5 Aug 2024 15:40:20 +0530 Subject: [PATCH] Added Events Page, API fetching is currently stopped (#80) event page --- .../[id]/components/currentWindowSize.jsx | 30 ++ src/app/event/[id]/components/event.jsx | 71 ++++ .../event/[id]/components/eventConvenors.jsx | 15 + .../event/[id]/components/eventDetails.jsx | 199 ++++++++++ .../event/[id]/components/eventDuration.jsx | 25 ++ src/app/event/[id]/components/eventMode.jsx | 38 ++ src/app/event/[id]/components/eventPoster.jsx | 9 + src/app/event/[id]/components/eventPrizes.jsx | 126 +++++++ .../[id]/components/eventRequirements.jsx | 34 ++ src/app/event/[id]/components/eventVenue.jsx | 27 ++ src/app/event/[id]/fetchEvent.jsx | 28 ++ src/app/event/[id]/page.jsx | 72 ++++ src/app/event/layout.tsx | 18 + src/app/event/page.jsx | 6 + src/components/footer.jsx | 18 +- src/components/navbar.jsx | 6 +- src/styles/event.css | 350 ++++++++++++++++++ src/styles/footer.css | 5 +- src/styles/navbar.css | 11 + 19 files changed, 1076 insertions(+), 12 deletions(-) create mode 100644 src/app/event/[id]/components/currentWindowSize.jsx create mode 100644 src/app/event/[id]/components/event.jsx create mode 100644 src/app/event/[id]/components/eventConvenors.jsx create mode 100644 src/app/event/[id]/components/eventDetails.jsx create mode 100644 src/app/event/[id]/components/eventDuration.jsx create mode 100644 src/app/event/[id]/components/eventMode.jsx create mode 100644 src/app/event/[id]/components/eventPoster.jsx create mode 100644 src/app/event/[id]/components/eventPrizes.jsx create mode 100644 src/app/event/[id]/components/eventRequirements.jsx create mode 100644 src/app/event/[id]/components/eventVenue.jsx create mode 100644 src/app/event/[id]/fetchEvent.jsx create mode 100644 src/app/event/[id]/page.jsx create mode 100644 src/app/event/layout.tsx create mode 100644 src/app/event/page.jsx create mode 100644 src/styles/event.css diff --git a/src/app/event/[id]/components/currentWindowSize.jsx b/src/app/event/[id]/components/currentWindowSize.jsx new file mode 100644 index 0000000..1f55cec --- /dev/null +++ b/src/app/event/[id]/components/currentWindowSize.jsx @@ -0,0 +1,30 @@ +import { useState, useEffect } from 'react'; + +export default function useWindowDimensions() { + + const hasWindow = typeof window !== 'undefined'; + + function getWindowDimensions() { + const width = hasWindow ? window.innerWidth : null; + const height = hasWindow ? window.innerHeight : null; + return { + width, + height, + }; + } + + const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions()); + + useEffect(() => { + if (hasWindow) { + function handleResize() { + setWindowDimensions(getWindowDimensions()); + } + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + } + }, [hasWindow]); + + return windowDimensions; +} \ No newline at end of file diff --git a/src/app/event/[id]/components/event.jsx b/src/app/event/[id]/components/event.jsx new file mode 100644 index 0000000..513525b --- /dev/null +++ b/src/app/event/[id]/components/event.jsx @@ -0,0 +1,71 @@ +import React, { useState, useEffect } from 'react'; +import "@/styles/event.css"; + +import EventPoster from "./eventPoster"; +import EventDetails from "./eventDetails"; +import useWindowDimensions from "./currentWindowSize"; + + +function GenerateEvent({props:event}){ + // Getting current window dimensions + const {width , height} = useWindowDimensions(); + + // console.log(width-height); + + const [scrollPosition, setScrollPosition] = useState(0); + const [eventDetailsFixed ,setEventDetailsFixed] = useState("event-details-fixed"); + const [eventPosterFixed ,setEventPosterFixed] = useState(""); + const [eventPosterCover, setEventPosterCover] = useState(""); + + const handleScroll = () => { + const position = window.scrollY; + setScrollPosition(position); + }; + + // To change classes + useEffect(()=>{ + if(width-height>0) { + if((scrollPosition>(width-height-(0.12*(width-height)))) ){ // + setEventDetailsFixed(""); + setEventPosterFixed("event-poster-fixed"); + } + else{ + setEventPosterFixed(""); + setEventDetailsFixed("event-details-fixed"); + } + setEventPosterCover("event-poster-cover"); + } + else{ + + setEventPosterFixed(""); + setEventDetailsFixed(""); + } + },[scrollPosition,width,height]); + + // To track scroll position + useEffect(() => { + window.addEventListener('scroll', handleScroll, { passive: true }); + + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + + const eventPoster = "https://media.licdn.com/dms/image/D4D22AQHTRDh3tAk0wA/feedshare-shrink_800/0/1713529970610?e=1725494400&v=beta&t=1BamLpGDgW7rWUcYBUFRkm_35Y1wseXAE9VZS80XbtE"; + return ( +
+
+ +
+ +
+
+ +
+
+ ) +} + +export default GenerateEvent; \ No newline at end of file diff --git a/src/app/event/[id]/components/eventConvenors.jsx b/src/app/event/[id]/components/eventConvenors.jsx new file mode 100644 index 0000000..d8a063b --- /dev/null +++ b/src/app/event/[id]/components/eventConvenors.jsx @@ -0,0 +1,15 @@ +import React from "react"; +export default function EventConvenors(props) { + return ( + <> +
+

Convenors

+ +
+ + ); +} \ No newline at end of file diff --git a/src/app/event/[id]/components/eventDetails.jsx b/src/app/event/[id]/components/eventDetails.jsx new file mode 100644 index 0000000..7d47a5a --- /dev/null +++ b/src/app/event/[id]/components/eventDetails.jsx @@ -0,0 +1,199 @@ +'use client' +import React, { useEffect, useState } from "react"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import EventMode from "./eventMode" +import EventDuration from "./eventDuration"; +import EventRequirements from "./eventRequirements"; +import EventPrizes from "./eventPrizes"; +import EventConvenors from "./eventConvenors"; +import EventVenue from "./eventVenue"; +import { Montserrat } from "next/font/google"; +const montserratFont = Montserrat({weight: ["100","400"], subsets: ["latin"]}); + + +function EventDetails(props){ + + const [isAdmin,setIsAdmin] = useState(true); //Set default to false + + const [event,setEvent] = useState(props.event); + const [eventName,setEventName] = useState(event.name); + const [eventDescription,setEventDescription] = useState(event.description); + const [registerUntilDate,setRegisterUntilDate] = useState(event.register_until); + const [registrationLink , setRegistrationLink] = useState(event.registration_link); + const [hostedRegistration , setHostedRegistration] = useState(event.hosted_registration); + const [hostLink, setHostLink] = useState(event.host_link); + const [daysLeftToRegister,setDaysLeftToRegister]= useState(CalculateDaysLeft(registerUntilDate)); + const [eventDate,setEventDate] = useState(event.date); + const [eventDuration , setEventDuration]=useState((CalculateEventDuration(event.duration))); + const [eventMode ,setEventMode] = useState(event.mode); + const [eventVenue ,setEventVenue] = useState(event.venue); + const [eventRequirements, setEventRequirements] = useState(event.requirements); + const [eventPrizes , setEventPrizes] = useState(event.prizes); + const [eventConvenors,setEventConvenors] = useState(event.convenors); + //To update the remaining registration time each second + useEffect(()=>{ + setInterval(()=>{ + setDaysLeftToRegister(CalculateDaysLeft(registerUntilDate)) + },1000) + },[daysLeftToRegister]) + + + + return <> +
+

{eventName}

+ +
+

{daysLeftToRegister}

+ + Register + + {isAdmin ? DeleteButton() : null} +
+
+
+
+

Event Date

+

{formatDate(new Date(eventDate))}

+
+
+

Event Time

+

{new Date(eventDate).toLocaleTimeString()}

+
+
+ +
+ +
+

About Event

+
{eventDescription}
+
+ +
+ + +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +} + +function DeleteButton(){ + const router = useRouter(); + + function onDeleteButtonClicked(){ + if(confirm("Are you sure you want to delete this event?")){ + router.push("/events"); + }else{ + return false; + } + } + + return( + + ) +} + + + +function CalculateDaysLeft(date){ + var today = new Date(); + var anotherDate = new Date(date); + const timeInMS = anotherDate.getTime() - today.getTime(); + var daysRemaining = Math.ceil(timeInMS / (1000 * 60 * 60 * 24)); + + var hoursRemaining = (Math.ceil(timeInMS / (1000 * 60 * 60 ))); + var minutesRemaining = (Math.ceil(timeInMS / (1000 * 60))); + var secondsRemaining = (Math.ceil(timeInMS / (1000))); + if(daysRemaining>3){ + return (daysRemaining+" days left") + } + else{ + if(hoursRemaining>1){ + return (hoursRemaining+" hours left"); + } + else{ + if(minutesRemaining>2){ + return(minutesRemaining+" minutes left"); + } + else{ + if(secondsRemaining>0){ + return(secondsRemaining+" seconds left"); + } + else{ + return("Registration closed"); + } + } + } + } +} + +function CalculateEventDuration (totalmins) { + + var absTotal= Math.abs(totalmins); + var mins= absTotal % 60; + var hours = Math.floor(absTotal / 60); + var days= Math.floor(hours / 24); + var hourss = hours % 24; + var duration =""; + if(days>0){ + ; + if(days==1){duration = duration+days+" Day"} + else{duration = duration+days+" Day"}; + if(hourss || mins){duration = duration+", ";} + } + if(hourss){ + if(hourss==1){duration = duration+hourss+" Hour"} + else{duration = duration+hourss+" Hours"}; + if(mins){duration = duration+", ";} + } + if(mins){ + duration = duration+mins+" Minutes"; + } + + return duration; + +} + +function formatDate(date) { + // Array of month names + const monthNames = [ + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + ]; + + // Array of day names + const dayNames = [ + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" + ]; + + // Extract day, month, and year from the date + const day = date.getDate(); + const month = monthNames[date.getMonth()]; + const year = date.getFullYear(); + const dayName = dayNames[date.getDay()]; + + // Format the date + return `${day < 10 ? '0' + day : day}-${month}-${year}, ${dayName}`; +} +export default EventDetails; \ No newline at end of file diff --git a/src/app/event/[id]/components/eventDuration.jsx b/src/app/event/[id]/components/eventDuration.jsx new file mode 100644 index 0000000..727bae1 --- /dev/null +++ b/src/app/event/[id]/components/eventDuration.jsx @@ -0,0 +1,25 @@ +import React from "react"; +export default function EventDuration(props) { + return ( + <> +
+
+

{props.eventDuration}

+
+ + ); +} + +const DurationIcon = () => ( + + + + +); diff --git a/src/app/event/[id]/components/eventMode.jsx b/src/app/event/[id]/components/eventMode.jsx new file mode 100644 index 0000000..4576533 --- /dev/null +++ b/src/app/event/[id]/components/eventMode.jsx @@ -0,0 +1,38 @@ +import React from "react"; +export default function EventMode(props) { + return <> +
+
{props.eventMode ? : }
+

{props.eventMode ? "Online" : props.eventVenue}

+
+ +} + +const OnlineIcon = ({ width = 24, height = 24}) => ( + + + +); + + +const OfflineIcon = ({ width = 32, height = 32}) => ( + + + + + + +); + diff --git a/src/app/event/[id]/components/eventPoster.jsx b/src/app/event/[id]/components/eventPoster.jsx new file mode 100644 index 0000000..cd4a45f --- /dev/null +++ b/src/app/event/[id]/components/eventPoster.jsx @@ -0,0 +1,9 @@ +import React from "react"; + +function EventPoster(props){ + return <> + + +} + +export default EventPoster; \ No newline at end of file diff --git a/src/app/event/[id]/components/eventPrizes.jsx b/src/app/event/[id]/components/eventPrizes.jsx new file mode 100644 index 0000000..dc143c2 --- /dev/null +++ b/src/app/event/[id]/components/eventPrizes.jsx @@ -0,0 +1,126 @@ +import React, { useState } from "react"; +export default function EventPrizes(props) { + var specialPrizes=false; + var specialPrizesIndex=0; + var specialPrizesArray = []; + + + if (props.eventPrizes === null || props.eventPrizes.length === 0) { + return <>; + } + else{ + props.eventPrizes.map((value, index) => { + if (typeof value === 'object') { + specialPrizes = true; + specialPrizesIndex = index; + }}); + Object.entries(props.eventPrizes[specialPrizesIndex]).forEach(([key, value]) => { + specialPrizesArray.push(

{key}

 {value}

); + }) + } + + return ( + <> +
+
+

Prizes

+ +
+
+

{specialPrizes ? "Special Prizes":null}

+ {specialPrizes ? + :null} +
+
+ + ); +} + +const FirstPrizeIcon = () => ( + + + + + + + + +); + +const SecondPrizeIcon = () => ( + + + + + + + + +); + +const ThirdPrizeIcon = () => ( + + + + + + + + +); diff --git a/src/app/event/[id]/components/eventRequirements.jsx b/src/app/event/[id]/components/eventRequirements.jsx new file mode 100644 index 0000000..9cd3ff9 --- /dev/null +++ b/src/app/event/[id]/components/eventRequirements.jsx @@ -0,0 +1,34 @@ +import React from "react"; +export default function EventRequirements(props) { + return ( + <> +
+

 Requirements

+ +
+ + ); +} + +const RequirementIcon = () => ( + + + + + + ); + \ No newline at end of file diff --git a/src/app/event/[id]/components/eventVenue.jsx b/src/app/event/[id]/components/eventVenue.jsx new file mode 100644 index 0000000..3c2beea --- /dev/null +++ b/src/app/event/[id]/components/eventVenue.jsx @@ -0,0 +1,27 @@ +import React from "react"; +export default function EventRequirements(props) { + return ( + <> +
+

Venue

+
+
+ + ); +} + +const OfflineIcon = ({ width = 32, height = 32}) => ( + + + + + + + ); + \ No newline at end of file diff --git a/src/app/event/[id]/fetchEvent.jsx b/src/app/event/[id]/fetchEvent.jsx new file mode 100644 index 0000000..e4ac05d --- /dev/null +++ b/src/app/event/[id]/fetchEvent.jsx @@ -0,0 +1,28 @@ +import { useState, useEffect } from 'react'; +import axios from 'axios'; + +const useFetchEvent = (eventId) => { + const [event, setEvent] = useState({}); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchEvent = async () => { + try { + const response = await axios.get(`/api/v1/get/event?id=${eventId}`); + const result = response.data; + setEvent(result.event); + setLoading(false); + } catch (error) { + setError(error); + setLoading(false); + } + }; + + fetchEvent(); + }, [eventId]); + + return { event, loading, error }; +}; + +export default useFetchEvent; diff --git a/src/app/event/[id]/page.jsx b/src/app/event/[id]/page.jsx new file mode 100644 index 0000000..0e1e96b --- /dev/null +++ b/src/app/event/[id]/page.jsx @@ -0,0 +1,72 @@ +'use client' +import React from 'react'; +import { useRouter } from 'next/navigation'; +import GenerateEvent from './components/event'; +import useFetchEvent from './fetchEvent'; +import Loading from '@/components/loading'; + +function Event({ params }) { + const eventId = params.id; + // const { event, loading, error } = useFetchEvent(eventId); + // const router = useRouter(); + + // if (loading) { + // return <> + // + // ; + // } + + // if (error) { + // console.error(error); + // router.push('/events'); + // return null; + // } + + + + // To start calling api delete the object below and uncomment the above code + const event = { + "id": 7, + "name": "Codestrike v6.0", + "description": `Join us for an exciting coding event organized by Coding Club IIITV, \nwhere teamwork and innovation take center stage! \nIn this unique competition, teams of three programmers will come together to \n solve complex coding challenges within a set timeframe. Participants will need to collaborate closely, leveraging each other's strengths to develop efficient and creative solutions. This event is designed to foster camaraderie, enhance problem-solving skills, and encourage effective communication among team members. Don't miss this opportunity to test your coding prowess, make new friends, and have a blast working together. Sign up now and be part of a thrilling coding adventure!`, + "date": "2024-08-05T15:30:00", + "duration": 60, + "mode": false, + "host_link": "https://www.hosted.com", + "venue": "Mess Hall", + "requirements": [ + "Laptop", + "Notebook", + "Pen", + "Pencil" + ], + "hosted_registration": true, + "register_until": "2024-08-05T15:32:30", + "registration_link": "https://www.registration.com", + "creator": "b4e05b86-df08-49d8-a118-51c205216401", + "prizes" : ["Rs. 10000","Rs. 5000", "Rs. 1000", + { + "Female Special":"Rs. 1000", + "FY Special":"Rs. 1000" + } + ], + "winners" : { + "Web Dev":["ABCDEGFHIJKL","ABCDEGFHIJKL","ABCDEGFHIJKL"], + "Cloud ":["ABCDEGFHIJKL"], + "CyberSecurity":["ABCDEGFHIJKL","ABCDEGFHIJKL"] + }, + "convenors":[ + "Devyash Saini","Devyash Saini","Devyash Saini","Devyash Saini" + ] + } + + + + return ( + + ); +} + +export default Event; diff --git a/src/app/event/layout.tsx b/src/app/event/layout.tsx new file mode 100644 index 0000000..1bcbaa6 --- /dev/null +++ b/src/app/event/layout.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import Navbar from "@/components/navbar" +import Footer from "@/components/footer" + + +interface RootLayoutProps { + children: React.ReactNode; +} + +export default function RootLayout({ children } : RootLayoutProps) { + return ( + <> + + {children} +