diff --git a/.convoys/ship-readiness.md b/.convoys/ship-readiness.md index d27240b..125c653 100644 --- a/.convoys/ship-readiness.md +++ b/.convoys/ship-readiness.md @@ -318,7 +318,7 @@ These MUST land before any anonymous traffic touches the production URL. | `pages/collections.js` | 989 | Similar structure to collection/[identifier]. Possibly share extracted pieces. | | `pages/card/[id].js` | 913 | `CardDetail` — split into header, owned-badge, add-to-collection-flow. | | `pages/deck-builder.js` | 823 | `DeckBuilder` — extract card-search, deck-list, mana-curve panels. | -| `components/CameraScanner.js` | 817 | Camera + AI-OCR + detection-loop — extract the detection loop into a hook. | +| `components/CameraScanner.js` | ~45 | **RESOLVED 2026-06-02** — god-component-split slice shipped PRs #67–#72 + view extract. Pre-split ~1,050 lines; now composes `useCameraScanner` + `useScannerIdentification` + `CameraScannerView`. Logic lives in `lib/scanner-card-detection.js`, `lib/scanner-card-identify.js`, `lib/scan-capture-upload.js`, `components/ScanDisambiguationDialog.js`. | | `pages/admin/card-editor.js` | 778 | Form heavy. Use a `useFormState` pattern + separate the search-results subview. | | `pages/scanner.js` | 776 | Mirror of CameraScanner concerns plus queue management. | | `pages/settings.js` | 669 | One screen per settings section is the usual fix. | @@ -360,7 +360,7 @@ The `getIcon` registry in `Layout.js` and `MobileNavigation.js` redefines the sa - **Error states** — error messages bubble to `console.error` and toast nothing. Add a global toast system (e.g. `sonner`) and wire every catch block. - **Empty states** — `/my-cards` and `/collections` when empty drop to "no cards yet". Replace with first-time CTA: "Scan your first card" or "Browse popular sets". - **Mobile drawer** — `MobileNavigation` is solid (recent commit `442e906`). One thing: the bottom-bar's active state contrast looks low in light mode; verify against AA. -- **Camera scanner UX** — 817 lines of detection loop. Add a one-line "scanning…" status under the viewfinder and a single "captured N cards" badge. The current toolbar is busy. +- **Camera scanner UX** — detection/identify logic split complete (PRs #67–#72); view markup in `CameraScannerView.js`. Remaining polish: theme-token cleanup for overlay hex colors, busier toolbar simplification. ### Role-design-system-auditor findings @@ -487,6 +487,7 @@ Six convoys authored from the scanner audit portfolio plan. Dependency order: - **`server-side-scan-pipeline`** — **RESOLVED 2026-05-27** — PR #35 (`e81dd49`). Server-owned identify, `card_submissions`, disambiguation. Convoy: `.convoys/server-side-scan-pipeline.md`. - **`add-real-ocr-layer`** — **RESOLVED 2026-05-27** — PR #38 (`d798e28`) + polish PR #39. Layer-1 Tesseract + `pg_trgm`. Convoy: `.convoys/add-real-ocr-layer.md`. - **`redesign-scanner-flow`** — **RESOLVED 2026-05-27** — PRs #42 (Brief 1), #43 (Brief 2), #44 (Brief 3). Post-PR audit `audit-redesign-scanner-flow-44` posted to PR #44; outcome comment-only. See `.convoys/redesign-scanner-flow/audit-redesign-scanner-flow-44.md`. Follow-ups: `scanner-redesign-a11y-fixes` **RESOLVED** PR #45; `scanner-user-cards-quantity-guard` **RESOLVED** PR #46; `test-scanner-redesign-surfaces` **RESOLVED** PR #47. +- **`god-component-split` / `CameraScanner.js` slice** — **RESOLVED 2026-06-02** — PRs #67–#72 (Briefs 1–5) + view extract (`CameraScannerView.js`). Pre-split ~1,050 lines → ~45-line composer + presentational view. Remaining `god-component-split` targets: `pages/cards.js`, `pages/scanner.js`, etc. (see § P2 #13 table). - **`rename-collections-vocabulary`** — **RESOLVED 2026-05-29** — PR #54 + follow-up PR #55. Convoy: `.convoys/rename-collections-vocabulary.md`. - **`scanner-correctness-polish`** — **RESOLVED 2026-05-27** — PR #41 (`55af7e3`). Convoy: `.convoys/scanner-correctness-polish.md`. - **`schema-cleanup-from-scanner-audit`** (priority: P2 schema; **deferred** — diff --git a/components/CameraScanner.js b/components/CameraScanner.js index 1f8a088..885018a 100644 --- a/components/CameraScanner.js +++ b/components/CameraScanner.js @@ -1,284 +1,44 @@ import { useRef } from 'react'; import { useCameraScanner } from '../lib/use-camera-scanner.js'; import { useScannerIdentification } from '../lib/use-scanner-identification.js'; -import ScanDisambiguationDialog from './ScanDisambiguationDialog.js'; +import CameraScannerView from './CameraScannerView.js'; export default function CameraScanner({ onCardScanned, onError }) { const verificationPausedRef = useRef(false); const onVerifyCardRef = useRef(() => {}); - const { - videoRef, - canvasRef, - detectionCanvasRef, - isStreaming, - isDetecting, - trackedCards, - videoMetrics, - startCamera, - stopCamera, - } = useCameraScanner({ + const camera = useCameraScanner({ onError, verificationPausedRef, onVerifyCard: (card) => onVerifyCardRef.current(card), }); - const { - disambiguation, - scanNotice, - submittingReview, - handleDisambiguationPick, - handleNotInCatalog, - cancelDisambiguation, - } = useScannerIdentification({ + const identification = useScannerIdentification({ onCardScanned, onError, - videoRef, - canvasRef, + videoRef: camera.videoRef, + canvasRef: camera.canvasRef, onVerifyCardRef, verificationPausedRef, }); - const foundCardCount = trackedCards.filter( - (card) => card.status === 'confirmed' || card.status === 'scanned' - ).length; - return ( -