diff options
| author | Ariel Costas Guerrero <ariel@costas.dev> | 2025-05-12 17:57:33 +0200 |
|---|---|---|
| committer | Ariel Costas Guerrero <ariel@costas.dev> | 2025-05-12 17:57:49 +0200 |
| commit | 1b54ef6a7da4b2d356a2a33abf98cbb7bf39df2f (patch) | |
| tree | ec86200071d92ecf7390f472e515cc8a40421f1b /src/pages | |
| parent | a327ed48c6d14bf2ccaf8fb0fa4b9ea641481748 (diff) | |
Fix bugs, add new setting, make app great again
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/Settings.tsx | 23 | ||||
| -rw-r--r-- | src/pages/StopList.tsx | 51 |
2 files changed, 48 insertions, 26 deletions
diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index e4a1a31..1ad15ab 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -2,7 +2,7 @@ import { useApp } from "../AppContext"; import "../styles/Settings.css"; export function Settings() { - const { theme, setTheme, tableStyle, setTableStyle } = useApp(); + const { theme, setTheme, tableStyle, setTableStyle, mapPositionMode, setMapPositionMode } = useApp(); return ( <div className="about-page"> @@ -15,20 +15,25 @@ export function Settings() { <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 as "light" | "dark")} - style={{ backgroundColor: theme === "dark" ? "#333" : "#fff", color: theme === "dark" ? "#fff" : "#000" }}> + <select id="theme" className="form-select-inline" value={theme} onChange={(e) => setTheme(e.target.value as "light" | "dark")}> <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 as "regular" | "grouped")} - style={{ backgroundColor: theme === "dark" ? "#333" : "#fff", color: theme === "dark" ? "#fff" : "#000" }}> + <select id="tableStyle" className="form-select-inline" value={tableStyle} onChange={(e) => setTableStyle(e.target.value as "regular" | "grouped")}> <option value="regular">Mostrar por orden</option> <option value="grouped">Agrupar por línea</option> </select> </div> + <div className="settings-content-inline"> + <label htmlFor="mapPositionMode" className="form-label-inline">Posición del mapa:</label> + <select id="mapPositionMode" className="form-select-inline" value={mapPositionMode} onChange={e => setMapPositionMode(e.target.value as 'gps' | 'last')}> + <option value="gps">Posición GPS</option> + <option value="last">Donde lo dejé</option> + </select> + </div> <details className="form-details"> <summary>¿Qué significa esto?</summary> <p> @@ -44,16 +49,16 @@ export function Settings() { </section> <h2>Créditos</h2> <p> - <a href="https://github.com/arielcostas/urbanovigo-web" className="about-link" style={{ color: theme === "dark" ? "#bbb" : "#000" }}> + <a href="https://github.com/arielcostas/urbanovigo-web" className="about-link" rel="nofollow noreferrer noopener"> Código en GitHub </a> - - Desarrollado por <a href="https://www.costas.dev" className="about-link" style={{ color: theme === "dark" ? "#bbb" : "#000" }}> + Desarrollado por <a href="https://www.costas.dev" className="about-link" rel="nofollow noreferrer noopener"> Ariel Costas </a> </p> <p> - Datos obtenidos de <a href="https://datos.vigo.org" style={{ color: theme === "dark" ? "#bbb" : "#000" }}>datos.vigo.org</a> bajo - licencia <a href="https://opendefinition.org/licenses/odc-by/" style={{ color: theme === "dark" ? "#bbb" : "#000" }}>Open Data Commons Attribution License</a> + Datos obtenidos de <a href="https://datos.vigo.org" className="about-link" rel="nofollow noreferrer noopener">datos.vigo.org</a> bajo + licencia <a href="https://opendefinition.org/licenses/odc-by/" className="about-link" rel="nofollow noreferrer noopener">Open Data Commons Attribution License</a> </p> </div> ) diff --git a/src/pages/StopList.tsx b/src/pages/StopList.tsx index a2269ec..b965456 100644 --- a/src/pages/StopList.tsx +++ b/src/pages/StopList.tsx @@ -1,35 +1,54 @@ -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import StopDataProvider, { Stop } from "../data/StopDataProvider"; import StopItem from "../components/StopItem"; import Fuse from "fuse.js"; const placeholders = [ - "Urzaiz", - "Gran Vía", - "Castelao", - "García Barbón", - "Valladares", - "Florida", - "Pizarro", - "Estrada Madrid", - "Sanjurjo Badía" + "Urzaiz", + "Gran Vía", + "Castelao", + "García Barbón", + "Valladares", + "Florida", + "Pizarro", + "Estrada Madrid", + "Sanjurjo Badía" ]; export function StopList() { const [data, setData] = useState<Stop[] | null>(null) const [searchResults, setSearchResults] = useState<Stop[] | null>(null); + const searchTimeout = useRef<NodeJS.Timeout | null>(null); + + const randomPlaceholder = useMemo(() => placeholders[Math.floor(Math.random() * placeholders.length)], []); + const fuse = useMemo(() => new Fuse(data || [], { threshold: 0.3, keys: ['name.original'] }), [data]); useEffect(() => { StopDataProvider.getStops().then((stops: Stop[]) => setData(stops)) }, []); const handleStopSearch = (event: React.ChangeEvent<HTMLInputElement>) => { - const stopName = event.target.value; - if (data) { - const fuse = new Fuse(data, { keys: ['name'], threshold: 0.3 }); - const results = fuse.search(stopName).map(result => result.item); - setSearchResults(results); + const stopName = event.target.value || ""; + + if (searchTimeout.current) { + clearTimeout(searchTimeout.current); } + + searchTimeout.current = setTimeout(() => { + if (stopName.length === 0) { + setSearchResults(null); + return; + } + + if (!data) { + console.error("No data available for search"); + return; + } + + const results = fuse.search(stopName); + const items = results.map(result => result.item); + setSearchResults(items); + }, 300); } const favouritedStops = useMemo(() => { @@ -50,8 +69,6 @@ export function StopList() { if (data === null) return <h1 className="page-title">Loading...</h1> - const randomPlaceholder = placeholders[Math.floor(Math.random() * placeholders.length)]; - return ( <div className="page-container"> <h1 className="page-title">UrbanoVigo Web</h1> |
