Skip to content

Commit 2e9bb0b

Browse files
feat: add public game lists to all user pages
1 parent 72056b5 commit 2e9bb0b

5 files changed

Lines changed: 93 additions & 67 deletions

File tree

__tests__/components/GameList.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,13 @@ describe('GameList', () => {
209209

210210
// Wait for the hand games to load and check subsection labels
211211
await waitFor(() => {
212-
expect(screen.getByText('Hand (1)')).toBeInTheDocument()
213-
expect(screen.getByText('Brain (0)')).toBeInTheDocument()
212+
expect(screen.getByText('Hand')).toBeInTheDocument()
213+
expect(screen.getByText('Brain')).toBeInTheDocument()
214214
})
215215

216216
// Click on Brain subsection
217217
await act(async () => {
218-
await user.click(screen.getByText('Brain (0)'))
218+
await user.click(screen.getByText('Brain'))
219219
})
220220

221221
// Verify API call for brain games

src/components/Analysis/AnalysisGameList.tsx

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Tournament } from 'src/components'
1212
import { AnalysisListContext } from 'src/contexts'
1313
import { getAnalysisGameList } from 'src/api'
1414
import { getCustomAnalysesAsWebGames } from 'src/lib/customAnalysis'
15+
import { AnalysisWebGame } from 'src/types'
1516
import { useRouter } from 'next/router'
1617

1718
interface GameData {
@@ -66,9 +67,15 @@ export const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
6667
const [currentPage, setCurrentPage] = useState(1)
6768
const [totalPages, setTotalPages] = useState(1)
6869
const [loading, setLoading] = useState(false)
69-
const [localPlayGames, setLocalPlayGames] = useState(analysisPlayList)
70-
const [localHandGames, setLocalHandGames] = useState(analysisHandList)
71-
const [localBrainGames, setLocalBrainGames] = useState(analysisBrainList)
70+
71+
const [gamesByPage, setGamesByPage] = useState<{
72+
[gameType: string]: { [page: number]: AnalysisWebGame[] }
73+
}>({
74+
play: {},
75+
hand: {},
76+
brain: {},
77+
})
78+
7279
const [customAnalyses, setCustomAnalyses] = useState(() => {
7380
if (typeof window !== 'undefined') {
7481
return getCustomAnalysesAsWebGames()
@@ -208,9 +215,14 @@ export const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
208215
[selected]: calculatedTotalPages,
209216
}))
210217

211-
if (selected === 'play') {
212-
setLocalPlayGames(parsedGames)
213-
}
218+
setGamesByPage((prev) => ({
219+
...prev,
220+
[selected]: {
221+
...prev[selected],
222+
[currentPage]: parsedGames,
223+
},
224+
}))
225+
214226
setLoading(false)
215227
})
216228
.catch(() => {
@@ -275,11 +287,14 @@ export const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
275287
[gameType]: calculatedTotalPages,
276288
}))
277289

278-
if (gameType === 'hand') {
279-
setLocalHandGames(parsedGames)
280-
} else if (gameType === 'brain') {
281-
setLocalBrainGames(parsedGames)
282-
}
290+
setGamesByPage((prev) => ({
291+
...prev,
292+
[gameType]: {
293+
...prev[gameType],
294+
[currentPage]: parsedGames,
295+
},
296+
}))
297+
283298
setLoading(false)
284299
})
285300
.catch(() => {
@@ -299,20 +314,23 @@ export const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
299314
const gameType = hbSubsection === 'hand' ? 'hand' : 'brain'
300315
if (totalPagesCache[gameType]) {
301316
setTotalPages(totalPagesCache[gameType])
317+
} else {
318+
setTotalPages(1)
302319
}
303-
setCurrentPage(currentPagePerTab[gameType])
320+
setCurrentPage(currentPagePerTab[gameType] || 1)
304321
} else if (totalPagesCache[selected]) {
305322
setTotalPages(totalPagesCache[selected])
323+
setCurrentPage(currentPagePerTab[selected] || 1)
306324
} else if (
307325
selected === 'lichess' ||
308326
selected === 'tournament' ||
309327
selected === 'custom'
310328
) {
311329
setTotalPages(1)
312-
}
313-
314-
if (selected !== 'hb') {
315-
setCurrentPage(currentPagePerTab[selected])
330+
setCurrentPage(1)
331+
} else {
332+
setTotalPages(1)
333+
setCurrentPage(currentPagePerTab[selected] || 1)
316334
}
317335
}, [selected, hbSubsection, totalPagesCache, currentPagePerTab])
318336

@@ -342,9 +360,10 @@ export const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
342360

