Wednesday, June 11, 2025

🔴🟠🟡🟢🔵🟣⚫🔴

Here's the complete, ready-to-deploy code for your public health dashboard with all tools integrated using free APIs: 1. Project Setup bash # Create project folder mkdir health-dashboard cd health-dashboard # Initialize Node.js project npm init -y # Install dependencies npm install express axios cors web-push body-parser dotenv npm install nodemon --save-dev # Create necessary files touch server.js .env .gitignore mkdir public cd public touch index.html styles.css app.js sw.js manifest.json 2. Backend (server.js) javascript require('dotenv').config(); const express = require('express'); const axios = require('axios'); const webpush = require('web-push'); const cors = require('cors'); const path = require('path'); const bodyParser = require('body-parser'); const app = express(); // Middleware app.use(cors()); app.use(bodyParser.json()); app.use(express.static('public')); // ====================== // API PROXY ENDPOINTS // ====================== // 1. COVID-19 Data (CDC) app.get('/api/covid/:state', async (req, res) => { try { const { state } = req.params; const url = `https://data.cdc.gov/resource/9mfq-cb36.json?state=${state}&$limit=7`; const response = await axios.get(url, { headers: { "X-App-Token": process.env.CDC_TOKEN || "" } }); // Process data const processed = response.data.map(item => ({ date: new Date(item.date).toLocaleDateString(), cases: item.new_cases, deaths: item.new_deaths })).reverse(); res.json(processed); } catch (error) { console.error("COVID API Error:", error.message); res.status(500).json({ error: "Failed to fetch COVID data" }); } }); // 2. Air Quality (AirNow) app.get('/api/air/:zip', async (req, res) => { try { const url = `https://www.airnowapi.org/aq/observation/zipCode/current/?format=application/json&zipCode=${req.params.zip}&distance=25&API_KEY=${process.env.AIRNOW_KEY}`; const response = await axios.get(url); if (response.data.length === 0) { return res.status(404).json({ error: "No air quality data for this location" }); } // Get primary pollutant const primary = response.data.find(item => item.parameter_name === "PM2.5") || response.data[0]; res.json({ aqi: primary.aqi, pollutant: primary.parameter_name, category: primary.category.name, reportingArea: primary.reporting_area }); } catch (error) { console.error("AirNow API Error:", error.message); res.status(500).json({ error: "Failed to fetch air quality data" }); } }); // 3. Flu Activity (CDC) app.get('/api/flu', async (req, res) => { try { const response = await axios.get( 'https://gis.cdc.gov/grasp/fluview/FluViewPhase2QuickData.json' ); // Process national data const nationalData = response.data .filter(item => item.region === "National") .sort((a, b) => new Date(b.weekend) - new Date(a.weekend)) .slice(0, 8); res.json(nationalData); } catch (error) { console.error("Flu API Error:", error.message); res.status(500).json({ error: "Failed to fetch flu data" }); } }); // 4. Location Services (Nominatim) app.get('/api/location', async (req, res) => { try { const { lat, lng } = req.query; const response = await axios.get( `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}` ); res.json({ state: response.data.address.state, zip: response.data.address.postcode, county: response.data.address.county }); } catch (error) { console.error("Geocoding Error:", error.message); res.status(500).json({ error: "Failed to determine location" }); } }); // ====================== // PUSH NOTIFICATIONS // ====================== const subscriptions = []; // Initialize web-push webpush.setVapidDetails( 'mailto:admin@healthdashboard.com', process.env.VAPID_PUBLIC_KEY, process.env.VAPID_PRIVATE_KEY ); // Store subscription app.post('/api/subscribe', (req, res) => { const subscription = req.body; subscriptions.push(subscription); res.status(201).json({}); }); // Send notification (admin endpoint) app.post('/api/notify', (req, res) => { const { title, message } = req.body; const payload = JSON.stringify({ title: title || "Health Alert", body: message || "New update available", icon: '/icon-192.png' }); // Send to all subscribers const sendPromises = subscriptions.map(sub => webpush.sendNotification(sub, payload) .catch(err => console.error("Push failed:", err)) ); Promise.all(sendPromises) .then(() => res.json({ success: true })) .catch(() => res.status(500).json({ error: "Some notifications failed" })); }); // Serve frontend app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'index.html')); }); // Start server const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); 3. Frontend (public/app.js) javascript // DOM Elements const covidChartEl = document.getElementById('covidChart'); const fluChartEl = document.getElementById('fluChart'); const aqiValueEl = document.getElementById('aqiValue'); const aqiStatusEl = document.getElementById('aqiStatus'); const locationBtn = document.getElementById('location-btn'); const notifyBtn = document.getElementById('notify-btn'); const stateSelect = document.getElementById('stateSelect'); const zipInput = document.getElementById('zipInput'); // Charts let covidChart, fluChart; // Initialize document.addEventListener('DOMContentLoaded', () => { loadDefaultData(); setupEventListeners(); checkNotificationSupport(); }); // ====================== // DATA LOADING // ====================== async function loadDefaultData() { // Default to California loadCovidData('CA'); loadAirQuality('90001'); loadFluData(); } async function loadCovidData(state) { try { const response = await fetch(`/api/covid/${state}`); const data = await response.json(); updateCovidChart(data); } catch (error) { console.error("Failed to load COVID data:", error); showError("Failed to load COVID-19 data"); } } async function loadAirQuality(zip) { try { const response = await fetch(`/api/air/${zip}`); const data = await response.json(); updateAirQualityDisplay(data); } catch (error) { console.error("Failed to load air quality:", error); showError("Failed to load air quality data"); } } async function loadFluData() { try { const response = await fetch('/api/flu'); const data = await response.json(); updateFluChart(data); } catch (error) { console.error("Failed to load flu data:", error); showError("Failed to load flu data"); } } // ====================== // VISUALIZATION // ====================== function updateCovidChart(data) { const labels = data.map(item => item.date); const cases = data.map(item => item.cases); if (covidChart) { covidChart.data.labels = labels; covidChart.data.datasets[0].data = cases; covidChart.update(); } else { covidChart = new Chart(covidChartEl, { type: 'line', data: { labels: labels, datasets: [{ label: 'New Cases', data: cases, borderColor: 'rgba(220, 53, 69, 1)', backgroundColor: 'rgba(220, 53, 69, 0.1)', tension: 0.3, fill: true }] }, options: { responsive: true, plugins: { title: { display: true, text: 'COVID-19 Cases (Last 7 Days)' } } } }); } } function updateFluChart(data) { const labels = data.map(item => `Week ${item.week}`); const activity = data.map(item => item.activity_level); if (fluChart) { fluChart.data.labels = labels; fluChart.data.datasets[0].data = activity; fluChart.update(); } else { fluChart = new Chart(fluChartEl, { type: 'bar', data: { labels: labels, datasets: [{ label: 'Activity Level', data: activity, backgroundColor: 'rgba(13, 110, 253, 0.7)' }] }, options: { responsive: true, plugins: { title: { display: true, text: 'Influenza Activity Level' } } } }); } } function updateAirQualityDisplay(data) { // AQI color scale const aqiColors = { "Good": "#28a745", "Moderate": "#ffc107", "Unhealthy for Sensitive Groups": "#fd7e14", "Unhealthy": "#dc3545", "Very Unhealthy": "#6f42c1", "Hazardous": "#6c757d" }; aqiValueEl.textContent = data.aqi; aqiStatusEl.textContent = `${data.category} (${data.pollutant})`; const bgColor = aqiColors[data.category] || "#6c757d"; aqiValueEl.parentElement.style.backgroundColor = bgColor; } // ====================== // LOCATION SERVICES // ====================== function setupEventListeners() { // Location button locationBtn.addEventListener('click', () => { getLocation() .then(location => { stateSelect.value = location.state; zipInput.value = location.zip; loadCovidData(location.state); loadAirQuality(location.zip); }) .catch(error => { console.error("Location error:", error); alert("Could not determine your location. Using default values."); }); }); // State/ZIP changes stateSelect.addEventListener('change', (e) => { loadCovidData(e.target.value); }); zipInput.addEventListener('change', (e) => { loadAirQuality(e.target.value); }); } function getLocation() { return new Promise((resolve, reject) => { if (!navigator.geolocation) { reject("Geolocation not supported"); return; } navigator.geolocation.getCurrentPosition( async position => { try { const { latitude, longitude } = position.coords; const response = await fetch(`/api/location?lat=${latitude}&lng=${longitude}`); const location = await response.json(); resolve({ state: location.state, zip: location.zip.split('-')[0], county: location.county }); } catch (error) { reject("Address lookup failed"); } }, error => { reject(error.message); }, { timeout: 10000 } ); }); } // ====================== // PUSH NOTIFICATIONS // ====================== function checkNotificationSupport() { if (!('serviceWorker' in navigator) || !('PushManager' in window)) { notifyBtn.style.display = 'none'; return; } notifyBtn.addEventListener('click', () => { requestNotificationPermission(); }); } async function requestNotificationPermission() { const permission = await Notification.requestPermission(); if (permission === 'granted') { registerServiceWorker(); } else { alert("Notifications blocked. You can enable them in browser settings."); } } async function registerServiceWorker() { try { const reg = await navigator.serviceWorker.register('/sw.js'); console.log("Service worker registered"); const sub = await reg.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(process.env.VAPID_PUBLIC_KEY) }); await fetch('/api/subscribe', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(sub) }); notifyBtn.textContent = "✓ Alerts Enabled"; notifyBtn.classList.remove('btn-outline-primary'); notifyBtn.classList.add('btn-success'); } catch (error) { console.error("Push registration failed:", error); alert("Failed to enable notifications"); } } function urlBase64ToUint8Array(base64String) { const padding = '='.repeat((4 - base64String.length % 4) % 4); const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/'); const rawData = window.atob(base64); return Uint8Array.from([...rawData].map(char => char.charCodeAt(0))); } // ====================== // UTILITIES // ====================== function showError(message) { const alertEl = document.createElement('div'); alertEl.className = 'alert alert-danger position-fixed top-0 end-0 m-3'; alertEl.textContent = message; document.body.appendChild(alertEl); setTimeout(() => { alertEl.remove(); }, 5000); } 4. Service Worker (public/sw.js) javascript const CACHE_NAME = 'health-dashboard-v1'; const urlsToCache = [ '/', '/index.html', '/styles.css', '/app.js', '/icon-192.png' ]; // Install service worker self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME) .then(cache => cache.addAll(urlsToCache)) ); }); // Cache-first strategy self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request) .then(response => response || fetch(event.request)) ); }); // Push notifications self.addEventListener('push', event => { const payload = event.data?.json() || { title: 'Health Alert', body: 'New update available' }; event.waitUntil( self.registration.showNotification(payload.title, { body: payload.body, icon: payload.icon || '/icon-192.png', vibrate: [200, 100, 200] }) ); }); // Notification click handler self.addEventListener('notificationclick', event => { event.notification.close(); event.waitUntil( clients.openWindow('/') ); }); 🔴🟠🟡🟢🔵🟣⚫🔴 5. Frontend HTML (public/index.html) html Public Health Dashboard

