Skip to content

Commit dffefec

Browse files
Merge pull request #121 from deveshsawant05/redesign-events-page
Redesigned Events Page
2 parents c64f9f6 + 272793a commit dffefec

File tree

5 files changed

+174
-103
lines changed

5 files changed

+174
-103
lines changed
+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import React, { useState } from "react";
2+
3+
import { getPublicUrl } from "@/lib/utils";
4+
import Link from "next/link";
5+
6+
import { Montserrat, Alata } from "next/font/google";
7+
const montserratFont = Montserrat({
8+
weight: ["100", "200", "400", "600"],
9+
subsets: ["latin"],
10+
});
11+
const boldMontserratFont = Montserrat({
12+
weight: ["600"],
13+
subsets: ["latin"],
14+
});
15+
16+
export default function EventCard(props) {
17+
const [event, setEvent] = useState(props.event);
18+
const [eventDate, setEventDate] = useState(event.date);
19+
const [eventTime, setEventTime] = useState(event.time);
20+
let posterUrl = getPublicUrl(`/events/${event.id}/poster`);
21+
return (
22+
<div className={`${montserratFont.className} lg:row-span-2 lg:col-span-1 w-full h-full`}>
23+
<Link href={`\\event\\${event.id}`}>
24+
<div className="flex flex-col">
25+
<div className="w-full h-full border-2 border-primary rounded-2xl overflow-hidden">
26+
<img src={posterUrl} className="object-cover" />
27+
</div>
28+
<div className={`${montserratFont.className} ms-2 mt-1`}>
29+
<p className="text-primary">{formatDate(eventDate)} | {formatTime(eventTime)}</p>
30+
<p className="font-semibold text-xl">{event.name}</p>
31+
<p className="text-sm">{trimString(event.description,50)}</p>
32+
</div>
33+
</div>
34+
</Link>
35+
</div>
36+
);
37+
}
38+
function formatDate(dateString) {
39+
const [year, month, day] = dateString.split("-");
40+
const date = new Date(year, month - 1, day); // Month is 0-indexed
41+
42+
const formattedDay = date.getDate();
43+
const monthName = date.toLocaleString("default", { month: "long" });
44+
const formattedYear = date.getFullYear();
45+
46+
return `${formattedDay} ${monthName} ${formattedYear}`;
47+
}
48+
49+
50+
const formatTime = (timeString) => {
51+
const timeRegex = /^(\d{2}):(\d{2}):(\d{2})$/;
52+
const match = timeString.match(timeRegex);
53+
if (!match) {
54+
return 'Invalid Time Format';
55+
}
56+
let hours = parseInt(match[1], 10);
57+
const minutes = parseInt(match[2], 10);
58+
const ampm = hours >= 12 ? 'PM' : 'AM';
59+
hours = hours % 12;
60+
hours = hours ? hours : 12;
61+
const formattedMinutes = String(minutes).padStart(2, '0');
62+
return `${hours}:${formattedMinutes} ${ampm}`;
63+
};
64+
65+
const trimString = (str, maxLength) => {
66+
if (str.length > maxLength) {
67+
return str.substring(0, maxLength) + '...';
68+
}
69+
return str;
70+
};

src/app/events/layout.tsx

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from "react";
2+
import Navbar from "@/components/navbar";
3+
import Footer from "@/components/footer";
4+
5+
interface RootLayoutProps {
6+
children: React.ReactNode;
7+
}
8+
9+
export default function RootLayout({ children }: RootLayoutProps) {
10+
return (
11+
<>
12+
<Navbar />
13+
{children}
14+
<Footer />
15+
</>
16+
);
17+
}

src/app/events/page.jsx

