Files
Kitchen/src/components/ui/BarcodeScannerModal.tsx
T

132 lines
5.7 KiB
TypeScript

'use client';
import { useState } from 'react';
import { Camera, Barcode, Check, X, Sparkles, Plus } from 'lucide-react';
import { toast } from 'sonner';
interface BarcodeScannerModalProps {
isOpen: boolean;
onClose: () => void;
onProductScanned: (product: { name: string; size: number; unit: string; priceCents: number }) => void;
}
const BARCODE_DATABASE: Record<string, { name: string; size: number; unit: string; priceCents: number }> = {
'4008234567890': { name: 'Hafermilch Barista Bio (Oatly)', size: 1, unit: 'Liter', priceCents: 149 },
'4012345678901': { name: 'Tofu Natur Bio (Taifun)', size: 200, unit: 'Gramm', priceCents: 199 },
'4023456789012': { name: 'Spaghetti 500g (Barilla)', size: 500, unit: 'Gramm', priceCents: 189 },
'4034567890123': { name: 'Bio Hefeflocken (Alnatura)', size: 200, unit: 'Gramm', priceCents: 299 },
'4045678901234': { name: 'Strauchtomaten Bio', size: 500, unit: 'Gramm', priceCents: 229 },
};
export function BarcodeScannerModal({ isOpen, onClose, onProductScanned }: BarcodeScannerModalProps) {
const [barcodeInput, setBarcodeInput] = useState('');
const [scanning, setScanning] = useState(false);
if (!isOpen) return null;
const handleSimulateScan = (code: string) => {
setScanning(true);
setTimeout(() => {
setScanning(false);
const match = BARCODE_DATABASE[code] || {
name: `Gescanntes Bio-Produkt (${code.slice(-4)})`,
size: 1,
unit: 'Stück',
priceCents: 199,
};
onProductScanned(match);
toast.success(`📷 Barcode gescannt: "${match.name}" erkannt! 🌱`);
onClose();
}, 800);
};
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4 backdrop-blur-md">
<div className="w-full max-w-md rounded-3xl border border-border/60 bg-card p-6 shadow-2xl space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-lg font-bold text-foreground flex items-center gap-2">
<Camera className="h-5 w-5 text-emerald-500" />
1-Klick Barcode Scanner
</h2>
<button onClick={onClose} className="rounded-full p-1 text-muted-foreground hover:bg-accent">
<X className="h-5 w-5" />
</button>
</div>
{/* Camera Scanner View Simulation */}
<div className="relative overflow-hidden rounded-2xl bg-black p-8 text-center text-white space-y-4 border-2 border-emerald-500/50 shadow-inner">
<div className="mx-auto flex h-20 w-20 items-center justify-center rounded-2xl bg-emerald-500/20 text-emerald-400 border border-emerald-500/40">
<Barcode className={`h-12 w-12 ${scanning ? 'animate-pulse text-emerald-300' : ''}`} />
</div>
<p className="text-xs font-semibold text-emerald-200">
{scanning ? 'Barcode wird dekodiert...' : 'Halte die Kamera über den Barcode oder wähle unten ein Produkt'}
</p>
<div className="absolute inset-x-0 top-1/2 border-b-2 border-rose-500/60 animate-pulse" />
</div>
{/* Quick Scan Preset Buttons */}
<div className="space-y-2">
<label className="block text-xs font-bold text-muted-foreground uppercase">
Direkt-Scan testen:
</label>
<div className="grid grid-cols-2 gap-2">
<button
onClick={() => handleSimulateScan('4008234567890')}
className="flex items-center gap-2 rounded-xl border border-emerald-500/30 bg-emerald-500/10 p-2.5 text-xs font-bold text-emerald-700 dark:text-emerald-300 hover:bg-emerald-600 hover:text-white transition-all text-left"
>
<span>🥛 Hafermilch</span>
</button>
<button
onClick={() => handleSimulateScan('4012345678901')}
className="flex items-center gap-2 rounded-xl border border-emerald-500/30 bg-emerald-500/10 p-2.5 text-xs font-bold text-emerald-700 dark:text-emerald-300 hover:bg-emerald-600 hover:text-white transition-all text-left"
>
<span>🧈 Taifun Tofu</span>
</button>
<button
onClick={() => handleSimulateScan('4023456789012')}
className="flex items-center gap-2 rounded-xl border border-emerald-500/30 bg-emerald-500/10 p-2.5 text-xs font-bold text-emerald-700 dark:text-emerald-300 hover:bg-emerald-600 hover:text-white transition-all text-left"
>
<span>🍝 Spaghetti 500g</span>
</button>
<button
onClick={() => handleSimulateScan('4034567890123')}
className="flex items-center gap-2 rounded-xl border border-emerald-500/30 bg-emerald-500/10 p-2.5 text-xs font-bold text-emerald-700 dark:text-emerald-300 hover:bg-emerald-600 hover:text-white transition-all text-left"
>
<span>🧀 Hefeflocken</span>
</button>
</div>
</div>
{/* Manual Barcode Code Entry */}
<form
onSubmit={e => {
e.preventDefault();
if (barcodeInput.trim()) handleSimulateScan(barcodeInput.trim());
}}
className="flex gap-2"
>
<input
type="text"
value={barcodeInput}
onChange={e => setBarcodeInput(e.target.value)}
placeholder="Barcode Nummer eingeben (z.B. 400823...)"
className="flex-1 rounded-xl border border-input bg-background px-3.5 py-2.5 text-xs"
/>
<button
type="submit"
className="rounded-xl bg-emerald-600 px-4 py-2.5 text-xs font-bold text-white hover:bg-emerald-500"
>
Scannen
</button>
</form>
</div>
</div>
);
}