Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 0 additions & 147 deletions MIGRATION_STATUS.md

This file was deleted.

1 change: 1 addition & 0 deletions apps/blade/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@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?

"canvas-confetti": "^1.9.4",
"csv-parse": "^6.1.0",
"csv-stringify": "^6.6.0",
Expand Down
10 changes: 6 additions & 4 deletions apps/blade/src/app/_components/admin/club/members/scanner.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use client";

import { useRef, useState } from "react";
import { Scanner } from "@yudiel/react-qr-scanner";
import { AwardIcon, WrenchIcon } from "lucide-react";
import { QrReader } from "react-qr-reader";
import { z } from "zod";

import type { HackerClass } from "@forge/db/schemas/knight-hacks";
Expand Down Expand Up @@ -234,15 +234,17 @@ const ScannerPopUp = ({ eventType }: { eventType: "Member" | "Hacker" }) => {
<DialogTitle className="absolute">Check-in {eventType}</DialogTitle>
</DialogHeader>
<div>
<QrReader
<Scanner
scanDelay={2000}
constraints={{ facingMode: "environment" }}
onResult={async (result, _) => {
formats={["qr_code"]}
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);
const eventId = form.getValues("eventId");
if (eventId) {
Expand Down
10 changes: 6 additions & 4 deletions apps/blade/src/app/_components/shared/scanner.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use client";

import { useRef, useState } from "react";
import { Scanner } from "@yudiel/react-qr-scanner";
import { AwardIcon, WrenchIcon } from "lucide-react";
import { QrReader } from "react-qr-reader";
import { z } from "zod";

import type { HackerClass } from "@forge/db/schemas/knight-hacks";
Expand Down Expand Up @@ -234,15 +234,17 @@ const ScannerPopUp = ({ eventType }: { eventType: "Member" | "Hacker" }) => {
<DialogTitle className="absolute">Check-in {eventType}</DialogTitle>
</DialogHeader>
<div>
<QrReader
<Scanner
scanDelay={2000}
constraints={{ facingMode: "environment" }}
onResult={async (result, _) => {
formats={["qr_code"]}
Comment on lines +237 to +240
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.

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);
Comment on lines +241 to 248
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.

const eventId = form.getValues("eventId");
if (eventId) {
Expand Down
Loading