+57-61
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,40 @@
11
"use client";
2-
import { useEffect, useState } from "react";
3-
import EventBox from "../../components/ui/EventBox";
4-
import { getPublicUrl } from "@/lib/utils";
5-
function Page() {
2+
import React, { useState ,useEffect } from "react";
3+
import { useRouter } from "next/navigation";
4+
import "./styles.css"
5+
import Loader from "@/components/ui/loader";
6+
import EventCard from "./components/eventCard"
7+
8+
import { Montserrat, Alata } from "next/font/google";
9+
const montserratFont = Montserrat({
10+
weight: ["100", "200", "400", "600"],
11+
subsets: ["latin"],
12+
});
13+
const alataFont = Alata({ weight: ["400"], subsets: ["latin"] });
14+
15+
export default function Events() {
16+
const router = useRouter();
617
const [events, setEvents] = useState([]);
718
const [nextPageEvents, setNextPageEvents] = useState([]);
819
const [pageCount, setPageCount] = useState(1);
9-
const [hasMoreEvents, setHasMoreEvents] = useState(true);
10-
const [columnCount, setColumnCount] = useState(3);
20+
const [hasMoreEvents, setHasMoreEvents] = useState(false);
21+
const [loading, setLoading] = useState(false);
1122

1223
const fetchEvents = async (page) => {
1324
try {
25+
setHasMoreEvents(false);
26+
setLoading(true);
1427
const response = await fetch(`/api/v1/get/events?page=${page}`);
1528
const data = await response.json();
1629
return data;
1730
} catch (error) {
1831
console.error("Error fetching events:", error);
1932
return [];
2033
}
34+
finally {
35+
setHasMoreEvents(true);
36+
setLoading(false);
37+
}
2138
};
2239

2340
const getMoreEvents = async () => {
@@ -44,69 +61,48 @@ function Page() {
4461
setHasMoreEvents(false);
4562
}
4663
};
47-
48-
const handleResize = () => {
49-
if (window.innerWidth < 768) {
50-
setColumnCount(2);
51-
} else {
52-
setColumnCount(3);
53-
}
54-
};
55-
56-
window.addEventListener("resize", handleResize);
57-
handleResize();
5864
loadInitialEvents();
59-
60-
return () => {
61-
window.removeEventListener("resize", handleResize);
62-
};
63-
}, []);
64-
65-
const columns = Array.from({ length: columnCount }, () => []);
66-
67-
events.forEach((event, index) => {
68-
let posterUrl = getPublicUrl(`/events/${event.id}/poster`);
69-
70-
columns[index % columnCount].push(
71-
<EventBox
72-
img={posterUrl}
73-
key={event.id}
74-
caption={event.description}
75-
time={event.date}
76-
category={event.name}
77-
hostLink={event.host_link}
78-
/>,
79-
);
80-
});
65+
}, []);
8166

8267
return (
83-
<div className="flex flex-col w-full h-full">
84-
<div className="self-center h-fit py-2 w-11/12 flex flex-col bg-[#201f31] mt-4">
85-
<p className="md:pl-12 pt-5 text-2xl font-medium mb-7 ">Events Near</p>
86-
<div className="self-center w-full grid grid-flow-row grid-cols-2 md:grid-cols-3">
87-
{columns.map((column, colIndex) => (
88-
<section
89-
key={colIndex}
90-
className={`h-fit w-full gap-8 py-4 grid grid-flow-row md:pl-12 ${
91-
colIndex === 1 && columnCount === 3 ? "mt-32" : ""
92-
}
93-
${colIndex === 1 && columnCount === 2 ? "mt-20" : ""}`}
94-
>
95-
{column}
96-
</section>
68+
<div className="w-full flex justify-center mt-6">
69+
<div className="w-[95%]">
70+
<p className={`underline text-3xl ml-4 ${alataFont.className}`}>
71+
Events
72+
</p>
73+
<div className="grid lg:grid-cols-3 gap-8 px-4 mt-6 sm:grid-cols-2 grid-cols-1 grid-rows-1">
74+
{/* Static Quote Box in 2nd column, 1st row */}
75+
<div className="h-full lg:col-start-2 lg:col-span-1 lg:row-start-1 lg:row-span-1 sm:col-span-2 col-span-1 p-4 bg-gray-700 rounded-2xl flex items-center justify-center text-white text-center">
76+
Random image or quote
77+
</div>
78+
79+
{events.map((event, index) => (
80+
<EventCard event={event} key={index}/>
9781
))}
9882
</div>
99-
{hasMoreEvents && (
100-
<button
101-
onClick={getMoreEvents}
102-
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"
83+
84+
{loading ? (
85+
<div className="w-full flex justify-center p-12">
86+
<p className={`text-xl px-5 ${montserratFont.className}`}>
87+
Loading...{" "}
88+
</p>
89+
<Loader />
90+
</div>
91+
) : (
92+
hasMoreEvents && (
93+
<div
94+
className={`${montserratFont.className} w-full flex justify-center my-10`}
10395
>
104-
Show More
105-
</button>
96+
<button
97+
className="show-more-button"
98+
onClick={getMoreEvents}
99+
>
100+
<p>Show More</p>
101+
</button>
102+
</div>
103+
)
106104
)}
107105
</div>
108106
</div>
109107
);
110108
}
111-
112-
export default Page;

src/app/events/styles.css

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
.show-more-button{
2+
3+
box-sizing: border-box;
4+
width: 300px;
5+
height: 45px;
6+
7+
background-color : color-mix(in srgb, var(--primary) 5%, transparent);
8+
box-shadow: color-mix(in srgb, #fff 5%, transparent) 1px 1px 15px;
9+
border: solid color-mix(in srgb, var(--primary) 20%, transparent) 1px;
10+
border-radius: 43px;
11+
12+
transition: 0.5s;
13+
}
14+
.show-more-button:hover{
15+
background-color : color-mix(in srgb, var(--muted-foreground) 40%, transparent);
16+
}
17+
.show-more-button>p{
18+
font-weight: 700;
19+
font-size: 18px;
20+
21+
color: var(--primary);
22+
}
23+
24+
@media screen and (max-width : 1024px){
25+
.show-more-button{
26+
27+
box-sizing: border-box;
28+
width: 200px;
29+
}
30+
}

src/components/ui/EventBox.jsx

-42
This file was deleted.

0 commit comments

Comments
 (0)