mirror of
https://github.com/immissmandy/Kitchen.git
synced 2026-07-27 12:25:30 +02:00
132 lines
5.7 KiB
TypeScript
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>
|
|
);
|
|
}
|