1
1
import { clsx } from "clsx"
2
- import { ics } from "calendar-link"
2
+ import { CalendarEvent , google , ics , outlook } from "calendar-link"
3
3
4
4
import { SchedSpeaker , ScheduleSession } from "@/app/conf/2023/types"
5
5
import { Button } from "@/app/conf/_design-system/button"
@@ -11,8 +11,10 @@ import PlusIcon from "@/app/conf/_design-system/pixelarticons/plus.svg?svgr"
11
11
import PlayIcon from "@/app/conf/_design-system/pixelarticons/play.svg?svgr"
12
12
import { findVideo } from "../../schedule/[id]/session-video"
13
13
import { getEventTitle } from "../../utils"
14
- import React from "react"
14
+ import React , { Fragment } from "react"
15
15
import { SessionTags } from "../../components/session-tags"
16
+ import { Menu , MenuItem , MenuItems , Transition } from "@headlessui/react"
17
+ import { MenuButton } from "@headlessui/react"
16
18
17
19
export interface LongSessionCardProps
18
20
extends React . HTMLAttributes < HTMLDivElement > {
@@ -159,29 +161,71 @@ function AddToCalendarLink({
159
161
eventTitle,
160
162
session,
161
163
speakers,
164
+ className,
162
165
} : {
163
166
eventTitle : string
164
167
session : ScheduleSession
165
168
speakers : SchedSpeaker [ ]
169
+ className ?: string
166
170
} ) {
171
+ const calendarEvent : CalendarEvent = {
172
+ title : eventTitle ,
173
+ start : session . event_start ,
174
+ end : session . event_end ,
175
+ description : session . description ,
176
+ location : session . venue ,
177
+ organizer : {
178
+ name : `GraphQLConf ${ new Date ( ) . getFullYear ( ) } ` ,
179
+
180
+ } ,
181
+ guests : speakers . map ( s => s . name ) ,
182
+ }
183
+
184
+ const calendars = {
185
+ ICS : ics ,
186
+ Google : google ,
187
+ Outlook : outlook ,
188
+ }
189
+
167
190
return (
168
- < a
169
- className = "relative z-[2] flex h-full flex-row items-center justify-center gap-0.5 p-4 text-neu-800 ring-inset ring-neu-400 hover:bg-sec-base/[.035] hover:ring-1 dark:ring-neu-100 lg:px-6"
170
- href = { ics ( {
171
- title : eventTitle ,
172
- start : session . event_start ,
173
- end : session . event_end ,
174
- description : session . description ,
175
- location : session . venue ,
176
- organizer : {
177
- name : `GraphQLConf ${ new Date ( ) . getFullYear ( ) } ` ,
178
-
179
- } ,
180
- guests : speakers . map ( s => s . name ) ,
181
- } ) }
182
- >
183
- < PlusIcon className = "size-4 shrink-0 text-sec-dark" />
184
- < span className = "typography-body-xs" > Add to calendar</ span >
185
- </ a >
191
+ < Menu as = "div" className = { clsx ( "relative z-[2] flex h-full" , className ) } >
192
+ < MenuButton
193
+ className = { clsx (
194
+ "relative z-[2] flex size-full h-full flex-row items-center justify-center gap-0.5 p-4 text-neu-800 ring-inset ring-neu-400 hover:bg-sec-base/[.035] hover:ring-1 focus:outline-none focus:ring-1 dark:ring-neu-100 lg:px-6 [&[aria-expanded=true]]:ring-1" ,
195
+ ) }
196
+ >
197
+ < PlusIcon className = "size-4 shrink-0 text-sec-dark" />
198
+ < span className = "typography-body-xs" > Add to calendar</ span >
199
+ </ MenuButton >
200
+ < Transition
201
+ as = { Fragment }
202
+ enter = "transition ease-out duration-100"
203
+ enterFrom = "transform opacity-0 scale-95"
204
+ enterTo = "transform opacity-100 scale-100"
205
+ leave = "transition ease-in duration-75"
206
+ leaveFrom = "transform opacity-100 scale-100"
207
+ leaveTo = "transform opacity-0 scale-95"
208
+ >
209
+ < MenuItems
210
+ anchor = "bottom end"
211
+ className = "mt-2 w-40 origin-top-right border border-neu-400 bg-neu-0 focus:outline-none dark:bg-neu-900"
212
+ >
213
+ < div className = "p-1" >
214
+ { Object . entries ( calendars ) . map ( ( [ name , calendar ] ) => (
215
+ < MenuItem key = { name } >
216
+ < a
217
+ href = { calendar ( calendarEvent ) }
218
+ target = "_blank"
219
+ rel = "noopener noreferrer"
220
+ className = "group typography-body-sm flex w-full items-center p-3 text-neu-800 [&[data-active]]:bg-neu-100 [&[data-active]]:text-neu-900"
221
+ >
222
+ { name }
223
+ </ a >
224
+ </ MenuItem >
225
+ ) ) }
226
+ </ div >
227
+ </ MenuItems >
228
+ </ Transition >
229
+ </ Menu >
186
230
)
187
231
}
0 commit comments