'use client'; import dynamic from 'next/dynamic'; import { useState, useEffect } from 'react'; import LibraryList from './components/LibraryList'; // Dynamically import the map component to avoid SSR issues const MapComponent = dynamic(() => import('./components/MapComponent'), { ssr: false, loading: () =>
Loading map...
}); interface LocationData { name: string; lat: number; lng: number; available: boolean; passType: string; } interface ApiResponse { locations: LocationData[]; lastUpdated: string; } export default function Home() { const [locations, setLocations] = useState([]); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [error, setError] = useState(null); const [lastUpdated, setLastUpdated] = useState(''); // Start with menu collapsed only on mobile const [panelCollapsed, setPanelCollapsed] = useState(false); useEffect(() => { // Collapse menu on mobile only if (typeof window !== 'undefined') { const isMobile = /Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(window.navigator.userAgent); if (isMobile) setPanelCollapsed(true); } // Trigger data refresh on page load fetchAvailability(); }, []); const fetchAvailability = async (isRefresh = false) => { try { if (isRefresh) { setRefreshing(true); } else { setLoading(true); } setError(null); // Add cache-busting parameter to ensure fresh data const timestamp = new Date().getTime(); const response = await fetch(`/api/availability?t=${timestamp}`, { cache: 'no-cache', headers: { 'Cache-Control': 'no-cache', }, }); if (!response.ok) { throw new Error('Failed to fetch data'); } const data: ApiResponse = await response.json(); setLocations(data.locations); setLastUpdated(data.lastUpdated); setError(null); } catch (err) { setError(err instanceof Error ? err.message : 'Unknown error'); } finally { if (isRefresh) { setRefreshing(false); } else { setLoading(false); } } }; const availableCount = locations.filter(loc => loc.available).length; const totalCount = locations.length; return (

SD Beach Park Pass Locator

{!panelCollapsed && ( <> {loading &&

Loading availability data...

} {error &&

Error: {error}

} {!loading && !error && ( <>

{availableCount} of {totalCount} locations have available passes

Legend:

Available
Not Available
{lastUpdated && (

Last updated: {new Date(lastUpdated).toLocaleString()}

)} )} )}
{!loading && !error && }
); }