feat: implement automated Whiskybase ID discovery
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { Edit2, Save, X, Info, Tag, FlaskConical, CircleDollarSign } from 'lucide-react';
|
||||
import { Edit2, Save, X, Info, Tag, FlaskConical, CircleDollarSign, Search, Loader2, ExternalLink } from 'lucide-react';
|
||||
import { updateBottle } from '@/services/update-bottle';
|
||||
import { discoverWhiskybaseId } from '@/services/discover-whiskybase';
|
||||
|
||||
interface EditBottleFormProps {
|
||||
bottle: {
|
||||
@@ -21,7 +22,9 @@ interface EditBottleFormProps {
|
||||
export default function EditBottleForm({ bottle, onComplete }: EditBottleFormProps) {
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [isSearching, setIsSearching] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [discoveryResult, setDiscoveryResult] = useState<{ id: string; url: string; title: string } | null>(null);
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
name: bottle.name,
|
||||
@@ -33,6 +36,33 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
|
||||
purchase_price: bottle.purchase_price || '',
|
||||
});
|
||||
|
||||
const handleDiscover = async () => {
|
||||
setIsSearching(true);
|
||||
setError(null);
|
||||
setDiscoveryResult(null);
|
||||
|
||||
const result = await discoverWhiskybaseId({
|
||||
name: formData.name,
|
||||
distillery: formData.distillery,
|
||||
abv: formData.abv,
|
||||
age: formData.age
|
||||
});
|
||||
|
||||
if (result.success && result.id) {
|
||||
setDiscoveryResult({ id: result.id!, url: result.url!, title: result.title! });
|
||||
} else {
|
||||
setError(result.error || 'Keinen Treffer gefunden.');
|
||||
}
|
||||
setIsSearching(false);
|
||||
};
|
||||
|
||||
const applyDiscovery = () => {
|
||||
if (discoveryResult) {
|
||||
setFormData({ ...formData, whiskybase_id: discoveryResult.id });
|
||||
setDiscoveryResult(null);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
setIsSaving(true);
|
||||
setError(null);
|
||||
@@ -142,13 +172,47 @@ export default function EditBottleForm({ bottle, onComplete }: EditBottleFormPro
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<label className="text-[10px] font-black uppercase text-zinc-400 ml-1">Whiskybase ID</label>
|
||||
<label className="text-[10px] font-black uppercase text-zinc-400 ml-1 flex justify-between items-center">
|
||||
<span>Whiskybase ID</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleDiscover}
|
||||
disabled={isSearching}
|
||||
className="text-amber-600 hover:text-amber-700 flex items-center gap-1 normal-case font-bold"
|
||||
>
|
||||
{isSearching ? <Loader2 size={10} className="animate-spin" /> : <Search size={10} />}
|
||||
Automatisch suchen
|
||||
</button>
|
||||
</label>
|
||||
<input
|
||||
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-amber-500"
|
||||
/>
|
||||
{discoveryResult && (
|
||||
<div className="mt-2 p-3 bg-zinc-50 dark:bg-zinc-800/50 border border-amber-500/20 rounded-xl animate-in fade-in slide-in-from-top-2">
|
||||
<p className="text-[10px] text-zinc-500 mb-2">Treffer gefunden:</p>
|
||||
<p className="text-[11px] font-bold text-zinc-800 dark:text-zinc-200 mb-2 truncate">{discoveryResult.title}</p>
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={applyDiscovery}
|
||||
className="px-3 py-1.5 bg-amber-600 text-white text-[10px] font-black uppercase rounded-lg hover:bg-amber-700 transition-colors"
|
||||
>
|
||||
ID Übernehmen
|
||||
</button>
|
||||
<a
|
||||
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"
|
||||
>
|
||||
<ExternalLink size={10} /> Prüfen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<label className="text-[10px] font-black uppercase text-amber-600 ml-1 flex items-center gap-1">
|
||||
|
||||
Reference in New Issue
Block a user