import { useQuery } from '@tanstack/react-query'; import { SKATE_SHOP_KIND, parseSkateShop, type SkateShop } from '@/lib/types'; import { useSkateRelays } from '@/hooks/useSkateRelays'; import { useAdminModeration, filterAdminHidden } from '@/hooks/useAdminModeration'; /** * Hook to fetch skate shops using the skate relay logic */ export function useSkateShops(limit: number = 100, options: { includeHidden?: boolean } = {}) { const { includeHidden = false } = options; const { querySkateContent, getQueryKeySuffix } = useSkateRelays(); const hidden = useAdminModeration(); return useQuery({ queryKey: ['skate-shops', limit, getQueryKeySuffix()], // `includeHidden` is for ADMIN TOOLING only (the review queue) so a hidden // item stays visible and its verdict can be undone. select: (shops: SkateShop[]) => includeHidden ? shops : filterAdminHidden(shops, SKATE_SHOP_KIND, hidden), queryFn: async () => { const signal = AbortSignal.timeout(10000); const events = await querySkateContent( [{ kinds: [SKATE_SHOP_KIND], '#t': ['skateshop'], limit }], { signal } ); // Parse events into SkateShop objects const shops: SkateShop[] = []; for (const event of events) { const shop = parseSkateShop(event); if (shop) shops.push(shop); } // Sort by created_at descending return shops.sort((a, b) => b.createdAt - a.createdAt); }, staleTime: 60000, // 1 minute }); } /** * Hook to fetch a single skate shop by pubkey and identifier */ export function useSkateShop(pubkey: string | undefined, identifier: string | undefined) { const { querySkateContent, getQueryKeySuffix } = useSkateRelays(); const hidden = useAdminModeration(); return useQuery({ queryKey: ['skate-shop', pubkey, identifier, getQueryKeySuffix()], select: (shop: SkateShop | null) => shop && hidden.has({ coord: `${SKATE_SHOP_KIND}:${shop.pubkey}:${shop.identifier}`, id: shop.id }) ? null : shop, queryFn: async () => { if (!pubkey || !identifier) return null; const signal = AbortSignal.timeout(10000); const events = await querySkateContent( [{ kinds: [SKATE_SHOP_KIND], authors: [pubkey], '#d': [identifier], limit: 1, }], { signal } ); if (events.length > 0) { return parseSkateShop(events[0]); } return null; }, enabled: !!pubkey && !!identifier, staleTime: 30000, }); }