@@ -4,44 +4,61 @@ import Image from "next-image-export-optimizer"
4
4
import type { StaticImageData } from "next/image"
5
5
6
6
import TwitterIcon from "@/icons/twitter.svg"
7
+ import LinkedInIcon from "@/icons/linkedin-filled.svg"
8
+
7
9
import { Button } from "@/app/conf/_design-system/button"
8
10
import { BECOME_A_SPEAKER_LINK } from "../../links"
9
11
import { StripesDecoration } from "@/app/conf/_design-system/stripes-decoration"
12
+ import {
13
+ SocialIconType ,
14
+ SocialIcon ,
15
+ urlForUser ,
16
+ } from "@/app/conf/_design-system/social-icon"
10
17
11
18
const previousConfSpeakers = {
12
19
benjie : {
13
20
name : "Benjie Gillam" ,
14
21
title : "GraphQL TSC & Spec" ,
15
22
src : "https://avatars.sched.co/b/99/18743846/avatar.jpg.320x320px.jpg" ,
16
- twitter : "benjie" ,
17
- linkedin : "benjiegillam" ,
23
+ socials : {
24
+ twitter : "benjie" ,
25
+ linkedin : "benjiegillam" ,
26
+ } ,
18
27
} ,
19
28
kewei : {
20
29
name : "Kewei Qu" ,
21
30
title : "Meta, Senior Staff Engineer" ,
22
31
src : "https://avatars.sched.co/9/1a/18743864/avatar.jpg.320x320px.jpg" ,
23
- twitter : "kewei_qu" ,
24
- linkedin : "keweiqu" ,
32
+ socials : {
33
+ twitter : "kewei_qu" ,
34
+ linkedin : "keweiqu" ,
35
+ } ,
25
36
} ,
26
37
donna : {
27
38
name : "Donna Zhou" ,
28
39
title : "Atlassian, GraphQL Java" ,
29
40
src : "https://avatars.sched.co/0/1d/18743879/avatar.jpg.320x320px.jpg?e1f" ,
30
- linkedin : "donnazhou" ,
41
+ socials : {
42
+ linkedin : "donnazhou" ,
43
+ } ,
31
44
} ,
32
45
uri : {
33
46
name : "Uri Goldshtein" ,
34
47
title : "The Guild, Founder" ,
35
48
src : "https://avatars.sched.co/8/2b/14900013/avatar.jpg.320x320px.jpg?9f1" ,
36
- twitter : "UriGoldshtein" ,
37
- linkedin : "urigo" ,
49
+ socials : {
50
+ twitter : "UriGoldshtein" ,
51
+ linkedin : "urigo" ,
52
+ } ,
38
53
} ,
39
54
alessia : {
40
55
name : "Alessia Bellisario" ,
41
56
title : "Apollo, Staff Engineer" ,
42
57
src : "https://avatars.sched.co/a/c6/18743837/avatar.jpg.320x320px.jpg?847" ,
43
- twitter : "alessbell" ,
44
- linkedin : "alessiabellisario" ,
58
+ socials : {
59
+ twitter : "alessbell" ,
60
+ linkedin : "alessiabellisario" ,
61
+ } ,
45
62
} ,
46
63
}
47
64
@@ -63,30 +80,30 @@ export default function TopMindsSection({
63
80
{ ...rest }
64
81
>
65
82
< div className = "flex grid-cols-2 flex-wrap [@media(444px<width<743px)]:grid [@media(width<=444px)]:flex-col [@media(width<=743px)]:justify-center [@media(width>=970px)]:*:border-b-0" >
66
- < h3 className = "mr-auto flex w-full grow text-pretty pb-6 pr-6 typography-h2 [@media(width>857px)]:basis-0" >
83
+ < h3 className = "typography-h2 mr-auto flex w-full grow text-pretty pb-6 pr-6 [@media(width>857px)]:basis-0" >
67
84
Meet the top industry minds
68
85
</ h3 >
69
- < SpeakerCard
86
+ < TopMindCard
70
87
{ ...previousConfSpeakers . benjie }
71
88
stripes = "linear-gradient(80deg, hsl(var(--color-pri-base)) 0%, hsl(var(--color-pri-base)) 5%, transparent 40%, transparent)"
72
89
/>
73
- < SpeakerCard
90
+ < TopMindCard
74
91
{ ...previousConfSpeakers . kewei }
75
92
className = "[@media(width<=742px)]:border-l"
76
93
stripes = "radial-gradient(circle at bottom right, hsl(var(--color-pri-base)) 0%, hsl(var(--color-pri-base)) 10%, transparent 40%, transparent)"
77
94
/>
78
95
< div className = "flex grow border-sec-dark [@media(width<970px)]:contents [@media(width>=970px)]:border-t [@media(width>=970px)]:*:border-t-0" >
79
- < SpeakerCard
96
+ < TopMindCard
80
97
{ ...previousConfSpeakers . donna }
81
98
className = "[@media(744px<=width<=970px)]:first-of-type:border-l-0"
82
99
stripes = "radial-gradient(ellipse at top left, hsl(var(--color-pri-base)) 0%, hsl(var(--color-pri-base)) 5%, transparent 40%, transparent, transparent 85%, black 100%)"
83
100
/>
84
- < SpeakerCard
101
+ < TopMindCard
85
102
{ ...previousConfSpeakers . uri }
86
103
className = "[@media(639px<=width<=970px)]:border-l"
87
104
stripes = "linear-gradient(-40deg, hsl(var(--color-pri-base)) 0%, hsl(var(--color-pri-base)) 5%, transparent 40%, transparent)"
88
105
/>
89
- < SpeakerCard
106
+ < TopMindCard
90
107
{ ...previousConfSpeakers . alessia }
91
108
className = "[@media(width<744px)]:border-l"
92
109
stripes = "radial-gradient(circle at top left, transparent 0%, transparent 65%, black 90%)"
@@ -108,23 +125,23 @@ export default function TopMindsSection({
108
125
)
109
126
}
110
127
111
- function SpeakerCard ( {
112
- name,
113
- title,
114
- src,
115
- twitter,
116
- linkedin,
117
- className,
118
- stripes,
119
- } : {
128
+ export interface TopMindCardProps {
120
129
name : string
121
130
title : string
122
131
src : string | StaticImageData
123
- twitter ?: string
124
- linkedin ?: string
125
132
className ?: string
126
133
stripes ?: string
127
- } ) {
134
+ socials : Partial < Record < SocialIconType , string > >
135
+ }
136
+
137
+ function TopMindCard ( {
138
+ name,
139
+ title,
140
+ src,
141
+ className,
142
+ stripes,
143
+ socials,
144
+ } : TopMindCardProps ) {
128
145
return (
129
146
< article
130
147
className = { clsx (
@@ -146,51 +163,28 @@ function SpeakerCard({
146
163
< div className = "flex flex-1 items-stretch border-t border-sec-dark" >
147
164
< div className = "flex grow flex-col justify-center gap-1 p-3 sm:h-[80px]" >
148
165
< h4 className = "typography-body-md" > { name } </ h4 >
149
- < p className = "text-neu-700 typography-body-xs" > { title } </ p >
166
+ < p className = "typography-body-xs text-neu-700 " > { title } </ p >
150
167
</ div >
151
- { ( linkedin || twitter ) && (
152
- < div className = "flex border-l border-sec-dark max-sm:divide-x sm:flex-col sm:items-center sm:divide-y sm:border-l" >
153
- { linkedin && (
168
+ < div className = "flex border-l border-sec-dark max-sm:divide-x sm:flex-col sm:items-center sm:divide-y sm:border-l" >
169
+ { SocialIconType . all . map ( type => {
170
+ if ( ! socials [ type ] ) return null
171
+ return (
154
172
< a
155
- href = { `https://www.linkedin.com/in/${ linkedin } ` }
156
- target = "_blank"
157
- rel = "noopener noreferrer"
158
- className = "flex grow items-center justify-center p-4 transition-colors hover:bg-neu-900/10 hover:text-neu-700 sm:p-2"
159
- >
160
- < LinkedInIcon />
161
- </ a >
162
- ) }
163
- { twitter && (
164
- < a
165
- href = { `https://x.com/${ twitter } ` }
173
+ href = { urlForUser ( type , socials [ type ] ) }
166
174
target = "_blank"
167
175
rel = "noopener noreferrer"
168
176
className = "flex grow items-center justify-center border-sec-dark p-4 transition-colors hover:bg-neu-900/10 hover:text-neu-700 sm:p-2"
169
177
>
170
- < TwitterIcon className = "size-6" />
178
+ < SocialIcon type = { type } className = "size-6" />
171
179
</ a >
172
- ) }
173
- </ div >
174
- ) }
180
+ )
181
+ } ) }
182
+ </ div >
175
183
</ div >
176
184
</ article >
177
185
)
178
186
}
179
187
180
- function LinkedInIcon ( props : HTMLAttributes < SVGElement > ) {
181
- return (
182
- < svg
183
- width = "24"
184
- height = "24"
185
- viewBox = "0 0 24 24"
186
- fill = "currentColor"
187
- { ...props }
188
- >
189
- < path d = "M19 3C19.5304 3 20.0391 3.21071 20.4142 3.58579C20.7893 3.96086 21 4.46957 21 5V19C21 19.5304 20.7893 20.0391 20.4142 20.4142C20.0391 20.7893 19.5304 21 19 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V5C3 4.46957 3.21071 3.96086 3.58579 3.58579C3.96086 3.21071 4.46957 3 5 3H19ZM18.5 18.5V13.2C18.5 12.3354 18.1565 11.5062 17.5452 10.8948C16.9338 10.2835 16.1046 9.94 15.24 9.94C14.39 9.94 13.4 10.46 12.92 11.24V10.13H10.13V18.5H12.92V13.57C12.92 12.8 13.54 12.17 14.31 12.17C14.6813 12.17 15.0374 12.3175 15.2999 12.5801C15.5625 12.8426 15.71 13.1987 15.71 13.57V18.5H18.5ZM6.88 8.56C7.32556 8.56 7.75288 8.383 8.06794 8.06794C8.383 7.75288 8.56 7.32556 8.56 6.88C8.56 5.95 7.81 5.19 6.88 5.19C6.43178 5.19 6.00193 5.36805 5.68499 5.68499C5.36805 6.00193 5.19 6.43178 5.19 6.88C5.19 7.81 5.95 8.56 6.88 8.56ZM8.27 18.5V10.13H5.5V18.5H8.27Z" />
190
- </ svg >
191
- )
192
- }
193
-
194
188
function Stripes ( { mask } : { mask ?: string } ) {
195
189
return (
196
190
< div
0 commit comments