diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 4a7ebaa..c8517b7 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useState, useEffect, useMemo } from "react"; import Sidebar from "./components/Sidebar"; import MapComponent from "./components/MapComponent"; import LoadingOverlay from "./components/LoadingOverlay"; @@ -21,8 +21,21 @@ function App() { const [loading, setLoading] = useState(false); const [clusteringEnabled, setClusteringEnabled] = useState(true); + // Search states: one is the raw user input, the other is the actual term we filter on + const [searchInput, setSearchInput] = useState(""); const [searchTerm, setSearchTerm] = useState(""); + // Debounce effect + useEffect(() => { + const handler = setTimeout(() => { + setSearchTerm(searchInput); + }, 300); // Adjust this delay as desired + + return () => { + clearTimeout(handler); + }; + }, [searchInput]); + const fetchData = async () => { setLoading(true); try { @@ -41,7 +54,6 @@ function App() { switch (item.objectType) { case "IrishRailTrain": objectTitle = "Irish Rail Train: " + item.trainCode; - let trainType; switch (item.trainType) { case "M": @@ -82,7 +94,6 @@ function App() { icon += "Late"; } - // Build the popup UI popupContent = (

{objectTitle}

@@ -97,13 +108,7 @@ function App() {
); - markerText = `Irish Rail Train: ${item.trainCode} - Train Details: ${splitMessage[1].split("(")[0]} - Train Type: ${trainType} - Status: ${trainStatus} - Direction: ${item.trainDirection} - Update: ${splitMessage[2]} - Punctuality: ${punctuality}`; + markerText = item.trainPublicMessage + " " + item.trainDirection; break; case "IrishRailStation": @@ -118,10 +123,7 @@ function App() { ); - - markerText = `Train Station: ${item.trainStationDesc} - ID: ${item.trainStationID} - Code: ${item.trainStationCode}`; + markerText = item.trainStationCode + " " + item.trainStationDesc; break; case "Bus": @@ -138,11 +140,7 @@ function App() { ); - - markerText = `Bus Agency: ${item.busRouteAgencyName} - Route: ${item.busRoute} - Route Short Name: ${item.busRouteShortName} - Route Long Name: ${item.busRouteLongName}`; + markerText = item.busRouteAgencyName + " " + item.busRouteShortName + " " + item.busRouteLongName; break; case "BusStop": @@ -157,10 +155,7 @@ function App() { ); - - markerText = `Bus Stop: ${item.busStopName} - ID: ${item.busStopID} - Code: ${item.busStopCode || "N/A"}`; + markerText = item.busStopName; break; case "LuasStop": @@ -180,8 +175,7 @@ function App() { popupContent = ( ); - markerText = `Luas Stop: ${item.luasStopName} - Line: ${luasLine}`; + markerText = item.luasStopIrishName + " " + item.luasStopName; break; default: @@ -200,6 +194,7 @@ function App() { markerText: markerText.toLowerCase(), }; }); + setMarkers(newMarkers); } catch (error) { console.error("Error fetching data:", error); @@ -207,17 +202,21 @@ function App() { setLoading(false); }; - const filteredMarkers = markers.filter((marker) => { + // 2. Memoize the filtered markers so it recalculates only if `searchTerm` or `markers` changes + const filteredMarkers = useMemo(() => { if (!searchTerm.trim()) { - return true; + return markers; } - return marker.markerText.includes(searchTerm.toLowerCase()); - }); + return markers.filter((marker) => + marker.markerText.includes(searchTerm.toLowerCase()) + ); + }, [searchTerm, markers]); return (
{loading && } + {/* SEARCH BOX */}
setSearchTerm(e.target.value)} + value={searchInput} + onChange={(e) => setSearchInput(e.target.value)} placeholder="Search..." style={{ - width: "250px", fontSize: "16px", padding: "6px", + width: "250px", fontSize: "16px", padding: "10px", background: "rgba(255, 255, 255, 0.9)", color: "black", - borderRadius: "10px", - display: "flex", flexDirection: "column", - alignItems: "center", zIndex: 1000, overflow: "hidden", justifyContent: "center" + borderRadius: "10px", overflow: "hidden" }} />