Skip to content

[#410] Fix for qr-code-scanner issue#417

Merged
DVidal1205 merged 3 commits intomainfrom
blade/qr-scanner-react19
Mar 10, 2026
Merged

[#410] Fix for qr-code-scanner issue#417
DVidal1205 merged 3 commits intomainfrom
blade/qr-scanner-react19

Conversation

@myr124
Copy link
Contributor

@myr124 myr124 commented Mar 10, 2026

that

Why

Fixes lack of video output in qr code scanning

What

Closes: #410

Replaced react-qr-scanner library with newer one from yudiel that has very similar components. I think it works better with the more strict mounting behavior for react 19 .

Test Plan

I went into events page and opened up scanner, set it to project launch event and video output showed up with my qr code scanning successfully

Checklist

  • Database: No schema changes, OR I have contacted the Development Lead to run db:push before merging
  • Environment Variables: No environment variables changed, OR I have contacted the Development Lead to modify them on Coolify BEFORE merging.

Summary by CodeRabbit

  • New Features

    • Improved QR scanning in the app — better QR code compatibility and more reliable scan results.
  • Chores

    • Updated QR scanner dependency used by the app.
  • Documentation

    • Removed the migration status document that tracked utility migrations and related notes.

@myr124 myr124 requested a review from a team as a code owner March 10, 2026 04:45
@myr124 myr124 added the Blade Change modifies code in Blade app label Mar 10, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 93650aea-0224-4bec-8173-71cf23d45be3

📥 Commits

Reviewing files that changed from the base of the PR and between e158b68 and cbeea54.

📒 Files selected for processing (1)
  • MIGRATION_STATUS.md
💤 Files with no reviewable changes (1)
  • MIGRATION_STATUS.md

📝 Walkthrough

Walkthrough

Adds the @yudiel/react-qr-scanner dependency, updates Blade scanner components to use the new Scanner API (callback and result changes), and removes the MIGRATION_STATUS.md document.

Changes

Cohort / File(s) Summary
Package Dependencies
apps/blade/package.json
Added @yudiel/react-qr-scanner@^2.5.1.
Scanner Components
apps/blade/src/app/_components/admin/club/members/scanner.tsx, apps/blade/src/app/_components/shared/scanner.tsx
Replaced QrReader with Scanner from @yudiel/react-qr-scanner; switched onResultonScan, used result.rawValue (or detectedCodes[0]) instead of result.getText(); added formats={["qr_code"]}; preserved scanDelay and constraints.
Docs / Misc
MIGRATION_STATUS.md
Removed the migration status document (full deletion).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested labels

Bug, UI, Minor

Suggested reviewers

  • must108
🚥 Pre-merge checks | ✅ 7 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The deletion of MIGRATION_STATUS.md is unrelated to the #410 QR scanner issue and represents an out-of-scope change that should be handled separately. Remove the MIGRATION_STATUS.md deletion from this PR and address it in a separate pull request focused on documentation cleanup or migration tracking.
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title includes the required issue bracket format [#410] and concisely describes the main change (fixing QR code scanner), staying well under 72 characters.
Linked Issues check ✅ Passed The PR successfully addresses issue #410 by replacing the non-functional react-qr-scanner with @yudiel/react-qr-scanner, restoring QR scanning functionality across both scanner components.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
No Hardcoded Secrets ✅ Passed Comprehensive examination of all modified files reveals no hardcoded secrets, API keys, passwords, or tokens. The code properly relies on environment variables for sensitive configuration.
Validated Env Access ✅ Passed PR modifications contain no direct process.env usage outside of designated config files; scanner components only update QR library implementation.
No Typescript Escape Hatches ✅ Passed Modified scanner components contain no prohibited TypeScript escape hatches: 'any' type, @ts-ignore, @ts-expect-error, or non-null assertions. Code maintains type safety through Zod schema validation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch blade/qr-scanner-react19

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/blade/src/app/_components/shared/scanner.tsx (1)

237-268: ⚠️ Potential issue | 🟡 Minor

Add length validation before extracting userId from QR code.

The QR code contains user:${userId} (generated server-side), so substring(5) extracts the userId. However, if the QR code content is shorter than expected, this returns an empty or partial string. While the API will return a "not found" error, it's better UX to validate the format immediately and show a clear message.

The server-side schema (z.string()) doesn't validate length, so defensive validation on the client improves the experience.

🛡️ Suggested fix
              const result = detectedCodes[0];
              if (!result) return;
+             if (!result.rawValue || result.rawValue.length < 6) {
+               toast.error("Invalid QR code format");
+               return;
+             }
              if (scanningRef.current) return;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/blade/src/app/_components/shared/scanner.tsx` around lines 237 - 268,
Validate the scanned QR payload before slicing: inside the Scanner onScan
handler, check result.rawValue startsWith("user:") and has a sufficient length
(e.g., rawValue.length > 5) before calling result.rawValue.substring(5); if it
fails, show a clear toast.error like "Invalid QR code" and return early (ensure
scanningRef.current is still handled as in the finally block). Then proceed to
set form.setValue("userId", userId) and the existing flow that calls
form.handleSubmit which triggers hackerEventCheckIn.mutate or
memberCheckIn.mutate based on eventType.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/blade/package.json`:
- Line 40: Remove the old react-qr-reader dependency from package.json to
complete the migration to `@yudiel/react-qr-scanner`: locate the dependencies
block in package.json and delete the "react-qr-reader" entry (the legacy package
string), ensuring only "@yudiel/react-qr-scanner": "^2.5.1" remains so there are
no duplicate/unused QR scanner packages listed.

---

Outside diff comments:
In `@apps/blade/src/app/_components/shared/scanner.tsx`:
- Around line 237-268: Validate the scanned QR payload before slicing: inside
the Scanner onScan handler, check result.rawValue startsWith("user:") and has a
sufficient length (e.g., rawValue.length > 5) before calling
result.rawValue.substring(5); if it fails, show a clear toast.error like
"Invalid QR code" and return early (ensure scanningRef.current is still handled
as in the finally block). Then proceed to set form.setValue("userId", userId)
and the existing flow that calls form.handleSubmit which triggers
hackerEventCheckIn.mutate or memberCheckIn.mutate based on eventType.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 6c546670-3ab3-410f-9623-f2b4e464e26d

📥 Commits

Reviewing files that changed from the base of the PR and between c936e2a and 5782720.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !pnpm-lock.yaml
📒 Files selected for processing (3)
  • apps/blade/package.json
  • apps/blade/src/app/_components/admin/club/members/scanner.tsx
  • apps/blade/src/app/_components/shared/scanner.tsx

"@trpc/client": "catalog:",
"@trpc/react-query": "catalog:",
"@trpc/server": "catalog:",
"@yudiel/react-qr-scanner": "^2.5.1",
Copy link

@coderabbitai coderabbitai bot Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove the old react-qr-reader dependency.

The new @yudiel/react-qr-scanner is added (line 40), but react-qr-reader (line 56) is still listed. Since the migration replaces the old library, it should be removed to reduce bundle size and avoid confusion.

🧹 Suggested fix
     "@yudiel/react-qr-scanner": "^2.5.1",
     "canvas-confetti": "^1.9.4",
     ...
     "react-qr-code": "^2.0.18",
-    "react-qr-reader": "3.0.0-beta-1",
     "recharts": "^3.7.0",

Also applies to: 56-56

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/blade/package.json` at line 40, Remove the old react-qr-reader
dependency from package.json to complete the migration to
`@yudiel/react-qr-scanner`: locate the dependencies block in package.json and
delete the "react-qr-reader" entry (the legacy package string), ensuring only
"@yudiel/react-qr-scanner": "^2.5.1" remains so there are no duplicate/unused QR
scanner packages listed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point rabbit

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@myr124, glad it helps! Since react-qr-reader is still listed in package.json, here's the one-line fix needed:

-    "react-qr-reader": "3.0.0-beta-1",

Also make sure to run pnpm install after the change to update the lockfile and fully remove the old package from node_modules. This keeps the bundle lean and avoids any accidental import of the legacy library in the future.

Would you like me to plan that change for you?

@myr124 myr124 self-assigned this Mar 10, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
MIGRATION_STATUS.md (1)

66-92: ⚠️ Potential issue | 🟡 Minor

Remove false duplicate function references from MIGRATION_STATUS.md.

Lines 66–92 reference duplicate functions in apps/blade/src/lib/utils.ts that don't exist:

  • formatDateRange (line 68–79): No duplicate at apps/blade/src/lib/utils.ts:29. Only definition is at packages/utils/src/time.ts:54.
  • getPermsAsList (line 82–92): No duplicate at apps/blade/src/lib/utils.ts:120. Only definition is at packages/utils/src/permissions.ts:45.

The file apps/blade/src/lib/utils.ts doesn't exist. Remove these false migration items or update with actual duplicates if they exist elsewhere.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@MIGRATION_STATUS.md` around lines 66 - 92, Update MIGRATION_STATUS.md to
remove or correct the false duplicate entries: delete the `formatDateRange` and
`getPermsAsList` duplicate references (lines describing
`apps/blade/src/lib/utils.ts`) since those functions only exist in
`packages/utils` (`formatDateRange`/`formatTimeRange` at
packages/utils/src/time.ts and `getPermsAsList` at
packages/utils/src/permissions.ts); alternatively, if a real duplicate exists
elsewhere, replace the incorrect path with the actual file where the duplicate
lives and update the suggested actions (e.g., import fixes to `@forge/utils` and
renaming guidance for `formatDateRange`/`formatTimeRange`) so the migration
notes accurately reflect the codebase.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/blade/src/app/_components/shared/scanner.tsx`:
- Around line 241-248: Validate result.rawValue in the onScan handler before
slicing: ensure result and result.rawValue are defined and that rawValue has at
least 6 characters and the expected prefix pattern (the first 5 chars) before
calling result.rawValue.substring(5); if validation fails, log or ignore the
scan and reset scanningRef appropriately to avoid silencing errors or setting an
empty userId; update the onScan logic (referencing onScan, scanningRef.current,
result, result.rawValue, and form.setValue("userId", ...)) to perform this
defensive check and handle malformed QR payloads gracefully.
- Around line 237-240: The QR handler currently assumes result.rawValue is
present and long enough (used to compute userId via substring) which can crash
on malformed QR data; update the QR scan result handling (the code that reads
result.rawValue and assigns userId) to first validate that result.rawValue is a
non-empty string and has at least 5 characters (and optionally startsWith the
expected prefix), show a user-facing error via toast.error and return early if
validation fails, otherwise safely compute userId = result.rawValue.substring(5)
and proceed; references: Scanner component, result.rawValue usage, userId
extraction, and toast.error.

---

Outside diff comments:
In `@MIGRATION_STATUS.md`:
- Around line 66-92: Update MIGRATION_STATUS.md to remove or correct the false
duplicate entries: delete the `formatDateRange` and `getPermsAsList` duplicate
references (lines describing `apps/blade/src/lib/utils.ts`) since those
functions only exist in `packages/utils` (`formatDateRange`/`formatTimeRange` at
packages/utils/src/time.ts and `getPermsAsList` at
packages/utils/src/permissions.ts); alternatively, if a real duplicate exists
elsewhere, replace the incorrect path with the actual file where the duplicate
lives and update the suggested actions (e.g., import fixes to `@forge/utils` and
renaming guidance for `formatDateRange`/`formatTimeRange`) so the migration
notes accurately reflect the codebase.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 1c8cc80d-0395-44d0-93a8-a74e3d0fdebc

📥 Commits

Reviewing files that changed from the base of the PR and between 5782720 and e158b68.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !pnpm-lock.yaml
📒 Files selected for processing (3)
  • MIGRATION_STATUS.md
  • apps/blade/src/app/_components/admin/club/members/scanner.tsx
  • apps/blade/src/app/_components/shared/scanner.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/blade/src/app/_components/admin/club/members/scanner.tsx

Comment on lines +237 to +240
<Scanner
scanDelay={2000}
constraints={{ facingMode: "environment" }}
onResult={async (result, _) => {
formats={["qr_code"]}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

@yudiel/react-qr-scanner version 2.5.1 API documentation formats prop

💡 Result:

In @yudiel/react-qr-scanner v2.5.1, the Scanner prop:

  • formats?: BarcodeFormat[]Optional. A list of barcode formats to detect. Default: “All” (if you don’t pass it, it will detect all supported formats). [1]

BarcodeFormat is a string union of:
'aztec' | 'code_128' | 'code_39' | 'code_93' | 'codabar' | 'databar' | 'databar_expanded' | 'data_matrix' | 'dx_film_edge' | 'ean_13' | 'ean_8' | 'itf' | 'maxi_code' | 'micro_qr_code' | 'pdf417' | 'qr_code' | 'rm_qr_code' | 'upc_a' | 'upc_e' | 'linear_codes' | 'matrix_codes' | 'unknown'. [1]

Example: formats={['qr_code','ean_13','code_128']}. [1]

Sources:
[1] v2.5.1 README (API Reference + Type Definitions) (raw.githubusercontent.com)

Citations:


🏁 Script executed:

find . -name "scanner.tsx" | grep -E "apps/blade"

Repository: KnightHacks/forge

Length of output: 176


🏁 Script executed:

cat -n ./apps/blade/src/app/_components/shared/scanner.tsx | sed -n '230,260p'

Repository: KnightHacks/forge

Length of output: 1527


🏁 Script executed:

cat -n ./apps/blade/src/app/_components/shared/scanner.tsx | head -20

Repository: KnightHacks/forge

Length of output: 707


🏁 Script executed:

cat -n ./apps/blade/src/app/_components/shared/scanner.tsx | sed -n '240,275p'

Repository: KnightHacks/forge

Length of output: 1656


Approve library migration, but add defensive validation for QR code format.

The formats={["qr_code"]} configuration aligns with @yudiel/react-qr-scanner v2.5.1 API. However, line 247 assumes rawValue exists and has at least 5 characters without validation:

const userId = result.rawValue?.substring(5) ?? "";
// or with explicit check:
if (!result.rawValue || result.rawValue.length < 5) {
  toast.error("Invalid QR code format");
  return;
}
const userId = result.rawValue.substring(5);

This prevents runtime errors if the QR code format differs from expectations (e.g., missing prefix or malformed data).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/blade/src/app/_components/shared/scanner.tsx` around lines 237 - 240,
The QR handler currently assumes result.rawValue is present and long enough
(used to compute userId via substring) which can crash on malformed QR data;
update the QR scan result handling (the code that reads result.rawValue and
assigns userId) to first validate that result.rawValue is a non-empty string and
has at least 5 characters (and optionally startsWith the expected prefix), show
a user-facing error via toast.error and return early if validation fails,
otherwise safely compute userId = result.rawValue.substring(5) and proceed;
references: Scanner component, result.rawValue usage, userId extraction, and
toast.error.

Comment on lines +241 to 248
onScan={async (detectedCodes) => {
const result = detectedCodes[0];
if (!result) return;
if (scanningRef.current) return;
scanningRef.current = true;
try {
const userId = result.getText().substring(5);
const userId = result.rawValue.substring(5);
form.setValue("userId", userId);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add defensive validation for rawValue before extraction.

Line 247 assumes rawValue exists and follows a specific format (prefix of 5 characters). If the QR code is malformed or from an unexpected source, this could silently produce an empty userId or throw if rawValue is undefined.

Consider validating the format:

🛡️ Suggested defensive check
 onScan={async (detectedCodes) => {
   const result = detectedCodes[0];
   if (!result) return;
+  if (!result.rawValue || result.rawValue.length < 5) {
+    toast.error("Invalid QR code format");
+    return;
+  }
   if (scanningRef.current) return;
   scanningRef.current = true;
   try {
     const userId = result.rawValue.substring(5);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/blade/src/app/_components/shared/scanner.tsx` around lines 241 - 248,
Validate result.rawValue in the onScan handler before slicing: ensure result and
result.rawValue are defined and that rawValue has at least 6 characters and the
expected prefix pattern (the first 5 chars) before calling
result.rawValue.substring(5); if validation fails, log or ignore the scan and
reset scanningRef appropriately to avoid silencing errors or setting an empty
userId; update the onScan logic (referencing onScan, scanningRef.current,
result, result.rawValue, and form.setValue("userId", ...)) to perform this
defensive check and handle malformed QR payloads gracefully.

@DVidal1205 DVidal1205 merged commit d75af21 into main Mar 10, 2026
8 checks passed
@DVidal1205 DVidal1205 deleted the blade/qr-scanner-react19 branch March 10, 2026 05:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Blade Change modifies code in Blade app

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Blade] QR code check in no longer works

2 participants