'use client'; import { useState, useEffect, useCallback } from 'react'; import { createClient } from '@/lib/supabase/client'; import { db, type CachedBottle, type CachedTasting } from '@/lib/db'; import { useLiveQuery } from 'dexie-react-hooks'; export function useBottleData(bottleId: string) { const supabase = createClient(); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // Live queries from Dexie const cachedBottle = useLiveQuery(() => db.cache_bottles.get(bottleId), [bottleId]); const cachedTastings = useLiveQuery(() => db.cache_tastings.where('bottle_id').equals(bottleId).sortBy('created_at'), [bottleId] ); const refreshData = useCallback(async () => { if (!navigator.onLine) { setLoading(false); return; } try { // 1. Fetch Bottle const { data: bottle, error: bottleError } = await supabase .from('bottles') .select('*') .eq('id', bottleId) .single(); if (bottleError) throw bottleError; // 2. Fetch Tastings const { data: tastings, error: tastingsError } = await supabase .from('tastings') .select(` *, tasting_sessions (id, name), tasting_tags ( tags (id, name, category) ) `) .eq('bottle_id', bottleId) .order('created_at', { ascending: false }); if (tastingsError) throw tastingsError; // 3. Update Dexie Cache await db.cache_bottles.put({ ...bottle, last_updated: Date.now() }); // Clear old cache for this bottle and put new await db.cache_tastings.where('bottle_id').equals(bottleId).delete(); if (tastings && tastings.length > 0) { await db.cache_tastings.bulkAdd(tastings as any); } } catch (err: any) { console.error('Error refreshing bottle data:', err); setError(err.message); } finally { setLoading(false); } }, [bottleId, supabase]); useEffect(() => { refreshData(); }, [refreshData]); return { bottle: cachedBottle, tastings: cachedTastings ? [...cachedTastings].reverse() : [], // Dexie sorted asc, we want desc loading: loading && !cachedBottle, // Only show loading if we have nothing at all error, refresh: refreshData, isOffline: !navigator.onLine }; }