import { useQuery } from '@tanstack/react-query' import type { WidgetConfig } from '../../hooks' import { weatherApi } from '../../api' import './widget-styles.css' interface AirQualityWidgetProps { config: WidgetConfig } export default function AirQualityWidget({ config }: AirQualityWidgetProps) { // Get city from config or use default (Pulse.eco city) const city = (config.visualization as Record)?.city as string || 'skopje' const { data: airQuality, isLoading, error } = useQuery({ queryKey: ['air-quality', city], queryFn: async () => { const response = await weatherApi.getAirQuality(city) return response.data }, refetchInterval: 300000, // Refresh every 5 minutes staleTime: 240000, // Consider fresh for 4 minutes }) if (isLoading) { return (
) } if (error) { return (

{config.title}

Failed to load air quality data for {city}

Try: skopje, bitola, tetovo

) } if (!airQuality) return null // Get AQI color based on status const getStatusColor = (status: string) => { switch (status.toLowerCase()) { case 'good': return 'success' case 'moderate': return 'warning' case 'unhealthy for sensitive groups': case 'unhealthy': return 'error' case 'very unhealthy': case 'hazardous': return 'error' default: return 'base-content/40' } } const statusColor = getStatusColor(airQuality.status) const pm10 = airQuality.measurements.pm10 const pm25 = airQuality.measurements.pm25 return (

{config.title}

{/* Air quality icon */} {/* PM Values */}
{pm10 && (
{pm10.average.toFixed(1)}
PM10 μg/m³
)} {pm25 && (
{pm25.average.toFixed(1)}
PM2.5 μg/m³
)}
{/* AQI Status badge */}
{airQuality.status}
{/* Additional pollutants */}
{Object.entries(airQuality.measurements).map(([pollutant, data]) => { if (pollutant === 'pm10' || pollutant === 'pm25') return null return (
{pollutant.toUpperCase()}: {data.average.toFixed(1)}
) })}
{/* City and sensor count */}
{airQuality.city.charAt(0).toUpperCase() + airQuality.city.slice(1)} • {airQuality.sensor_count} sensors
) }