[frontend]: Add primitive search

This commit is contained in:
2025-03-03 22:19:47 +00:00
parent 1f3d6f25c3
commit 22b6313421

View File

@ -21,6 +21,8 @@ function App() {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [clusteringEnabled, setClusteringEnabled] = useState(true); const [clusteringEnabled, setClusteringEnabled] = useState(true);
const [searchTerm, setSearchTerm] = useState("");
const fetchData = async () => { const fetchData = async () => {
setLoading(true); setLoading(true);
try { try {
@ -34,6 +36,7 @@ function App() {
let icon = item.objectType; let icon = item.objectType;
let popupContent; let popupContent;
let objectTitle; let objectTitle;
let markerText = "";
switch (item.objectType) { switch (item.objectType) {
case "IrishRailTrain": case "IrishRailTrain":
@ -63,24 +66,23 @@ function App() {
trainStatus = "Running"; trainStatus = "Running";
break; break;
default: default:
trainStatus = "Not running" trainStatus = "Not running";
} }
const splitMessage = item.trainPublicMessage.split("\\n"); const splitMessage = item.trainPublicMessage.split("\\n");
const match = splitMessage[1].match(/\((.*?)\)/); const match = splitMessage[1].match(/\((.*?)\)/);
const punctuality = match ? match[1] : "N/A"; const punctuality = match ? match[1] : "N/A";
// set icon depending on lateness of train and type of train // set icon depending on lateness of train and type
if (trainStatus == "Not running") { if (trainStatus === "Not running") {
icon += "NotRunning"; icon += "NotRunning";
} } else if (punctuality.charAt(0) === "-" || punctuality.charAt(0) === "0") {
else if (punctuality.charAt(0) === "-" || punctuality.charAt(0) === "0") {
icon += "OnTime"; icon += "OnTime";
} } else {
else { icon += "Late";
icon += "Late"
} }
// Build the popup UI
popupContent = ( popupContent = (
<div> <div>
<h3>{objectTitle}</h3> <h3>{objectTitle}</h3>
@ -94,11 +96,18 @@ function App() {
</ul> </ul>
</div> </div>
); );
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}`;
break; break;
case "IrishRailStation": case "IrishRailStation":
objectTitle = item.trainStationDesc + " Train Station"; objectTitle = item.trainStationDesc + " Train Station";
popupContent = ( popupContent = (
<div> <div>
<h3>{objectTitle}</h3> <h3>{objectTitle}</h3>
@ -109,11 +118,14 @@ function App() {
</ul> </ul>
</div> </div>
); );
markerText = `Train Station: ${item.trainStationDesc}
ID: ${item.trainStationID}
Code: ${item.trainStationCode}`;
break; break;
case "Bus": case "Bus":
objectTitle = item.busRouteAgencyName + ": " + item.busRouteShortName; objectTitle = item.busRouteAgencyName + ": " + item.busRouteShortName;
popupContent = ( popupContent = (
<div> <div>
<h3>{objectTitle}</h3> <h3>{objectTitle}</h3>
@ -124,14 +136,17 @@ function App() {
<li><b>Bus Route Long Name:</b> {item.busRouteLongName}</li> <li><b>Bus Route Long Name:</b> {item.busRouteLongName}</li>
<li><b>Agency: </b> {item.busRouteAgencyName}</li> <li><b>Agency: </b> {item.busRouteAgencyName}</li>
</ul> </ul>
</div> </div>
); );
markerText = `Bus Agency: ${item.busRouteAgencyName}
Route: ${item.busRoute}
Route Short Name: ${item.busRouteShortName}
Route Long Name: ${item.busRouteLongName}`;
break; break;
case "BusStop": case "BusStop":
objectTitle = item.busStopName + " Bus Stop"; objectTitle = item.busStopName + " Bus Stop";
popupContent = ( popupContent = (
<div> <div>
<h3>{objectTitle}</h3> <h3>{objectTitle}</h3>
@ -142,12 +157,16 @@ function App() {
</ul> </ul>
</div> </div>
); );
markerText = `Bus Stop: ${item.busStopName}
ID: ${item.busStopID}
Code: ${item.busStopCode || "N/A"}`;
break; break;
case "LuasStop": case "LuasStop":
objectTitle = item.luasStopName + " Luas Stop"; objectTitle = item.luasStopName + " Luas Stop";
let luasLine;
let luasLine;
switch (item.luasStopLineID) { switch (item.luasStopLineID) {
case "1": case "1":
luasLine = "Green Line"; luasLine = "Green Line";
@ -158,10 +177,11 @@ function App() {
default: default:
luasLine = "N/A"; luasLine = "N/A";
} }
popupContent = ( popupContent = (
<LuasPopup item={item} objectTitle={objectTitle} luasLine={luasLine} /> <LuasPopup item={item} objectTitle={objectTitle} luasLine={luasLine} />
); );
markerText = `Luas Stop: ${item.luasStopName}
Line: ${luasLine}`;
break; break;
default: default:
@ -170,12 +190,14 @@ function App() {
<h3>{item.objectType}</h3> <h3>{item.objectType}</h3>
</div> </div>
); );
markerText = `Unknown Object Type: ${item.objectType}`;
} }
return { return {
coords: [item.latitude, item.longitude], coords: [item.latitude, item.longitude],
popup: popupContent, popup: popupContent,
icon: icon, icon: icon,
markerText: markerText.toLowerCase(),
}; };
}); });
setMarkers(newMarkers); setMarkers(newMarkers);
@ -185,9 +207,41 @@ function App() {
setLoading(false); setLoading(false);
}; };
const filteredMarkers = markers.filter((marker) => {
if (!searchTerm.trim()) {
return true;
}
return marker.markerText.includes(searchTerm.toLowerCase());
});
return ( return (
<div style={{ height: "100vh", width: "100vw", display: "flex", position: "relative" }}> <div style={{ height: "100vh", width: "100vw", display: "flex", position: "relative" }}>
{loading && <LoadingOverlay />} {loading && <LoadingOverlay />}
<div
style={{
position: "absolute",
top: "10px",
left: "50%",
transform: "translateX(-50%)",
zIndex: 1000
}}
>
<input
type="text"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
placeholder="Search..."
style={{
width: "250px", fontSize: "16px", padding: "6px",
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"
}}
/>
</div>
<Sidebar <Sidebar
selectedSources={selectedSources} selectedSources={selectedSources}
setSelectedSources={setSelectedSources} setSelectedSources={setSelectedSources}
@ -196,7 +250,7 @@ function App() {
fetchData={fetchData} fetchData={fetchData}
/> />
<div style={{ flex: 1 }}> <div style={{ flex: 1 }}>
<MapComponent markers={markers} clusteringEnabled={clusteringEnabled} /> <MapComponent markers={filteredMarkers} clusteringEnabled={clusteringEnabled} />
</div> </div>
</div> </div>
); );