From 68ce1a16707dcadee9017b3e8f9fe1c6fe1a5498 Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sat, 13 Dec 2025 16:32:38 -0500 Subject: [PATCH 01/16] added a timebar on the left of the schedule. Currently working to dynamically set each event to the appropriate times --- src/pages/Schedule.tsx | 130 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 11 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index 1334254..f86ac6d 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -1,7 +1,7 @@ import { Layout } from "@/components/Layout"; import { useState } from "react"; import { cn } from "@/lib/utils"; -import { Clock, MapPin, Users } from "lucide-react"; +import { Clock, Grid, Grid2X2, MapPin, Users } from "lucide-react"; type Day = "friday" | "saturday" | "sunday"; @@ -13,6 +13,29 @@ interface ScheduleEvent { type: "social" | "main" | "food" | "activity"; } +const times = [ + { id: 1, hour: '05', timeOfDay: "am"}, + { id: 2, hour: '06', timeOfDay: "am"}, + { id: 3, hour: '07', timeOfDay: "am"}, + { id: 4, hour: '08', timeOfDay: "am"}, + { id: 5, hour: '09', timeOfDay: "am"}, + { id: 6, hour: '10', timeOfDay: "am"}, + { id: 7, hour: '11', timeOfDay: "am"}, + { id: 8, hour: '12', timeOfDay: "am"}, + { id: 9, hour: '01', timeOfDay: "pm"}, + { id: 10, hour: '02', timeOfDay: "pm"}, + { id: 11, hour: '03', timeOfDay: "pm"}, + { id: 12, hour: '04', timeOfDay: "pm"}, + { id: 13, hour: '05', timeOfDay: "pm"}, + { id: 14, hour: '06', timeOfDay: "pm"}, + { id: 15, hour: '07', timeOfDay: "pm"}, + { id: 16, hour: '08', timeOfDay: "pm"}, + { id: 17, hour: '09', timeOfDay: "pm"}, + { id: 18, hour: '10', timeOfDay: "pm"}, + { id: 19, hour: '11', timeOfDay: "pm"}, + { id: 20, hour: '12', timeOfDay: "pm"}, + ] + // PLACEHOLDER: Update all event times, descriptions, and locations as they are finalized const scheduleData: Record = { friday: [ @@ -120,6 +143,63 @@ const typeColors: Record = { activity: "bg-emerald-500/20 text-emerald-400 border-emerald-500/30", }; +const baseHour = 5; // the first viable hour (currently 5am) +/** + * // calculate the row index an event should start at given its start time (in military time) + * @param hhmm (In military time. Ex: 18:00 == 06:00pm) + * @returns index of the row + */ +function timeToRowStart(time: string): number { + + const startWithTimeOfDay = time.split(" - ")[0]; + + var hhmm = startWithTimeOfDay.split(" "); // process the time into something usable by the function + + if(hhmm[1] == "PM"){ // convert to military time if needed + const startTime = hhmm[0].split[":"]; + hhmm[0] = (parseInt(startTime[0], 10) * 12).toString() + startTime[1]; + } + + const [hString, mString] = hhmm[0].split(":"); + const h = parseInt(hString, 10); + const m = parseInt(mString, 10); + const hourOffset = (h - baseHour) * 4; // calculate the hour + const quarterOffset = Math.floor(m / 15); // calculate the quarter in the hour + return hourOffset + quarterOffset + 1; // return the row index +} + +/** + * Duration in rows based on 15-minute slots. + * @param start time given in military time (13:00) + * @param end time given in military time (18:00) + * @returns the number of rows that the given time frame spans + */ +function durationToRowSpan(time: string): number { + + const [startWithTimeOfDay, endWithTimeOfDay] = time.split(" - "); + + var start = startWithTimeOfDay.split(" "); // process the time into something usable by the function + var end = endWithTimeOfDay.split(" "); + + if(start[1] == "PM"){ // convert to military time if needed + const startTime = start[0].split[":"]; + start[0] = (parseInt(startTime[0], 10) * 12).toString() + startTime[1]; + } + if(end[1] == "PM"){ // convert to military time if needed + const endTime = end[0].split[":"]; + end[0] = (parseInt(endTime[0], 10) * 12).toString() + endTime[1]; + } + + const toMinutes = (t: string) => { // helper function for + const [hStr, mStr] = t.split(":"); + return parseInt(hStr, 10) * 60 + parseInt(mStr, 10); + }; + + const minutes = toMinutes(end[0]) - toMinutes(start[0]); + return Math.max(1, Math.ceil(minutes / 15)); +} + + const Schedule = () => { const [selectedDay, setSelectedDay] = useState("friday"); @@ -133,7 +213,7 @@ const Schedule = () => { Event Schedule

- Three days of events, activities, and celebrations. Click on a day to see what's happening. + Three days of events, activities, and celebrations.

