// app/screen-scan.jsx — /cook · point the camera at the fridge. AI detects // items with confidence, you correct the list, then it suggests dinners. const SCAN_BOXES = [ { top: '15%', left: '18%', w: 72, h: 72, label: 'chicken' }, { top: '42%', left: '52%', w: 60, h: 60, label: 'chilli oil' }, { top: '60%', left: '14%', w: 56, h: 56, label: 'garlic' }, { top: '24%', left: '70%', w: 60, h: 60, label: 'spring onion' }, ]; function ScanScreen() { const { layout, SCAN_ITEMS, allRecipes, openRecipe, photoFor } = useApp(); const isMobile = layout === 'mobile'; const [items, setItems] = React.useState(() => SCAN_ITEMS.map((x, i) => ({ ...x, id: i, on: true }))); const [adding, setAdding] = React.useState(''); const [showResults, setShowResults] = React.useState(false); const remove = (id) => setItems((xs) => xs.filter((x) => x.id !== id)); const toggle = (id) => setItems((xs) => xs.map((x) => (x.id === id ? { ...x, on: !x.on } : x))); const addItem = () => { if (!adding.trim()) return; setItems((xs) => [...xs, { id: Date.now(), item: adding.trim(), conf: 100, on: true }]); setAdding(''); }; // matching recipes — simple ingredient/word overlap const matches = React.useMemo(() => { const have = items.filter((x) => x.on).map((x) => x.item.toLowerCase()); const scored = allRecipes.map((r) => { const hay = (r.name + ' ' + r.ingredients.join(' ')).toLowerCase(); const score = have.reduce((s, h) => { const key = h.split(/[ ,(]/)[0]; return s + (key.length > 2 && hay.includes(key) ? 1 : 0); }, 0); return { r, score }; }).filter((x) => x.score > 0).sort((a, b) => b.score - a.score); return scored.slice(0, 8).map((x) => x.r); }, [items, allRecipes]); const Capture = (
{SCAN_BOXES.map((b, i) => (
{b.label}
))}
{isMobile ? 'Photo' : 'Take another photo'} {items.length} items detected
); const List = (
What we found · {items.length} items tap to keep · ✕ to remove
{items.map((it) => (
{it.item}
80 ? 'var(--olive)' : it.conf > 65 ? '#d9a04b' : '#d96a4a' }} />
))}
setAdding(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') addItem(); }} placeholder="+ add an item" style={{ flex: 1, padding: '10px 12px', borderRadius: 8, background: 'transparent', border: '1px dashed var(--hairline)', color: 'var(--ink)', fontFamily: 'Bricolage Grotesque', fontSize: 13, outline: 'none' }} /> Add
setShowResults(true)} style={{ minHeight: 58 }}> Show me what I can cook
); const Results = showResults && (
{matches.length} recipes you can make right now
{matches.map((r) => (
openRecipe(r.id)} style={{ cursor: 'pointer' }}>
))}
); const Intro = (
What can I cook?

Show us the fridge.

We'll list what we see — correct it before we suggest dinners. AI gets things wrong; you have the final say.

); return ( {Intro}
{Capture} {List}
{Results}
); } Object.assign(window, { ScanScreen });