A real-time, mission-control-style dashboard that plots live natural disaster and earthquake data on an interactive world map. Built with React + Vite, powered by NASA and USGS public APIs — no API key required.
- NASA EONET v3 — wildfires, volcanic eruptions, severe storms, floods, sea ice, and 7 more categories. Auto-refreshes every 5 minutes.
- USGS Earthquake Feed — every earthquake from the last 24 hours, updated every minute. Auto-refreshes every 5 minutes.
- Full-screen interactive world map with CartoDB dark and light tiles
- Marker clustering — dense regions collapse into smart cluster bubbles (blue → amber → red by density)
- EONET events: animated emoji markers per category, colour-coded by type, spring bounce on appear
- USGS earthquakes: CircleMarkers scaled by magnitude, gold / orange / red by severity
- Hover tooltips on all markers
- Click map background to close sidebar
- Cinematic vignette shadow around map edges
Clicking any marker opens a premium glassmorphism panel that slides in from the right:
- Country flag via reverse geocoding (Nominatim, no key)
- Relative timestamp — "2 hours ago", "5 days ago"
- Live Conditions widget — fires two parallel API calls (Open-Meteo weather + air quality) the moment a marker is clicked:
- Temperature & feels-like (°C)
- Wind speed (km/h)
- Humidity (%)
- Precipitation (mm/hr)
- AQI badge colour-coded Good → Hazardous + PM2.5
- Animated skeleton loader while fetching; silently hidden on failure
USGS earthquake sidebar adds:
- Large magnitude badge styled by severity (Minor / Light / Moderate / Major
⚠️ ) - Depth in km
- PAGER alert level pill (green / yellow / orange / red)
- Pulsing blue tsunami warning banner when applicable
- Always-visible category pill bar — multi-select EONET categories with per-category event counts and glow highlights
- Open / Closed status toggle
- 🫨 Earthquakes toggle with live count badge, defaults ON
- Custom zoom controls + "fit to events" button
- Dark and light mode with OS preference detection and localStorage persistence
- Glassmorphism panels throughout (backdrop blur + translucent backgrounds)
- Gradient brand name in the header
- Animated pulsing "Live" badge
- Framer Motion spring animations — sidebar slide, legend stagger, pill entrance
- Fully responsive — works on mobile, tablet, and desktop
| Layer | Library |
|---|---|
| Framework | React 19 + Vite 8 |
| Map | Leaflet + React-Leaflet v5 |
| Clustering | react-leaflet-cluster |
| Animation | Framer Motion 12 |
| Styling | Tailwind CSS v4 (CSS Modules + @apply) |
| Tiles | CartoDB (dark & light) |
| API | Used for |
|---|---|
| NASA EONET v3 | Natural disaster events |
| USGS Earthquake GeoJSON | Real-time earthquake data |
| Open-Meteo | Current weather at event location |
| Open-Meteo Air Quality | AQI + PM2.5 at event location |
| Nominatim (OSM) | Reverse geocoding for country name |
| Flags API | Country flag images |
# Clone the repository
git clone https://github.com/iamsurajdev/eonet-map.git
cd eonet-map
# Install dependencies
npm install
# Start the dev server
npm run devOpen http://localhost:5173 in your browser.
# Build for production
npm run build
# Preview the production build
npm run previewsrc/
├── components/
│ ├── CategoryPills.jsx # Always-visible filter pill bar
│ ├── EventMarker.jsx # EONET divIcon markers
│ ├── Legend.jsx # Collapsible category legend
│ ├── LiveConditions.jsx # Weather + AQI widget
│ ├── LoadingScreen.jsx # Full-screen initial loader
│ ├── Map.jsx # MapContainer + layers
│ ├── MapControls.jsx # Zoom +/−/fit buttons
│ ├── Sidebar.jsx # Event detail panel (EONET + USGS)
│ ├── StatsBar.jsx # Per-category event counts
│ ├── ThemeToggle.jsx # Dark/light mode toggle
│ └── UsgsLayer.jsx # USGS CircleMarker layer
├── hooks/
│ ├── useCountry.js # Reverse geocoding hook
│ ├── useEvents.js # EONET data + 5-min refresh
│ ├── useLiveConditions.js # Parallel weather + AQI fetch
│ └── useUsgsEarthquakes.js # USGS data + 5-min refresh
├── utils/
│ ├── categories.js # EONET category colours + icons
│ └── timeAgo.js # Relative time formatter
├── App.jsx
└── index.css
EONET and USGS both return coordinates as [longitude, latitude, depth?]. All components flip them to [lat, lng] before passing to Leaflet.
Created with ♥ by Suraj Biswas