-
Notifications
You must be signed in to change notification settings - Fork 6.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: events/calendar page and a few minor fixes on components relate…
…d to time, calendars, etc (#6266) * chore: refactor a few utils * chore: add calendar redirect * chore: updated constants and i18n * chore: add failsafe for blog data parsing * chore: added gcal types * feat: updated components for Time and new Calendar/Event components * feat: updated layouts * chore: home page changes requested by TSC * chore: explain about api key * fix: fixed events page * chore: updated array type usage * chore: minor fixes * chore: updated text * chore: storybook is pain * chore: make utc small * Apply suggestions from code review Co-authored-by: Brian Muenzenmeyer <[email protected]> Signed-off-by: Claudio W <[email protected]> * chore: code-review changes * chore: center content on extra large screens --------- Signed-off-by: Claudio W <[email protected]> Co-authored-by: Brian Muenzenmeyer <[email protected]>
- Loading branch information
1 parent
c6cb417
commit 69753c8
Showing
45 changed files
with
443 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
.container { | ||
@apply max-w-full; | ||
@apply max-w-full | ||
flex-1; | ||
} | ||
|
||
.subtitle { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import type { DateTimeFormatOptions } from 'next-intl'; | ||
import { useFormatter } from 'next-intl'; | ||
import type { FC } from 'react'; | ||
|
||
import { DEFAULT_DATE_FORMAT } from '@/next.calendar.constants.mjs'; | ||
|
||
type FormattedTimeProps = { | ||
date: string | Date; | ||
format?: DateTimeFormatOptions; | ||
}; | ||
|
||
const FormattedTime: FC<FormattedTimeProps> = ({ date, format }) => { | ||
const formatter = useFormatter(); | ||
|
||
const dateObject = new Date(date); | ||
|
||
return ( | ||
<time dateTime={dateObject.toISOString()}> | ||
{formatter.dateTime(dateObject, format ?? DEFAULT_DATE_FORMAT)} | ||
</time> | ||
); | ||
}; | ||
|
||
export default FormattedTime; |
File renamed without changes.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
.event { | ||
@apply flex | ||
w-fit | ||
flex-col | ||
gap-1; | ||
|
||
.title { | ||
@apply flex | ||
flex-row | ||
gap-2; | ||
|
||
span { | ||
@apply text-sm | ||
font-bold; | ||
} | ||
} | ||
|
||
a { | ||
@apply text-sm; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import type { FC } from 'react'; | ||
|
||
import FormattedTime from '@/components/Common/FormattedTime'; | ||
import Link from '@/components/Link'; | ||
import { getZoomLink, isZoned } from '@/components/MDX/Calendar/utils'; | ||
import type { CalendarEvent } from '@/types'; | ||
|
||
import styles from './index.module.css'; | ||
|
||
type EventProps = Pick< | ||
CalendarEvent, | ||
'start' | 'end' | 'summary' | 'location' | 'description' | ||
>; | ||
|
||
const Event: FC<EventProps> = ({ | ||
start, | ||
end, | ||
description, | ||
summary, | ||
location, | ||
}) => ( | ||
<div className={styles.event}> | ||
<div className={styles.title}> | ||
<span> | ||
<FormattedTime | ||
date={isZoned(start) ? start.dateTime : start.date} | ||
format={{ hour: 'numeric', minute: 'numeric' }} | ||
/> | ||
</span> | ||
<span>-</span> | ||
<span> | ||
<FormattedTime | ||
date={isZoned(end) ? end.dateTime : end.date} | ||
format={{ hour: 'numeric', minute: 'numeric' }} | ||
/> | ||
</span> | ||
<small>(UTC)</small> | ||
</div> | ||
|
||
<Link href={getZoomLink({ description, location })}>{summary}</Link> | ||
</div> | ||
); | ||
|
||
export default Event; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import type { FC } from 'react'; | ||
|
||
import FormattedTime from '@/components/Common/FormattedTime'; | ||
import Event from '@/components/MDX/Calendar/Event'; | ||
import { getZoomLink, isZoned } from '@/components/MDX/Calendar/utils'; | ||
import { CALENDAR_NODEJS_ID } from '@/next.calendar.constants.mjs'; | ||
import { getCalendarEvents } from '@/next.calendar.mjs'; | ||
import type { CalendarEvent } from '@/types'; | ||
|
||
import styles from './calendar.module.css'; | ||
|
||
type GrouppedEntries = Record<string, Array<CalendarEvent>>; | ||
|
||
const UpcomingEvents: FC = async () => { | ||
const events = await getCalendarEvents(CALENDAR_NODEJS_ID); | ||
|
||
const groupedEntries = events.filter(getZoomLink).reduce((acc, event) => { | ||
const startDate = new Date( | ||
isZoned(event.start) ? event.start.dateTime : event.start.date | ||
); | ||
|
||
const datePerDay = startDate.toDateString(); | ||
|
||
acc[datePerDay] = acc[datePerDay] || []; | ||
acc[datePerDay].push(event); | ||
|
||
return acc; | ||
}, {} as GrouppedEntries); | ||
|
||
const sortedGroupedEntries = Object.entries(groupedEntries).sort( | ||
([dateA], [dateB]) => new Date(dateA).getTime() - new Date(dateB).getTime() | ||
); | ||
|
||
return sortedGroupedEntries.map(([date, entries]) => ( | ||
<div key={date} className={styles.events}> | ||
<h4> | ||
<FormattedTime date={date} format={{ day: 'numeric', month: 'long' }} /> | ||
</h4> | ||
|
||
{entries.map(({ id, start, end, summary, location, description }) => ( | ||
<Event | ||
key={id} | ||
start={start} | ||
end={end} | ||
summary={summary} | ||
location={location} | ||
description={description} | ||
/> | ||
))} | ||
</div> | ||
)); | ||
}; | ||
|
||
export default UpcomingEvents; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { getTranslations } from 'next-intl/server'; | ||
import type { FC } from 'react'; | ||
|
||
import BlogPostCard from '@/components/Common/BlogPostCard'; | ||
import getBlogData from '@/next-data/blogData'; | ||
|
||
import styles from './calendar.module.css'; | ||
|
||
const UpcomingSummits: FC = async () => { | ||
const t = await getTranslations(); | ||
const { posts } = await getBlogData('events', 0); | ||
|
||
const currentDate = new Date(); | ||
const filteredPosts = posts.filter(post => post.date >= currentDate); | ||
|
||
const fallbackPosts = Array(2).fill({ | ||
title: t('components.mdx.upcomingEvents.defaultTitle'), | ||
categories: ['events'], | ||
}); | ||
|
||
const mappedPosts = fallbackPosts.map((post, key) => { | ||
const actualPost = filteredPosts[key] || post; | ||
|
||
return ( | ||
<BlogPostCard | ||
key={actualPost.slug || key} | ||
title={actualPost.title} | ||
category={actualPost.categories[0]} | ||
date={actualPost.date} | ||
slug={actualPost.slug} | ||
/> | ||
); | ||
}); | ||
|
||
return <div className={styles.summits}>{mappedPosts}</div>; | ||
}; | ||
|
||
export default UpcomingSummits; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
.events { | ||
@apply flex | ||
flex-col | ||
gap-2; | ||
|
||
h4 { | ||
@apply text-xl | ||
font-bold; | ||
} | ||
} | ||
|
||
.summits { | ||
@apply flex | ||
flex-col | ||
gap-3 | ||
md:flex-row; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import type { CalendarEvent, ZonedCalendarTime } from '@/types'; | ||
|
||
export const isZoned = (d: object): d is ZonedCalendarTime => | ||
'dateTime' in d && 'timeZone' in d; | ||
|
||
export const getZoomLink = ( | ||
event: Pick<CalendarEvent, 'description' | 'location'> | ||
) => | ||
event.description?.match(/https:\/\/zoom.us\/j\/\d+/)?.[0] || | ||
event.location?.match(/https:\/\/zoom.us\/j\/\d+/)?.[0]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.