import { useQuery } from '@tanstack/react-query'; import { CALENDAR_EVENT_KIND, parseSkateEvent, type SkateEvent } from '@/lib/types'; import { useSkateRelays } from '@/hooks/useSkateRelays'; export function useSkateEvents(limit = 50) { const { querySkateContent, getQueryKeySuffix } = useSkateRelays(); return useQuery({ queryKey: ['skate-events', limit, getQueryKeySuffix()], queryFn: async () => { const signal = AbortSignal.timeout(15000); const events = await querySkateContent( [ { kinds: [CALENDAR_EVENT_KIND], '#t': ['skateboarding'], limit, }, ], { signal } ); const skateEvents: SkateEvent[] = []; for (const event of events) { const skateEvent = parseSkateEvent(event); if (skateEvent) skateEvents.push(skateEvent); } // Sort by start time return skateEvents.sort((a, b) => a.start - b.start); }, staleTime: 60000, }); } export function useUpcomingSkateEvents(limit = 20) { const { querySkateContent, getQueryKeySuffix } = useSkateRelays(); const now = Math.floor(Date.now() / 1000); return useQuery({ queryKey: ['upcoming-skate-events', limit, getQueryKeySuffix()], queryFn: async () => { const signal = AbortSignal.timeout(15000); const events = await querySkateContent( [ { kinds: [CALENDAR_EVENT_KIND], '#t': ['skateboarding'], limit: limit * 2, // Fetch more to filter }, ], { signal } ); const skateEvents: SkateEvent[] = []; for (const event of events) { const skateEvent = parseSkateEvent(event); // Only include future events if (skateEvent && skateEvent.start >= now) { skateEvents.push(skateEvent); } } // Sort by start time ascending (soonest first) return skateEvents.sort((a, b) => a.start - b.start).slice(0, limit); }, staleTime: 60000, }); } export function useSkateEvent(identifier: string, pubkey?: string) { const { querySkateContent, getQueryKeySuffix } = useSkateRelays(); return useQuery({ queryKey: ['skate-event', identifier, pubkey, getQueryKeySuffix()], queryFn: async () => { const signal = AbortSignal.timeout(10000); const filter: { kinds: number[]; '#d': string[]; authors?: string[]; limit: number; } = { kinds: [CALENDAR_EVENT_KIND], '#d': [identifier], limit: 1, }; if (pubkey) { filter.authors = [pubkey]; } const events = await querySkateContent([filter], { signal }); if (events.length === 0) return null; return parseSkateEvent(events[0]); }, enabled: !!identifier, staleTime: 60000, }); }