feat: optimize scan flow with WebP compression and fix admin metrics visibility

This commit is contained in:
2025-12-22 10:15:29 +01:00
parent f0588418c8
commit 5e35710b67
19 changed files with 477 additions and 332 deletions

View File

@@ -107,13 +107,13 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
<div className="flex flex-col gap-2">
<button
onClick={() => setIsEditing(true)}
className="flex items-center gap-2 px-4 py-2 bg-zinc-100 dark:bg-zinc-800 hover:bg-zinc-200 dark:hover:bg-zinc-700 text-zinc-600 dark:text-zinc-400 rounded-xl text-sm font-bold transition-all w-fit"
className="flex items-center gap-2 px-4 py-2 bg-zinc-800 hover:bg-zinc-700 text-zinc-400 rounded-xl text-sm font-bold transition-all w-fit border border-zinc-700"
>
<Edit2 size={16} />
{t('bottle.editDetails')}
</button>
{bottle.purchase_price && (
<div className="flex items-center gap-2 px-4 py-2 bg-green-50 dark:bg-green-900/10 text-green-700 dark:text-green-400 rounded-xl text-sm font-bold border border-green-100 dark:border-green-900/30 w-fit">
<div className="flex items-center gap-2 px-4 py-2 bg-green-900/10 text-green-400 rounded-xl text-sm font-bold border border-green-900/30 w-fit">
<CircleDollarSign size={16} />
{t('bottle.priceLabel')}: {parseFloat(bottle.purchase_price.toString()).toLocaleString(locale === 'de' ? 'de-DE' : 'en-US', { style: 'currency', currency: 'EUR' })}
</div>
@@ -143,7 +143,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 text-zinc-200"
/>
</div>
<div className="space-y-1">
@@ -152,7 +152,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.distillery}
onChange={(e) => setFormData({ ...formData, distillery: e.target.value })}
className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 text-zinc-200"
/>
</div>
<div className="space-y-1">
@@ -161,7 +161,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.category}
onChange={(e) => setFormData({ ...formData, category: e.target.value })}
className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 text-zinc-200"
/>
</div>
<div className="grid grid-cols-2 gap-2">
@@ -172,7 +172,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
step="0.1"
value={formData.abv}
onChange={(e) => setFormData({ ...formData, abv: parseFloat(e.target.value) })}
className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 text-zinc-200"
/>
</div>
<div className="space-y-1">
@@ -181,7 +181,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="number"
value={formData.age}
onChange={(e) => setFormData({ ...formData, age: parseInt(e.target.value) })}
className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 text-zinc-200"
/>
</div>
</div>
@@ -202,7 +202,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
type="text"
value={formData.whiskybase_id}
onChange={(e) => setFormData({ ...formData, whiskybase_id: e.target.value })}
className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 text-zinc-200"
/>
{discoveryResult && (
<div className="mt-2 p-3 bg-zinc-950 border border-orange-500/20 rounded-xl animate-in fade-in slide-in-from-top-2">
@@ -220,7 +220,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
href={discoveryResult.url}
target="_blank"
rel="noopener noreferrer"
className="px-3 py-1.5 bg-zinc-200 dark:bg-zinc-700 text-zinc-600 dark:text-zinc-300 text-[10px] font-black uppercase rounded-lg hover:bg-zinc-300 dark:hover:bg-zinc-600 transition-colors flex items-center gap-1"
className="px-3 py-1.5 bg-zinc-800 text-zinc-400 text-[10px] font-black uppercase rounded-lg hover:bg-zinc-700 transition-colors flex items-center gap-1 border border-zinc-700"
>
<ExternalLink size={10} /> {t('common.check')}
</a>
@@ -247,7 +247,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. 2010"
value={formData.distilled_at}
onChange={(e) => setFormData({ ...formData, distilled_at: e.target.value })}
className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 text-zinc-200"
/>
</div>
@@ -258,7 +258,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. 2022"
value={formData.bottled_at}
onChange={(e) => setFormData({ ...formData, bottled_at: e.target.value })}
className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 text-zinc-200"
/>
</div>
@@ -269,7 +269,7 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
placeholder="z.B. Batch 12 oder L-Code"
value={formData.batch_info}
onChange={(e) => setFormData({ ...formData, batch_info: e.target.value })}
className="w-full px-4 py-2 bg-zinc-50 dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50"
className="w-full px-4 py-2 bg-zinc-800 border border-zinc-700 rounded-xl outline-none focus:ring-2 focus:ring-orange-600/50 text-zinc-200"
/>
</div>
</div>