import { Alert, Button, Card, CardContent, Chip, Container, Dialog, DialogContent, DialogTitle, Divider, Stack, Typography, } from '@mui/material'; import { liveQuery } from 'dexie'; import { useEffect, useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { BarcodeScannerView } from '../components/BarcodeScannerView'; import { useDatabase } from '../context/DBProvider'; import { Area } from '../models/Area'; import { PickList } from '../models/PickList'; import { Product } from '../models/Product'; interface ProductLookup { product?: Product | null; pickLists: { list: PickList; area?: Area }[]; } export const BarcodeScannerScreen = () => { const db = useDatabase(); const navigate = useNavigate(); const [lastCode, setLastCode] = useState(''); const [lookup, setLookup] = useState({ pickLists: [] }); const [scannerOpen, setScannerOpen] = useState(false); useEffect(() => { if (!lastCode) { setLookup({ pickLists: [] }); return undefined; } const subscription = liveQuery(async () => { const product = await db.products.where('barcode').equals(lastCode).first(); if (!product) { return { product: null, pickLists: [] } satisfies ProductLookup; } const pickItems = await db.pickItems.where('product_id').equals(product.id).toArray(); const pickListIds = Array.from(new Set(pickItems.map((item) => item.pick_list_id))); const pickLists = (await db.pickLists.bulkGet(pickListIds)).filter( (list): list is PickList => Boolean(list), ); const areas = await db.areas.bulkGet(pickLists.map((list) => list.area_id)); const areaMap = new Map(); areas.forEach((area) => { if (area) areaMap.set(area.id, area); }); return { product, pickLists: pickLists.map((list) => ({ list, area: areaMap.get(list.area_id) })), } satisfies ProductLookup; }).subscribe({ next: setLookup, }); return () => subscription.unsubscribe(); }, [db, lastCode]); const hasProduct = useMemo(() => lookup.product && lookup.product !== null, [lookup.product]); const handleDetected = (code: string) => { setLastCode(code); setScannerOpen(false); }; const handleAddProduct = () => { if (!lastCode) return; navigate('/products', { state: { newBarcode: lastCode } }); }; return ( Barcode Scanner Scan barcodes Open the camera in a popup to keep scanned details easy to read. {lastCode ? ( ) : null} {lastCode ? ( Last detected {lastCode} {lookup.product === null ? ( This barcode is not present in the product list. ) : null} ) : null} {lookup.product ? ( Product {lookup.product.name} Category: {lookup.product.category} {lookup.product.barcode ? ( Barcode: {lookup.product.barcode} ) : null} ) : null} {hasProduct ? ( Pick lists containing this product {lookup.pickLists.length === 0 ? ( This product is not in any pick lists yet. ) : ( } spacing={1}> {lookup.pickLists.map(({ list, area }) => ( Pick List #{list.id.slice(0, 8)} Area: {area?.name ?? 'Unknown area'} ))} )} ) : null} setScannerOpen(false)} fullWidth> Scan a barcode ); };