@@ -181,6 +181,19 @@ export function AuthenticatorProofGenerator({
181181 ] ;
182182 } ;
183183
184+ // Auto-cycle through QR codes when proof is ready
185+ // biome-ignore lint/correctness/useExhaustiveDependencies: getProofQRData is stable and only depends on proof
186+ useEffect ( ( ) => {
187+ if ( status === "ready" && proof ) {
188+ const qrCodes = getProofQRData ( ) ;
189+ const interval = setInterval ( ( ) => {
190+ setCurrentQRIndex ( ( prev ) => ( prev + 1 ) % qrCodes . length ) ;
191+ } , 2000 ) ; // Change QR every 2 seconds
192+
193+ return ( ) => clearInterval ( interval ) ;
194+ }
195+ } , [ status , proof ] ) ; // getProofQRData is stable since it only depends on proof
196+
184197 return (
185198 < Card >
186199 < CardHeader >
@@ -274,20 +287,26 @@ export function AuthenticatorProofGenerator({
274287 Proof Generated Successfully
275288 </ p >
276289 < p className = "mt-1 text-muted-foreground" >
277- Show QR codes { currentQRIndex + 1 } /
278- { getProofQRData ( ) . length } to your transaction device.
290+ QR codes auto-cycling. Scan all { getProofQRData ( ) . length } { " " }
291+ codes with your transaction device.
279292 </ p >
280293 </ div >
281294 </ div >
282295
283296 < div className = "flex flex-col items-center gap-4 rounded-lg border border-border bg-background p-6" >
284- < QRCodeSVG
285- value = { getProofQRData ( ) [ currentQRIndex ] }
286- size = { 300 }
287- level = "M"
288- includeMargin
289- />
290- < div className = "flex items-center gap-2" >
297+ < div className = "relative" >
298+ { /* Large QR number badge */ }
299+ < div className = "absolute -top-2 -right-2 z-10 flex h-12 w-12 items-center justify-center rounded-full border-2 border-primary bg-primary text-2xl font-bold text-primary-foreground" >
300+ { currentQRIndex + 1 }
301+ </ div >
302+ < QRCodeSVG
303+ value = { getProofQRData ( ) [ currentQRIndex ] }
304+ size = { 300 }
305+ level = "M"
306+ includeMargin
307+ />
308+ </ div >
309+ < div className = "flex items-center gap-3" >
291310 < Button
292311 onClick = { ( ) =>
293312 setCurrentQRIndex ( ( prev ) =>
@@ -297,11 +316,20 @@ export function AuthenticatorProofGenerator({
297316 variant = "outline"
298317 size = "sm"
299318 >
300- Previous
319+ ← Previous
301320 </ Button >
302- < span className = "text-sm text-muted-foreground" >
303- { currentQRIndex + 1 } / { getProofQRData ( ) . length }
304- </ span >
321+ < div className = "flex items-center gap-1 text-sm font-medium" >
322+ { getProofQRData ( ) . map ( ( qrData , index ) => (
323+ < div
324+ key = { `qr-dot-${ index } -${ qrData . substring ( 0 , 10 ) } ` }
325+ className = { `h-2 w-2 rounded-full transition-colors ${
326+ index === currentQRIndex
327+ ? "bg-primary"
328+ : "bg-muted-foreground/30"
329+ } `}
330+ />
331+ ) ) }
332+ </ div >
305333 < Button
306334 onClick = { ( ) =>
307335 setCurrentQRIndex ( ( prev ) =>
@@ -311,9 +339,12 @@ export function AuthenticatorProofGenerator({
311339 variant = "outline"
312340 size = "sm"
313341 >
314- Next
342+ Next →
315343 </ Button >
316344 </ div >
345+ < p className = "text-center text-xs text-muted-foreground" >
346+ Auto-cycling every 2 seconds
347+ </ p >
317348 </ div >
318349
319350 < Button
0 commit comments