diff --git a/diary.md b/diary.md
index 933e59f..6ade3b9 100644
--- a/diary.md
+++ b/diary.md
@@ -3,6 +3,7 @@
- Add 'favourite' button to train station pop-up.
- Create `IrishRailTrainPopup` with favourite button.
- Create `BusPopup` with favourite button.
+- Create `BusStopPopup` with favourite button.
## Wed 12 Mar 2025
- Fix search input freezing when there's a large number of data.
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 714487b..a35e043 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -13,6 +13,7 @@ import LuasPopup from "./components/LuasPopup";
import TrainStationPopup from "./components/TrainStationPopup";
import IrishRailTrainPopup from "./components/IrishRailTrainPopup";
import BusPopup from "./components/BusPopup.jsx";
+import BusStopPopup from "./components/BusStopPopup.jsx";
const TRANSIENT_DATA_API = "https://281bc6mcm5.execute-api.us-east-1.amazonaws.com/transient_data";
const PERMANENT_DATA_API = "https://a6y312dpuj.execute-api.us-east-1.amazonaws.com/permanent_data";
@@ -35,6 +36,7 @@ const defaultFavourites = {
function App() {
const [favourites, setFavourites] = useState(defaultFavourites);
+ const [showFaovouritesOnly, setShowFavouritesOnly] = useState(false);
useEffect(() => {
try {
@@ -270,7 +272,8 @@ function App() {
((showRunning && trainStatus == "Running") || (showNotYetRunning && trainStatus == "Not yet running") || (showTerminated && trainStatus == "Terminated")) &&
((trainStatus == "Running" && showEarly && punctualityStr == "early") || (trainStatus == "Running" && showOnTime && punctualityStr == "On time") || (trainStatus == "Running" && showLate && punctualityStr == "late")
|| (trainStatus == "Not yet running" && showNotYetRunning) || (trainStatus == "Terminated" && showTerminated))) &&
- (numberInputValue && userLocationAvailable ? haversineDistance(userLocation, [item.latitude, item.longitude]) < numberInputValue : true);
+ (numberInputValue && userLocationAvailable ? haversineDistance(userLocation, [item.latitude, item.longitude]) < numberInputValue : true) &&
+ (showFaovouritesOnly ? favourites.IrishRailTrain.includes(item.trainCode) : true);
break;
@@ -287,7 +290,8 @@ function App() {
markerText = item.trainStationCode + " " + item.trainStationDesc;
display = (item.latitude !== "0" && item.longitude !== "0") &&
- (numberInputValue && userLocationAvailable ? haversineDistance(userLocation, [item.latitude, item.longitude]) < numberInputValue : true);
+ (numberInputValue && userLocationAvailable ? haversineDistance(userLocation, [item.latitude, item.longitude]) < numberInputValue : true) &&
+ (showFaovouritesOnly ? favourites.IrishRailStation.includes(item.trainStationCode) : true);
break;
@@ -300,40 +304,30 @@ function App() {
toggleFavourite={toggleFavourite}
favourites={favourites}
/>
- //
- //
{objectTitle}
- //
- // - Bus ID: {item.busID}
- // - Bus Route ID: {item.busRoute}
- // - Bus Route Short Name: {item.busRouteShortName}
- // - Bus Route Long Name: {item.busRouteLongName}
- // - Agency: {item.busRouteAgencyName}
- //
- //
);
markerText = item.busRouteAgencyName + " " + item.busRouteShortName + " " + item.busRouteLongName;
display = (item.latitude !== "0" && item.longitude !== "0") &&
- (numberInputValue && userLocationAvailable ? haversineDistance(userLocation, [item.latitude, item.longitude]) < numberInputValue : true);
+ (numberInputValue && userLocationAvailable ? haversineDistance(userLocation, [item.latitude, item.longitude]) < numberInputValue : true) &&
+ (showFaovouritesOnly ? favourites.Bus.includes(item.busRoute) : true);
break;
case "BusStop":
objectTitle = item.busStopName + " Bus Stop";
popupContent = (
-
-
{objectTitle}
-
- - Bus Stop ID: {item.busStopID}
- - Bus Stop Name: {item.busStopName}
- - Bus Stop Code: {item.busStopCode || "N/A"}
-
-
+
);
markerText = item.busStopName;
display = (item.latitude !== "0" && item.longitude !== "0") &&
- (numberInputValue && userLocationAvailable ? haversineDistance(userLocation, [item.latitude, item.longitude]) < numberInputValue : true);
+ (numberInputValue && userLocationAvailable ? haversineDistance(userLocation, [item.latitude, item.longitude]) < numberInputValue : true) &&
+ (showFaovouritesOnly ? favourites.BusStop.includes(item.busStopID) : true);
break;
@@ -370,7 +364,8 @@ function App() {
(showEnabled && item.luasStopIsEnabled === "1" || showDisabled && item.luasStopIsEnabled === "0") &&
(!showCycleAndRide || (showCycleAndRide && item.luasStopIsCycleAndRide === "1")) &&
(!showParkAndRide || (showParkAndRide && item.luasStopIsParkAndRide === "1")) &&
- (numberInputValue && userLocationAvailable ? haversineDistance(userLocation, [item.latitude, item.longitude]) < numberInputValue : true)
+ (numberInputValue && userLocationAvailable ? haversineDistance(userLocation, [item.latitude, item.longitude]) < numberInputValue : true) &&
+ (showFaovouritesOnly ? favourites.LuasStop.includes(item.luasStopID) : true)
);
break;
@@ -469,6 +464,8 @@ function App() {
setClusteringEnabled={setClusteringEnabled}
fetchData={fetchData}
userLocationAvailable={userLocationAvailable}
+ showFavouritesOnly={showFaovouritesOnly}
+ setShowFavouritesOnly={setShowFavouritesOnly}
/>
{
+const Sidebar = ({ selectedSources, setSelectedSources, clusteringEnabled, setClusteringEnabled, fetchData, userLocationAvailable, showFavouritesOnly, setShowFavouritesOnly }) => {
const [isOpen, setIsOpen] = useState(false);
const [enabledSources, setEnabledSources] = useState([]); // New state to track enabled sources
const [numberInputValue, setNumberInputValue] = useState(""); // State to manage number input value
@@ -183,41 +183,54 @@ const Sidebar = ({ selectedSources, setSelectedSources, clusteringEnabled, setCl
setEnabledSources={setEnabledSources}
/>
))}
-
+
+
setClusteringEnabled(!clusteringEnabled)}
+ id="showFavouritesOnly"
+ checked={showFavouritesOnly}
+ onChange={() => setShowFavouritesOnly(!showFavouritesOnly)}
/>
-
+
- {userLocationAvailable && (
-
-
+
+
setNumberInputValue(e.target.value)}
- style={{maxWidth: "40%"}}
+ type="checkbox"
+ id="toggleClustering"
+ checked={clusteringEnabled}
+ onChange={() => setClusteringEnabled(!clusteringEnabled)}
/>
+
+ {userLocationAvailable && (
+
+
+ setNumberInputValue(e.target.value)}
+ style={{maxWidth: "40%"}}
+ />
+
+ )}
+
+
)}
-
- )}
-
- );
-};
+ );
+ };
-Sidebar.propTypes = {
- selectedSources: PropTypes.array.isRequired,
- setSelectedSources: PropTypes.func.isRequired,
- clusteringEnabled: PropTypes.bool.isRequired,
- setClusteringEnabled: PropTypes.func.isRequired,
- fetchData: PropTypes.func.isRequired,
- userLocationAvailable: PropTypes.bool.isRequired,
-};
+ Sidebar.propTypes = {
+ selectedSources: PropTypes.array.isRequired,
+ setSelectedSources: PropTypes.func.isRequired,
+ clusteringEnabled: PropTypes.bool.isRequired,
+ setClusteringEnabled: PropTypes.func.isRequired,
+ fetchData: PropTypes.func.isRequired,
+ userLocationAvailable: PropTypes.bool.isRequired,
+ showFavouritesOnly: PropTypes.bool.isRequired,
+ setShowFavouritesOnly: PropTypes.func.isRequired,
+ };
-export default Sidebar
+ export default Sidebar