1
1
import Head from 'next/head'
2
- import React , { useCallback , useEffect , useState } from 'react'
2
+ import React , { useEffect , useState } from 'react'
3
3
import { motion , AnimatePresence } from 'framer-motion'
4
4
5
- import {
6
- BrainIcon ,
7
- HandIcon ,
8
- RegularPlayIcon ,
9
- TrainIcon ,
10
- BotOrNotIcon ,
11
- } from 'src/components/Common/Icons'
12
5
import { fetchLeaderboard } from 'src/api'
13
6
import { LeaderboardColumn , DelayedLoading } from 'src/components'
14
7
import { LeaderboardProvider } from 'src/components/Leaderboard/LeaderboardContext'
@@ -18,7 +11,6 @@ const Leaderboard: React.FC = () => {
18
11
const [ lastUpdated , setLastUpdated ] = useState < Date | null > ( null )
19
12
const [ leaderboard , setLeaderboard ] = useState <
20
13
{
21
- icon : React . JSX . Element
22
14
ranking : { display_name : string ; elo : number } [ ]
23
15
name : 'Regular' | 'Puzzles' | 'Bot/Not' | 'Hand' | 'Brain'
24
16
id : 'regular' | 'puzzles' | 'turing' | 'hand' | 'brain'
@@ -51,31 +43,29 @@ const Leaderboard: React.FC = () => {
51
43
setLeaderboard ( [
52
44
{
53
45
id : 'regular' ,
54
- icon : < RegularPlayIcon /> ,
55
46
name : 'Regular' ,
56
47
ranking : lb . play_leaders ,
57
48
} ,
58
49
{
59
50
id : 'puzzles' ,
60
- icon : < TrainIcon /> ,
61
51
name : 'Puzzles' ,
62
52
ranking : lb . puzzles_leaders ,
63
53
} ,
64
54
{
65
55
id : 'turing' ,
66
- icon : < BotOrNotIcon /> ,
56
+
67
57
name : 'Bot/Not' ,
68
58
ranking : lb . turing_leaders ,
69
59
} ,
70
60
{
71
61
id : 'hand' ,
72
- icon : < HandIcon /> ,
62
+
73
63
name : 'Hand' ,
74
64
ranking : lb . hand_leaders ,
75
65
} ,
76
66
{
77
67
id : 'brain' ,
78
- icon : < BrainIcon /> ,
68
+
79
69
name : 'Brain' ,
80
70
ranking : lb . brain_leaders ,
81
71
} ,
@@ -125,47 +115,60 @@ const Leaderboard: React.FC = () => {
125
115
< LeaderboardProvider >
126
116
< DelayedLoading isLoading = { loading } >
127
117
< AnimatePresence mode = "wait" >
128
- < motion . div
129
- key = "leaderboard-content"
130
- variants = { containerVariants }
131
- initial = "hidden"
132
- animate = "visible"
133
- exit = "exit"
134
- style = { { willChange : 'transform, opacity' } }
135
- className = "mx-auto flex h-full w-[90%] flex-col items-start justify-center gap-3 py-[1%]"
136
- >
137
- < Head >
138
- < title > Leaderboard – Maia Chess</ title >
139
- < meta
140
- name = "description"
141
- content = "View top-ranked players across all Maia Chess game modes. Competitive leaderboards for regular play, puzzles, bot detection, hand & brain chess with live ratings and statistics."
142
- />
143
- </ Head >
144
- < motion . div
145
- variants = { itemVariants }
146
- className = "flex w-full flex-col items-start justify-between md:flex-row md:items-end"
147
- >
148
- < h1 className = "text-2xl font-bold" > Rating Leaderboards</ h1 >
149
- < p className = "text-sm text-secondary" >
150
- Last updated: { lastUpdated ? getTimeAgo ( lastUpdated ) : '...' }
151
- </ p >
152
- </ motion . div >
118
+ < >
119
+ < div
120
+ className = "pointer-events-none absolute inset-0"
121
+ style = { {
122
+ background :
123
+ 'radial-gradient(ellipse 75% 60% at center top, rgba(239, 68, 68, 0.08) 0%, transparent 60%)' ,
124
+ } }
125
+ />
153
126
< motion . div
154
- variants = { itemVariants }
155
- className = "grid h-full w-full grid-cols-1 justify-start gap-2 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5"
127
+ key = "leaderboard-content"
128
+ variants = { containerVariants }
129
+ initial = "hidden"
130
+ animate = "visible"
131
+ exit = "exit"
132
+ style = { { willChange : 'transform, opacity' } }
133
+ className = "container relative mx-auto px-6 py-8"
156
134
>
157
- { leaderboard ?. map ( ( column , index ) => (
158
- < LeaderboardColumn key = { index } { ...column } />
159
- ) ) }
160
- </ motion . div >
161
- < motion . div variants = { itemVariants } className = "my-2 w-full" >
162
- < p className = "text-xs text-secondary" >
163
- < span className = "font-medium" > Note:</ span > Each leaderboard
164
- column only features players who have played atleast one game of
165
- the corresponding type within the last 7 days.
166
- </ p >
135
+ < Head >
136
+ < title > Leaderboard – Maia Chess</ title >
137
+ < meta
138
+ name = "description"
139
+ content = "View top-ranked players across all Maia Chess game modes. Competitive leaderboards for regular play, puzzles, bot detection, hand & brain chess with live ratings and statistics."
140
+ />
141
+ </ Head >
142
+ < motion . div
143
+ variants = { itemVariants }
144
+ className = "mb-2 flex w-full flex-col items-start justify-between md:flex-row md:items-center"
145
+ >
146
+ < h1 className = "mb-2 text-3xl font-bold text-white" >
147
+ Rating Leaderboards
148
+ </ h1 >
149
+
150
+ < p className = "mt-4 text-sm text-white/60 md:mt-0" >
151
+ Last updated: { lastUpdated ? getTimeAgo ( lastUpdated ) : '...' }
152
+ </ p >
153
+ </ motion . div >
154
+ < motion . div
155
+ variants = { itemVariants }
156
+ className = "grid w-full grid-cols-1 justify-start gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5"
157
+ >
158
+ { leaderboard ?. map ( ( column , index ) => (
159
+ < LeaderboardColumn key = { index } { ...column } />
160
+ ) ) }
161
+ </ motion . div >
162
+ < motion . div variants = { itemVariants } className = "mt-3 w-full" >
163
+ < p className = "text-xs text-white/60" >
164
+ < span className = "font-medium text-white/80" > Note:</ span > Each
165
+ leaderboard column only features players who have played at
166
+ least one game of the corresponding type within the last 7
167
+ days.
168
+ </ p >
169
+ </ motion . div >
167
170
</ motion . div >
168
- </ motion . div >
171
+ </ >
169
172
</ AnimatePresence >
170
173
</ DelayedLoading >
171
174
</ LeaderboardProvider >
0 commit comments