diff options
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/Estimates.tsx | 16 | ||||
| -rw-r--r-- | src/pages/Map.tsx | 101 |
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='© <a href="http://osm.org/copyright">OpenStreetMap</a>, © <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> + ); } |
