// data.jsx — fetcher hooks against Supabase. Each returns { data, loading, error, refresh }. // Loaded after auth.jsx, before pages.jsx. const { useState: useStateD, useEffect: useEffectD, useCallback: useCallbackD } = React; function useQuery(buildQuery, deps) { const [data, setData] = useStateD(null); const [loading, setLoading] = useStateD(true); const [error, setError] = useStateD(null); const run = useCallbackD(async () => { setLoading(true); setError(null); try { const q = buildQuery(); if (!q) { setData(null); setLoading(false); return; } const { data: rows, error: err } = await q; if (err) throw err; setData(rows); } catch (e) { setError(e); } finally { setLoading(false); } // eslint-disable-next-line react-hooks/exhaustive-deps }, deps || []); useEffectD(() => { run(); }, [run]); return { data, loading, error, refresh: run }; } window.useQuery = useQuery; /* ───────────────────────────────────────────────────────────── Public-read hooks ──────────────────────────────────────────────────────────── */ function usePromos() { return useQuery(() => window.sb.from("promos") .select("*") .eq("active", true) .order("sort_order"), []); } window.usePromos = usePromos; function useProducts() { return useQuery(() => window.sb.from("products") .select("*") .eq("active", true) .order("sort_order"), []); } window.useProducts = useProducts; function useHotGames() { return useQuery(() => window.sb.from("games") .select("*") .eq("active", true) .order("sort_order"), []); } window.useHotGames = useHotGames; function useProviders(category) { return useQuery(() => { let q = window.sb.from("providers").select("*").eq("active", true).order("sort_order"); if (category) q = q.eq("category", category); return q; }, [category]); } window.useProviders = useProviders; function useHeroSlides() { return useQuery(() => window.sb.from("hero_slides") .select("*") .eq("active", true) .order("sort_order"), []); } window.useHeroSlides = useHeroSlides; function useMarqueeItems() { return useQuery(() => window.sb.from("marquee_items") .select("*") .eq("active", true) .order("sort_order"), []); } window.useMarqueeItems = useMarqueeItems; function useFeatureCards() { return useQuery(() => window.sb.from("feature_cards") .select("*") .eq("active", true) .order("sort_order"), []); } window.useFeatureCards = useFeatureCards; function useSiteSetting(key) { return useQuery(() => key ? window.sb.from("site_settings") .select("value") .eq("id", key) .maybeSingle() : null, [key]); } window.useSiteSetting = useSiteSetting; /* ───────────────────────────────────────────────────────────── Auth-scoped hooks ──────────────────────────────────────────────────────────── */ function useProfile() { const { session } = window.useSession(); return useQuery(() => session ? window.sb.from("profiles") .select("*") .eq("id", session.user.id) .maybeSingle() : null, [session?.user?.id]); } window.useProfile = useProfile; function useTransactions() { const { session } = window.useSession(); return useQuery(() => session ? window.sb.from("transactions") .select("*") .eq("user_id", session.user.id) .order("created_at", { ascending: false }) : null, [session?.user?.id]); } window.useTransactions = useTransactions; function useBets() { const { session } = window.useSession(); return useQuery(() => session ? window.sb.from("bets") .select("*") .eq("user_id", session.user.id) .order("played_at", { ascending: false }) : null, [session?.user?.id]); } window.useBets = useBets;