Skip to content

Commit df1aa07

Browse files
committed
Add ics links to Schedule cards
1 parent 5225c4e commit df1aa07

File tree

1 file changed

+49
-3
lines changed

1 file changed

+49
-3
lines changed

src/app/conf/2025/schedule/_components/schedule-session-card.tsx

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import React from "react"
2+
import { ics } from "calendar-link"
3+
import { clsx } from "clsx"
24

35
import { SchedSpeaker, ScheduleSession } from "@/app/conf/_api/sched-types"
46
import { Anchor } from "@/app/conf/_design-system/anchor"
@@ -7,6 +9,7 @@ import { Tag } from "@/app/conf/_design-system/tag"
79
import { PinIcon } from "@/app/conf/_design-system/pixelarticons/pin-icon"
810

911
import { getEventTitle } from "../../utils"
12+
import { CalendarIcon } from "@/app/conf/_design-system/pixelarticons/calendar-icon"
1013

1114
function isString(x: unknown): x is string {
1215
return Object.prototype.toString.call(x) === "[object String]"
@@ -83,13 +86,56 @@ export function ScheduleSessionCard({
8386
))}
8487
</span>
8588
)}
86-
<span className="typography-body-xs mt-2 flex items-center gap-0.5">
87-
<PinIcon className="size-4 text-pri-base" />
88-
{session.venue}
89+
<span className="mt-4 flex items-center justify-between gap-2 xl:mt-6">
90+
<span className="typography-body-xs flex items-center gap-0.5">
91+
<PinIcon className="size-4 text-pri-base" />
92+
{session.venue}
93+
</span>
94+
<AddToCalendarLink
95+
eventTitle={eventTitle}
96+
session={session}
97+
speakers={session.speakers || []}
98+
/>
8999
</span>
90100
</span>
91101
</span>
92102
</span>
93103
</div>
94104
)
95105
}
106+
107+
function AddToCalendarLink({
108+
eventTitle,
109+
session,
110+
speakers,
111+
className,
112+
}: {
113+
eventTitle: string
114+
session: ScheduleSession
115+
speakers: SchedSpeaker[]
116+
className?: string
117+
}) {
118+
return (
119+
<a
120+
className={clsx(
121+
"relative z-[2] -m-1 flex gap-0.5 p-1 ring-neu-100 hover:bg-neu-50/50 hover:ring-1",
122+
className,
123+
)}
124+
href={ics({
125+
title: eventTitle,
126+
start: session.event_start,
127+
end: session.event_end,
128+
description: session.description,
129+
location: session.venue,
130+
organizer: {
131+
name: `GraphQLConf ${new Date().getFullYear()}`,
132+
133+
},
134+
guests: speakers.map(s => s.name),
135+
})}
136+
>
137+
<CalendarIcon className="size-4 shrink-0 text-pri-base" />
138+
<span className="typography-body-xs">Add to calendar</span>
139+
</a>
140+
)
141+
}

0 commit comments

Comments
 (0)