From 331911cd2b0e6b0367512a1a25dbdfece260984f Mon Sep 17 00:00:00 2001
From: Randall Stillwell
Date: Tue, 22 Jul 2025 08:27:11 -0500
Subject: [PATCH] Add debug component to troubleshoot scanner issues
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
🔧 Debug Component:
- Add DebugInfo component to Scanner page
- Tests camera support and permissions
- Tests API connectivity and token validation
- Shows detailed error information
- Helps diagnose both collection API and camera issues
This will help identify:
❓ Why collections API fails in browser but works in curl
❓ Why camera UI doesn't appear after starting camera
❓ Token/authentication issues
❓ Browser permissions and support
---
src/components/DebugInfo.tsx | 144 +++++++++++++++++++++++++++++++++++
src/pages/Scanner.tsx | 4 +
2 files changed, 148 insertions(+)
create mode 100644 src/components/DebugInfo.tsx
diff --git a/src/components/DebugInfo.tsx b/src/components/DebugInfo.tsx
new file mode 100644
index 0000000..4c8cf2e
--- /dev/null
+++ b/src/components/DebugInfo.tsx
@@ -0,0 +1,144 @@
+import React, { useState, useEffect } from 'react';
+import { useAuth } from '../contexts/AuthContext';
+
+const DebugInfo: React.FC = () => {
+ const { user } = useAuth();
+ const [debugInfo, setDebugInfo] = useState(null);
+ const [cameraSupported, setCameraSupported] = useState(null);
+
+ useEffect(() => {
+ // Check camera support
+ setCameraSupported(
+ navigator.mediaDevices &&
+ navigator.mediaDevices.getUserMedia &&
+ typeof navigator.mediaDevices.getUserMedia === 'function'
+ );
+
+ // Test API connectivity
+ testAPIs();
+ }, [user]);
+
+ const testAPIs = async () => {
+ const token = localStorage.getItem('token');
+ const results: any = {
+ token: token ? `${token.substring(0, 20)}...` : 'No token',
+ tokenLength: token?.length || 0,
+ user: user ? {
+ id: user.id,
+ username: user.username,
+ roles: user.roles
+ } : 'Not logged in'
+ };
+
+ try {
+ // Test collections API
+ const collectionsResponse = await fetch('/api/collections', {
+ headers: {
+ 'Authorization': `Bearer ${token}`,
+ 'Content-Type': 'application/json'
+ }
+ });
+
+ results.collectionsAPI = {
+ status: collectionsResponse.status,
+ ok: collectionsResponse.ok,
+ data: collectionsResponse.ok ? await collectionsResponse.json() : await collectionsResponse.text()
+ };
+ } catch (error: any) {
+ results.collectionsAPI = {
+ error: error.message
+ };
+ }
+
+ setDebugInfo(results);
+ };
+
+ const testCamera = async () => {
+ try {
+ const stream = await navigator.mediaDevices.getUserMedia({
+ video: { facingMode: 'environment' }
+ });
+
+ setDebugInfo((prev: any) => ({
+ ...prev,
+ cameraTest: '✅ Camera access successful',
+ cameraStream: {
+ active: stream.active,
+ tracks: stream.getVideoTracks().length
+ }
+ }));
+
+ // Stop the test stream
+ stream.getTracks().forEach(track => track.stop());
+ } catch (error: any) {
+ setDebugInfo((prev: any) => ({
+ ...prev,
+ cameraTest: `❌ Camera error: ${error.message}`,
+ cameraError: error.name
+ }));
+ }
+ };
+
+ if (!debugInfo) return Loading debug info...
;
+
+ return (
+
+
🔧 Debug Information
+
+
+
+ Camera Support: {cameraSupported ? '✅ Supported' : '❌ Not supported'}
+
+
+
+ User: {JSON.stringify(debugInfo.user, null, 2)}
+
+
+
+ Token: {debugInfo.token} (Length: {debugInfo.tokenLength})
+
+
+
+
Collections API:
+
+ {JSON.stringify(debugInfo.collectionsAPI, null, 2)}
+
+
+
+ {debugInfo.cameraTest && (
+
+
Camera Test: {debugInfo.cameraTest}
+ {debugInfo.cameraStream && (
+
+ Active: {debugInfo.cameraStream.active ? 'Yes' : 'No'},
+ Tracks: {debugInfo.cameraStream.tracks}
+
+ )}
+ {debugInfo.cameraError && (
+
+ Error Type: {debugInfo.cameraError}
+
+ )}
+
+ )}
+
+
+
+
+
+
+
+ );
+};
+
+export default DebugInfo;
\ No newline at end of file
diff --git a/src/pages/Scanner.tsx b/src/pages/Scanner.tsx
index e73ef03..dfe7f36 100644
--- a/src/pages/Scanner.tsx
+++ b/src/pages/Scanner.tsx
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
import CameraScanner from '../components/CameraScanner';
import GlowingCard from '../components/GlowingCard';
import CardImageDisplay from '../components/CardImageDisplay';
+import DebugInfo from '../components/DebugInfo';
import { cardMatcher } from '../services/cardMatcher';
import { useAuth } from '../contexts/AuthContext';
@@ -275,6 +276,9 @@ const Scanner: React.FC = () => {
+ {/* Debug Information */}
+
+
{/* Error Display */}
{error && (