From d4fb1415177149ce1e364c030f54c711bf02f913 Mon Sep 17 00:00:00 2001 From: "paololahoud2004@gmail.com" Date: Thu, 16 Oct 2025 23:33:03 -0400 Subject: [PATCH] added affiliated clubs and updated events page --- src/components/event/EventBlock.svelte | 230 ++++++++++++++---- src/components/event/EventTabPanel.svelte | 125 +++++++++- .../homepage/AffiliatedClubs.svelte | 123 ++++++++++ src/components/homepage/SocialLinks.svelte | 166 ------------- src/routes/+page.svelte | 7 +- src/routes/events/+page.server.ts | 117 +++++++++ 6 files changed, 534 insertions(+), 234 deletions(-) create mode 100644 src/components/homepage/AffiliatedClubs.svelte delete mode 100644 src/components/homepage/SocialLinks.svelte diff --git a/src/components/event/EventBlock.svelte b/src/components/event/EventBlock.svelte index 7249c88..57b45c5 100644 --- a/src/components/event/EventBlock.svelte +++ b/src/components/event/EventBlock.svelte @@ -1,6 +1,6 @@ -
-
+
+ +
+ {#if thumbnail} + {eventTitle} + {:else if eventCategory?.[0] === 'social'} + Social Event + {:else if eventCategory?.[0] === 'technical'} + Technical Event + {:else if eventCategory?.[0] === 'professional'} + Professional Event + {:else if eventCategory?.[0] === 'academic'} + Academic Event + {:else} + ECSESS Event + {/if} + +
- {#if thumbnail} - Event banner - {:else if eventCategory?.[0] === 'social'} - Social Placeholder - {:else if eventCategory?.[0] === 'technical'} - Technical Placeholder - {:else if eventCategory?.[0] === 'professional'} - Professional Placeholder - {:else if eventCategory?.[0] === 'academic'} - Academic Placeholder + class="absolute inset-0 bg-gradient-to-b from-transparent via-black/30 to-black/80 dark:to-black/90" + >
+ + +
+ {#if isPastEvent} + + Past Event + {:else} - Default Placeholder + + Upcoming + {/if} + + {#if eventCategory && eventCategory.length > 0} +
+ {#each eventCategory as category} + + {category} + + {/each} +
+ {/if} +
+ + +
+

+ {eventTitle} +

- -
-

- {eventTitle} -

- + +
+ {#if eventDescription} -
+
{/if} -
-
-
- - Datetime: -

{date}

+ +
+
+
+
- -
- - Location: -

{location ?? 'TBA'}

+
+

{date}

-
-
- - Registration: +
+
+ +
+
+

+ {location ?? 'TBA'} +

+
+
+
+ + + {#if !isPastEvent} +
+ + + + +
{#if registrationLink} - Register Here + + Register {:else} -

Just drop in!

+
+ + Drop In +
{/if} -
-
- - Payment: {#if paymentLink} - Pay Here + + Pay {:else} -

Free!

+
+ Free! +
{/if}
-
+ {/if}
diff --git a/src/components/event/EventTabPanel.svelte b/src/components/event/EventTabPanel.svelte index 4d96785..e6012b3 100644 --- a/src/components/event/EventTabPanel.svelte +++ b/src/components/event/EventTabPanel.svelte @@ -17,22 +17,121 @@ return Array.isArray(c) ? c.includes(category) : (c as string) === category; }; + const parseEventDate = (dateString: string): Date => { + // Try to parse various date formats + const parsed = new Date(dateString); + return isNaN(parsed.getTime()) ? new Date() : parsed; + }; + + const formatEventDate = (dateString: string): string => { + const date = parseEventDate(dateString); + + // Check if the time is midnight (00:00) which likely means no time was specified + const isMidnight = date.getUTCHours() === 0 && date.getUTCMinutes() === 0; + + if (isMidnight) { + // Format without time - just the date + return date.toLocaleDateString('en-US', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }); + } else { + // Format with time + return date.toLocaleDateString('en-US', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + hour: 'numeric', + minute: '2-digit', + hour12: true + }); + } + }; + + const isPastEvent = (dateString: string): boolean => { + const eventDate = parseEventDate(dateString); + const now = new Date(); + return eventDate < now; + }; + const filtered = $derived((events ?? []).filter(matchCategory)); + + const upcomingEvents = $derived( + filtered + .filter((e) => !isPastEvent(e.date)) + .sort((a, b) => parseEventDate(a.date).getTime() - parseEventDate(b.date).getTime()) + ); + + const finishedEvents = $derived( + filtered + .filter((e) => isPastEvent(e.date)) + .sort((a, b) => parseEventDate(b.date).getTime() - parseEventDate(a.date).getTime()) + ); -
- {#each filtered as e (e._id ?? e.name)} - - {/each} +
+ + {#if upcomingEvents.length > 0} +
+
+
+

Upcoming Events

+
+
+ {#each upcomingEvents as e (e._id ?? e.name)} + + {/each} +
+
+ {/if} + + + {#if finishedEvents.length > 0} +
+
+
+

Past Events

+
+
+ {#each finishedEvents as e (e._id ?? e.name)} + + {/each} +
+
+ {/if} + + + {#if upcomingEvents.length === 0 && finishedEvents.length === 0} +
+
+

No events in this category yet

+

Check back soon for updates!

+
+
+ {/if}
diff --git a/src/components/homepage/AffiliatedClubs.svelte b/src/components/homepage/AffiliatedClubs.svelte new file mode 100644 index 0000000..b3509bc --- /dev/null +++ b/src/components/homepage/AffiliatedClubs.svelte @@ -0,0 +1,123 @@ + + +
+
+ +
+

+ Affiliated Clubs & Labs +

+

+ Explore opportunities to enhance your skills, build innovative projects, and connect with + the engineering community through our affiliated organizations. +

+
+ + +
+ {#each clubs as club} +
+ +
+ +
+ +
+
+ {#if club.icon === Wrench} + + {:else if club.icon === Zap} + + {:else if club.icon === Code2} + + {/if} +
+

+ {club.name} +

+
+ + +

+ {club.description} +

+ + +
+ {#each club.features as feature} +
+
+ + {feature} + +
+ {/each} +
+ + + + Visit Website + + +
+
+ {/each} +
+ + +
+

+ Want to get involved? Visit their websites to learn about upcoming events and how to join! +

+
+
+
diff --git a/src/components/homepage/SocialLinks.svelte b/src/components/homepage/SocialLinks.svelte deleted file mode 100644 index 59335f2..0000000 --- a/src/components/homepage/SocialLinks.svelte +++ /dev/null @@ -1,166 +0,0 @@ - - -
- -
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 5d3faab..a7d257a 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -5,7 +5,7 @@ import OhSchedule from 'components/officehour/OHSchedule.svelte'; import Link from 'components/Link.svelte'; import SeoMetaTags from 'components/layout/SeoMetaTags.svelte'; - import SocialLinks from 'components/homepage/SocialLinks.svelte'; + import AffiliatedClubs from 'components/homepage/AffiliatedClubs.svelte'; import { fade } from 'svelte/transition'; /** loading things from the server side */ @@ -55,7 +55,6 @@
-
@@ -64,6 +63,10 @@
+ + + +
diff --git a/src/routes/events/+page.server.ts b/src/routes/events/+page.server.ts index d3918d0..22f1f42 100644 --- a/src/routes/events/+page.server.ts +++ b/src/routes/events/+page.server.ts @@ -1,3 +1,31 @@ +// import type { EventPost } from '$lib/schemas'; +// import { getFromCMS } from '$lib/utils.js'; + +// const eventQuery = `*[_type == "events"]{ +// name, +// category, +// date, +// location, +// description, +// reglink, +// paylink, +// "thumbnail": thumbnail.asset->url+"?h=800&fm=webp", +// "lastUpdated": _updatedAt, +// }`; + +// export const load = async ({ url }) => { +// let listOfEvents: EventPost[] = await getFromCMS(eventQuery); + +// let sortedEvents = listOfEvents.sort( +// (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() +// ); + +// return { +// events: sortedEvents, +// canonical: url.href +// }; +// }; + import type { EventPost } from '$lib/schemas'; import { getFromCMS } from '$lib/utils.js'; @@ -13,9 +41,96 @@ const eventQuery = `*[_type == "events"]{ "lastUpdated": _updatedAt, }`; +// Mock future events for testing +const getMockFutureEvents = (): EventPost[] => { + const today = new Date(); + const nextWeek = new Date(today); + nextWeek.setDate(today.getDate() + 7); + + const twoWeeks = new Date(today); + twoWeeks.setDate(today.getDate() + 14); + + const nextMonth = new Date(today); + nextMonth.setMonth(today.getMonth() + 1); + + return [ + { + _id: 'mock-1', + name: "Antoine's Smash Workshop", + category: ['technical'], + date: nextWeek.toISOString(), + location: 'ECSESS Lounge', + description: [ + { + _type: 'block', + children: [ + { + _type: 'span', + text: 'Antoine should reall get gud at smash' + } + ] + } + ], + reglink: 'https://example.com/register', + paylink: null, + thumbnail: null, + lastUpdated: today.toISOString() + }, + { + _id: 'mock-2', + name: 'ECSESS Annual Networking Night', + category: ['professional', 'social'], + date: twoWeeks.toISOString(), + location: 'Trottier ', + description: [ + { + _type: 'block', + children: [ + { + _type: 'span', + text: 'I love placeholder text!' + } + ] + } + ], + reglink: 'https://example.com/register', + paylink: 'https://example.com/payment', + thumbnail: null, + lastUpdated: today.toISOString() + }, + { + _id: 'mock-3', + name: 'Midterm Study Session', + category: ['academic'], + date: nextMonth.toISOString(), + location: 'Trottier 5th floor', + description: [ + { + _type: 'block', + children: [ + { + _type: 'span', + text: 'TIME TO LOCK THE FUCK IN' + } + ] + } + ], + reglink: null, + paylink: null, + thumbnail: null, + lastUpdated: today.toISOString() + } + ]; +}; + export const load = async ({ url }) => { let listOfEvents: EventPost[] = await getFromCMS(eventQuery); + // TEMPORARY: Add mock future events for testing the UI + const mockEvents = getMockFutureEvents(); + listOfEvents = [...listOfEvents, ...mockEvents]; + // END TEMPORARY - Remove the above two lines when you have real future events + let sortedEvents = listOfEvents.sort( (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() ); @@ -25,3 +140,5 @@ export const load = async ({ url }) => { canonical: url.href }; }; + +// TODO: Remember to remove mock events once real future events are available in the CMS.