diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f60a9e1..238a6ae 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -19,6 +19,7 @@ "react-helmet": "^6.1.0", "react-leaflet": "^5.0.0-rc.2", "react-leaflet-markercluster": "^5.0.0-rc.0", + "react-router-dom": "^7.3.0", "tailwindcss": "^4.0.9" }, "devDependencies": { @@ -1349,6 +1350,12 @@ "vite": "^5.2.0 || ^6" } }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -1831,6 +1838,15 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -4124,6 +4140,46 @@ "react-leaflet": "^5.0.0" } }, + "node_modules/react-router": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.3.0.tgz", + "integrity": "sha512-466f2W7HIWaNXTKM5nHTqNxLrHTyXybm7R0eBlVSt0k/u55tTCDO194OIx/NrYD4TS5SXKTNekXfT37kMKUjgw==", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0", + "turbo-stream": "2.4.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.3.0.tgz", + "integrity": "sha512-z7Q5FTiHGgQfEurX/FBinkOXhWREJIAB2RiU24lvcBa82PxUpwqvs/PAXb9lJyPjTs2jrl6UkLvCZVGJPeNuuQ==", + "license": "MIT", + "dependencies": { + "react-router": "7.3.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -4305,6 +4361,12 @@ "semver": "bin/semver.js" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -4614,6 +4676,12 @@ "node": ">=6" } }, + "node_modules/turbo-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==", + "license": "ISC" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index a553e2f..bce69d8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,6 +21,7 @@ "react-helmet": "^6.1.0", "react-leaflet": "^5.0.0-rc.2", "react-leaflet-markercluster": "^5.0.0-rc.0", + "react-router-dom": "^7.3.0", "tailwindcss": "^4.0.9" }, "devDependencies": { diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index b770363..900d229 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,8 +1,12 @@ import React, { useState, useEffect, useMemo } from "react"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; + import Sidebar from "./components/Sidebar"; import MapComponent from "./components/MapComponent"; import LoadingOverlay from "./components/LoadingOverlay"; import LuasPopup from "./components/LuasPopup"; +import Navbar from "./components/Navbar"; +import Statistics from "./components/Statistics.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"; @@ -300,46 +304,54 @@ function App() { }, [searchTerm, markers]); return ( -
- {loading && } + + + + + {loading && }
+ setSearchInput(e.target.value)} + placeholder="Search..." + style={{ + width: "250px", fontSize: "16px", + top: "6vh", marginTop: "5vh", + padding: "10px", background: "rgba(255, 255, 255, 0.9)", color: "black", + borderRadius: "10px", overflow: "hidden" + }} + /> +
- {/* SEARCH BOX */} -
- setSearchInput(e.target.value)} - placeholder="Search..." - style={{ - width: "250px", fontSize: "16px", - padding: "10px", background: "rgba(255, 255, 255, 0.9)", color: "black", - borderRadius: "10px", overflow: "hidden" - }} + +
+ +
+
+ } /> -
- - -
- -
- + } /> + + ); } - export default App; \ No newline at end of file diff --git a/frontend/src/components/LuasPopup.jsx b/frontend/src/components/LuasPopup.jsx index 0e2f458..46311af 100644 --- a/frontend/src/components/LuasPopup.jsx +++ b/frontend/src/components/LuasPopup.jsx @@ -41,7 +41,7 @@ const LuasPopup = ({ item, objectTitle, luasLine }) => {
  • Cycle & ride?: {(item.luasStopIsCycleAndRide === "1") ? "Yes" : "No"}
  • Operational?: {(item.luasStopIsEnabled === "1") ? "Yes" : "No"}
  • -
    diff --git a/frontend/src/components/Navbar.jsx b/frontend/src/components/Navbar.jsx new file mode 100644 index 0000000..ea318e3 --- /dev/null +++ b/frontend/src/components/Navbar.jsx @@ -0,0 +1,71 @@ +import React from "react"; +import { Link } from "react-router-dom"; + +const Navbar = () => { + return ( + +); +}; + +export default Navbar; diff --git a/frontend/src/components/Sidebar.jsx b/frontend/src/components/Sidebar.jsx index becca80..34ef840 100644 --- a/frontend/src/components/Sidebar.jsx +++ b/frontend/src/components/Sidebar.jsx @@ -153,7 +153,7 @@ const Sidebar = ({ selectedSources, setSelectedSources, clusteringEnabled, setCl return (
    {isOpen && (
    -

    Select Data Sources

    {menuData.map((item) => ( ))} - +
    )}
    diff --git a/frontend/src/components/Statistics.jsx b/frontend/src/components/Statistics.jsx new file mode 100644 index 0000000..06f70c8 --- /dev/null +++ b/frontend/src/components/Statistics.jsx @@ -0,0 +1,12 @@ +import React from "react"; + +const Statistics = () => { + return ( +
    +

    About This Application

    +

    This application provides real-time and permanent data on Irish Rail, Luas, and bus services.

    +
    + ); +}; + +export default Statistics; diff --git a/frontend/src/index.css b/frontend/src/index.css index c4a5da7..f8ef5f3 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,7 +1,5 @@ -/* @tailwind base; -@tailwind components; -@tailwind utilities; - */ +@import "tailwindcss"; + :root { font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; line-height: 1.5; @@ -83,4 +81,17 @@ button:focus-visible { .leaflet-container { height: 100vh; +} + +h3 { + font-size: 1.4em; + font-weight: bold; +} + +body, html, #root { + height: 100%; + margin: 0; + padding: 0; + box-sizing: border-box; + overflow-x: hidden; } \ No newline at end of file diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 2328e17..7d1d6f7 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -1,7 +1,11 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react-swc' +import tailwindcss from '@tailwindcss/vite' // https://vite.dev/config/ export default defineConfig({ - plugins: [react()], + plugins: [ + react(), + tailwindcss() + ], })