'use client'; import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet'; import L from 'leaflet'; import Link from 'next/link'; import { SensorWithLatestReading } from '@/lib/types'; import { useEffect, useState } from 'react'; // Fix for default marker icon in Next.js delete (L.Icon.Default.prototype as any)._getIconUrl; L.Icon.Default.mergeOptions({ iconRetinaUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon-2x.png', iconUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-icon.png', shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/images/marker-shadow.png', }); // Custom marker icon based on water quality function getMarkerIcon(reading: any) { const color = reading ? '#10b981' : '#6b7280'; // Green if has data, gray otherwise return L.divIcon({ className: 'custom-marker', html: `
`, iconSize: [24, 24], iconAnchor: [12, 12], }); } // Component to handle map events function MapEvents({ selectedSensor }: { selectedSensor: SensorWithLatestReading | null }) { const map = useMap(); useEffect(() => { if (selectedSensor) { map.flyTo([selectedSensor.latitude, selectedSensor.longitude], 10, { duration: 1.5 }); } }, [selectedSensor, map]); return null; } interface MapViewProps { sensors: SensorWithLatestReading[]; selectedSensor: SensorWithLatestReading | null; onSelectSensor: (sensor: SensorWithLatestReading | null) => void; } export default function MapView({ sensors, selectedSensor, onSelectSensor }: MapViewProps) { const [isClient, setIsClient] = useState(false); useEffect(() => { setIsClient(true); }, []); if (!isClient) { return (

Loading map...

); } return ( <> {sensors.map((sensor) => ( onSelectSensor(sensor), }} >

{sensor.locationName || sensor.sensorId}

{sensor.latestReading ? (
pH: {sensor.latestReading.ph.toFixed(2)}
Turbidity: {sensor.latestReading.turbidity.toFixed(2)} NTU
Temperature: {sensor.latestReading.temperature.toFixed(1)}°C
Hardness: {sensor.latestReading.hardness.toFixed(1)} mg/L
Last updated: {new Date(sensor.latestReading.timestamp).toLocaleString()}
) : (

No data available

)} Open Full Dashboard
))}
{/* Dashboard Panel */} {selectedSensor && (

{selectedSensor.locationName || selectedSensor.sensorId}

View full dashboard
)} ); } // Import dashboard component import SensorDashboard from './SensorDashboard';