'use client'; import React, { useState, useMemo } from 'react'; import Link from 'next/link'; import { Search, Filter, X, Calendar, Clock, Package, FlaskConical, AlertCircle, Trash2, AlertTriangle, PlusCircle } from 'lucide-react'; import { getStorageUrl } from '@/lib/supabase'; import { useSearchParams } from 'next/navigation'; import { validateSession } from '@/services/validate-session'; import { useI18n } from '@/i18n/I18nContext'; import { useSession } from '@/context/SessionContext'; import { shortenCategory } from '@/lib/format'; interface Bottle { id: string; name: string; distillery: string; category: string; abv: number; age: number; image_url: string; purchase_price?: number | null; created_at: string; last_tasted?: string | null; is_whisky?: boolean; confidence?: number; } interface BottleCardProps { bottle: Bottle; sessionId?: string | null; } function BottleCard({ bottle, sessionId }: BottleCardProps) { const { t, locale } = useI18n(); return ( {/* Image Layer - Clean Split Top */}
{bottle.name}
{/* Info Layer - Clean Split Bottom */}

{bottle.distillery}

{bottle.name || t('grid.unknownBottle')}

{shortenCategory(bottle.category)} {bottle.abv}% VOL
{/* Metadata items */}
{new Date(bottle.created_at).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
{bottle.last_tasted && (
{new Date(bottle.last_tasted).toLocaleDateString(locale === 'de' ? 'de-DE' : 'en-US')}
)}
{/* Top Overlays */} {(bottle.is_whisky === false || (bottle.confidence && bottle.confidence < 70)) && (
)} {sessionId && (
ADD
)} ); } interface BottleGridProps { bottles: any[]; } export default function BottleGrid({ bottles }: BottleGridProps) { const { t } = useI18n(); const { activeSession } = useSession(); const searchParams = useSearchParams(); const sessionIdFromUrl = searchParams.get('session_id'); const effectiveSessionId = activeSession?.id || sessionIdFromUrl; const [validatedSessionId, setValidatedSessionId] = useState(null); React.useEffect(() => { const checkSession = async () => { if (effectiveSessionId) { const isValid = await validateSession(effectiveSessionId); setValidatedSessionId(isValid ? effectiveSessionId : null); } else { setValidatedSessionId(null); } }; checkSession(); }, [effectiveSessionId]); const [searchQuery, setSearchQuery] = useState(''); const [selectedCategory, setSelectedCategory] = useState(null); const [selectedDistillery, setSelectedDistillery] = useState(null); const [sortBy, setSortBy] = useState<'name' | 'last_tasted' | 'created_at'>('created_at'); const categories = useMemo(() => { const cats = new Set(bottles.map(b => b.category).filter(Boolean)); return Array.from(cats).sort() as string[]; }, [bottles]); const distilleries = useMemo(() => { const dists = new Set(bottles.map(b => b.distillery).filter(Boolean)); return Array.from(dists).sort() as string[]; }, [bottles]); const filteredBottles = useMemo(() => { const result = bottles.filter((bottle) => { const searchLower = searchQuery.toLowerCase(); const tastingNotesMatch = bottle.tastings?.some((t: any) => (t.nose_notes?.toLowerCase().includes(searchLower)) || (t.palate_notes?.toLowerCase().includes(searchLower)) || (t.finish_notes?.toLowerCase().includes(searchLower)) ); const matchesSearch = bottle.name.toLowerCase().includes(searchLower) || bottle.distillery?.toLowerCase().includes(searchLower) || bottle.category?.toLowerCase().includes(searchLower) || tastingNotesMatch; const matchesCategory = !selectedCategory || bottle.category === selectedCategory; const matchesDistillery = !selectedDistillery || bottle.distillery === selectedDistillery; return matchesSearch && matchesCategory && matchesDistillery; }); // Sorting logic return result.sort((a, b) => { if (sortBy === 'name') { return (a.name || '').localeCompare(b.name || ''); } else if (sortBy === 'last_tasted') { const dateA = a.last_tasted ? new Date(a.last_tasted).getTime() : 0; const dateB = b.last_tasted ? new Date(b.last_tasted).getTime() : 0; return dateB - dateA; } else { // sortBy === 'created_at' return new Date(b.created_at).getTime() - new Date(a.created_at).getTime(); } }); }, [bottles, searchQuery, selectedCategory, selectedDistillery, sortBy]); const [isFiltersOpen, setIsFiltersOpen] = useState(false); if (!bottles || bottles.length === 0) { return (

{t('home.noBottles')}

); } const activeFiltersCount = (selectedCategory ? 1 : 0) + (selectedDistillery ? 1 : 0); return (
{/* Search and Filters - Minimalist Look */}
setSearchQuery(e.target.value)} className="w-full pl-8 pr-8 py-4 bg-transparent border-b border-zinc-800 focus:border-orange-500 outline-none transition-all text-zinc-50 placeholder:text-zinc-500" /> {searchQuery && ( )}
{/* Category Quick Filter - Flat Chips */}
{categories.map((cat) => ( ))}
{/* Collapsible Advanced Filters - Industrial Overlay */} {isFiltersOpen && (
{distilleries.map((dist) => ( ))}
)}
{/* Grid */} {filteredBottles.length > 0 ? (
{filteredBottles.map((bottle) => ( ))}
) : (

{t('grid.noResults')}

)}
); }