Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 104 additions & 78 deletions app/(with-layout)/event/schedule/page.tsx
Original file line number Diff line number Diff line change
@@ -1,103 +1,129 @@
"use client";

import NavBar from "@/components/nav-bar/nav-bar";
import "@/app/globals.css";
import { useState, useEffect } from "react";
import type { Event } from "@/data/schedule";
import {
saturdayTimes,
sundayTimes,
SATURDAY_START,
SUNDAY_START
} from "@/data/schedule";

import Schedule from "@/components/schedule/schedule";
import HackRPILink from "@/components/themed-components/hackrpi-link";
import scheduleData from "@/data/scheduleData.json";

type RawEvent = {
id: string;
title: string;
description: string;
location: string;
speaker: string;
eventType: "workshop" | "constant" | "important" | "food" | "deadline";
visible: boolean;
column: number;
width: number; // Added width for multi-column spanning
startMinutesFromDayStart: number; // minutes offset
durationMinutes: number; // length
_id: string;
name: string;
location: string;
host: string;
description: string;
start_time: string;
end_time: string;
column: number;
event_type: string;
};

const DEFAULT_WIDTH = 1;
const isSaturday = (date: Date) => date.getDay() === 6; // Saturday is day 6 (0=Sun, 6=Sat)

// convert fetched data from DB to Event Type
function convertToEvent(ev: RawEvent): Event {
const startTime = new Date(ev.start_time).getTime();
const endTime = new Date(ev.end_time).getTime();

let eventType: "workshop" | "constant" | "important" | "food" | "deadline" = "workshop";
switch (ev.event_type) {
case "food":
eventType = "food";
break;
case "ceremony":
eventType = "important";
break;
case "deadline":
eventType = "deadline";
break;
default:
eventType = "workshop";
}

return {
id: ev._id,
title: ev.name,
description: ev.description ?? "",
startTime,
endTime,
location: ev.location ?? "",
speaker: ev.host ?? "",
eventType,
visible: true,
column: ev.column,
width: DEFAULT_WIDTH,
};
}

export default function Page() {
const [currentDateTime, setCurrentDateTime] = useState(new Date());
const [saturdayEvents, setSaturdayEvents] = useState<Event[]>([]);
const [sundayEvents, setSundayEvents] = useState<Event[]>([]);
const [state, setState] = useState<"loading" | "loaded" | "error">("loading");
const [modalEvent, setModalEvent] = useState<Event | null>(null);

useEffect(() => {
try {
// Convert raw scheduleData into real Events
const satConverted: Event[] = (scheduleData.saturdayEvents as RawEvent[]).map((ev) => {
const startTime = SATURDAY_START + ev.startMinutesFromDayStart * 60_000;
const endTime = startTime + ev.durationMinutes * 60_000;

return {
id: ev.id,
title: ev.title,
description: ev.description ?? "",
startTime,
endTime,
location: ev.location ?? "",
speaker: ev.speaker ?? "",
eventType: ev.eventType ?? "general",
visible: ev.visible,
column: ev.column,
width: ev.width // New property to handle multi-column span
};
});

const sunConverted: Event[] = (scheduleData.sundayEvents as RawEvent[]).map((ev) => {
const startTime = SUNDAY_START + ev.startMinutesFromDayStart * 60_000;
const endTime = startTime + ev.durationMinutes * 60_000;

return {
id: ev.id,
title: ev.title,
description: ev.description ?? "",
startTime,
endTime,
location: ev.location ?? "",
speaker: ev.speaker ?? "",
eventType: ev.eventType ?? "general",
visible: ev.visible,
column: ev.column,
width: ev.width // New property to handle multi-column span
};
});

setSaturdayEvents(satConverted);
setSundayEvents(sunConverted);

setState("loaded");
} catch (e) {
console.error(e);
setState("error");
}

const interval = setInterval(() => {
setCurrentDateTime(new Date());
}, 1000);

addEventListener("keydown", (event) => {
if (event.key === "Escape") {
setModalEvent(null);
}
});

return () => clearInterval(interval);
}, []);
useEffect(() => {
async function fetchSchedule() {
try {
setState("loading");
const response = await fetch("/api/schedule");

if (!response.ok) {
throw new Error("Failed to fetch schedule data");
}

const rawEvents: RawEvent[] = await response.json();
const satEvents: Event[] = [];
const sunEvents: Event[] = [];

// process data
rawEvents.forEach((rawEv) => {
const convertedEvent = convertToEvent(rawEv);
const eventDate = new Date(convertedEvent.startTime);

// Separate events into Saturday and Sunday based on the start date
if (isSaturday(eventDate)) {
satEvents.push(convertedEvent);
} else {
sunEvents.push(convertedEvent);
}
});

// TODO: investigate possibility of infinite re-rendering
// update saturdayEvents and sundayEvents arrays
setSaturdayEvents(satEvents);
setSundayEvents(sunEvents);

setState("loaded");
} catch (e) {
console.error(e);
setState("error");
}
}

fetchSchedule();

const interval = setInterval(() => {
setCurrentDateTime(new Date());
}, 1000);

const keydownHandler = (event: KeyboardEvent) => {
if (event.key === "Escape") {
setModalEvent(null);
}
}

return () => {
clearInterval(interval);
window.removeEventListener("keydown", keydownHandler);
}
}, []);

return (
<div className="flex flex-col w-full h-fit min-h-screen items-center justify-center">
Expand Down Expand Up @@ -201,4 +227,4 @@ export default function Page() {
</div>
</div>
);
}
}
6 changes: 3 additions & 3 deletions app/api/mongodb.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as dotenv from "dotenv";
import mongoose from "mongoose";

dotenv.config();
dotenv.config({path:"./config.env"});

const MONGO_URI = process.env.MONGO_URI;

console.log("Mongo URI:", MONGO_URI);

// connect to DB
// being called twice, see https://github.com/vercel/next.js/issues/37715
export async function connectDB() {
if (MONGO_URI) {
const connectDB = mongoose
Expand Down
1 change: 1 addition & 0 deletions app/api/schedule/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export async function GET() {
try {
await connectDB();
const items = await Schedule.find().sort({ start_time: 1, createdAt: -1 });

return NextResponse.json(items);
} catch (err) {
console.error("Error fetching schedule:", err);
Expand Down
1 change: 0 additions & 1 deletion components/schedule/schedule.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useState } from "react";
import type { Event } from "@/data/schedule";

export default function Schedule(props: {
Expand Down
Loading
Loading