Public Health Dashboard

COVID-19 Tracker

Air Quality Index

--
Loading...

Influenza Activity

Data sources: CDC, AirNow | Updated:

🔴🟠🟡🟢🔵🟣⚫🔴 6. Styles (public/styles.css) css :root { --light-bg: #f8f9fa; --dark-bg: #212529; --light-text: #212529; --dark-text: #f8f9fa; } body { background-color: var(--light-bg); color: var(--light-text); transition: all 0.3s ease; } body.dark-mode { background-color: var(--dark-bg); color: var(--dark-text); } .card { transition: transform 0.2s ease, box-shadow 0.2s ease; border: none; } .card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0,0,0,0.1); } .chart-container { position: relative; height: 300px; width: 100%; } #aqiDisplay { background-color: #e9ecef; transition: background-color 0.5s ease; } /* Responsive adjustments */ @media (max-width: 768px) { .chart-container { height: 250px; } .display-2 { font-size: 3rem; } } 🔴🟠🟡🟢🔵🟣⚫🔴 7. Manifest (public/manifest.json) json { "name": "Public Health Dashboard", "short_name": "HealthDash", "start_url": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#0d6efd", "icons": [ { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" }, { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" } ] } 8. Environment Variables (.env) ini # Required for AirNow API AIRNOW_KEY=YOUR_AIRNOW_KEY # Optional for CDC API (higher limits) CDC_TOKEN=YOUR_CDC_TOKEN # Required for push notifications VAPID_PUBLIC_KEY=YOUR_PUBLIC_KEY VAPID_PRIVATE_KEY=YOUR_PRIVATE_KEY 9. Package.json (Add these scripts) json "scripts": { "start": "node server.js", "dev": "nodemon server.js", "test": "echo \"Error: no test specified\" && exit 1" } How to Run Get API keys: AirNow CDC (optional) Generate VAPID keys: npx web-push generate-vapid-keys Start the server: bash npm run dev Open in browser: text http://localhost:3000

No comments:

Post a Comment

Advanced Image Resizer Online 🟡🟢🔵🟣⚫🔴

Advanced Image Resizer Online Intro| Free Photo Size Reducer & Optimizer Tool ...