@@ -3,13 +3,20 @@ import type { SchedSpeaker } from "@/app/conf/2023/types"
3
3
import {
4
4
ConferenceOpengraphImageHeader ,
5
5
normalizeProtocolRelativeUrl ,
6
+ colors ,
7
+ OpengraphImageFooter ,
8
+ fonts ,
6
9
} from "./speaker-opengraph-image"
7
10
import { getEventTitle } from "../utils"
8
11
import { formatSpeakerPosition } from "./format-speaker-position"
12
+ import { speakers as allSpeakers } from "../_data"
9
13
10
- interface ScheduleOpengraphImageProps
14
+ export interface SessionOpengraphImageProps
11
15
extends React . HTMLAttributes < HTMLElement > {
12
- session : Pick < ScheduleSession , "name" | "speakers" | "event_type" >
16
+ session : Pick <
17
+ ScheduleSession ,
18
+ "name" | "speakers" | "event_type" | "event_subtype"
19
+ >
13
20
date : string
14
21
year : string
15
22
location : string
@@ -19,19 +26,23 @@ function isString(x: unknown): x is string {
19
26
return Object . prototype . toString . call ( x ) === "[object String]"
20
27
}
21
28
22
- export default function ScheduleOpengraphImage ( {
29
+ export function SessionOpengraphImage ( {
23
30
session,
24
31
date,
25
32
location,
26
33
year,
27
34
...rest
28
- } : ScheduleOpengraphImageProps ) {
35
+ } : SessionOpengraphImageProps ) {
29
36
const speakers = session . speakers
30
37
? isString ( session . speakers )
31
38
? ( session . speakers as string )
32
39
. split ( "," )
33
40
. map ( name => ( { name, username : "" , avatar : "" } ) )
34
- : ( session . speakers as SchedSpeaker [ ] )
41
+ : session . speakers . map ( speaker => {
42
+ return (
43
+ allSpeakers . find ( s => s . username === speaker . username ) || speaker
44
+ )
45
+ } )
35
46
: [ ]
36
47
37
48
const eventTitle = getEventTitle (
@@ -41,7 +52,17 @@ export default function ScheduleOpengraphImage({
41
52
42
53
return (
43
54
< article
44
- className = "flex h-[630px] w-[1200px] flex-col overflow-hidden border-2 border-neu-300 bg-neu-100"
55
+ style = { {
56
+ display : "flex" ,
57
+ height : "630px" ,
58
+ width : "1200px" ,
59
+ flexDirection : "column" ,
60
+ overflow : "hidden" ,
61
+ borderWidth : "2px" ,
62
+ borderColor : colors . neu600 ,
63
+ backgroundColor : colors . neu100 ,
64
+ fontFamily : fonts . sans ,
65
+ } }
45
66
{ ...rest }
46
67
>
47
68
< ConferenceOpengraphImageHeader
@@ -50,11 +71,28 @@ export default function ScheduleOpengraphImage({
50
71
location = { location }
51
72
/>
52
73
53
- < div className = "flex flex-1 flex-col justify-between p-10" >
54
- < div className = "flex flex-col gap-10" >
74
+ < div
75
+ style = { {
76
+ display : "flex" ,
77
+ flex : 1 ,
78
+ flexDirection : "column" ,
79
+ justifyContent : "space-between" ,
80
+ padding : "2.5rem" ,
81
+ } }
82
+ >
83
+ < div
84
+ style = { {
85
+ display : "flex" ,
86
+ flexDirection : "column" ,
87
+ gap : "2.5rem" ,
88
+ } }
89
+ >
55
90
< h3
56
- className = "m-0 font-sans leading-tight text-neu-900"
57
91
style = { {
92
+ margin : 0 ,
93
+ fontFamily : fonts . sans ,
94
+ lineHeight : "1.25" ,
95
+ color : colors . neu900 ,
58
96
fontSize : eventTitle . length <= 32 ? "72px" : "32px" ,
59
97
} }
60
98
>
@@ -63,25 +101,76 @@ export default function ScheduleOpengraphImage({
63
101
</ div >
64
102
65
103
{ speakers . length === 1 && speakers [ 0 ] && (
66
- < div className = "flex items-center gap-10" >
104
+ < div
105
+ style = { {
106
+ display : "flex" ,
107
+ alignItems : "flex-end" ,
108
+ gap : "2.5rem" ,
109
+ } }
110
+ >
67
111
{ speakers [ 0 ] ?. avatar && (
68
- < div className = "relative overflow-hidden" >
69
- < div className = "absolute inset-0 z-[1] bg-sec-lighter mix-blend-multiply" />
112
+ < div
113
+ style = { {
114
+ position : "relative" ,
115
+ overflow : "hidden" ,
116
+ display : "flex" ,
117
+ } }
118
+ >
70
119
< img
71
120
src = { normalizeProtocolRelativeUrl ( speakers [ 0 ] . avatar ) }
72
121
alt = ""
73
- className = "size-[120px] object-cover"
122
+ style = { {
123
+ width : "120px" ,
124
+ height : "120px" ,
125
+ objectFit : "cover" ,
126
+ filter : "sepia(1) hue-rotate(37.5deg)" ,
127
+ } }
74
128
width = { 120 }
75
129
height = { 120 }
76
130
/>
131
+ < div
132
+ style = { {
133
+ position : "absolute" ,
134
+ top : 0 ,
135
+ left : 0 ,
136
+ width : "120px" ,
137
+ height : "120px" ,
138
+ backgroundColor : colors . secLighter ,
139
+ opacity : 0.25 ,
140
+ } }
141
+ />
77
142
</ div >
78
143
) }
79
- < div className = "flex flex-col gap-4" >
80
- < h4 className = "m-0 font-sans text-[48px] font-normal leading-tight text-neu-900" >
144
+ < div
145
+ style = { {
146
+ display : "flex" ,
147
+ flexDirection : "column" ,
148
+ justifyContent : "flex-end" ,
149
+ gap : "1rem" ,
150
+ } }
151
+ >
152
+ < h4
153
+ style = { {
154
+ margin : 0 ,
155
+ fontFamily : fonts . sans ,
156
+ fontSize : "48px" ,
157
+ fontWeight : "normal" ,
158
+ lineHeight : "1" ,
159
+ color : colors . neu900 ,
160
+ } }
161
+ >
81
162
{ speakers [ 0 ] . name }
82
163
</ h4 >
83
164
{ "company" in speakers [ 0 ] && speakers [ 0 ] . company && (
84
- < span className = "font-sans text-[32px] font-normal leading-tight text-neu-700" >
165
+ < span
166
+ style = { {
167
+ fontFamily : fonts . sans ,
168
+ fontSize : "32px" ,
169
+ fontWeight : "normal" ,
170
+ lineHeight : "1" ,
171
+ color : colors . neu700 ,
172
+ } }
173
+ >
85
174
{ formatSpeakerPosition ( speakers [ 0 ] as SchedSpeaker ) }
86
175
</ span >
87
176
) }
@@ -90,10 +179,20 @@ export default function ScheduleOpengraphImage({
90
179
) }
91
180
92
181
{ speakers . length > 1 && (
93
- < div className = "flex flex-col gap-4" >
182
+ < div
183
+ style = { {
184
+ display : "flex" ,
185
+ flexDirection : "column" ,
186
+ gap : "1rem" ,
187
+ } }
188
+ >
94
189
< h4
95
- className = "m-0 font-sans font-normal leading-tight text-neu-900"
96
190
style = { {
191
+ margin : 0 ,
192
+ fontFamily : fonts . sans ,
193
+ fontWeight : "normal" ,
194
+ lineHeight : "1.25" ,
195
+ color : colors . neu900 ,
97
196
fontSize : speakers . length < 4 ? "48px" : "32px" ,
98
197
} }
99
198
>
@@ -103,12 +202,12 @@ export default function ScheduleOpengraphImage({
103
202
) }
104
203
</ div >
105
204
106
- { session . event_type && (
107
- < footer className = "flex items-center border-t-2 border-neu-300 px-16 py-8 pl-10" >
108
- < span className = "font-mono text-2xl font-normal uppercase leading-none text-neu-900" >
109
- { session . event_type }
110
- </ span >
111
- </ footer >
205
+ { ( session . event_type || session . event_subtype ) && (
206
+ < OpengraphImageFooter >
207
+ { [ session . event_type , session . event_subtype ]
208
+ . filter ( Boolean )
209
+ . join ( " — " ) }
210
+ </ OpengraphImageFooter >
112
211
) }
113
212
</ article >
114
213
)
0 commit comments