@@ -125,213 +125,202 @@ const BroadcastsPage: NextPage = () => {
125125 />
126126 </ Head >
127127
128- < div className = "min-h-screen bg-backdrop" >
129- < div
130- className = "pointer-events-none absolute inset-0"
131- style = { {
132- background :
133- 'radial-gradient(ellipse 75% 60% at center top, rgba(239, 68, 68, 0.08) 0%, transparent 60%)' ,
134- } }
135- />
128+ < div
129+ className = "pointer-events-none absolute inset-0"
130+ style = { {
131+ background :
132+ 'radial-gradient(ellipse 75% 60% at center top, rgba(239, 68, 68, 0.08) 0%, transparent 60%)' ,
133+ } }
134+ />
136135
137- < motion . div
138- className = "container relative mx-auto px-6 py-8"
139- initial = "initial"
140- animate = "animate"
141- variants = { staggerContainer }
142- >
143- < motion . div className = "mb-8 text-center" variants = { fadeInUp } >
144- < h1 className = "mb-2 text-3xl font-bold text-white" >
145- Live Broadcasts
146- </ h1 >
147- < p className = "text-white/80" >
148- Watch ongoing chess tournaments with real-time Maia AI analysis
149- </ p >
150- </ motion . div >
136+ < motion . div
137+ className = "container relative mx-auto px-6 py-8"
138+ initial = "initial"
139+ animate = "animate"
140+ variants = { staggerContainer }
141+ >
142+ < motion . div className = "mb-8 text-center" variants = { fadeInUp } >
143+ < h1 className = "mb-2 text-3xl font-bold text-white" >
144+ Live Broadcasts
145+ </ h1 >
146+ < p className = "text-white/80" >
147+ Watch ongoing chess tournaments with real-time Maia AI analysis
148+ </ p >
149+ </ motion . div >
151150
152- { broadcastSections . length === 0 ? (
153- < motion . div
154- className = "flex flex-col items-center justify-center py-16 text-center"
155- variants = { fadeInUp }
151+ { broadcastSections . length === 0 ? (
152+ < motion . div
153+ className = "flex flex-col items-center justify-center py-16 text-center"
154+ variants = { fadeInUp }
155+ >
156+ < span className = "material-symbols-outlined mb-4 !text-6xl text-white/60" >
157+ live_tv
158+ </ span >
159+ < h2 className = "mb-2 text-xl font-semibold text-white" >
160+ No Live Broadcasts
161+ </ h2 >
162+ < p className = "text-white/70" >
163+ There are currently no ongoing tournaments available.
164+ </ p >
165+ < button
166+ onClick = { ( ) => {
167+ setLoading ( true )
168+ loadBroadcasts ( ) . finally ( ( ) => setLoading ( false ) )
169+ } }
170+ className = "mt-4 rounded border border-human-4/30 bg-human-4 px-4 py-2 text-white transition-all duration-200 hover:border-human-4/50 hover:bg-human-4/80"
156171 >
157- < span className = "material-symbols-outlined mb-4 !text-6xl text-white/60" >
158- live_tv
159- </ span >
160- < h2 className = "mb-2 text-xl font-semibold text-white" >
161- No Live Broadcasts
162- </ h2 >
163- < p className = "text-white/70" >
164- There are currently no ongoing tournaments available.
165- </ p >
166- < button
167- onClick = { ( ) => {
168- setLoading ( true )
169- loadBroadcasts ( ) . finally ( ( ) => setLoading ( false ) )
172+ Refresh
173+ </ button >
174+ </ motion . div >
175+ ) : (
176+ < motion . div className = "space-y-6" variants = { staggerContainer } >
177+ { broadcastSections . map ( ( section , sectionIndex ) => (
178+ < motion . div
179+ key = { section . type }
180+ className = "space-y-3"
181+ variants = { {
182+ initial : { opacity : 0 , y : 15 } ,
183+ animate : {
184+ opacity : 1 ,
185+ y : 0 ,
186+ transition : {
187+ duration : 0.25 ,
188+ ease : 'easeOut' ,
189+ delay : sectionIndex * 0.2 ,
190+ } ,
191+ } ,
170192 } }
171- className = "mt-4 rounded border border-human-4/30 bg-human-4 px-4 py-2 text-white transition-all duration-200 hover:border-human-4/50 hover:bg-human-4/80"
172193 >
173- Refresh
174- </ button >
175- </ motion . div >
176- ) : (
177- < motion . div className = "space-y-6" variants = { staggerContainer } >
178- { broadcastSections . map ( ( section , sectionIndex ) => (
194+ { section . type === 'past' && (
195+ < h2 className = "text-xl font-semibold text-white" >
196+ { section . title }
197+ </ h2 >
198+ ) }
199+
179200 < motion . div
180- key = { section . type }
181- className = "space-y-3"
201+ className = {
202+ section . type === 'official-active'
203+ ? 'flex flex-wrap gap-4'
204+ : 'grid gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5'
205+ }
206+ initial = "initial"
207+ animate = "animate"
182208 variants = { {
183- initial : { opacity : 0 , y : 15 } ,
184209 animate : {
185- opacity : 1 ,
186- y : 0 ,
187210 transition : {
188- duration : 0.25 ,
189- ease : 'easeOut' ,
190- delay : sectionIndex * 0.2 ,
211+ staggerChildren : 0.03 ,
212+ delayChildren : sectionIndex * 0.2 + 0.15 ,
191213 } ,
192214 } ,
193215 } }
194216 >
195- < h2 className = "flex items-center gap-2 text-xl font-semibold text-white" >
196- { section . title }
197- { ( section . type === 'official-active' ||
198- section . type === 'unofficial-active' ) && (
199- < div className = "flex items-center gap-1" >
200- < div className = "h-2 w-2 animate-pulse rounded-full bg-red-500" > </ div >
201- < span className = "text-xs font-medium text-red-400" >
202- LIVE
203- </ span >
204- </ div >
205- ) }
206- </ h2 >
207-
208- < motion . div
209- className = {
210- section . type === 'official-active'
211- ? 'flex flex-wrap gap-4'
212- : 'grid gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5'
213- }
214- initial = "initial"
215- animate = "animate"
216- variants = { {
217- animate : {
218- transition : {
219- staggerChildren : 0.03 ,
220- delayChildren : sectionIndex * 0.2 + 0.15 ,
221- } ,
222- } ,
223- } }
224- >
225- { section . broadcasts . map ( ( broadcast ) => {
226- const ongoingRounds = broadcast . rounds . filter (
227- ( r ) => r . ongoing ,
228- )
229- const hasOngoingRounds = ongoingRounds . length > 0
230- const isActive =
231- section . type . includes ( 'active' ) ||
232- section . type . includes ( 'community' )
233- const isPast = section . type === 'past'
217+ { section . broadcasts . map ( ( broadcast ) => {
218+ const ongoingRounds = broadcast . rounds . filter (
219+ ( r ) => r . ongoing ,
220+ )
221+ const hasOngoingRounds = ongoingRounds . length > 0
222+ const isActive =
223+ section . type . includes ( 'active' ) ||
224+ section . type . includes ( 'community' )
225+ const isPast = section . type === 'past'
234226
235- return (
236- < motion . div
237- key = { broadcast . tour . id }
238- className = { `from-white/8 to-white/4 hover:from-white/12 hover:to-white/6 group relative flex flex-col overflow-hidden rounded-lg border border-white/10 bg-gradient-to-br backdrop-blur-md transition-all duration-300 hover:border-white/20 ${
239- section . type === 'official-active'
240- ? 'w-[280px]'
241- : ''
242- } `}
243- variants = { {
244- initial : { opacity : 0 , y : 15 } ,
245- animate : {
246- opacity : 1 ,
247- y : 0 ,
248- transition : { duration : 0.2 , ease : 'easeOut' } ,
249- } ,
250- } }
251- >
252- < div className = "flex flex-1 flex-col gap-3 p-4" >
253- < div className = "flex items-start justify-between gap-3" >
254- < div className = "min-w-0 flex-1" >
255- < h3 className = "line-clamp-2 text-base font-semibold text-white/95 transition-colors duration-300 group-hover:text-white" >
256- { broadcast . tour . name }
257- </ h3 >
258- { hasOngoingRounds && isActive && (
259- < div className = "mt-2 flex items-center gap-1.5" >
260- < div className = "h-2 w-2 animate-pulse rounded-full bg-red-500" > </ div >
261- < span className = "text-xs font-medium text-red-400" >
262- LIVE
263- </ span >
264- </ div >
227+ return (
228+ < motion . div
229+ key = { broadcast . tour . id }
230+ className = { `from-white/8 to-white/4 hover:from-white/12 hover:to-white/6 group relative flex flex-col overflow-hidden rounded-lg border border-white/10 bg-gradient-to-br backdrop-blur-md transition-all duration-300 hover:border-white/20 ${
231+ section . type === 'official-active' ? 'w-[280px]' : ''
232+ } `}
233+ variants = { {
234+ initial : { opacity : 0 , y : 15 } ,
235+ animate : {
236+ opacity : 1 ,
237+ y : 0 ,
238+ transition : { duration : 0.2 , ease : 'easeOut' } ,
239+ } ,
240+ } }
241+ >
242+ < div className = "flex flex-1 flex-col gap-3 p-4" >
243+ < div className = "flex items-start justify-between gap-3" >
244+ < div className = "min-w-0 flex-1" >
245+ < h3 className = "line-clamp-2 text-base font-semibold text-white/95 transition-colors duration-300 group-hover:text-white" >
246+ { broadcast . tour . name }
247+ </ h3 >
248+ { hasOngoingRounds && isActive && (
249+ < div className = "mt-2 flex items-center gap-1.5" >
250+ < div className = "h-2 w-2 animate-pulse rounded-full bg-red-500" > </ div >
251+ < span className = "text-xs font-medium text-red-400" >
252+ LIVE
253+ </ span >
254+ </ div >
255+ ) }
256+ </ div >
257+ < div className = "flex flex-col items-end gap-1" >
258+ < span className = "text-xs text-white/60" >
259+ Tier { broadcast . tour . tier }
260+ </ span >
261+ { broadcast . tour . dates &&
262+ broadcast . tour . dates . length > 0 && (
263+ < span className = "text-xs text-white/60" >
264+ { formatDate ( broadcast . tour . dates [ 0 ] ) }
265+ </ span >
265266 ) }
266- </ div >
267- < div className = "flex flex-col items-end gap-1" >
268- < span className = "text-xs text-white/60" >
269- Tier { broadcast . tour . tier }
270- </ span >
271- { broadcast . tour . dates &&
272- broadcast . tour . dates . length > 0 && (
273- < span className = "text-xs text-white/60" >
274- { formatDate ( broadcast . tour . dates [ 0 ] ) }
275- </ span >
276- ) }
277- </ div >
278267 </ div >
268+ </ div >
279269
280- < div className = "text-xs text-white/70" >
281- { broadcast . rounds . length } round
282- { broadcast . rounds . length !== 1 ? 's' : '' }
283- { hasOngoingRounds && (
284- < span className = "ml-2 text-red-400" >
285- • { ongoingRounds . length } live
286- </ span >
287- ) }
288- </ div >
270+ < div className = "text-xs text-white/70" >
271+ { broadcast . rounds . length } round
272+ { broadcast . rounds . length !== 1 ? 's' : '' }
273+ { hasOngoingRounds && (
274+ < span className = "ml-2 text-red-400" >
275+ • { ongoingRounds . length } live
276+ </ span >
277+ ) }
289278 </ div >
279+ </ div >
290280
291- < button
292- onClick = { ( ) => handleSelectBroadcast ( broadcast ) }
293- disabled = { ! hasOngoingRounds && ! isPast }
294- className = { `border-t py-2 text-sm font-medium tracking-wide transition-all duration-300 ${
295- hasOngoingRounds
296- ? 'border-red-500/30 bg-red-500/20 text-red-400 group-hover:bg-red-500/30'
297- : isPast
298- ? 'border-white/10 bg-white/5 text-white/60 group-hover:bg-white/10 group-hover:text-white/80'
299- : 'cursor-not-allowed border-white/10 bg-white/5 text-white/40'
300- } `}
301- >
302- { hasOngoingRounds
303- ? 'Watch Live'
281+ < button
282+ onClick = { ( ) => handleSelectBroadcast ( broadcast ) }
283+ disabled = { ! hasOngoingRounds && ! isPast }
284+ className = { `border-t py-2 text-sm font-medium tracking-wide transition-all duration-300 ${
285+ hasOngoingRounds
286+ ? 'border-red-500/30 bg-red-500/20 text-red-400 group-hover:bg-red-500/30'
304287 : isPast
305- ? 'View Tournament'
306- : 'Coming Soon' }
307- </ button >
308- </ motion . div >
309- )
310- } ) }
311- </ motion . div >
288+ ? 'border-white/10 bg-white/5 text-white/60 group-hover:bg-white/10 group-hover:text-white/80'
289+ : 'cursor-not-allowed border-white/10 bg-white/5 text-white/40'
290+ } `}
291+ >
292+ { hasOngoingRounds
293+ ? 'Watch Live'
294+ : isPast
295+ ? 'View Tournament'
296+ : 'Coming Soon' }
297+ </ button >
298+ </ motion . div >
299+ )
300+ } ) }
312301 </ motion . div >
313- ) ) }
314- </ motion . div >
315- ) }
316-
317- < motion . div
318- className = "mt-8 text-center text-xs text-white/60"
319- variants = { fadeInUp }
320- >
321- < p >
322- Broadcasts streamed from{ ' ' }
323- < a
324- href = "https://lichess.org"
325- target = "_blank"
326- rel = "noopener noreferrer"
327- className = "text-white/80 underline hover:text-white"
328- >
329- Lichess
330- </ a >
331- </ p >
302+ </ motion . div >
303+ ) ) }
332304 </ motion . div >
305+ ) }
306+
307+ < motion . div
308+ className = "mt-8 text-center text-xs text-white/60"
309+ variants = { fadeInUp }
310+ >
311+ < p >
312+ Broadcasts streamed from{ ' ' }
313+ < a
314+ href = "https://lichess.org"
315+ target = "_blank"
316+ rel = "noopener noreferrer"
317+ className = "text-white/80 underline hover:text-white"
318+ >
319+ Lichess
320+ </ a >
321+ </ p >
333322 </ motion . div >
334- </ div >
323+ </ motion . div >
335324 </ >
336325 )
337326}
0 commit comments