aboutsummaryrefslogtreecommitdiff
path: root/src/pages
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/Estimates.tsx16
-rw-r--r--src/pages/Map.tsx101
2 files changed, 42 insertions, 75 deletions
diff --git a/src/pages/Estimates.tsx b/src/pages/Estimates.tsx
index d3b4ced..3f002be 100644
--- a/src/pages/Estimates.tsx
+++ b/src/pages/Estimates.tsx
@@ -23,13 +23,17 @@ interface StopDetails {
export function Estimates(): JSX.Element {
const sdp = new StopDataProvider();
const [data, setData] = useState<StopDetails | null>(null);
+ const [dataDate, setDataDate] = useState<Date | null>(null);
const [favourited, setFavourited] = useState(false);
const params = useParams();
const loadData = () => {
fetch(`/api/GetStopEstimates?id=${params.stopId}`)
.then(r => r.json())
- .then((body: StopDetails) => setData(body));
+ .then((body: StopDetails) => {
+ setData(body);
+ setDataDate(new Date());
+ });
};
useEffect(() => {
@@ -80,17 +84,9 @@ export function Estimates(): JSX.Element {
</h1>
</div>
- <div className="button-group">
- <Link to="/stops" className="button">
- 🔙 Volver al listado de paradas
- </Link>
-
- <button className="button" onClick={loadData}>⬇️ Recargar</button>
- </div>
-
<div className="table-responsive">
<table className="table">
- <caption>Estimaciones de llegadas</caption>
+ <caption>Estimaciones de llegadas a las {dataDate?.toLocaleTimeString()}</caption>
<thead>
<tr>
diff --git a/src/pages/Map.tsx b/src/pages/Map.tsx
index dbf5b9f..4d89ae0 100644
--- a/src/pages/Map.tsx
+++ b/src/pages/Map.tsx
@@ -1,76 +1,47 @@
-import { useEffect, useMemo, useState } from "react";
-import { Link, useNavigate } from "react-router";
-import { Stop, StopDataProvider } from "../data/StopDataProvider";
-import LineIcon from "../components/LineIcon";
+import { StopDataProvider, Stop } from "../data/StopDataProvider";
+
+import 'leaflet/dist/leaflet.css'
+import 'react-leaflet-markercluster/styles'
+
+import { useEffect, useState } from 'react';
+import LineIcon from '../components/LineIcon';
+import { Link } from 'react-router';
+import { MapContainer } from "react-leaflet/MapContainer";
+import { TileLayer } from "react-leaflet/TileLayer";
+import { Marker } from "react-leaflet/Marker";
+import { Popup } from "react-leaflet/Popup";
+import MarkerClusterGroup from "react-leaflet-markercluster";
const sdp = new StopDataProvider();
export function StopMap() {
- const [data, setData] = useState<Stop[] | null>(null)
- const navigate = useNavigate();
+ const [stops, setStops] = useState<Stop[]>([]);
+ const position = [42.229188855975046, -8.72246955783102]
useEffect(() => {
- sdp.getStops().then((stops: Stop[]) => setData(stops))
+ sdp.getStops().then((stops) => { setStops(stops); });
}, []);
- const handleStopSearch = async (event: React.FormEvent) => {
- event.preventDefault()
-
- const stopId = (event.target as HTMLFormElement).stopId.value
- const searchNumber = parseInt(stopId)
- if (data?.find(stop => stop.stopId === searchNumber)) {
- navigate(`/estimates/${searchNumber}`)
- } else {
- alert("Parada no encontrada")
- }
- }
-
- if (data === null) return <h1 className="page-title">Loading...</h1>
-
return (
- <div className="page-container">
- <h1 className="page-title">Map View</h1>
-
- <div className="map-container">
- {/* Map placeholder - in a real implementation, this would be a map component */}
- <div style={{
- height: '100%',
- backgroundColor: '#f0f0f0',
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- borderRadius: '8px'
- }}>
- <p>Map will be displayed here</p>
- </div>
- </div>
-
- <form className="search-form" onSubmit={handleStopSearch}>
- <div className="form-group">
- <label className="form-label" htmlFor="stopId">
- Find Stop by ID
- </label>
- <input className="form-input" type="number" placeholder="Stop ID" id="stopId" />
- </div>
-
- <button className="form-button" type="submit">Search</button>
- </form>
+ <MapContainer center={position} zoom={14} scrollWheelZoom={true} style={{ height: '100%' }}>
+ <TileLayer
+ attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a>, &copy; <a href="https://carto.com/attributions">CARTO</a>'
+ url="https://d.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png"
+ />
+ <MarkerClusterGroup>
+ {stops.map((stop) => (
+ <Marker key={stop.stopId} position={[stop.latitude, stop.longitude]}>
+ <Popup>
+ <Link to={`/estimates/${stop.stopId}`}>{stop.name}</Link>
+ <br />
+ {stop.lines.map((line) => (
+ <LineIcon key={line} line={line} />
+ ))}
+ </Popup>
+ </Marker>
+ ))}
+ </MarkerClusterGroup>
- <div className="list-container">
- <h2 className="page-subtitle">Nearby Stops</h2>
- <ul className="list">
- {data?.slice(0, 5).map((stop: Stop) => (
- <li className="list-item" key={stop.stopId}>
- <Link className="list-item-link" to={`/estimates/${stop.stopId}`}>
- ({stop.stopId}) {stop.name}
- <div className="line-icons">
- {stop.lines?.map(line => <LineIcon key={line} line={line} />)}
- </div>
- </Link>
- </li>
- ))}
- </ul>
- </div>
- </div>
- )
+ </MapContainer>
+ );
}