Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull Request Overview
This PR adds QR code scanning functionality, implements an initialization state for proper auth flow control, and introduces an embedded Moonbeam indexer page.
- Adds jsQR library for client-side QR code scanning with automatic detection
- Implements
initialisedflag in user store to prevent premature routing during auth bootstrap - Creates onboarding utility functions and hooks to enforce onboarding completion requirements across protected pages
Reviewed Changes
Copilot reviewed 25 out of 26 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml / package.json | Adds jsqr@1.4.0 dependency for QR code scanning |
| frontend/src/lib/store.ts | Adds initialised boolean state to track auth initialization |
| frontend/src/lib/onboarding.ts | New module with hasCompletedOnboarding utility and hooks for route protection |
| frontend/src/components/QRScanner.tsx | Enhances QR scanner with jsQR integration for automatic code detection |
| frontend/src/components/AuthProvider.tsx | Sets initialised flag after auth bootstrap and on session changes |
| frontend/src/app/(routes)/vouch/page.tsx | Uses useRequireCompletedOnboarding hook for access control |
| frontend/src/app/(routes)/signin/page.tsx | Refactored to use hasCompletedOnboarding helper |
| frontend/src/app/(routes)/scan/my-qr/page.tsx | Uses useRequireCompletedOnboarding and adds QR refresh interval |
| frontend/src/app/(routes)/scan/camera/page.tsx | Integrates QR scanner callbacks and uses useRequireCompletedOnboarding |
| frontend/src/app/(routes)/results/page.tsx | Uses useRequireCompletedOnboarding for access control |
| frontend/src/app/(routes)/profile/page.tsx | Adds wallet connection button and uses useRequireCompletedOnboarding |
| frontend/src/app/(routes)/new-user/page.tsx | Uses useRestrictToIncompleteOnboarding and generates random cubid_id |
| frontend/src/app/(routes)/indexer/page.tsx | New page embedding Moonbeam indexer in iframe |
| frontend/src/app/(routes)/circle/page.tsx | Refactored to use useRequireCompletedOnboarding and group outbound by circle |
| frontend/src/app/page.tsx | Adds indexer links to home page |
| frontend/src/components/AppHeader.tsx | Adds indexer link to navigation |
| frontend/src/components/AppFooter.tsx | Adds indexer to developer shortcuts |
| Test files | Updated to mock router.replace and include required user fields |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (result?.data) { | ||
| const now = Date.now(); | ||
| const recentlyDetected = now - lastDetectedAtRef.current < 1500; | ||
| if (result.data !== lastDetectedRef.current || !recentlyDetected) { |
There was a problem hiding this comment.
The debouncing logic is inverted. It should only trigger the callback when the QR code is different OR when enough time has passed since the last detection. The current condition !recentlyDetected will trigger on every scan after 1.5 seconds, even for the same QR code. Change to: if (result.data !== lastDetectedRef.current || recentlyDetected)
| if (result.data !== lastDetectedRef.current || !recentlyDetected) { | |
| if (result.data !== lastDetectedRef.current || recentlyDetected) { |
| })); | ||
| }, [initialCubidId, profile?.cubid_id, profile?.display_name, profile?.photo_url]); | ||
|
|
||
| if (!ready && !profile?.cubid_id) { |
There was a problem hiding this comment.
This condition allows rendering the form when ready is true but profile?.cubid_id exists, which contradicts the purpose of useRestrictToIncompleteOnboarding. The hook redirects users with completed onboarding to /circle. The check should be if (!ready) to show loading until initialization completes.
| if (!ready && !profile?.cubid_id) { | |
| if (!ready) { |
| return ( | ||
| <section className="space-y-4"> | ||
| <h1 className="text-3xl font-semibold">Preparing your scanner…</h1> | ||
| <p className="text-sm text-slate-300/80">We’re confirming your onboarding details.</p> |
There was a problem hiding this comment.
Corrected contraction to match the pattern used elsewhere in the codebase.
| <p className="text-sm text-slate-300/80">We’re confirming your onboarding details.</p> | |
| <p className="text-sm text-slate-300/80">We're confirming your onboarding details.</p> |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "use client"; | ||
|
|
||
| import jsQR from "jsqr"; | ||
| import { useEffect, useRef, useState } from "react"; | ||
|
|
There was a problem hiding this comment.
Provide TypeScript types for jsqr import
The new QR scanner relies on import jsQR from "jsqr", but the jsqr package ships no type declarations. With strict mode enabled, next build and tsc emit TS7016: Could not find a declaration file for module 'jsqr', which fails the build for the frontend. To keep the build green you need to add @types/jsqr or a local declare module "jsqr" shim before using the library.
Useful? React with 👍 / 👎.
| const INDEXER_URL = "https://moonbeam.moonscan.io/"; | ||
|
|
||
| export default function IndexerPage() { | ||
| return ( | ||
| <section className="space-y-6"> | ||
| <header className="space-y-2"> | ||
| <span className="text-xs font-semibold uppercase tracking-[0.3em] text-sky-400/80">Moonbeam tooling</span> | ||
| <h1 className="text-3xl font-semibold text-slate-50">Moonbeam indexer</h1> | ||
| <p className="max-w-3xl text-sm text-slate-300/90"> | ||
| Browse transaction details, contract events, and on-chain history without leaving Trust Me Bro. The | ||
| Moonbeam explorer loads below inside the app shell so you can jump straight back into handshakes when you are | ||
| done. | ||
| </p> | ||
| </header> | ||
|
|
||
| <div className="overflow-hidden rounded-3xl border border-slate-700/60 bg-slate-950/70 shadow-inner shadow-black/50"> | ||
| <iframe | ||
| className="h-[70vh] w-full" | ||
| src={INDEXER_URL} | ||
| title="Moonbeam indexer" | ||
| allowFullScreen |
There was a problem hiding this comment.
Moonbeam explorer cannot render inside an iframe
The new indexer page embeds https://moonbeam.moonscan.io/ inside an <iframe>, but Moonscan sends X-Frame-Options: SAMEORIGIN / Content-Security-Policy: frame-ancestors 'self', which prevents the page from being framed by other origins. In browsers the iframe will stay blank or show an error, so the indexer page never displays the explorer. Consider linking out to Moonscan or proxying data instead of embedding.
Useful? React with 👍 / 👎.
Summary
Testing
Codex Task