From 5d6fd75899e96826f8e8aa0c84f7f186cbc7e471 Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero Date: Wed, 22 Oct 2025 00:06:52 +0200 Subject: Confirm region change, make app name more consistent --- README.md | 15 ++-- .../Properties/launchSettings.json | 2 +- src/frontend/app/AppContext.tsx | 14 ++-- src/frontend/app/i18n/locales/en-GB.json | 4 +- src/frontend/app/i18n/locales/es-ES.json | 2 +- src/frontend/app/i18n/locales/gl-ES.json | 2 +- src/frontend/app/root.tsx | 14 ++-- src/frontend/app/routes/settings.css | 83 ++++++++++++++++++++++ src/frontend/app/routes/settings.tsx | 72 +++++++++++++++++-- src/frontend/app/routes/stoplist.tsx | 3 +- src/frontend/public/manifest.webmanifest | 6 +- src/frontend/public/pwa-worker.js | 2 +- 12 files changed, 180 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index c4009ea..a1cfad1 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,13 @@ Busurbano is a web application designed to help users find bus stops and arrival - **Backend**: - ASP.NET Core 9 Web API - [Costasdev.VigoTransitApi](https://github.com/arielcostas/VigoTransitApi) + - WIP: Santiago de Compostela API - Not a package yet - **Mapping**: - - [Leaflet](https://leafletjs.com/) via [React-Leaflet](https://react-leaflet.js.org/) - - [Leaflet Locate Control](https://github.com/domoritz/leaflet-locatecontrol) - - [Leaflet Marker Cluster](https://github.com/Leaflet/Leaflet.markercluster) + - [MapLibre GL JS](https://maplibre.org) + - OpenStreetMap + - [OpenFreeMap tiles](https://openfreemap.org) - **Styling**: Good old CSS -- **Fonts**: [Roboto Variable](https://fonts.google.com/specimen/Roboto) via [@fontsource](https://fontsource.org/fonts/outfit) +- **Fonts**: [Roboto Variable](https://fonts.google.com/specimen/Roboto) via [@fontsource](https://fontsource.org/fonts/roboto) ## Getting Started @@ -31,6 +32,8 @@ Busurbano is a web application designed to help users find bus stops and arrival ### Installation +TODO: Update instructions + 1. Clone the repository: ```sh @@ -55,10 +58,6 @@ Busurbano is a web application designed to help users find bus stops and arrival 2. Open your browser and navigate to `http://localhost:5173`. -### Deployment - -The application is (or will soon be) deployed to [busurbano.costas.dev](https://busurbano.costas.dev) via GitHub Actions, on a normal Ubuntu server with Nginx and a reverse proxy. - ## Contributing Contributions are welcome! Please open an issue or submit a pull request. diff --git a/src/Costasdev.Busurbano.Backend/Properties/launchSettings.json b/src/Costasdev.Busurbano.Backend/Properties/launchSettings.json index 783d5cc..74f9522 100644 --- a/src/Costasdev.Busurbano.Backend/Properties/launchSettings.json +++ b/src/Costasdev.Busurbano.Backend/Properties/launchSettings.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/launchsettings.json", "profiles": { - "urbanovigoWeb": { + "busurbano": { "commandName": "Project", "dotnetRunMessages": true, "applicationUrl": "https://localhost:7240", diff --git a/src/frontend/app/AppContext.tsx b/src/frontend/app/AppContext.tsx index 1a9b511..8f47a49 100644 --- a/src/frontend/app/AppContext.tsx +++ b/src/frontend/app/AppContext.tsx @@ -7,7 +7,7 @@ import { type ReactNode, } from "react"; import { type LngLatLike } from "maplibre-gl"; -import { type RegionId, DEFAULT_REGION, getRegionConfig, isValidRegion } from "./data/RegionConfig"; +import { type RegionId, DEFAULT_REGION, getRegionConfig, isValidRegion, REGIONS } from "./data/RegionConfig"; export type Theme = "light" | "dark" | "system"; type TableStyle = "regular" | "grouped"; @@ -43,10 +43,6 @@ interface AppContextProps { setRegion: (region: RegionId) => void; } -// Coordenadas por defecto centradas en Vigo -const DEFAULT_CENTER: LngLatLike = [42.229188855975046, -8.72246955783102]; -const DEFAULT_ZOOM = 14; - const AppContext = createContext(undefined); export const AppProvider = ({ children }: { children: ReactNode }) => { @@ -187,8 +183,8 @@ export const AppProvider = ({ children }: { children: ReactNode }) => { try { const parsed = JSON.parse(savedMapState); return { - center: parsed.center || DEFAULT_CENTER, - zoom: parsed.zoom || DEFAULT_ZOOM, + center: parsed.center || REGIONS[region].defaultCenter, + zoom: parsed.zoom || REGIONS[region].defaultZoom, userLocation: parsed.userLocation || null, hasLocationPermission: parsed.hasLocationPermission || false, }; @@ -197,8 +193,8 @@ export const AppProvider = ({ children }: { children: ReactNode }) => { } } return { - center: DEFAULT_CENTER, - zoom: DEFAULT_ZOOM, + center: REGIONS[region].defaultCenter, + zoom: REGIONS[region].defaultZoom, userLocation: null, hasLocationPermission: false, }; diff --git a/src/frontend/app/i18n/locales/en-GB.json b/src/frontend/app/i18n/locales/en-GB.json index 4d0c91b..12c8121 100644 --- a/src/frontend/app/i18n/locales/en-GB.json +++ b/src/frontend/app/i18n/locales/en-GB.json @@ -1,7 +1,7 @@ { "about": { - "title": "About UrbanoVigo Web", - "description": "Web app to find stops and arrival times for Vigo's urban buses, Spain.", + "title": "About BusUrbano", + "description": "Web app to find stops and arrival times for urban buses, Spain.", "credits": "Credits", "github": "Code on GitHub", "developed_by": "Developed by", diff --git a/src/frontend/app/i18n/locales/es-ES.json b/src/frontend/app/i18n/locales/es-ES.json index 0915361..e929382 100644 --- a/src/frontend/app/i18n/locales/es-ES.json +++ b/src/frontend/app/i18n/locales/es-ES.json @@ -1,6 +1,6 @@ { "about": { - "title": "Sobre UrbanoVigo Web", + "title": "Sobre BusUrbano", "description": "Aplicación web para encontrar paradas y tiempos de llegada de los autobuses urbanos de Vigo, España.", "credits": "Créditos", "github": "Código en GitHub", diff --git a/src/frontend/app/i18n/locales/gl-ES.json b/src/frontend/app/i18n/locales/gl-ES.json index 8949333..ed1ef53 100644 --- a/src/frontend/app/i18n/locales/gl-ES.json +++ b/src/frontend/app/i18n/locales/gl-ES.json @@ -1,6 +1,6 @@ { "about": { - "title": "Sobre UrbanoVigo Web", + "title": "Sobre BusUrbano", "description": "Aplicación web para atopar paradas e tempos de chegada dos autobuses urbanos de Vigo, España.", "credits": "Créditos", "github": "Código en GitHub", diff --git a/src/frontend/app/root.tsx b/src/frontend/app/root.tsx index 25a873f..4815d2f 100644 --- a/src/frontend/app/root.tsx +++ b/src/frontend/app/root.tsx @@ -45,28 +45,28 @@ export function Layout({ children }: { children: React.ReactNode }) { - + - + - + diff --git a/src/frontend/app/routes/settings.css b/src/frontend/app/routes/settings.css index ef9fbd5..c08ed68 100644 --- a/src/frontend/app/routes/settings.css +++ b/src/frontend/app/routes/settings.css @@ -183,6 +183,76 @@ to { transform: rotate(360deg); } } +/* Modal styles */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + padding: 1rem; +} + +.modal-content { + background-color: var(--message-background-color); + padding: 2rem; + border-radius: 12px; + max-width: 500px; + width: 100%; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.modal-content h2 { + margin-top: 0; + margin-bottom: 1rem; + color: var(--text-color); +} + +.modal-content p { + margin-bottom: 1.5rem; + line-height: 1.6; + color: var(--text-color); +} + +.modal-buttons { + display: flex; + gap: 1rem; + justify-content: flex-end; +} + +.modal-button { + padding: 0.75rem 1.5rem; + border: none; + border-radius: 8px; + font-size: 1rem; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; +} + +.modal-button-cancel { + background-color: #6c757d; + color: white; +} + +.modal-button-cancel:hover { + background-color: #5a6268; +} + +.modal-button-confirm { + background-color: var(--button-background-color); + color: white; +} + +.modal-button-confirm:hover { + background-color: var(--button-hover-background-color); +} + @media (max-width: 768px) { .update-controls { flex-direction: column; @@ -192,4 +262,17 @@ .clear-cache-button { justify-content: center; } + + .modal-content { + padding: 1.5rem; + } + + .modal-buttons { + flex-direction: column; + gap: 0.5rem; + } + + .modal-button { + width: 100%; + } } diff --git a/src/frontend/app/routes/settings.tsx b/src/frontend/app/routes/settings.tsx index eae6ad8..cb64f4e 100644 --- a/src/frontend/app/routes/settings.tsx +++ b/src/frontend/app/routes/settings.tsx @@ -2,10 +2,12 @@ import { type Theme, useApp } from "../AppContext"; import "./settings.css"; import { useTranslation } from "react-i18next"; import { useState } from "react"; -import { getAvailableRegions } from "../data/RegionConfig"; +import { getAvailableRegions, REGIONS } from "../data/RegionConfig"; +import { useNavigate } from "react-router"; export default function Settings() { const { t, i18n } = useTranslation(); + const navigate = useNavigate(); const { theme, setTheme, @@ -18,6 +20,29 @@ export default function Settings() { } = useApp(); const regions = getAvailableRegions(); + const [showModal, setShowModal] = useState(false); + const [pendingRegion, setPendingRegion] = useState(null); + + const handleRegionChange = (newRegion: string) => { + if (newRegion !== region) { + setPendingRegion(newRegion); + setShowModal(true); + } + }; + + const confirmRegionChange = () => { + if (pendingRegion) { + setRegion(pendingRegion as any); + setShowModal(false); + setPendingRegion(null); + navigate("/stops"); + } + }; + + const cancelRegionChange = () => { + setShowModal(false); + setPendingRegion(null); + }; return (
@@ -33,7 +58,7 @@ export default function Settings() { id="region" className="form-select-inline" value={region} - onChange={(e) => setRegion(e.target.value as any)} + onChange={(e) => handleRegionChange(e.target.value)} > {regions.map((r) => (
); } diff --git a/src/frontend/app/routes/stoplist.tsx b/src/frontend/app/routes/stoplist.tsx index 13d3584..71b7d3c 100644 --- a/src/frontend/app/routes/stoplist.tsx +++ b/src/frontend/app/routes/stoplist.tsx @@ -6,6 +6,7 @@ import Fuse from "fuse.js"; import "./stoplist.css"; import { useTranslation } from "react-i18next"; import { useApp } from "../AppContext"; +import { REGIONS } from "~/data/RegionConfig"; export default function StopList() { const { t } = useTranslation(); @@ -100,7 +101,7 @@ export default function StopList() { return (
-

UrbanoVigo Web

+

BusUrbano - {REGIONS[region].name}

diff --git a/src/frontend/public/manifest.webmanifest b/src/frontend/public/manifest.webmanifest index fe0cf39..e685a23 100644 --- a/src/frontend/public/manifest.webmanifest +++ b/src/frontend/public/manifest.webmanifest @@ -1,9 +1,9 @@ { "$schema": "https://raw.githubusercontent.com/SchemaStore/schemastore/refs/heads/master/src/schemas/json/web-manifest.json", "id": "https://busurbano.costas.dev/", - "name": "UrbanoVigo Web", - "description": "Aplicación web para encontrar paradas y tiempos de llegada de los autobuses urbanos de Vigo, España.", - "short_name": "UrbanoVigo", + "name": "BusUrbano", + "description": "Aplicación web para encontrar paradas y tiempos de llegada de los autobuses urbanos.", + "short_name": "BusUrbano", "start_url": "/stops", "display": "standalone", "orientation": "portrait-primary", diff --git a/src/frontend/public/pwa-worker.js b/src/frontend/public/pwa-worker.js index f9bb758..810478d 100644 --- a/src/frontend/public/pwa-worker.js +++ b/src/frontend/public/pwa-worker.js @@ -1,4 +1,4 @@ -const CACHE_VERSION = "20251021b"; +const CACHE_VERSION = "20251022a"; const STATIC_CACHE_NAME = `static-cache-${CACHE_VERSION}`; const STATIC_CACHE_ASSETS = [ "/favicon.ico", -- cgit v1.3