diff options
| author | Ariel Costas Guerrero <94913521+arielcostas@users.noreply.github.com> | 2025-03-04 00:51:42 +0100 |
|---|---|---|
| committer | Ariel Costas Guerrero <94913521+arielcostas@users.noreply.github.com> | 2025-03-04 00:51:42 +0100 |
| commit | 79f3c42b0c04c7fd77481c14e6e9c345677b8c42 (patch) | |
| tree | 6022fdb9d4cad1a77bc98eea88ad29803290f67d /src/pages | |
| parent | 0a96e26ade5d3eafe64807fcbd877742d6bcf6da (diff) | |
Add table layout like iTranvias, remake settings page
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/About.tsx | 45 | ||||
| -rw-r--r-- | src/pages/Estimates.tsx | 68 |
2 files changed, 43 insertions, 70 deletions
diff --git a/src/pages/About.tsx b/src/pages/About.tsx index 918d484..7e1b0d3 100644 --- a/src/pages/About.tsx +++ b/src/pages/About.tsx @@ -1,8 +1,9 @@ -import { Moon, Sun } from "lucide-react"; -import { useTheme } from "../ThemeContext"; +import { List, Moon, Sun, Table, Table2, TableCellsMerge, TableColumnsSplit } from "lucide-react"; +import { useApp } from "../AppContext"; +import "../styles/About.css"; export function About() { - const {theme, toggleTheme} = useTheme(); + const { theme, setTheme, tableStyle, setTableStyle } = useApp(); return ( <div className="about-page"> @@ -11,12 +12,36 @@ export function About() { Aplicación web para encontrar paradas y tiempos de llegada de los autobuses urbanos de Vigo, España. </p> - <button className="form-button" onClick={toggleTheme}> - {theme === 'light' ? - <><Moon size={24} /> Usar modo oscuro</> : - <><Sun size={24} /> Usar modo claro</> - } - </button> + <section className="settings-section"> + <h2>Ajustes</h2> + <div className="settings-content-inline"> + <label htmlFor="theme" className="form-label-inline">Modo:</label> + <select id="theme" className="form-select-inline" value={theme} onChange={(e) => setTheme(e.target.value)}> + <option value="light">Claro</option> + <option value="dark">Oscuro</option> + </select> + </div> + <div className="settings-content-inline"> + <label htmlFor="tableStyle" className="form-label-inline">Estilo de tabla:</label> + <select id="tableStyle" className="form-select-inline" value={tableStyle} onChange={(e) => setTableStyle(e.target.value)}> + <option value="regular">Mostrar por orden</option> + <option value="grouped">Agrupar por línea</option> + </select> + </div> + <details className="form-details"> + <summary>¿Qué significa esto?</summary> + <p> + La tabla de horarios puede mostrarse de dos formas: + </p> + <dl> + <dt>Mostrar por orden</dt> + <dd>Las paradas se muestran en el orden en que se visitan. Aplicaciones como Infobus (Vitrasa) usan este estilo.</dd> + <dt>Agrupar por línea</dt> + <dd>Las paradas se agrupan por la línea de autobús. Aplicaciones como iTranvias (A Coruña) o Moovit (más o menos) usan este estilo.</dd> + </dl> + </details> + </section> + <h2>Créditos</h2> <p> <a href="https://github.com/arielcostas/urbanovigo-web" className="about-link"> Código en GitHub @@ -26,7 +51,7 @@ export function About() { </a> </p> <p> - Datos obtenidos de <a href="https://datos.vigo.org">datos.vigo.org</a> bajo + Datos obtenidos de <a href="https://datos.vigo.org">datos.vigo.org</a> bajo licencia <a href="https://opendefinition.org/licenses/odc-by/">Open Data Commons Attribution License</a> </p> </div> diff --git a/src/pages/Estimates.tsx b/src/pages/Estimates.tsx index a445300..900ffc5 100644 --- a/src/pages/Estimates.tsx +++ b/src/pages/Estimates.tsx @@ -1,11 +1,13 @@ import { JSX, useEffect, useState } from "react"; import { useParams } from "react-router"; import { StopDataProvider } from "../data/StopDataProvider"; -import LineIcon from "../components/LineIcon"; import { Star } from 'lucide-react'; import "../styles/Estimates.css"; +import { RegularTable } from "../components/RegularTable"; +import { useApp } from "../AppContext"; +import { GroupedTable } from "../components/GroupedTable"; -interface StopDetails { +export interface StopDetails { stop: { id: number; name: string; @@ -32,6 +34,7 @@ export function Estimates(): JSX.Element { const [dataDate, setDataDate] = useState<Date | null>(null); const [favourited, setFavourited] = useState(false); const params = useParams(); + const { tableStyle } = useApp(); useEffect(() => { loadData(params.stopId!) @@ -48,22 +51,6 @@ export function Estimates(): JSX.Element { ); }, [params.stopId]); - const absoluteArrivalTime = (minutes: number) => { - const now = new Date() - const arrival = new Date(now.getTime() + minutes * 60000) - return Intl.DateTimeFormat(navigator.language, { - hour: '2-digit', - minute: '2-digit' - }).format(arrival) - } - - const formatDistance = (meters: number) => { - if (meters > 1024) { - return `${(meters / 1000).toFixed(1)} km`; - } else { - return `${meters} m`; - } - } const toggleFavourite = () => { if (favourited) { @@ -87,48 +74,9 @@ export function Estimates(): JSX.Element { </div> <div className="table-responsive"> - <table className="table"> - <caption>Estimaciones de llegadas a las {dataDate?.toLocaleTimeString()}</caption> - - <thead> - <tr> - <th>Línea</th> - <th>Ruta</th> - <th>Minutos</th> - <th>Metros</th> - </tr> - </thead> - - <tbody> - {data.estimates - .sort((a, b) => a.minutes - b.minutes) - .map((estimate, idx) => ( - <tr key={idx}> - <td><LineIcon line={estimate.line} /></td> - <td>{estimate.route}</td> - <td> - {estimate.minutes > 15 - ? absoluteArrivalTime(estimate.minutes) - : `${estimate.minutes} min`} - </td> - <td> - {estimate.meters > -1 - ? formatDistance(estimate.meters) - : "No disponible" - } - </td> - </tr> - ))} - </tbody> - - {data?.estimates.length === 0 && ( - <tfoot> - <tr> - <td colSpan={4}>No hay estimaciones disponibles</td> - </tr> - </tfoot> - )} - </table> + {tableStyle === 'grouped' ? + <GroupedTable data={data} dataDate={dataDate} /> : + <RegularTable data={data} dataDate={dataDate} />} </div> </div> ) |
