diff --git a/backend/src/main/java/com/rit/portal/service/BusLocationService.java b/backend/src/main/java/com/rit/portal/service/BusLocationService.java index 4976e82..40b803b 100644 --- a/backend/src/main/java/com/rit/portal/service/BusLocationService.java +++ b/backend/src/main/java/com/rit/portal/service/BusLocationService.java @@ -12,7 +12,7 @@ import java.util.List; public class BusLocationService { private final Map locationCache = new ConcurrentHashMap<>(); - private static final Duration STALE_DURATION = Duration.ofMinutes(2); + private static final Duration STALE_DURATION = Duration.ofMinutes(20); public void updateLocation(String routeNumber, Double latitude, Double longitude) { locationCache.put(routeNumber, new BusLocation( diff --git a/src/components/BusRouteMap/BusRouteMap.tsx b/src/components/BusRouteMap/BusRouteMap.tsx index 1ba994f..55b46f3 100644 --- a/src/components/BusRouteMap/BusRouteMap.tsx +++ b/src/components/BusRouteMap/BusRouteMap.tsx @@ -46,30 +46,17 @@ const isRealStopCoordinate = (stop: { name: string; lat?: number; lng?: number } return true; }; -// Custom Premium DivIcons using Tailwind CSS -const getStartIcon = (label: string = "1") => L.divIcon({ - html: `
${label}
`, - className: '', - iconSize: [24, 24], - iconAnchor: [12, 12], -}); -const getStopIcon = (num: number) => L.divIcon({ - html: `
${num}
`, - className: '', - iconSize: [22, 22], - iconAnchor: [11, 11], -}); -const campusIcon = L.divIcon({ - html: `
🏫
`, +const liveBusIcon = L.divIcon({ + html: `
🚌
`, className: '', iconSize: [36, 36], iconAnchor: [18, 18], }); -const liveBusIcon = L.divIcon({ - html: `
🚌
`, +const stoppedBusIcon = L.divIcon({ + html: `
🚌
`, className: '', iconSize: [36, 36], iconAnchor: [18, 18], @@ -94,7 +81,7 @@ interface BusRouteMapProps { const DEFAULT_CENTER = [13.0118, 80.0214]; // RIT Campus default export default function BusRouteMap({ selectedRoute, allRoutes }: BusRouteMapProps) { - const [allLiveLocations, setAllLiveLocations] = useState>({}); + const [allLiveLocations, setAllLiveLocations] = useState>({}); useEffect(() => { const fetchLiveLocations = () => { @@ -103,12 +90,12 @@ export default function BusRouteMap({ selectedRoute, allRoutes }: BusRouteMapPro if (res.ok) return res.json(); return []; }) - .then((data: Array<{ routeNumber: string; latitude: number; longitude: number }>) => { + .then((data: Array<{ routeNumber: string; latitude: number; longitude: number; lastUpdated: string }>) => { if (Array.isArray(data)) { - const locMap: Record = {}; + const locMap: Record = {}; data.forEach((item) => { if (item.routeNumber && item.latitude && item.longitude) { - locMap[item.routeNumber] = { latitude: item.latitude, longitude: item.longitude }; + locMap[item.routeNumber] = { latitude: item.latitude, longitude: item.longitude, lastUpdated: item.lastUpdated }; } }); setAllLiveLocations(locMap); @@ -175,83 +162,7 @@ export default function BusRouteMap({ selectedRoute, allRoutes }: BusRouteMapPro return pathCoordinates as L.LatLngBoundsExpression; }, [pathCoordinates]); - // Determine which markers to display - const renderMarkers = () => { - if (selectedRoute) { - // Filter out stops that do not have valid/real coordinates - const validStops = selectedRoute.stops.filter(stop => isRealStopCoordinate(stop)); - return ( - <> - {validStops.map((stop, index) => { - const isStart = index === 0; - const isEnd = index === validStops.length - 1; - const isRit = stop.name.toLowerCase().includes("rit"); - - let currentIcon = getStopIcon(index + 1); - if (isStart) currentIcon = getStartIcon("Start"); - if (isRit || isEnd) currentIcon = campusIcon; - - return ( - - -
-
- - Stop #{index + 1} - -

{stop.name}

-
-

Estimated Arrival: {stop.time}

- {isStart && Departure Stop} - {isRit && RIT Campus} -
-
-
- ); - })} - - ); - } - - // Default view: Draw RIT Campus pin + Start pins for all routes (only if coordinates are valid) - return ( - <> - - -
-

Rajalakshmi Institute of Technology

-

Kuthambakkam, Chennai

-
-
-
- {allRoutes.map((r, i) => { - if (!isValidCoordinate(r.from_lat, r.from_lng)) return null; - return ( - - -
- - {r.number} - -

{r.name}

-

Starts: {r.from} at {r.departureTime}

-
-
-
- ); - })} - - ); - }; return (
@@ -266,23 +177,32 @@ export default function BusRouteMap({ selectedRoute, allRoutes }: BusRouteMapPro url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> - {renderMarkers()} - {Object.entries(allLiveLocations).map(([rNum, loc]) => { if (selectedRoute && selectedRoute.number !== rNum) return null; + + const isStale = loc.lastUpdated ? (new Date().getTime() - new Date(loc.lastUpdated).getTime() > 120000) : false; + return (
- - LIVE TRACKING - + {isStale ? ( + + LOCATION SHARING STOPPED + + ) : ( + + LIVE TRACKING + + )}

Bus {rNum}

-

Broadcasting live coordinates

+

+ {isStale ? "Last known location" : "Broadcasting live coordinates"} +

diff --git a/telegram-bot/bot_mappings.db b/telegram-bot/bot_mappings.db index 02d75e5..1224bcd 100644 Binary files a/telegram-bot/bot_mappings.db and b/telegram-bot/bot_mappings.db differ