343361
const getCurrentGames = () => {
344362
if (selected === 'play') {
345-
return localPlayGames
363+
return gamesByPage.play[currentPage] || []
346364
} else if (selected === 'hb') {
347-
return hbSubsection === 'hand' ? localHandGames : localBrainGames
365+
const gameType = hbSubsection === 'hand' ? 'hand' : 'brain'
366+
return gamesByPage[gameType]?.[currentPage] || []
348367
} else if (selected === 'custom') {
349368
return customAnalyses
350369
} else if (selected === 'lichess') {
@@ -397,34 +416,32 @@ export const AnalysisGameList: React.FC<AnalysisGameListProps> = ({
397416
<div className="flex border-b border-white border-opacity-10">
398417
<button
399418
onClick={() => setHbSubsection('hand')}
400-
className={`flex-1 px-3 py-2 text-sm ${
419+
className={`flex-1 px-3 text-sm ${
401420
hbSubsection === 'hand'
402421
? 'bg-background-2 text-primary'
403422
: 'bg-background-1/50 text-secondary hover:bg-background-2'
404423
}`}
405424
>
406-
<div className="flex items-center justify-center gap-2">
407-
<span className="material-symbols-outlined text-xs">
425+
<div className="flex items-center justify-center gap-1">
426+
<span className="material-symbols-outlined !text-lg">
408427
hand_gesture
409428
</span>
410-
<span className="text-xs">Hand ({localHandGames.length})</span>
429+
<span className="text-xs">Hand</span>
411430
</div>
412431
</button>
413432
<button
414433
onClick={() => setHbSubsection('brain')}
415-
className={`flex-1 px-3 py-2 text-sm ${
434+
className={`flex-1 px-3 text-sm ${
416435
hbSubsection === 'brain'
417436
? 'bg-background-2 text-primary'
418437
: 'bg-background-1/50 text-secondary hover:bg-background-2'
419438
}`}
420439
>
421-
<div className="flex items-center justify-center gap-2">
422-
<span className="material-symbols-outlined text-xs">
423-
psychology
424-
</span>
425-
<span className="text-xs">
426-
Brain ({localBrainGames.length})
440+
<div className="flex items-center justify-center gap-1">
441+
<span className="material-symbols-outlined !text-lg">
442+
neurology
427443
</span>
444+
<span className="text-xs">Brain</span>
428445
</div>
429446
</button>
430447
</div>

src/components/Profile/GameList.tsx

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,15 @@ export const GameList = ({
3838
>('play')
3939
const [hbSubsection, setHbSubsection] = useState<'hand' | 'brain'>('hand')
4040
const [games, setGames] = useState<AnalysisWebGame[]>([])
41-
const [playGames, setPlayGames] = useState<AnalysisWebGame[]>([])
42-
const [handGames, setHandGames] = useState<AnalysisWebGame[]>([])
43-
const [brainGames, setBrainGames] = useState<AnalysisWebGame[]>([])
41+
42+
const [gamesByPage, setGamesByPage] = useState<{
43+
[gameType: string]: { [page: number]: AnalysisWebGame[] }
44+
}>({
45+
play: {},
46+
hand: {},
47+
brain: {},
48+
})
49+
4450
const [customAnalyses, setCustomAnalyses] = useState(() => {
4551
if (typeof window !== 'undefined') {
4652
return getCustomAnalysesAsWebGames()
@@ -155,13 +161,14 @@ export const GameList = ({
155161
[gameType]: calculatedTotalPages,
156162
}))
157163

158-
if (gameType === 'play') {
159-
setPlayGames(parsedGames)
160-
} else if (gameType === 'hand') {
161-
setHandGames(parsedGames)
162-
} else if (gameType === 'brain') {
163-
setBrainGames(parsedGames)
164-
}
164+
// Store games by page instead of replacing
165+
setGamesByPage((prev) => ({
166+
...prev,
167+
[gameType]: {
168+
...prev[gameType],
169+
[currentPage]: parsedGames,
170+
},
171+
}))
165172

166173
setLoading(false)
167174
})
@@ -190,19 +197,23 @@ export const GameList = ({
190197
const gameType = hbSubsection
191198
if (totalPagesCache[gameType]) {
192199
setTotalPages(totalPagesCache[gameType])
200+
} else {
201+
setTotalPages(1) // Default to 1 page until data is loaded
193202
}
194-
setCurrentPage(currentPagePerTab[gameType])
203+
setCurrentPage(currentPagePerTab[gameType] || 1)
195204
} else if (totalPagesCache[selected]) {
196205
setTotalPages(totalPagesCache[selected])
206+
setCurrentPage(currentPagePerTab[selected] || 1)
197207
} else if (
198208
(selected === 'lichess' && showLichess) ||
199209
(selected === 'custom' && showCustom)
200210
) {
201211
setTotalPages(1)
202-
}
203-
204-
if (selected !== 'hb') {
205-
setCurrentPage(currentPagePerTab[selected])
212+
setCurrentPage(1)
213+
} else {
214+
// For other sections (like 'play'), default to page 1 until data loads
215+
setTotalPages(1)
216+
setCurrentPage(currentPagePerTab[selected] || 1)
206217
}
207218
}, [
208219
selected,
@@ -237,9 +248,10 @@ export const GameList = ({
237248

238249
const getCurrentGames = () => {
239250
if (selected === 'play') {
240-
return playGames
251+
return gamesByPage.play[currentPage] || []
241252
} else if (selected === 'hb') {
242-
return hbSubsection === 'hand' ? handGames : brainGames
253+
const gameType = hbSubsection
254+
return gamesByPage[gameType]?.[currentPage] || []
243255
} else if (selected === 'custom' && showCustom) {
244256
return customAnalyses
245257
} else if (selected === 'lichess' && showLichess) {
@@ -299,32 +311,32 @@ export const GameList = ({
299311
<div className="flex border-b border-white border-opacity-10">
300312
<button
301313
onClick={() => setHbSubsection('hand')}
302-
className={`flex-1 px-3 py-1.5 text-sm ${
314+
className={`flex-1 px-3 text-sm ${
303315
hbSubsection === 'hand'
304316
? 'bg-background-2 text-primary'
305317
: 'bg-background-1/50 text-secondary hover:bg-background-2'
306318
}`}
307319
>
308-
<div className="flex items-center justify-center gap-2">
309-
<span className="material-symbols-outlined text-xs">
320+
<div className="flex items-center justify-center gap-1">
321+
<span className="material-symbols-outlined !text-lg">
310322
hand_gesture
311323
</span>
312-
<span className="text-xs">Hand ({handGames.length})</span>
324+
<span className="text-xs">Hand</span>
313325
</div>
314326
</button>
315327
<button
316328
onClick={() => setHbSubsection('brain')}
317-
className={`flex-1 px-3 py-1.5 text-sm ${
329+
className={`flex-1 px-3 text-sm ${
318330
hbSubsection === 'brain'
319331
? 'bg-background-2 text-primary'
320332
: 'bg-background-1/50 text-secondary hover:bg-background-2'
321333
}`}
322334
>
323-
<div className="flex items-center justify-center gap-2">
324-
<span className="material-symbols-outlined text-xs">
325-
psychology
335+
<div className="flex items-center justify-center gap-1">
336+
<span className="material-symbols-outlined !text-lg">
337+
neurology
326338
</span>
327-
<span className="text-xs">Brain ({brainGames.length})</span>
339+
<span className="text-xs">Brain</span>
328340
</div>
329341
</button>
330342
</div>
@@ -350,7 +362,7 @@ export const GameList = ({
350362
<div className="flex h-full w-10 items-center justify-center bg-background-2 py-1 group-hover:bg-white/5">
351363
<p className="text-sm text-secondary">
352364
{selected === 'play' || selected === 'hb'
353-
? (currentPage - 1) * 100 + index + 1
365+
? (currentPage - 1) * 25 + index + 1
354366
: index + 1}
355367
</p>
356368
</div>

src/components/Profile/UserProfile.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@ import { ProfileColumn } from 'src/components'
1111
import { PlayerStats } from 'src/types'
1212

1313
interface Props {
14-
wide?: boolean
1514
stats: PlayerStats
1615
}
1716

18-
export const UserProfile = ({ wide, stats }: Props) => {
17+
export const UserProfile = ({ stats }: Props) => {
1918
return (
20-
<div
21-
className={`grid h-full w-full grid-cols-1 gap-3 md:gap-6 ${wide ? 'md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4' : 'lg:grid-cols-2 2xl:grid-cols-3'}`}
22-
>
19+
<div className="grid h-full w-full grid-cols-1 gap-3 md:gap-6 lg:grid-cols-2 2xl:grid-cols-3">
2320
<ProfileColumn
2421
icon={<RegularPlayIcon />}
2522
name="Regular"

src/pages/profile/[name].tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ const Profile: React.FC<Props> = (props: Props) => {
151151
variants={itemVariants}
152152
className="flex flex-row items-center gap-2"
153153
>
154-
<span className="material-symbols-outlined text-6xl">
154+
<span className="material-symbols-outlined !text-6xl">
155155
account_circle
156156
</span>
157157
<div className="flex flex-col">
@@ -174,7 +174,7 @@ const Profile: React.FC<Props> = (props: Props) => {
174174
showCustom={false}
175175
showLichess={false}
176176
/>
177-
<UserProfile stats={props.stats} wide />
177+
<UserProfile stats={props.stats} />
178178
</motion.div>
179179
</motion.div>
180180
)
@@ -207,7 +207,7 @@ const Profile: React.FC<Props> = (props: Props) => {
207207
showCustom={false}
208208
showLichess={false}
209209
/>
210-
<UserProfile stats={props.stats} wide />
210+
<UserProfile stats={props.stats} />
211211
</motion.div>
212212
</motion.div>
213213
)

0 commit comments

Comments
 (0)