const BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001'; async function apiFetch(path: string, options?: RequestInit): Promise { const res = await fetch(`${BASE_URL}${path}`, { ...options, headers: { 'Content-Type': 'application/json', ...(options?.headers ?? {}), }, next: { revalidate: 30 }, }); if (!res.ok) throw new Error(`API error ${res.status}: ${path}`); return res.json() as Promise; } export interface Stat { owlCount: number; burrowCount: number; volunteerHours: number; activeStreams: number; } export interface Stream { id: string; name: string; location: string; status: 'live' | 'offline'; viewerCount: number; thumbnailUrl?: string; hlsUrl?: string; description?: string; } export interface Wildlife { id: string; name: string; scientificName: string; status: string; description: string; habitat: string; imageUrl?: string; } export interface Campaign { id: string; title: string; description: string; goal: number; raised: number; imageUrl?: string; } export interface Event { id: string; title: string; date: string; location: string; description: string; rsvpCount: number; capacity?: number; } export interface Sighting { id: string; species: string; gps_lat: number; gps_lng: number; photo_url?: string; description: string; verified: boolean; created_at: string; reporter?: { id: string; name: string }; } export interface Burrow { id: string; lat: number; lng: number; name?: string; active: boolean; } export const api = { getStats: () => apiFetch('/api/stats'), getStreams: () => apiFetch('/api/streams'), getStream: (id: string) => apiFetch(`/api/streams/${id}`), getWildlife: () => apiFetch('/api/wildlife'), getCampaigns: () => apiFetch('/api/campaigns'), getEvents: () => apiFetch('/api/events'), rsvpEvent: (id: string, email: string) => apiFetch(`/api/events/${id}/rsvp`, { method: 'POST', body: JSON.stringify({ email }), }), getBurrows: () => apiFetch('/api/burrows'), getSightings: () => apiFetch('/api/sightings'), };