1
1
'use client' ;
2
2
3
- import React , { useState } from 'react' ;
3
+ import React , { useState , Suspense } from 'react' ;
4
4
import { useSearchParams } from 'next/navigation' ;
5
5
import Link from 'next/link' ;
6
6
import { useCardsForReview , useCreateReviewEventMutation } from '@/hooks/queryHooks' ;
@@ -19,7 +19,8 @@ function buildPlayQueryString(currentParams: URLSearchParams, newParams: Record<
19
19
return params . toString ( ) ;
20
20
}
21
21
22
- export default function GlobalPlayPage ( ) {
22
+ // Original page content moved to this client component
23
+ function PlayPageClientContent ( ) {
23
24
const searchParams = useSearchParams ( ) ;
24
25
const { token, isLoading : isAuthLoading } = useAuth ( ) ;
25
26
@@ -59,7 +60,6 @@ export default function GlobalPlayPage() {
59
60
onSuccess : ( ) => {
60
61
const nextIndex = currentCardIndex + 1 ;
61
62
setCurrentCardIndex ( nextIndex ) ;
62
- // Don't automatically refetch, let user decide to play again
63
63
} ,
64
64
onError : ( err ) => {
65
65
alert ( `Failed to record review: ${ err . message } ` ) ;
@@ -69,11 +69,10 @@ export default function GlobalPlayPage() {
69
69
} ;
70
70
71
71
const handlePlayAgain = ( ) => {
72
- refetch ( ) ; // Refetch the card sequence
72
+ refetch ( ) ;
73
73
setCurrentCardIndex ( 0 ) ;
74
74
} ;
75
75
76
- // Determine loading state
77
76
const isLoading = isAuthLoading || isLoadingCards ;
78
77
79
78
if ( isLoading ) {
@@ -106,7 +105,6 @@ export default function GlobalPlayPage() {
106
105
) ;
107
106
}
108
107
109
- // Finished state
110
108
if ( currentCardIndex >= reviewSequence . length ) {
111
109
return (
112
110
< div className = "text-center space-y-6 py-10" >
@@ -133,26 +131,24 @@ export default function GlobalPlayPage() {
133
131
< h1 className = "text-lg sm:text-xl font-semibold text-gray-700 text-center order-first sm:order-none" >
134
132
Reviewing All Decks ({ strategy === 'missedFirst' ? 'Missed First' : 'Random' } , { limit } )
135
133
</ h1 >
136
- { /* Strategy Switch Links */ }
137
134
< div className = "text-center sm:text-right text-xs sm:min-w-[100px]" >
138
135
{ strategy === 'random' ? (
139
136
< Link
140
137
href = { `/play?${ buildPlayQueryString ( searchParams , { strategy : 'missedFirst' } ) } ` }
141
138
className = "text-primary hover:underline"
142
- replace // Use replace to avoid bloating history
139
+ replace
143
140
>
144
141
Switch to Missed First
145
142
</ Link >
146
143
) : (
147
144
< Link
148
145
href = { `/play?${ buildPlayQueryString ( searchParams , { strategy : 'random' } ) } ` }
149
146
className = "text-primary hover:underline"
150
- replace // Use replace to avoid bloating history
147
+ replace
151
148
>
152
149
Switch to Random
153
150
</ Link >
154
151
) }
155
- { /* TODO: Add options for limit, flipped? */ }
156
152
</ div >
157
153
</ div >
158
154
< hr className = "border-gray-300" />
@@ -169,4 +165,22 @@ export default function GlobalPlayPage() {
169
165
/>
170
166
</ div >
171
167
) ;
168
+ }
169
+
170
+ // Loading component for Suspense fallback
171
+ function LoadingState ( ) {
172
+ return (
173
+ < div className = "flex justify-center items-center py-10" >
174
+ < Spinner /> < span className = "ml-2 text-gray-500" > Loading play options...</ span >
175
+ </ div >
176
+ ) ;
177
+ }
178
+
179
+ // Default export is now the server component wrapping the client component in Suspense
180
+ export default function GlobalPlayPage ( ) {
181
+ return (
182
+ < Suspense fallback = { < LoadingState /> } >
183
+ < PlayPageClientContent />
184
+ </ Suspense >
185
+ ) ;
172
186
}
0 commit comments