Skip to content

Commit b941960

Browse files
committed
Enhance event card with timezone display and improve date formatting
1 parent 650b3f2 commit b941960

2 files changed

Lines changed: 28 additions & 10 deletions

File tree

web/components/events/event-card.tsx

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import clsx from 'clsx'
22
import {HOUR_MS} from 'common/util/time'
33
import dayjs from 'dayjs'
4-
import {capitalize} from 'lodash'
54
import Link from 'next/link'
65
import {Event} from 'web/hooks/use-events'
76
import {useUser} from 'web/hooks/use-user'
87
import {useLocale, useT} from 'web/lib/locale'
9-
import {formatTimeShort, fromNow} from 'web/lib/util/time'
8+
import {capitalizePure, formatTimeShort, fromNow} from 'web/lib/util/time'
109

1110
import {UserLink, UserLinkFromId} from './user-link'
1211

@@ -26,7 +25,8 @@ export function EventCard(props: {
2625
const isRsvped = user && event.participants.includes(user.id)
2726
const isMaybe = user && event.maybe.includes(user.id)
2827
const isCreator = user && event.creator_id === user.id
29-
const isPast = new Date(event.event_start_time) < new Date()
28+
const start = new Date(event.event_start_time)
29+
const isPast = start < new Date()
3030

3131
const formattedDate = formatTimeShort(event.event_start_time, locale)
3232
const formattedEnd =
@@ -36,10 +36,22 @@ export function EventCard(props: {
3636
locale,
3737
dayjs(event.event_end_time).isSame(event.event_start_time, 'day'),
3838
)
39+
40+
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
41+
const longFormatter = new Intl.DateTimeFormat(locale, {
42+
timeZone,
43+
timeZoneName: 'long',
44+
})
45+
const offsetFormatter = new Intl.DateTimeFormat(locale, {
46+
timeZone,
47+
timeZoneName: 'longOffset', // gives "GMT+5:30", "GMT-5:00", etc.
48+
})
49+
const longName = longFormatter.formatToParts(start).find((p) => p.type === 'timeZoneName')?.value
50+
const offset = offsetFormatter.formatToParts(start).find((p) => p.type === 'timeZoneName')?.value
51+
const timezone = `${longName} (${offset})`
52+
3953
let timeAgo = fromNow(event.event_start_time, false, t, locale)
40-
const assumedEnd = new Date(
41-
event.event_end_time ?? new Date(event.event_start_time).getTime() + 24 * HOUR_MS,
42-
)
54+
const assumedEnd = new Date(event.event_end_time ?? start.getTime() + 24 * HOUR_MS)
4355
if (isPast && assumedEnd > new Date())
4456
timeAgo = t('events.started', 'Started {time}', {time: timeAgo})
4557

@@ -61,9 +73,11 @@ export function EventCard(props: {
6173
{/* Date & Time */}
6274
<div className="mb-3">
6375
<p className="text-ink-700 font-medium">
64-
{formattedDate} - {formattedEnd}
76+
{capitalizePure(formattedDate)} {formattedEnd && '- '}
77+
{formattedEnd}
6578
</p>
66-
<p className="text-ink-500 text-sm">{capitalize(timeAgo)}</p>
79+
<p className="text-ink-500 text-sm">{capitalizePure(timezone)}</p>
80+
<p className="text-ink-500 text-sm">{capitalizePure(timeAgo)}</p>
6781
</div>
6882

6983
{/* Description */}

web/lib/util/time.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ export function formatTimeShort(
3030
hourOnly: boolean | null = null,
3131
) {
3232
let date = dayjs(time)
33-
let template = hourOnly ? 'h:mm A' : 'MMM D, h:mm A'
33+
let template = hourOnly ? 'h:mm A' : 'dddd, MMMM D · h:mm A'
3434
if (locale) {
3535
date = date.locale(locale)
36-
if (locale !== 'en') template = hourOnly ? 'HH:mm' : 'D MMM, HH:mm'
36+
if (locale !== 'en') template = hourOnly ? 'HH:mm' : 'dddd D MMMM · HH:mm'
3737
}
3838
return date.format(template)
3939
}
@@ -71,3 +71,7 @@ export const getCountdownStringHoursMinutes = (endDate: Date) => {
7171

7272
return `${isPast ? '-' : ''} ${hoursStr} ${minutesStr}`
7373
}
74+
75+
export function capitalizePure(word: string): string {
76+
return word.charAt(0).toUpperCase() + word.slice(1)
77+
}

0 commit comments

Comments
 (0)