import { useEffect, useMemo } from 'react';
import { MapContainer, TileLayer, Marker, Popup, Polyline, useMap } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import type { BusRoute } from '@/types';
// Standard Leaflet Icon fix for Vite
import markerIcon2x from 'leaflet/dist/images/marker-icon-2x.png';
import markerIcon from 'leaflet/dist/images/marker-icon.png';
import markerShadow from 'leaflet/dist/images/marker-shadow.png';
delete (L.Icon.Default.prototype as any)._getIconUrl;
L.Icon.Default.mergeOptions({
iconUrl: markerIcon,
iconRetinaUrl: markerIcon2x,
shadowUrl: markerShadow,
});
// Custom Premium DivIcons using Tailwind CSS
const startIcon = L.divIcon({
html: `
A
`,
className: '',
iconSize: [24, 24],
iconAnchor: [12, 12],
});
const stopIcon = L.divIcon({
html: ``,
className: '',
iconSize: [14, 14],
iconAnchor: [7, 7],
});
const campusIcon = L.divIcon({
html: `🏫
`,
className: '',
iconSize: [36, 36],
iconAnchor: [18, 18],
});
// Helper component to auto-pan and fit the map bounds to the active route
function MapUpdater({ bounds }: { bounds: L.LatLngBoundsExpression | null }) {
const map = useMap();
useEffect(() => {
if (bounds && (bounds as any).length > 0) {
map.fitBounds(bounds, { padding: [50, 50], maxZoom: 14, animate: true });
}
}, [bounds, map]);
return null;
}
interface BusRouteMapProps {
selectedRoute: BusRoute | null;
allRoutes: BusRoute[];
}
const DEFAULT_CENTER = [13.0118, 80.0214]; // RIT Campus default
export default function BusRouteMap({ selectedRoute, allRoutes }: BusRouteMapProps) {
// Collect coordinates for the polyline path
const pathCoordinates = useMemo(() => {
if (!selectedRoute) return [];
const coords: [number, number][] = [];
// Add start stop coords if present
if (selectedRoute.from_lat && selectedRoute.from_lng) {
coords.push([selectedRoute.from_lat, selectedRoute.from_lng]);
}
// Add all intermediary stop coords
selectedRoute.stops.forEach(stop => {
if (stop.lat && stop.lng) {
coords.push([stop.lat, stop.lng]);
}
});
// Add end stop coords if present
if (selectedRoute.to_lat && selectedRoute.to_lng) {
coords.push([selectedRoute.to_lat, selectedRoute.to_lng]);
}
return coords;
}, [selectedRoute]);
// Determine map bounds
const mapBounds = useMemo(() => {
if (pathCoordinates.length === 0) return null;
return pathCoordinates as L.LatLngBoundsExpression;
}, [pathCoordinates]);
// Determine which routes to display (either the selected one, or all route start pins as overview)
const renderMarkers = () => {
if (selectedRoute) {
return (
<>
{selectedRoute.stops.map((stop, index) => {
const isStart = index === 0;
const isEnd = index === selectedRoute.stops.length - 1;
const isRit = stop.name.toLowerCase().includes("rit");
let currentIcon = stopIcon;
if (isStart) currentIcon = startIcon;
if (isRit || isEnd) currentIcon = campusIcon;
if (!stop.lat || !stop.lng) return null;
return (
{stop.name}
Estimated: {stop.time}
{isStart &&
Departure Stop}
{isRit &&
RIT Campus}
);
})}
>
);
}
// Default view: Draw RIT Campus pin + Start pins for all routes
return (
<>
Rajalakshmi Institute of Technology
Kuthambakkam, Chennai
{allRoutes.map((r, i) => {
if (!r.from_lat || !r.from_lng) return null;
return (
{r.number}
{r.name}
Starts: {r.from} at {r.departureTime}
);
})}
>
);
};
return (
{renderMarkers()}
{selectedRoute && pathCoordinates.length > 1 && (
)}
{/* Floating Info Overlay on Selected Route */}
{selectedRoute && (
{selectedRoute.number}
{selectedRoute.name}
🏁 Start: {selectedRoute.from} ({selectedRoute.departureTime})
🏫 Destination: RIT Campus ({selectedRoute.arrivalTime})
📍 Total Stops: {selectedRoute.stops.length} mapped stops
)}
);
}