85 lines
2.6 KiB
TypeScript
85 lines
2.6 KiB
TypeScript
'use client';
|
|
import React, { useEffect, useState } from 'react';
|
|
import { MapContainer, TileLayer, Marker, Popup, CircleMarker } from 'react-leaflet';
|
|
import L from 'leaflet';
|
|
import 'leaflet/dist/leaflet.css';
|
|
|
|
interface Burrow {
|
|
id: string;
|
|
gps_lat: number;
|
|
gps_lng: number;
|
|
status: string;
|
|
location_description: string;
|
|
}
|
|
|
|
// Fix default marker icons in Next.js
|
|
const activeIcon = new L.DivIcon({
|
|
className: '',
|
|
html: '<div style="width:14px;height:14px;border-radius:50%;background:#0082a7;box-shadow:0 0 10px rgba(0,130,167,0.8);border:2px solid rgba(255,255,255,0.3)"></div>',
|
|
iconSize: [14, 14],
|
|
iconAnchor: [7, 7],
|
|
});
|
|
|
|
const inactiveIcon = new L.DivIcon({
|
|
className: '',
|
|
html: '<div style="width:12px;height:12px;border-radius:50%;background:#57534e;border:2px solid rgba(255,255,255,0.15)"></div>',
|
|
iconSize: [12, 12],
|
|
iconAnchor: [6, 6],
|
|
});
|
|
|
|
export default function BurrowMap() {
|
|
const [burrows, setBurrows] = useState<Burrow[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001';
|
|
fetch(`${apiUrl}/api/burrows`)
|
|
.then((r) => r.json())
|
|
.then((data) => { setBurrows(data); setLoading(false); })
|
|
.catch(() => setLoading(false));
|
|
}, []);
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="w-full h-full flex items-center justify-center text-stone-500">
|
|
<div className="animate-spin w-8 h-8 border-2 border-teal border-t-transparent rounded-full" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Cape Coral center
|
|
const center: [number, number] = [26.6029, -81.9595];
|
|
|
|
return (
|
|
<MapContainer
|
|
center={center}
|
|
zoom={13}
|
|
className="w-full h-full rounded-3xl"
|
|
style={{ background: '#0a1a15' }}
|
|
attributionControl={false}
|
|
>
|
|
<TileLayer
|
|
url="https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png"
|
|
attribution='© <a href="https://carto.com/">CARTO</a>'
|
|
/>
|
|
{burrows.map((b) => (
|
|
<Marker
|
|
key={b.id}
|
|
position={[b.gps_lat, b.gps_lng]}
|
|
icon={b.status === 'active' ? activeIcon : inactiveIcon}
|
|
>
|
|
<Popup>
|
|
<div className="text-sm space-y-1" style={{ color: '#1a1a1a' }}>
|
|
<div className="font-bold">{b.status === 'active' ? '🟢 Active' : '⚫ Inactive'} Burrow</div>
|
|
<div>{b.location_description}</div>
|
|
<div className="text-xs text-gray-500">
|
|
{b.gps_lat.toFixed(4)}, {b.gps_lng.toFixed(4)}
|
|
</div>
|
|
</div>
|
|
</Popup>
|
|
</Marker>
|
|
))}
|
|
</MapContainer>
|
|
);
|
|
}
|