Skip to content

Commit ee86863

Browse files
committed
feat(frontend): implement auto-cycling QR codes in proof generator
1 parent 975b4e3 commit ee86863

File tree

1 file changed

+45
-14
lines changed

1 file changed

+45
-14
lines changed

frontend/src/components/authenticator-proof-generator.tsx

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)