diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e4f0e14..30ce676 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,7 +16,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 with: - version: 8 + version: 9 - name: Set up config files run: cp config/config.example.toml config/config.toml @@ -46,7 +46,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 with: - version: 8 + version: 9 - name: Set up config files run: cp config/config.example.toml config/config.toml diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 7a4600a..fd2afea 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -15,7 +15,7 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 with: - version: 8 + version: 9 - name: Set up known_hosts file run: | diff --git a/src/lib/event.ts b/src/lib/event.ts new file mode 100644 index 0000000..334ddf6 --- /dev/null +++ b/src/lib/event.ts @@ -0,0 +1,29 @@ +import { IEventGroup } from "../models/EventGroup.js"; + +export interface EventListEvent { + id: string; + name: string; + location: string; + displayDate: string; + eventHasConcluded: boolean; + startMoment: moment.Moment; + endMoment: moment.Moment; + eventGroup?: IEventGroup; +} + +export const bucketEventsByMonth = ( + acc: Record[], + event: EventListEvent, +) => { + const month = event.startMoment.format("MMMM YYYY"); + const matchingBucket = acc.find((bucket) => bucket.title === month); + if (!matchingBucket) { + acc.push({ + title: month, + events: [event], + }); + } else { + matchingBucket.events.push(event); + } + return acc; +}; diff --git a/src/routes/frontend.ts b/src/routes/frontend.ts index 86ad69c..14bb779 100644 --- a/src/routes/frontend.ts +++ b/src/routes/frontend.ts @@ -18,6 +18,7 @@ import { import MagicLink from "../models/MagicLink.js"; import { getConfigMiddleware } from "../lib/middleware.js"; import { getMessage } from "../util/messages.js"; +import { EventListEvent, bucketEventsByMonth } from "../lib/event.js"; const router = Router(); @@ -89,7 +90,7 @@ router.get("/events", async (_: Request, res: Response) => { .populate("eventGroup") .lean() .sort("start"); - const updatedEvents = events.map((event) => { + const updatedEvents: EventListEvent[] = events.map((event) => { const startMoment = moment.tz(event.start, event.timezone); const endMoment = moment.tz(event.end, event.timezone); const isSameDay = startMoment.isSame(endMoment, "day"); @@ -105,14 +106,16 @@ router.get("/events", async (_: Request, res: Response) => { )}`, eventHasConcluded: endMoment.isBefore(moment.tz(event.timezone)), eventGroup: event.eventGroup as any as IEventGroup, + startMoment, + endMoment, }; }); - const upcomingEvents = updatedEvents.filter( - (event) => event.eventHasConcluded === false, - ); - const pastEvents = updatedEvents.filter( - (event) => event.eventHasConcluded === true, - ); + const upcomingEventsInMonthBuckets = updatedEvents + .filter((event) => event.eventHasConcluded === false) + .reduce(bucketEventsByMonth, []); + const pastEventsInMonthBuckets = updatedEvents + .filter((event) => event.eventHasConcluded === true) + .reduce(bucketEventsByMonth, []); const eventGroups = await EventGroup.find({ showOnPublicList: true, }).lean(); @@ -130,8 +133,8 @@ router.get("/events", async (_: Request, res: Response) => { res.render("publicEventList", { title: "Public events", - upcomingEvents: upcomingEvents, - pastEvents: pastEvents, + upcomingEvents: upcomingEventsInMonthBuckets, + pastEvents: pastEventsInMonthBuckets, eventGroups: updatedEventGroups, instanceDescription: instanceDescription(), instanceRules: instanceRules(), @@ -425,7 +428,7 @@ router.get("/group/:eventGroupID", async (req: Request, res: Response) => { .lean() .sort("start"); - const updatedEvents = events.map((event) => { + const updatedEvents: EventListEvent[] = events.map((event) => { const startMoment = moment.tz(event.start, event.timezone); const endMoment = moment.tz(event.end, event.timezone); const isSameDay = startMoment.isSame(endMoment, "day"); @@ -442,12 +445,18 @@ router.get("/group/:eventGroupID", async (req: Request, res: Response) => { eventHasConcluded: endMoment.isBefore( moment.tz(event.timezone), ), + startMoment, + endMoment, }; }); - const upcomingEventsExist = updatedEvents.some( - (e) => !e.eventHasConcluded, - ); + const upcomingEventsInMonthBuckets = updatedEvents + .filter((event) => !event.eventHasConcluded) + .reduce(bucketEventsByMonth, []); + + const pastEventsInMonthBuckets = updatedEvents + .filter((event) => event.eventHasConcluded) + .reduce(bucketEventsByMonth, []); let firstLoad = false; if (eventGroup.firstLoad === true) { @@ -494,8 +503,8 @@ router.get("/group/:eventGroupID", async (req: Request, res: Response) => { title: eventGroup.name, eventGroupData: eventGroup, escapedName: escapedName, - events: updatedEvents, - upcomingEventsExist: upcomingEventsExist, + upcomingEvents: upcomingEventsInMonthBuckets, + pastEvents: pastEventsInMonthBuckets, parsedDescription: parsedDescription, editingEnabled: editingEnabled, eventGroupHasCoverImage: eventGroupHasCoverImage, diff --git a/views/eventgroup.handlebars b/views/eventgroup.handlebars index 9658b60..3151aea 100755 --- a/views/eventgroup.handlebars +++ b/views/eventgroup.handlebars @@ -109,31 +109,22 @@ {{/if}} -
-
About
-
- {{{parsedDescription}}} -
-
-
-
Upcoming events
-
- {{#if upcomingEventsExist}} - {{#each events}} - {{#unless this.eventHasConcluded}} - - - {{this.name}} - {{#if this.location}} {{this.location}}{{/if}} - {{this.displayDate}} - - {{/unless}} - {{/each}} - {{else}} -
No events!
- {{/if}} -
-
+
+
About
+
+ {{{parsedDescription}}} +
+
+ +
+
Upcoming events
+ {{> eventList upcomingEvents}} +
+ +
+
Past events
+ {{> eventList pastEvents}} +
{{#if editingEnabled}} diff --git a/views/partials/eventList.handlebars b/views/partials/eventList.handlebars new file mode 100644 index 0000000..6c8e7a4 --- /dev/null +++ b/views/partials/eventList.handlebars @@ -0,0 +1,22 @@ +
+{{#if this}} + {{#each this}} +
+
{{this.title}}
+
+ {{#each this.events}} + + + {{this.name}} + {{#if this.location}} {{this.location}}{{/if}} + {{this.displayDate}} + {{#if this.eventGroup}} + {{this.eventGroup.name}} + {{/if}} + + {{/each}} + {{/each}} +{{else}} +
No events!
+{{/if}} +
diff --git a/views/publicEventList.handlebars b/views/publicEventList.handlebars index 8dccaaa..b8cacd0 100644 --- a/views/publicEventList.handlebars +++ b/views/publicEventList.handlebars @@ -21,44 +21,13 @@
-
Upcoming events
- +
Upcoming events
+ {{> eventList upcomingEvents }}
-
Past events
-
- {{#if pastEvents}} - {{#each pastEvents}} - - - {{this.name}} - {{this.displayDate}} - {{#if this.eventGroup}} - {{this.eventGroup.name}} - {{/if}} - - {{/each}} - {{else}} -
No events!
- {{/if}} -
+
Past events
+ {{> eventList pastEvents }}
@@ -79,4 +48,4 @@ {{/if}} - \ No newline at end of file +