@@ -17,6 +17,8 @@ import { NavbarPlaceholder } from "../../components/navbar"
17
17
import { BackLink } from "../_components/back-link"
18
18
import { Tag } from "@/app/conf/_design-system/tag"
19
19
import { eventsColors } from "../../utils"
20
+ import { PinIcon } from "../../pixelarticons/pin-icon"
21
+ import { CalendarIcon } from "../../pixelarticons/calendar-icon"
20
22
21
23
function getEventTitle ( event : ScheduleSession , speakers : string [ ] ) : string {
22
24
let { name } = event
@@ -72,129 +74,146 @@ export default function SessionPage({ params }: SessionProps) {
72
74
speakers . find ( s => s . username === speaker . username ) ,
73
75
)
74
76
75
- const eventType = event . event_type . endsWith ( "s" )
76
- ? event . event_type . slice ( 0 , - 1 )
77
- : event . event_type
78
-
79
77
const eventTitle = getEventTitle (
80
78
event ,
81
79
event . speakers ! . map ( s => s . name ) ,
82
80
)
83
81
84
82
return (
85
- < main className = "gql-all-anchors-focusable" >
83
+ < main className = "gql-all-anchors-focusable gql-conf-container gql-conf-section " >
86
84
< NavbarPlaceholder className = "top-0 bg-neu-0 before:bg-white/40 dark:bg-pri-darker dark:before:bg-blk/30" />
87
85
< div className = "gql-conf-container gql-conf-navbar-strip text-neu-900 before:bg-white/40 before:dark:bg-blk/30" >
88
86
< div className = "py-10" >
89
- < section className = "xs:px-0 mx-auto min-h-[80vh] flex-col justify-center px-2 md:container lg:justify-between" >
90
- < BackLink year = "2025" kind = "schedule" />
87
+ < section className = "mx-auto min-h-[80vh] flex-col justify-center px-2 sm:px-0 lg:justify-between" >
88
+ < SessionHeader event = { event } eventTitle = { eventTitle } />
91
89
< SessionVideo event = { event } eventTitle = { eventTitle } />
92
-
93
- < div className = "mx-auto mt-10 flex flex-col self-center sm:space-y-4" >
94
- < div className = "space-y-5" >
95
- < div className = "flex flex-wrap gap-3" >
96
- { eventType && (
97
- < Tag color = { eventsColors [ event . event_type ] } >
98
- { eventType }
99
- </ Tag >
100
- ) }
101
- { event . audience && (
102
- < Tag
103
- color = {
104
- eventsColors [ event . audience ] ||
105
- "hsl(var(--color-neu-700))"
106
- }
107
- >
108
- { event . audience }
109
- </ Tag >
110
- ) }
111
- { event . event_subtype && (
112
- < Tag
113
- color = {
114
- eventsColors [ event . event_subtype ] ||
115
- "hsl(var(--color-sec-base))"
116
- }
117
- >
118
- { event . event_subtype }
119
- </ Tag >
120
- ) }
90
+ < p > { event . description } </ p >
91
+
92
+ < div className = "py-8" >
93
+ { event . files ?. map ( ( { path } ) => (
94
+ < div key = { path } >
95
+ < a href = { path } target = "_blank" rel = "noreferrer" >
96
+ View Full PDF{ " " }
97
+ < span className = "font-sans text-2xl font-light" > ↗</ span >
98
+ </ a >
99
+ < iframe src = { path } className = "aspect-video size-full" />
121
100
</ div >
122
- < h1 className = "mt-0 typography-h1" > { eventTitle } </ h1 >
123
- < time dateTime = { event . event_start } className = "mt-4" >
124
- { format (
125
- parseISO ( event . event_start ) ,
126
- "EEEE, MMMM d / hh:mmaaaa 'PDT'" ,
127
- ) } { " " }
128
- - { format ( parseISO ( event . event_end ) , "hh:mmaaaa 'PDT'" ) }
129
- </ time >
130
- </ div >
131
- < div className = "mt-8 flex flex-col flex-wrap gap-5 lg:flex-row" >
132
- { event . speakers ! . map ( speaker => (
133
- < div
134
- className = { `flex w-full items-center gap-3 ${ event ?. speakers ?. length || 0 > 1 ? "max-w-[320px]" : "" } ` }
135
- key = { speaker . username }
136
- >
137
- < Avatar
138
- className = "size-[100px] lg:size-[120px]"
139
- avatar = { speaker . avatar }
140
- name = { speaker . name }
141
- />
142
-
143
- < div className = "flex flex-col gap-1.5 lg:gap-1" >
101
+ ) ) }
102
+ </ div >
103
+ </ section >
104
+ </ div >
105
+ </ div >
106
+ </ main >
107
+ )
108
+ }
109
+
110
+ function SessionTags ( { session } : { session : ScheduleSession } ) {
111
+ const eventType = session . event_type . endsWith ( "s" )
112
+ ? session . event_type . slice ( 0 , - 1 )
113
+ : session . event_type
114
+
115
+ return (
116
+ < div className = "flex flex-wrap gap-3" >
117
+ { eventType && (
118
+ < Tag color = { eventsColors [ session . event_type ] } > { eventType } </ Tag >
119
+ ) }
120
+ { session . audience && (
121
+ < Tag
122
+ color = { eventsColors [ session . audience ] || "hsl(var(--color-neu-700))" }
123
+ >
124
+ { session . audience }
125
+ </ Tag >
126
+ ) }
127
+ { session . event_subtype && (
128
+ < Tag
129
+ color = {
130
+ eventsColors [ session . event_subtype ] || "hsl(var(--color-sec-base))"
131
+ }
132
+ >
133
+ { session . event_subtype }
134
+ </ Tag >
135
+ ) }
136
+ </ div >
137
+ )
138
+ }
139
+
140
+ function SessionHeader ( {
141
+ event,
142
+ eventTitle,
143
+ } : {
144
+ event : ScheduleSession
145
+ eventTitle : string | null
146
+ } ) {
147
+ return (
148
+ < header >
149
+ < BackLink year = "2025" kind = "schedule" />
150
+ < h1 className = "my-6 typography-h2" > { eventTitle } </ h1 >
151
+ < div className = "flex flex-wrap items-center justify-between gap-2" >
152
+ < div className = "flex flex-col gap-4 typography-body-md md:flex-row md:gap-6" >
153
+ < div className = "flex items-center gap-2" >
154
+ < CalendarIcon className = "size-5 text-sec-darker dark:text-sec-light/90 sm:size-6" />
155
+ < time dateTime = "2025-09-08" > September 08</ time >
156
+ < span > -</ span >
157
+ < time dateTime = "2025-09-10" > 10, 2025</ time >
158
+ </ div >
159
+ < div className = "flex items-center gap-2" >
160
+ < PinIcon className = "size-5 text-sec-darker dark:text-sec-light/90 sm:size-6" />
161
+ < span > { event . venue } </ span >
162
+ </ div >
163
+ </ div >
164
+ < SessionTags session = { event } />
165
+ </ div >
166
+
167
+ < div className = "mt-8 flex flex-col flex-wrap gap-5 lg:flex-row" >
168
+ { event . speakers ! . map ( speaker => (
169
+ < div
170
+ className = { `flex w-full items-center gap-3 ${ event ?. speakers ?. length || 0 > 1 ? "max-w-[320px]" : "" } ` }
171
+ key = { speaker . username }
172
+ >
173
+ < Avatar
174
+ className = "size-[100px] lg:size-[120px]"
175
+ avatar = { speaker . avatar }
176
+ name = { speaker . name }
177
+ />
178
+
179
+ < div className = "flex flex-col gap-1.5 lg:gap-1" >
180
+ < a
181
+ href = { `/conf/2024/speakers/${ speaker . username } ` }
182
+ className = "mt-0 typography-body-lg"
183
+ >
184
+ { speaker . name }
185
+ </ a >
186
+
187
+ < span className = "typography-body-sm" >
188
+ < span > { speaker . company } </ span >
189
+ { speaker . company && ", " }
190
+ { speaker . position }
191
+ </ span >
192
+ { speaker . socialurls ?. length ? (
193
+ < div className = "mt-0 text-[#333333]" >
194
+ < div className = "flex space-x-2" >
195
+ { speaker . socialurls . map ( social => (
144
196
< a
145
- href = { `/conf/2024/speakers/${ speaker . username } ` }
146
- className = "mt-0 typography-body-lg"
197
+ key = { social . url }
198
+ href = { social . url }
199
+ target = "_blank"
200
+ rel = "noreferrer"
201
+ className = "flex items-center text-blk"
147
202
>
148
- { speaker . name }
203
+ < SocialMediaIcon
204
+ service = {
205
+ social . service . toLowerCase ( ) as SocialMediaIconServiceType
206
+ }
207
+ />
149
208
</ a >
150
-
151
- < span className = "typography-body-sm" >
152
- < span > { speaker . company } </ span >
153
- { speaker . company && ", " }
154
- { speaker . position }
155
- </ span >
156
- { speaker . socialurls ?. length ? (
157
- < div className = "mt-0 text-[#333333]" >
158
- < div className = "flex space-x-2" >
159
- { speaker . socialurls . map ( social => (
160
- < a
161
- key = { social . url }
162
- href = { social . url }
163
- target = "_blank"
164
- rel = "noreferrer"
165
- className = "flex items-center text-blk"
166
- >
167
- < SocialMediaIcon
168
- service = {
169
- social . service . toLowerCase ( ) as SocialMediaIconServiceType
170
- }
171
- />
172
- </ a >
173
- ) ) }
174
- </ div >
175
- </ div >
176
- ) : null }
177
- </ div >
178
- </ div >
179
- ) ) }
180
- </ div >
181
- < p > { event . description } </ p >
182
-
183
- < div className = "py-8" >
184
- { event . files ?. map ( ( { path } ) => (
185
- < div key = { path } >
186
- < a href = { path } target = "_blank" rel = "noreferrer" >
187
- View Full PDF{ " " }
188
- < span className = "font-sans text-2xl font-light" > ↗</ span >
189
- </ a >
190
- < iframe src = { path } className = "aspect-video size-full" />
209
+ ) ) }
191
210
</ div >
192
- ) ) }
193
- </ div >
211
+ </ div >
212
+ ) : null }
194
213
</ div >
195
- </ section >
196
- </ div >
214
+ </ div >
215
+ ) ) }
197
216
</ div >
198
- </ main >
217
+ </ header >
199
218
)
200
219
}
0 commit comments