@@ -164,8 +244,12 @@ const Schedule = () => { {/* TODO: Change the Event to look more like Google Calendar and get the events to open a Expanded Dialog to show the Venue, where it is, and an expanded description*/} {/* Schedule Timeline */} + {/* Plan: Make a grid and set the starting column to the start time and have it span columns a value of the time rounded to 15 or one of those time sections*/}
-
+
{/* Day Header */}
@@ -177,13 +261,37 @@ const Schedule = () => {

- {/* Events */} -
+ {/* Events */} {/* Adding grid rows*/} +
+ + {/* Create Timeline on the left */} + {times.map(time => ( +
+
+ {time.hour} {time.timeOfDay} - +
+
+ -{time.hour}:15 - +
+
+ -{time.hour}:30 - +
+
+ -{time.hour}:45 - +
+
+ ))} + + {/* Display the events on the right of the timeline*/} {scheduleData[selectedDay].map((event, index) => (
@@ -209,13 +317,13 @@ const Schedule = () => { {event.type === "main" ? "Main Event" : event.type.charAt(0).toUpperCase() + event.type.slice(1)}
-

+ {/*

{event.description}

{event.location} -
+
*/}
@@ -225,8 +333,8 @@ const Schedule = () => {
- {/* Remove this portion */} - {/* Legend */} + {/* Remove this portion + {/* Legend }
@@ -251,7 +359,7 @@ const Schedule = () => {
-
+ */} ); }; From 5a07419f90e4d756c8079d1059415c9159485d6c Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sat, 13 Dec 2025 16:33:27 -0500 Subject: [PATCH 02/16] reverted changes --- src/pages/Schedule.tsx | 130 ++++------------------------------------- 1 file changed, 11 insertions(+), 119 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index f86ac6d..1334254 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -1,7 +1,7 @@ import { Layout } from "@/components/Layout"; import { useState } from "react"; import { cn } from "@/lib/utils"; -import { Clock, Grid, Grid2X2, MapPin, Users } from "lucide-react"; +import { Clock, MapPin, Users } from "lucide-react"; type Day = "friday" | "saturday" | "sunday"; @@ -13,29 +13,6 @@ interface ScheduleEvent { type: "social" | "main" | "food" | "activity"; } -const times = [ - { id: 1, hour: '05', timeOfDay: "am"}, - { id: 2, hour: '06', timeOfDay: "am"}, - { id: 3, hour: '07', timeOfDay: "am"}, - { id: 4, hour: '08', timeOfDay: "am"}, - { id: 5, hour: '09', timeOfDay: "am"}, - { id: 6, hour: '10', timeOfDay: "am"}, - { id: 7, hour: '11', timeOfDay: "am"}, - { id: 8, hour: '12', timeOfDay: "am"}, - { id: 9, hour: '01', timeOfDay: "pm"}, - { id: 10, hour: '02', timeOfDay: "pm"}, - { id: 11, hour: '03', timeOfDay: "pm"}, - { id: 12, hour: '04', timeOfDay: "pm"}, - { id: 13, hour: '05', timeOfDay: "pm"}, - { id: 14, hour: '06', timeOfDay: "pm"}, - { id: 15, hour: '07', timeOfDay: "pm"}, - { id: 16, hour: '08', timeOfDay: "pm"}, - { id: 17, hour: '09', timeOfDay: "pm"}, - { id: 18, hour: '10', timeOfDay: "pm"}, - { id: 19, hour: '11', timeOfDay: "pm"}, - { id: 20, hour: '12', timeOfDay: "pm"}, - ] - // PLACEHOLDER: Update all event times, descriptions, and locations as they are finalized const scheduleData: Record = { friday: [ @@ -143,63 +120,6 @@ const typeColors: Record = { activity: "bg-emerald-500/20 text-emerald-400 border-emerald-500/30", }; -const baseHour = 5; // the first viable hour (currently 5am) -/** - * // calculate the row index an event should start at given its start time (in military time) - * @param hhmm (In military time. Ex: 18:00 == 06:00pm) - * @returns index of the row - */ -function timeToRowStart(time: string): number { - - const startWithTimeOfDay = time.split(" - ")[0]; - - var hhmm = startWithTimeOfDay.split(" "); // process the time into something usable by the function - - if(hhmm[1] == "PM"){ // convert to military time if needed - const startTime = hhmm[0].split[":"]; - hhmm[0] = (parseInt(startTime[0], 10) * 12).toString() + startTime[1]; - } - - const [hString, mString] = hhmm[0].split(":"); - const h = parseInt(hString, 10); - const m = parseInt(mString, 10); - const hourOffset = (h - baseHour) * 4; // calculate the hour - const quarterOffset = Math.floor(m / 15); // calculate the quarter in the hour - return hourOffset + quarterOffset + 1; // return the row index -} - -/** - * Duration in rows based on 15-minute slots. - * @param start time given in military time (13:00) - * @param end time given in military time (18:00) - * @returns the number of rows that the given time frame spans - */ -function durationToRowSpan(time: string): number { - - const [startWithTimeOfDay, endWithTimeOfDay] = time.split(" - "); - - var start = startWithTimeOfDay.split(" "); // process the time into something usable by the function - var end = endWithTimeOfDay.split(" "); - - if(start[1] == "PM"){ // convert to military time if needed - const startTime = start[0].split[":"]; - start[0] = (parseInt(startTime[0], 10) * 12).toString() + startTime[1]; - } - if(end[1] == "PM"){ // convert to military time if needed - const endTime = end[0].split[":"]; - end[0] = (parseInt(endTime[0], 10) * 12).toString() + endTime[1]; - } - - const toMinutes = (t: string) => { // helper function for - const [hStr, mStr] = t.split(":"); - return parseInt(hStr, 10) * 60 + parseInt(mStr, 10); - }; - - const minutes = toMinutes(end[0]) - toMinutes(start[0]); - return Math.max(1, Math.ceil(minutes / 15)); -} - - const Schedule = () => { const [selectedDay, setSelectedDay] = useState("friday"); @@ -213,7 +133,7 @@ const Schedule = () => { Event Schedule

- Three days of events, activities, and celebrations. + Three days of events, activities, and celebrations. Click on a day to see what's happening.

@@ -244,12 +164,8 @@ const Schedule = () => { {/* TODO: Change the Event to look more like Google Calendar and get the events to open a Expanded Dialog to show the Venue, where it is, and an expanded description*/} {/* Schedule Timeline */} - {/* Plan: Make a grid and set the starting column to the start time and have it span columns a value of the time rounded to 15 or one of those time sections*/}
-
+
{/* Day Header */}
@@ -261,37 +177,13 @@ const Schedule = () => {

- {/* Events */} {/* Adding grid rows*/} -
- - {/* Create Timeline on the left */} - {times.map(time => ( -
-
- {time.hour} {time.timeOfDay} - -
-
- -{time.hour}:15 - -
-
- -{time.hour}:30 - -
-
- -{time.hour}:45 - -
-
- ))} - - {/* Display the events on the right of the timeline*/} + {/* Events */} +
{scheduleData[selectedDay].map((event, index) => (
@@ -317,13 +209,13 @@ const Schedule = () => { {event.type === "main" ? "Main Event" : event.type.charAt(0).toUpperCase() + event.type.slice(1)}
- {/*

+

{event.description}

{event.location} -
*/} +
@@ -333,8 +225,8 @@ const Schedule = () => {
- {/* Remove this portion - {/* Legend } + {/* Remove this portion */} + {/* Legend */}
@@ -359,7 +251,7 @@ const Schedule = () => {
-
*/} + ); }; From 088bb3661febdbe6a6232b40cf34b8a5bba6810d Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sat, 13 Dec 2025 16:34:10 -0500 Subject: [PATCH 03/16] reverted changes --- src/pages/Schedule.tsx | 130 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 11 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index 1334254..f86ac6d 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -1,7 +1,7 @@ import { Layout } from "@/components/Layout"; import { useState } from "react"; import { cn } from "@/lib/utils"; -import { Clock, MapPin, Users } from "lucide-react"; +import { Clock, Grid, Grid2X2, MapPin, Users } from "lucide-react"; type Day = "friday" | "saturday" | "sunday"; @@ -13,6 +13,29 @@ interface ScheduleEvent { type: "social" | "main" | "food" | "activity"; } +const times = [ + { id: 1, hour: '05', timeOfDay: "am"}, + { id: 2, hour: '06', timeOfDay: "am"}, + { id: 3, hour: '07', timeOfDay: "am"}, + { id: 4, hour: '08', timeOfDay: "am"}, + { id: 5, hour: '09', timeOfDay: "am"}, + { id: 6, hour: '10', timeOfDay: "am"}, + { id: 7, hour: '11', timeOfDay: "am"}, + { id: 8, hour: '12', timeOfDay: "am"}, + { id: 9, hour: '01', timeOfDay: "pm"}, + { id: 10, hour: '02', timeOfDay: "pm"}, + { id: 11, hour: '03', timeOfDay: "pm"}, + { id: 12, hour: '04', timeOfDay: "pm"}, + { id: 13, hour: '05', timeOfDay: "pm"}, + { id: 14, hour: '06', timeOfDay: "pm"}, + { id: 15, hour: '07', timeOfDay: "pm"}, + { id: 16, hour: '08', timeOfDay: "pm"}, + { id: 17, hour: '09', timeOfDay: "pm"}, + { id: 18, hour: '10', timeOfDay: "pm"}, + { id: 19, hour: '11', timeOfDay: "pm"}, + { id: 20, hour: '12', timeOfDay: "pm"}, + ] + // PLACEHOLDER: Update all event times, descriptions, and locations as they are finalized const scheduleData: Record = { friday: [ @@ -120,6 +143,63 @@ const typeColors: Record = { activity: "bg-emerald-500/20 text-emerald-400 border-emerald-500/30", }; +const baseHour = 5; // the first viable hour (currently 5am) +/** + * // calculate the row index an event should start at given its start time (in military time) + * @param hhmm (In military time. Ex: 18:00 == 06:00pm) + * @returns index of the row + */ +function timeToRowStart(time: string): number { + + const startWithTimeOfDay = time.split(" - ")[0]; + + var hhmm = startWithTimeOfDay.split(" "); // process the time into something usable by the function + + if(hhmm[1] == "PM"){ // convert to military time if needed + const startTime = hhmm[0].split[":"]; + hhmm[0] = (parseInt(startTime[0], 10) * 12).toString() + startTime[1]; + } + + const [hString, mString] = hhmm[0].split(":"); + const h = parseInt(hString, 10); + const m = parseInt(mString, 10); + const hourOffset = (h - baseHour) * 4; // calculate the hour + const quarterOffset = Math.floor(m / 15); // calculate the quarter in the hour + return hourOffset + quarterOffset + 1; // return the row index +} + +/** + * Duration in rows based on 15-minute slots. + * @param start time given in military time (13:00) + * @param end time given in military time (18:00) + * @returns the number of rows that the given time frame spans + */ +function durationToRowSpan(time: string): number { + + const [startWithTimeOfDay, endWithTimeOfDay] = time.split(" - "); + + var start = startWithTimeOfDay.split(" "); // process the time into something usable by the function + var end = endWithTimeOfDay.split(" "); + + if(start[1] == "PM"){ // convert to military time if needed + const startTime = start[0].split[":"]; + start[0] = (parseInt(startTime[0], 10) * 12).toString() + startTime[1]; + } + if(end[1] == "PM"){ // convert to military time if needed + const endTime = end[0].split[":"]; + end[0] = (parseInt(endTime[0], 10) * 12).toString() + endTime[1]; + } + + const toMinutes = (t: string) => { // helper function for + const [hStr, mStr] = t.split(":"); + return parseInt(hStr, 10) * 60 + parseInt(mStr, 10); + }; + + const minutes = toMinutes(end[0]) - toMinutes(start[0]); + return Math.max(1, Math.ceil(minutes / 15)); +} + + const Schedule = () => { const [selectedDay, setSelectedDay] = useState("friday"); @@ -133,7 +213,7 @@ const Schedule = () => { Event Schedule

- Three days of events, activities, and celebrations. Click on a day to see what's happening. + Three days of events, activities, and celebrations.

@@ -164,8 +244,12 @@ const Schedule = () => { {/* TODO: Change the Event to look more like Google Calendar and get the events to open a Expanded Dialog to show the Venue, where it is, and an expanded description*/} {/* Schedule Timeline */} + {/* Plan: Make a grid and set the starting column to the start time and have it span columns a value of the time rounded to 15 or one of those time sections*/}
-
+
{/* Day Header */}
@@ -177,13 +261,37 @@ const Schedule = () => {

- {/* Events */} -
+ {/* Events */} {/* Adding grid rows*/} +
+ + {/* Create Timeline on the left */} + {times.map(time => ( +
+
+ {time.hour} {time.timeOfDay} - +
+
+ -{time.hour}:15 - +
+
+ -{time.hour}:30 - +
+
+ -{time.hour}:45 - +
+
+ ))} + + {/* Display the events on the right of the timeline*/} {scheduleData[selectedDay].map((event, index) => (
@@ -209,13 +317,13 @@ const Schedule = () => { {event.type === "main" ? "Main Event" : event.type.charAt(0).toUpperCase() + event.type.slice(1)}
-

+ {/*

{event.description}

{event.location} -
+
*/}
@@ -225,8 +333,8 @@ const Schedule = () => {
- {/* Remove this portion */} - {/* Legend */} + {/* Remove this portion + {/* Legend }
@@ -251,7 +359,7 @@ const Schedule = () => {
-
+ */} ); }; From a219023bde02ccf91c4d4065a4a5f245a9440b61 Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sat, 13 Dec 2025 16:35:48 -0500 Subject: [PATCH 04/16] ignore previous commit message, it actually was: 'added a timebar on the left of the schedule. Currently working to dynamically set each event to the appropriate times' --- src/pages/Schedule.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index f86ac6d..60aec7b 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -362,6 +362,6 @@ const Schedule = () => { */} ); -}; +}; export default Schedule; From 9da0a49176e343eefa4c51af1401c993ee634101 Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sat, 13 Dec 2025 17:03:39 -0500 Subject: [PATCH 05/16] event cards are placed on their respective time frames and overlap eachother --- src/pages/Schedule.tsx | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index 60aec7b..f93c30d 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -154,10 +154,11 @@ function timeToRowStart(time: string): number { const startWithTimeOfDay = time.split(" - ")[0]; var hhmm = startWithTimeOfDay.split(" "); // process the time into something usable by the function - + if(hhmm[1] == "PM"){ // convert to military time if needed - const startTime = hhmm[0].split[":"]; - hhmm[0] = (parseInt(startTime[0], 10) * 12).toString() + startTime[1]; + const startTime = hhmm[0].split(":"); + + hhmm[0] = (parseInt(startTime[0], 10) + 12).toString() + ":" + startTime[1]; } const [hString, mString] = hhmm[0].split(":"); @@ -182,12 +183,12 @@ function durationToRowSpan(time: string): number { var end = endWithTimeOfDay.split(" "); if(start[1] == "PM"){ // convert to military time if needed - const startTime = start[0].split[":"]; - start[0] = (parseInt(startTime[0], 10) * 12).toString() + startTime[1]; + const startTime = start[0].split(":"); + start[0] = (parseInt(startTime[0], 10) + 12).toString() + ":" + startTime[1]; } if(end[1] == "PM"){ // convert to military time if needed - const endTime = end[0].split[":"]; - end[0] = (parseInt(endTime[0], 10) * 12).toString() + endTime[1]; + const endTime = end[0].split(":"); + end[0] = (parseInt(endTime[0], 10) + 12).toString() + ":" + endTime[1]; } const toMinutes = (t: string) => { // helper function for @@ -270,7 +271,7 @@ const Schedule = () => { {/* Create Timeline on the left */} {times.map(time => ( -
+
{time.hour} {time.timeOfDay} -
@@ -291,9 +292,13 @@ const Schedule = () => {
{/* Time */} From 5eca3b3e2e37748c14625c89e1fc8bc6958dfac0 Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sat, 13 Dec 2025 17:14:51 -0500 Subject: [PATCH 06/16] added some comments --- src/pages/Schedule.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index f93c30d..8b010de 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -13,6 +13,10 @@ interface ScheduleEvent { type: "social" | "main" | "food" | "activity"; } +/** + * The time frame for events for the day in hours. + * (id) is only used for keys and does not matter the order, just don't repeat them. + */ const times = [ { id: 1, hour: '05', timeOfDay: "am"}, { id: 2, hour: '06', timeOfDay: "am"}, @@ -146,7 +150,7 @@ const typeColors: Record = { const baseHour = 5; // the first viable hour (currently 5am) /** * // calculate the row index an event should start at given its start time (in military time) - * @param hhmm (In military time. Ex: 18:00 == 06:00pm) + * @param time accepts the following input format: "11:00 AM - 1:00 PM" * @returns index of the row */ function timeToRowStart(time: string): number { @@ -171,12 +175,11 @@ function timeToRowStart(time: string): number { /** * Duration in rows based on 15-minute slots. - * @param start time given in military time (13:00) - * @param end time given in military time (18:00) + * @param time accepts the following input format: "11:00 AM - 1:00 PM" * @returns the number of rows that the given time frame spans */ function durationToRowSpan(time: string): number { - + const [startWithTimeOfDay, endWithTimeOfDay] = time.split(" - "); var start = startWithTimeOfDay.split(" "); // process the time into something usable by the function @@ -287,12 +290,12 @@ const Schedule = () => {
))} - {/* Display the events on the right of the timeline*/} + {/* Display events on the right of timeline */} {scheduleData[selectedDay].map((event, index) => (
Date: Sat, 13 Dec 2025 17:22:24 -0500 Subject: [PATCH 07/16] more comments and organized code --- src/pages/Schedule.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index 8b010de..f17a01c 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -13,6 +13,7 @@ interface ScheduleEvent { type: "social" | "main" | "food" | "activity"; } +//----- Constants & Arrays for Event Data-----// /** * The time frame for events for the day in hours. * (id) is only used for keys and does not matter the order, just don't repeat them. @@ -40,6 +41,9 @@ const times = [ { id: 20, hour: '12', timeOfDay: "pm"}, ] +/** + * Holds the data for events shown on the Schedule Page + */ // PLACEHOLDER: Update all event times, descriptions, and locations as they are finalized const scheduleData: Record = { friday: [ @@ -147,12 +151,13 @@ const typeColors: Record = { activity: "bg-emerald-500/20 text-emerald-400 border-emerald-500/30", }; -const baseHour = 5; // the first viable hour (currently 5am) +//----- Helper Functions -----// /** * // calculate the row index an event should start at given its start time (in military time) * @param time accepts the following input format: "11:00 AM - 1:00 PM" * @returns index of the row */ +const baseHour = 5; // the first viable hour (currently 5am) function timeToRowStart(time: string): number { const startWithTimeOfDay = time.split(" - ")[0]; @@ -204,6 +209,7 @@ function durationToRowSpan(time: string): number { } +//----- Webpage HTML -----// const Schedule = () => { const [selectedDay, setSelectedDay] = useState("friday"); @@ -279,13 +285,13 @@ const Schedule = () => { {time.hour} {time.timeOfDay} -
- -{time.hour}:15 - + - {time.hour}:15 -
- -{time.hour}:30 - + - {time.hour}:30 -
- -{time.hour}:45 - + - {time.hour}:45 -
))} From 30ba4cfe5a20ee3bf7e7e5c985269433a5ac179e Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sat, 13 Dec 2025 18:24:53 -0500 Subject: [PATCH 08/16] event cards now appear on their own columns --- src/pages/Schedule.tsx | 56 ++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index f17a01c..21e3c77 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -26,7 +26,7 @@ const times = [ { id: 5, hour: '09', timeOfDay: "am"}, { id: 6, hour: '10', timeOfDay: "am"}, { id: 7, hour: '11', timeOfDay: "am"}, - { id: 8, hour: '12', timeOfDay: "am"}, + { id: 8, hour: '12', timeOfDay: "pm"}, { id: 9, hour: '01', timeOfDay: "pm"}, { id: 10, hour: '02', timeOfDay: "pm"}, { id: 11, hour: '03', timeOfDay: "pm"}, @@ -38,7 +38,7 @@ const times = [ { id: 17, hour: '09', timeOfDay: "pm"}, { id: 18, hour: '10', timeOfDay: "pm"}, { id: 19, hour: '11', timeOfDay: "pm"}, - { id: 20, hour: '12', timeOfDay: "pm"}, + { id: 20, hour: '12', timeOfDay: "am"}, ] /** @@ -167,7 +167,9 @@ function timeToRowStart(time: string): number { if(hhmm[1] == "PM"){ // convert to military time if needed const startTime = hhmm[0].split(":"); - hhmm[0] = (parseInt(startTime[0], 10) + 12).toString() + ":" + startTime[1]; + if(parseInt(startTime[0], 10) != 12){ // ignore 12pm + hhmm[0] = (parseInt(startTime[0], 10) + 12).toString() + ":" + startTime[1]; + } } const [hString, mString] = hhmm[0].split(":"); @@ -192,11 +194,23 @@ function durationToRowSpan(time: string): number { if(start[1] == "PM"){ // convert to military time if needed const startTime = start[0].split(":"); - start[0] = (parseInt(startTime[0], 10) + 12).toString() + ":" + startTime[1]; + + if(parseInt(startTime[0], 10) != 12){ // ignore 12pm + start[0] = (parseInt(startTime[0], 10) + 12).toString() + ":" + startTime[1]; + } } if(end[1] == "PM"){ // convert to military time if needed const endTime = end[0].split(":"); - end[0] = (parseInt(endTime[0], 10) + 12).toString() + ":" + endTime[1]; + + if(parseInt(endTime[0], 10) != 12){ // ignore 12pm + end[0] = (parseInt(endTime[0], 10) + 12).toString() + ":" + endTime[1]; + } + } + else if(end[1] == "AM"){ // convert to military time if needed + const endTime = end[0].split(":"); + if(endTime[0] == "12"){ // can end at 12AM + end[0] = (parseInt(endTime[0], 10) + 12).toString() + ":" + endTime[1]; + } } const toMinutes = (t: string) => { // helper function for @@ -208,6 +222,14 @@ function durationToRowSpan(time: string): number { return Math.max(1, Math.ceil(minutes / 15)); } +var currentCol = 2; +function nextColumn(): number{ + if(currentCol > 4){ + currentCol = 2; + } + return currentCol++; +} + //----- Webpage HTML -----// const Schedule = () => { @@ -254,13 +276,12 @@ const Schedule = () => { {/* TODO: Change the Event to look more like Google Calendar and get the events to open a Expanded Dialog to show the Venue, where it is, and an expanded description*/} {/* Schedule Timeline */} - {/* Plan: Make a grid and set the starting column to the start time and have it span columns a value of the time rounded to 15 or one of those time sections*/}
-
+
{/* Day Header */}

@@ -273,14 +294,13 @@ const Schedule = () => { {/* Events */} {/* Adding grid rows*/}
- {/* Create Timeline on the left */} {times.map(time => ( -
+
{time.hour} {time.timeOfDay} -
@@ -301,25 +321,23 @@ const Schedule = () => {
-
- {/* Time */} -
+
+ {/* Content */} +
+ {/* Time */}
{event.time}
-
- - {/* Content */} -

{event.title} From 05926e1e62c2f84f7f05f513a55483240abed2eb Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sat, 13 Dec 2025 18:34:53 -0500 Subject: [PATCH 09/16] styled the event cards to look a little nicer --- src/pages/Schedule.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index 21e3c77..6c6e51b 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -145,10 +145,10 @@ const dayLabels: Record = { }; const typeColors: Record = { - social: "bg-blue-500/20 text-blue-400 border-blue-500/30", + social: "bg-blue-500/70 text-blue-200 border-blue-500/30", main: "bg-gradient-csh text-primary-foreground", - food: "bg-amber-500/20 text-amber-400 border-amber-500/30", - activity: "bg-emerald-500/20 text-emerald-400 border-emerald-500/30", + food: "bg-amber-500/70 text-amber-200 border-amber-500/30", + activity: "bg-emerald-500/70 text-emerald-200 border-emerald-500/30", }; //----- Helper Functions -----// @@ -334,7 +334,7 @@ const Schedule = () => { {/* Content */}
{/* Time */} -
+
{event.time}
@@ -349,13 +349,13 @@ const Schedule = () => { {event.type === "main" ? "Main Event" : event.type.charAt(0).toUpperCase() + event.type.slice(1)}
- {/*

+

{event.description}

-
+
{event.location} -
*/} +

From 49e3b9a505b678445c98e6e44b144cdc811a5b4d Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sun, 14 Dec 2025 12:22:38 -0500 Subject: [PATCH 10/16] updated some comments --- src/pages/Schedule.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index 6c6e51b..aa28048 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -212,6 +212,9 @@ function durationToRowSpan(time: string): number { end[0] = (parseInt(endTime[0], 10) + 12).toString() + ":" + endTime[1]; } } + else if(end[0].toLowerCase() == "late"){ // treat late as if it was 1am + end[0] = "25:00"; + } const toMinutes = (t: string) => { // helper function for const [hStr, mStr] = t.split(":"); @@ -222,6 +225,9 @@ function durationToRowSpan(time: string): number { return Math.max(1, Math.ceil(minutes / 15)); } +/** + * Calculate the next column to place events in. (iterates between columns 2, 3, and 4) + */ var currentCol = 2; function nextColumn(): number{ if(currentCol > 4){ @@ -276,10 +282,10 @@ const Schedule = () => { {/* TODO: Change the Event to look more like Google Calendar and get the events to open a Expanded Dialog to show the Venue, where it is, and an expanded description*/} {/* Schedule Timeline */} -
+
{/* Day Header */} @@ -322,7 +328,7 @@ const Schedule = () => { key={index} className={cn( "col-start-2 col-span-1 row-span-1 overflow-y-auto flex flex-wrap border-4 border-csh-magenta p-6 rounded-2xl transition-all duration-300 hover:scale-[1.02] bg-pink-300", - event.type === "main" && "border-2 border-primary/50 glow-csh" + event.type === "main" && "border-8 border-primary/100 glow-csh" )} style={{ gridRowStart: timeToRowStart(event.time), @@ -362,7 +368,7 @@ const Schedule = () => { ))}
-
+

{/* Remove this portion From dc704d3d9a946179add2c4b3ca88884a04992a6e Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sat, 20 Dec 2025 18:09:41 -0500 Subject: [PATCH 11/16] Time bars now span the whole schedule --- src/pages/Schedule.tsx | 102 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 8 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index aa28048..5b9bebc 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -151,6 +151,11 @@ const typeColors: Record = { activity: "bg-emerald-500/70 text-emerald-200 border-emerald-500/30", }; +/** + * The number of sections in the grid + */ +var SectionCount = 0; + //----- Helper Functions -----// /** * // calculate the row index an event should start at given its start time (in military time) @@ -237,9 +242,74 @@ function nextColumn(): number{ } +/** + * Increments the SectionCount by 1 + */ +function incrementSectionCount(): void{ + SectionCount++; +} + +/** + * Increments the SectionCount by (i) + */ +function incrementSectionCountBy(i: number): void{ + SectionCount += i; +} + +/** + * Resets the SectionCount to 0 + */ +function resetSectionCount(){ + SectionCount = 0; +} + +/** + * Returns the number of unused cells in the grid + * @returns number + */ +function getEmptySpacesCount(): number{ + return (240);// - SectionCount; +} + +/** + * Given an index, returns the spacer's column + * @param index index of the spacer + * @returns number + */ +function setSpacerColumn(index: number): number { + if(index % 3 == 0){ + return 2; + } + else if((index - 1) % 3 == 0){ + return 3; + } + else if((index - 2) % 3 == 0){ + return 4; + } +} + +/** + * Given an index, returns the spacer's row + * @param index index of the spacer + * @returns number + */ +function setSpacerRow(index: number): number { + if(index % 3 == 0){ + return (index / 3) + 1; + } + else if((index - 1) % 3 == 0){ + return ((index - 1) / 3) + 1; + } + else if((index - 2) % 3 == 0){ + return ((index - 2) / 3) + 1; + } +} + + //----- Webpage HTML -----// const Schedule = () => { const [selectedDay, setSelectedDay] = useState("friday"); + resetSectionCount(); // reset the section count on the page reloading return ( @@ -264,7 +334,7 @@ const Schedule = () => { {(Object.keys(scheduleData) as Day[]).map((day) => (
- {/* TODO: Change the Event to look more like Google Calendar and get the events to open a Expanded Dialog to show the Venue, where it is, and an expanded description*/} {/* Schedule Timeline */}
{ > {/* Create Timeline on the left */} {times.map(time => ( -
-
+ <> +
{time.hour} {time.timeOfDay} -
-
+
- {time.hour}:15 -
-
+
- {time.hour}:30 -
-
+
- {time.hour}:45 -
-
+ + ))} + + {/* Fill in empty spaces */} + {Array.from({ length: getEmptySpacesCount() }, (_, index) => ( +
))} {/* Display events on the right of timeline */} {scheduleData[selectedDay].map((event, index) => ( + incrementSectionCountBy(durationToRowSpan(event.time)), // increment the section count to have how many events are on the page
{
))} +
From 39b3efb7e2b6c6f84221654658e00c0189033c1e Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sat, 20 Dec 2025 18:43:38 -0500 Subject: [PATCH 12/16] decreased the spacer sizes --- src/pages/Schedule.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index 5b9bebc..3e239a1 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -357,6 +357,7 @@ const Schedule = () => { "border-8 border-primary/50" )}>
+ {/* Day Header */}

@@ -369,7 +370,7 @@ const Schedule = () => { {/* Events */} {/* Adding grid rows*/}
@@ -393,7 +394,7 @@ const Schedule = () => { {/* Fill in empty spaces */} {Array.from({ length: getEmptySpacesCount() }, (_, index) => ( -
Date: Sun, 21 Dec 2025 08:34:37 -0500 Subject: [PATCH 13/16] timeline on the left takes up less space --- src/pages/Schedule.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index 3e239a1..c42b083 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -351,12 +351,12 @@ const Schedule = () => {

{/* Schedule Timeline */} -
+
-
+
{/* Day Header */}
@@ -370,23 +370,23 @@ const Schedule = () => { {/* Events */} {/* Adding grid rows*/}
{/* Create Timeline on the left */} {times.map(time => ( <> -
+
{time.hour} {time.timeOfDay} -
-
+
- {time.hour}:15 -
-
+
- {time.hour}:30 -
-
+
- {time.hour}:45 -
From 8beb9b1db99ac875ce6bbff57af08d2674e6d47d Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sun, 21 Dec 2025 09:12:55 -0500 Subject: [PATCH 14/16] added comment to address the warning --- src/pages/Schedule.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index c42b083..f22d8bb 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -375,8 +375,8 @@ const Schedule = () => { )} > {/* Create Timeline on the left */} - {times.map(time => ( - <> + {times.map(time => ( // source of Warning:(react_jsx-dev-runtime.js?v=7f273f88:64 Warning: Each child in a list should have a unique "key" prop.), because of <> + <>
{time.hour} {time.timeOfDay} -
From 7ce019094b5e55a73e9ffccb84327a27fa15a0b1 Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sun, 21 Dec 2025 12:41:36 -0500 Subject: [PATCH 15/16] implemented EventPopups, a popup now appears when the user selects an event and disappears when the screen is clicked again. BUG: The events are re-shuffled when a popup appears, which does not look good --- src/pages/EventPopup.tsx | 68 ++++++++++++++++++++++++++++ src/pages/Schedule.tsx | 93 +++++++++++++++++++++++--------------- src/pages/ScheduleEvent.ts | 10 ++++ 3 files changed, 135 insertions(+), 36 deletions(-) create mode 100644 src/pages/EventPopup.tsx create mode 100644 src/pages/ScheduleEvent.ts diff --git a/src/pages/EventPopup.tsx b/src/pages/EventPopup.tsx new file mode 100644 index 0000000..9a40423 --- /dev/null +++ b/src/pages/EventPopup.tsx @@ -0,0 +1,68 @@ +import { cn } from "@/lib/utils"; +import { Clock, MapPin } from "lucide-react"; +import { ScheduleEvent } from "./ScheduleEvent"; + +/** + * EventPopupProp that allows onClose() to be passed in + */ +interface EventPopupProps extends ScheduleEvent { + onClose: () => void +} + +export default function EventPopup(event: EventPopupProps,){ + + return ( +
+ {/* If the user clicks anywhere, then the popup is closed */} + +
+ ); +}; \ No newline at end of file diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index f22d8bb..41966aa 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -1,18 +1,12 @@ import { Layout } from "@/components/Layout"; import { useState } from "react"; import { cn } from "@/lib/utils"; -import { Clock, Grid, Grid2X2, MapPin, Users } from "lucide-react"; +import { Clock, MapPin } from "lucide-react"; +import { ScheduleEvent } from "./ScheduleEvent"; +import EventPopup from "./EventPopup"; type Day = "friday" | "saturday" | "sunday"; -interface ScheduleEvent { - time: string; - title: string; - description: string; - location: string; - type: "social" | "main" | "food" | "activity"; -} - //----- Constants & Arrays for Event Data-----// /** * The time frame for events for the day in hours. @@ -305,12 +299,23 @@ function setSpacerRow(index: number): number { } } - //----- Webpage HTML -----// const Schedule = () => { const [selectedDay, setSelectedDay] = useState("friday"); + const [openEvent, setOpenEvent] = useState(null); + resetSectionCount(); // reset the section count on the page reloading + /** + * Given an event, returns an EventPopup element + * @param event an event + * @returns EventPopup + */ + function openEventPopup(event: ScheduleEvent) { + console.log("I WAS RAN") + setOpenEvent(event); + } + return ( {/* Header */} @@ -422,40 +427,56 @@ const Schedule = () => { gridColumnStart: nextColumn(), }} > -
- {/* Content */} -
- {/* Time */} -
- - {event.time} -
-
-

- {event.title} -

- - {event.type === "main" ? "Main Event" : event.type.charAt(0).toUpperCase() + event.type.slice(1)} - -
-

- {event.description} -

-
- - {event.location} +
+
))}
+ + {openEvent && ( + setOpenEvent(null)} + /> + )} +
{/* Remove this portion diff --git a/src/pages/ScheduleEvent.ts b/src/pages/ScheduleEvent.ts new file mode 100644 index 0000000..3b02c1a --- /dev/null +++ b/src/pages/ScheduleEvent.ts @@ -0,0 +1,10 @@ +/** + * Interface for an Event on the schedule + */ +export interface ScheduleEvent { + time: string, + title: string, + description: string, + location: string, + type: "social" | "main" | "food" | "activity" +} \ No newline at end of file From ef006827e77aa810203e095df566edb6364a6343 Mon Sep 17 00:00:00 2001 From: ShadowArcher289 Date: Sun, 21 Dec 2025 18:20:57 -0500 Subject: [PATCH 16/16] popups no longer re-shuffle the events --- src/pages/EventPopup.tsx | 7 +++-- src/pages/Schedule.tsx | 61 ++++++++++++++++++++++------------------ 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/pages/EventPopup.tsx b/src/pages/EventPopup.tsx index 9a40423..92e47df 100644 --- a/src/pages/EventPopup.tsx +++ b/src/pages/EventPopup.tsx @@ -6,10 +6,11 @@ import { ScheduleEvent } from "./ScheduleEvent"; * EventPopupProp that allows onClose() to be passed in */ interface EventPopupProps extends ScheduleEvent { - onClose: () => void + onClose: () => void, + typeColors: Record } -export default function EventPopup(event: EventPopupProps,){ +export default function EventPopup(event: EventPopupProps){ return (
{event.type === "main" ? "Main Event" : event.type.charAt(0).toUpperCase() + event.type.slice(1)} diff --git a/src/pages/Schedule.tsx b/src/pages/Schedule.tsx index 41966aa..cf88a50 100644 --- a/src/pages/Schedule.tsx +++ b/src/pages/Schedule.tsx @@ -228,13 +228,19 @@ function durationToRowSpan(time: string): number { * Calculate the next column to place events in. (iterates between columns 2, 3, and 4) */ var currentCol = 2; -function nextColumn(): number{ +function nextColumn(): number { if(currentCol > 4){ currentCol = 2; } return currentCol++; } +/** + * Reset the currentCol to 2 + */ +function resetCurrentCol(): void { + currentCol = 2; +} /** * Increments the SectionCount by 1 @@ -305,6 +311,7 @@ const Schedule = () => { const [openEvent, setOpenEvent] = useState(null); resetSectionCount(); // reset the section count on the page reloading + resetCurrentCol(); // reset the currentCol on page refresh /** * Given an event, returns an EventPopup element @@ -429,33 +436,32 @@ const Schedule = () => { > @@ -474,6 +480,7 @@ const Schedule = () => { location={openEvent.location} type={openEvent.type} onClose={() => setOpenEvent(null)} + typeColors = {typeColors} /> )}