deckhearth/pages/scanner.js
varutasu 2273fc6be0
refactor(scanner): extract ScannerPageView component (page Brief 3) (#76)
Move scanner page markup into ScannerPageView.js. pages/scanner.js is now
a thin composer of session state, useScannerQueue, and the view.
Mark pages/scanner.js resolved in ship-readiness god-component-split table.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 21:56:34 -05:00

78 lines
2.6 KiB
JavaScript

import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import Layout from '../components/Layout';
import ScannerPageView from '../components/ScannerPageView';
import { useAuth } from '../lib/use-auth';
import {
DEFAULT_SCANNER_DESTINATION,
loadSavedScannerSession,
saveScannerSession,
} from '../lib/scanner-session.js';
import { useScannerQueue } from '../lib/use-scanner-queue.js';
export default function Scanner() {
const { user, loading: authLoading } = useAuth();
const router = useRouter();
const [showOCRSettings, setShowOCRSettings] = useState(false);
const [sessionDestination, setSessionDestination] = useState(
() => loadSavedScannerSession().destination
);
const [gameFilter, setGameFilter] = useState(() => loadSavedScannerSession().gameFilter);
const [scanDefaults, setScanDefaults] = useState(() => loadSavedScannerSession().scanDefaults);
const queue = useScannerQueue({ user, sessionDestination, scanDefaults });
useEffect(() => {
if (!authLoading && !user) {
router.push('/login');
}
}, [authLoading, user, router]);
useEffect(() => {
saveScannerSession({ destination: sessionDestination, gameFilter, scanDefaults });
}, [sessionDestination, gameFilter, scanDefaults]);
const handleGameFilterChange = (nextFilter) => {
setGameFilter(nextFilter);
setSessionDestination((current) => {
if (!current || current.type === 'owned') return current;
return DEFAULT_SCANNER_DESTINATION;
});
};
const handleScannerError = (error) => {
console.error('Scanner error:', error);
};
if (authLoading) {
return (
<Layout user={null}>
<div className="flex items-center justify-center min-h-[50vh]">
<div className="animate-spin rounded-full h-12 w-12 border-b-2" style={{ borderColor: 'var(--text-accent)' }} />
</div>
</Layout>
);
}
if (!user) {
return <div>Redirecting to login...</div>;
}
return (
<Layout user={user}>
<ScannerPageView
gameFilter={gameFilter}
onGameFilterChange={handleGameFilterChange}
sessionDestination={sessionDestination}
onDestinationChange={setSessionDestination}
scanDefaults={scanDefaults}
onScanDefaultsChange={(patch) => setScanDefaults((current) => ({ ...current, ...patch }))}
queue={queue}
showOCRSettings={showOCRSettings}
onOpenOCRSettings={() => setShowOCRSettings(true)}
onCloseOCRSettings={() => setShowOCRSettings(false)}
onScannerError={handleScannerError}
/>
</Layout>
);
}