'use client'; import React, { useState, useEffect } from 'react'; import { motion } from 'framer-motion'; import { ChevronDown, Wind, Utensils, Droplets, Sparkles, Send, Users, Star, AlertTriangle, Check, Zap } from 'lucide-react'; import { BottleMetadata } from '@/types/whisky'; import TagSelector from './TagSelector'; import { useLiveQuery } from 'dexie-react-hooks'; import { db } from '@/lib/db'; import { createClient } from '@/lib/supabase/client'; import { useI18n } from '@/i18n/I18nContext'; interface TastingEditorProps { bottleMetadata: BottleMetadata; image: string | null; onSave: (data: any) => void; onOpenSessions: () => void; activeSessionName?: string; activeSessionId?: string; } export default function TastingEditor({ bottleMetadata, image, onSave, onOpenSessions, activeSessionName, activeSessionId }: TastingEditorProps) { const { t } = useI18n(); const supabase = createClient(); const [rating, setRating] = useState(85); const [noseNotes, setNoseNotes] = useState(''); const [palateNotes, setPalateNotes] = useState(''); const [finishNotes, setFinishNotes] = useState(''); const [isSample, setIsSample] = useState(false); // Sliders for evaluation const [noseScore, setNoseScore] = useState(50); const [tasteScore, setTasteScore] = useState(50); const [finishScore, setFinishScore] = useState(50); const [complexityScore, setComplexityScore] = useState(75); const [balanceScore, setBalanceScore] = useState(85); const [noseTagIds, setNoseTagIds] = useState([]); const [palateTagIds, setPalateTagIds] = useState([]); const [finishTagIds, setFinishTagIds] = useState([]); const [textureTagIds, setTextureTagIds] = useState([]); const [selectedBuddyIds, setSelectedBuddyIds] = useState([]); const buddies = useLiveQuery(() => db.cache_buddies.toArray(), [], [] as any[]); const [lastDramInSession, setLastDramInSession] = useState<{ name: string; isSmoky: boolean; timestamp: number } | null>(null); const [showPaletteWarning, setShowPaletteWarning] = useState(false); const suggestedTags = bottleMetadata.suggested_tags || []; const suggestedCustomTags = bottleMetadata.suggested_custom_tags || []; // Session-based pre-fill and Palette Checker useEffect(() => { const fetchSessionData = async () => { if (activeSessionId) { const { data: participants } = await supabase .from('session_participants') .select('buddy_id') .eq('session_id', activeSessionId); if (participants) { setSelectedBuddyIds(participants.map(p => p.buddy_id)); } const { data: lastTastings } = await supabase .from('tastings') .select(` id, tasted_at, bottles(name, category), tasting_tags(tags(name)) `) .eq('session_id', activeSessionId) .order('tasted_at', { ascending: false }) .limit(1); if (lastTastings && lastTastings.length > 0) { const last = lastTastings[0]; const tags = (last as any).tasting_tags?.map((t: any) => t.tags.name) || []; const category = (last as any).bottles?.category || ''; const text = (tags.join(' ') + ' ' + category).toLowerCase(); const smokyKeywords = ['rauch', 'torf', 'smoke', 'peat', 'islay', 'ash', 'lagerfeuer']; const isSmoky = smokyKeywords.some(kw => text.includes(kw)); setLastDramInSession({ name: (last as any).bottles?.name || 'Unbekannt', isSmoky, timestamp: new Date(last.tasted_at).getTime() }); } } }; fetchSessionData(); }, [activeSessionId, supabase]); useEffect(() => { if (lastDramInSession?.isSmoky) { const now = Date.now(); const diffMin = (now - lastDramInSession.timestamp) / (1000 * 60); if (diffMin < 20) setShowPaletteWarning(true); } }, [lastDramInSession]); const toggleBuddy = (id: string) => { setSelectedBuddyIds(prev => prev.includes(id) ? prev.filter(bid => bid !== id) : [...prev, id]); }; const handleInternalSave = () => { onSave({ rating, nose_notes: noseNotes, palate_notes: palateNotes, finish_notes: finishNotes, is_sample: isSample, buddy_ids: selectedBuddyIds, tag_ids: [...noseTagIds, ...palateTagIds, ...finishTagIds, ...textureTagIds], // Visual data for ResultCard nose: noseScore, taste: tasteScore, finish: finishScore, complexity: complexityScore, balance: balanceScore }); }; return (
{/* Top Context Bar - Flex Child 1 */} {/* Main Scrollable Content - Flex Child 2 */}
{/* Palette Warning */} {showPaletteWarning && (

Palette-Checker

Dein letzter Dram "{lastDramInSession?.name}" war torfig. Trink etwas Wasser!

)} {/* Hero Section */}
{image ? ( Bottle Preview ) : (
No Photo
)}

{bottleMetadata.distillery || 'Destillerie'}

{bottleMetadata.name || 'Unbekannter Malt'}

{bottleMetadata.category || 'Whisky'} {bottleMetadata.abv ? `• ${bottleMetadata.abv}%` : ''} {bottleMetadata.age ? `• ${bottleMetadata.age}y` : ''}

{/* Rating Slider */}
{rating}/100
setRating(parseInt(e.target.value))} className="w-full h-2 bg-zinc-800 rounded-full appearance-none cursor-pointer accent-amber-600 transition-all" />
Swill Dram Legendary
{['Bottle', 'Sample'].map(type => ( ))}
{/* Evaluation Sliders Area */}
} /> } />
{/* Sections */}
{/* Nose Section */}

{t('tasting.nose')}

Aroma & Bouquet

} />

Tags

setNoseTagIds(prev => prev.includes(id) ? prev.filter(i => i !== id) : [...prev, id])} suggestedTagNames={suggestedTags} suggestedCustomTagNames={suggestedCustomTags} />

Eigene Notizen