From 9dd007657a2f28c40eee2220b3648d6210fd1853 Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Tue, 19 May 2026 10:46:44 +0100 Subject: [PATCH] feat(events): pipe displayTimezone through list and sidebar formatters Sidebar (EventsMiniSidebar), public events list, member dashboard "Upcoming" block, and EventTicketPurchase all formatted dates in viewer-local TZ. Switch each formatter to accept the event (or an eventTimezone prop) and pass it to Intl.DateTimeFormat so the displayed wall-clock matches the event's intended zone. --- app/components/EventTicketPurchase.vue | 5 +++++ app/components/EventsMiniSidebar.vue | 13 +++++++----- app/pages/events/[slug].vue | 1 + app/pages/events/index.vue | 28 ++++++++++++++++---------- app/pages/member/dashboard.vue | 18 ++++++++--------- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/app/components/EventTicketPurchase.vue b/app/components/EventTicketPurchase.vue index 0e61903..02a6e6a 100644 --- a/app/components/EventTicketPurchase.vue +++ b/app/components/EventTicketPurchase.vue @@ -231,6 +231,10 @@ const props = defineProps({ type: String, required: true, }, + eventTimezone: { + type: String, + default: "America/Toronto", + }, userEmail: { type: String, default: null, @@ -415,6 +419,7 @@ const formatEventDate = (date) => { month: "long", day: "numeric", year: "numeric", + timeZone: props.eventTimezone || "America/Toronto", }); }; diff --git a/app/components/EventsMiniSidebar.vue b/app/components/EventsMiniSidebar.vue index df953d6..0a9aa0b 100644 --- a/app/components/EventsMiniSidebar.vue +++ b/app/components/EventsMiniSidebar.vue @@ -6,7 +6,7 @@
- {{ formatDate(event.startDate) }} + {{ formatDate(event) }} [] }, }); -const formatDate = (dateStr) => { - if (!dateStr) return ""; - const d = new Date(dateStr); - return d.toLocaleDateString("en-US", { month: "short", day: "numeric" }); +const formatDate = (event) => { + if (!event?.startDate) return ""; + return new Date(event.startDate).toLocaleDateString("en-US", { + month: "short", + day: "numeric", + timeZone: event.displayTimezone || "America/Toronto", + }); }; diff --git a/app/pages/events/[slug].vue b/app/pages/events/[slug].vue index 1befb81..61117f9 100644 --- a/app/pages/events/[slug].vue +++ b/app/pages/events/[slug].vue @@ -131,6 +131,7 @@ :event-id="event._id || event.id" :event-start-date="event.startDate" :event-title="event.title" + :event-timezone="eventTimeZone" :user-email="memberData?.email" :user-name="memberData?.name" @success="handleTicketSuccess" diff --git a/app/pages/events/index.vue b/app/pages/events/index.vue index 66c90e9..bfcf9b3 100644 --- a/app/pages/events/index.vue +++ b/app/pages/events/index.vue @@ -34,8 +34,8 @@ :class="{ 'is-cancelled': event.isCancelled }" >
- {{ formatDate(event.startDate) }} - {{ formatTime(event.startDate) }} + {{ formatDate(event) }} + {{ formatTime(event) }}
@@ -152,18 +152,24 @@ const activeSeries = computed(() => { ); }); -const formatDate = (dateStr) => { - if (!dateStr) return ""; - const d = new Date(dateStr); - const opts = { month: "short", day: "numeric" }; - if (d.getFullYear() !== new Date().getFullYear()) opts.year = "numeric"; +const formatDate = (event) => { + if (!event?.startDate) return ""; + const tz = event.displayTimezone || "America/Toronto"; + const d = new Date(event.startDate); + const opts = { month: "short", day: "numeric", timeZone: tz }; + const dYear = d.toLocaleDateString("en-US", { year: "numeric", timeZone: tz }); + const nowYear = new Date().toLocaleDateString("en-US", { year: "numeric", timeZone: tz }); + if (dYear !== nowYear) opts.year = "numeric"; return d.toLocaleDateString("en-US", opts); }; -const formatTime = (dateStr) => { - if (!dateStr) return ""; - const d = new Date(dateStr); - return d.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" }); +const formatTime = (event) => { + if (!event?.startDate) return ""; + return new Date(event.startDate).toLocaleTimeString("en-US", { + hour: "numeric", + minute: "2-digit", + timeZone: event.displayTimezone || "America/Toronto", + }); }; const formatLocation = (event) => { diff --git a/app/pages/member/dashboard.vue b/app/pages/member/dashboard.vue index de91d71..91d088b 100644 --- a/app/pages/member/dashboard.vue +++ b/app/pages/member/dashboard.vue @@ -60,9 +60,7 @@ :to="`/events/${evt.slug || evt._id}`" class="event-item" > - {{ - formatEventDate(evt.startDate) - }} + {{ formatEventDate(evt) }} {{ evt.title }} @@ -365,20 +363,22 @@ const getEventImageUrl = (featureImage) => { return ""; }; -const formatEventDate = (dateString) => { - const date = new Date(dateString); +const formatEventDate = (event) => { + if (!event?.startDate) return ""; return new Intl.DateTimeFormat("en-US", { month: "short", day: "numeric", - }).format(date); + timeZone: event.displayTimezone || "America/Toronto", + }).format(new Date(event.startDate)); }; -const formatEventTime = (dateString) => { - const date = new Date(dateString); +const formatEventTime = (event) => { + if (!event?.startDate) return ""; return new Intl.DateTimeFormat("en-US", { hour: "numeric", minute: "2-digit", - }).format(date); + timeZone: event.displayTimezone || "America/Toronto", + }).format(new Date(event.startDate)); }; const formatMemberSince = (dateString) => {