[frontend]: Add navbar and statistics page
This commit is contained in:
@ -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 (
|
||||
<div style={{ height: "100vh", width: "100vw", display: "flex", position: "relative" }}>
|
||||
{loading && <LoadingOverlay message={"Loading data..."}/>}
|
||||
<Router>
|
||||
<Navbar />
|
||||
<Routes>
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<div style={{ height: "100vh", width: "100vw", display: "flex", position: "relative", paddingTop: "5vh" }}>
|
||||
{loading && <LoadingOverlay message={"Loading data..."} />} <div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "1vh",
|
||||
height: "5vh",
|
||||
width: "250px", minWidth: "50px",
|
||||
left: "50%",
|
||||
transform: "translateX(-50%)",
|
||||
zIndex: 1000
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value={searchInput}
|
||||
onChange={(e) => 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"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* SEARCH BOX */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "1vh",
|
||||
height: "5vh",
|
||||
width: "250px", minWidth: "50px",
|
||||
left: "50%",
|
||||
transform: "translateX(-50%)",
|
||||
zIndex: 1000
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value={searchInput}
|
||||
onChange={(e) => 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"
|
||||
}}
|
||||
<Sidebar
|
||||
selectedSources={selectedSources}
|
||||
setSelectedSources={setSelectedSources}
|
||||
clusteringEnabled={clusteringEnabled}
|
||||
setClusteringEnabled={setClusteringEnabled}
|
||||
fetchData={fetchData}
|
||||
/>
|
||||
<div style={{ flex: 1 }}>
|
||||
<MapComponent markers={filteredMarkers} clusteringEnabled={clusteringEnabled} />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Sidebar
|
||||
selectedSources={selectedSources}
|
||||
setSelectedSources={setSelectedSources}
|
||||
clusteringEnabled={clusteringEnabled}
|
||||
setClusteringEnabled={setClusteringEnabled}
|
||||
fetchData={fetchData}
|
||||
/>
|
||||
<div style={{ flex: 1 }}>
|
||||
<MapComponent markers={filteredMarkers} clusteringEnabled={clusteringEnabled} />
|
||||
</div>
|
||||
</div>
|
||||
<Route path="/statistics" element={<Statistics />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
@ -41,7 +41,7 @@ const LuasPopup = ({ item, objectTitle, luasLine }) => {
|
||||
<li><b>Cycle & ride?:</b> {(item.luasStopIsCycleAndRide === "1") ? "Yes" : "No"}</li>
|
||||
<li><b>Operational?:</b> {(item.luasStopIsEnabled === "1") ? "Yes" : "No"}</li>
|
||||
</ul>
|
||||
<button onClick={fetchLuasData} style={{ padding: "5px", marginTop: "5px", cursor: "pointer" }}>
|
||||
<button onClick={fetchLuasData} style={{ padding: "5px", marginTop: "5px", cursor: "pointer", color: "white" }}>
|
||||
Load Luas Schedule
|
||||
</button>
|
||||
<div dangerouslySetInnerHTML={{ __html: luasInfo }} style={{ marginTop: "10px" }}></div>
|
||||
|
71
frontend/src/components/Navbar.jsx
Normal file
71
frontend/src/components/Navbar.jsx
Normal file
@ -0,0 +1,71 @@
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const Navbar = () => {
|
||||
return (
|
||||
<nav
|
||||
style={{
|
||||
position: "fixed",
|
||||
top: "0",
|
||||
right: "0",
|
||||
left: "0",
|
||||
height: "5vh",
|
||||
background: "rgba(255, 255, 255, 0.9)",
|
||||
color: "black",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
padding: "0 20px",
|
||||
transition: "height 0.2s ease-in-out, padding 0.2s ease-in-out",
|
||||
zIndex: 1200,
|
||||
boxShadow: "0 2px 5px rgba(0, 0, 0, 0.1)"
|
||||
}}
|
||||
>
|
||||
<div style={{display: "flex", alignItems: "center", gap: "10px"}}>
|
||||
<img
|
||||
src="/ticket.png" // Ensure this path is correct
|
||||
alt="Iompar"
|
||||
style={{width: "24px", height: "24px", borderRadius: "5px"}}
|
||||
/>
|
||||
<div style={{fontSize: "18px", fontWeight: "bold"}}>
|
||||
<Link to="/" style={{textDecoration: "none", color: "black"}}>
|
||||
Iompar
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{display: "flex", gap: "20px"}}>
|
||||
<Link
|
||||
to="/"
|
||||
style={{
|
||||
textDecoration: "none",
|
||||
color: "black",
|
||||
padding: "5px 10px",
|
||||
borderRadius: "5px",
|
||||
transition: "background 0.2s",
|
||||
}}
|
||||
onMouseEnter={(e) => (e.target.style.background = "rgba(0, 0, 0, 0.1)")}
|
||||
onMouseLeave={(e) => (e.target.style.background = "transparent")}
|
||||
>
|
||||
Home
|
||||
</Link>
|
||||
<Link
|
||||
to="/statistics"
|
||||
style={{
|
||||
textDecoration: "none",
|
||||
color: "black",
|
||||
padding: "5px 10px",
|
||||
borderRadius: "5px",
|
||||
transition: "background 0.2s",
|
||||
}}
|
||||
onMouseEnter={(e) => (e.target.style.background = "rgba(0, 0, 0, 0.1)")}
|
||||
onMouseLeave={(e) => (e.target.style.background = "transparent")}
|
||||
>
|
||||
Statistics
|
||||
</Link>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navbar;
|
@ -153,7 +153,7 @@ const Sidebar = ({ selectedSources, setSelectedSources, clusteringEnabled, setCl
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
position: "absolute", top: window.innerWidth < 900 ? "8vh" : "1vh", right: "1vh",
|
||||
position: "absolute", top: window.innerWidth < 900 ? "8vh" : "6vh", right: "1vh",
|
||||
width: "250px", minWidth: "50px",
|
||||
padding: isOpen ? "10px" : "5px 10px", background: "rgba(255, 255, 255, 0.9)", color: "black",
|
||||
borderRadius: "10px", transition: "height 0.2s ease-in-out, padding 0.2s ease-in-out",
|
||||
@ -165,7 +165,6 @@ const Sidebar = ({ selectedSources, setSelectedSources, clusteringEnabled, setCl
|
||||
</button>
|
||||
{isOpen && (
|
||||
<div style={{ display: "flex", flexDirection: "column", alignItems: "flex-start", width: "100%" }}>
|
||||
<h3>Select Data Sources</h3>
|
||||
{menuData.map((item) => (
|
||||
<CheckboxItem
|
||||
key={item.id}
|
||||
@ -176,7 +175,7 @@ const Sidebar = ({ selectedSources, setSelectedSources, clusteringEnabled, setCl
|
||||
setEnabledSources={setEnabledSources}
|
||||
/>
|
||||
))}
|
||||
<button onClick={handleSubmit} style={{ marginTop: "10px" }}>Submit</button>
|
||||
<button onClick={handleSubmit} style={{ marginTop: "10px", color: "white" }}>Submit</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
12
frontend/src/components/Statistics.jsx
Normal file
12
frontend/src/components/Statistics.jsx
Normal file
@ -0,0 +1,12 @@
|
||||
import React from "react";
|
||||
|
||||
const Statistics = () => {
|
||||
return (
|
||||
<div style={{height: "100vh", width: "100vw", display: "flex", position: "relative", paddingTop: "5vh"}}>
|
||||
<h1 className="text-2xl font-bold mb-4">About This Application</h1>
|
||||
<p>This application provides real-time and permanent data on Irish Rail, Luas, and bus services.</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Statistics;
|
@ -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;
|
||||
}
|
Reference in New Issue
Block a user