From 77cdd394b947a99b70654cd1f5aff3ee724b76fc Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero Date: Thu, 1 Jan 2026 02:46:29 +0100 Subject: Add enmarcha announcement --- .../app/components/EnMarchaAnnouncement.tsx | 119 +++++++++++++++++++++ src/frontend/app/components/layout/AppShell.tsx | 5 + src/frontend/app/hooks/useEnMarchaAnnouncement.ts | 29 +++++ src/frontend/app/i18n/locales/en-GB.json | 17 +++ src/frontend/app/i18n/locales/es-ES.json | 17 +++ src/frontend/app/i18n/locales/gl-ES.json | 17 +++ 6 files changed, 204 insertions(+) create mode 100644 src/frontend/app/components/EnMarchaAnnouncement.tsx create mode 100644 src/frontend/app/hooks/useEnMarchaAnnouncement.ts (limited to 'src/frontend') diff --git a/src/frontend/app/components/EnMarchaAnnouncement.tsx b/src/frontend/app/components/EnMarchaAnnouncement.tsx new file mode 100644 index 0000000..0e7d0dd --- /dev/null +++ b/src/frontend/app/components/EnMarchaAnnouncement.tsx @@ -0,0 +1,119 @@ +import { AlertCircle, CheckCircle2, ExternalLink, Smartphone, X } from "lucide-react"; +import React from "react"; +import { useTranslation } from "react-i18next"; +import { Sheet } from "react-modal-sheet"; + +interface EnMarchaAnnouncementProps { + isOpen: boolean; + onClose: () => void; +} + +export const EnMarchaAnnouncement: React.FC = ({ + isOpen, + onClose, +}) => { + const { t } = useTranslation(); + + const features = [ + "feature_planner", + "feature_realtime", + "feature_operators", + "feature_ui", + "feature_more", + ]; + + return ( + + + + +
+
+

+ {t("enmarcha_announcement.title")} +

+ +
+ +
+
+ +

+ {t("enmarcha_announcement.discontinuation_notice")} +

+
+ +

+ {t("enmarcha_announcement.description")} +

+ +
+

+ {t("enmarcha_announcement.features_title")} +

+
    + {features.map((feature) => ( +
  • + + {t(`enmarcha_announcement.${feature}`)} +
  • + ))} +
+
+ + + {t("enmarcha_announcement.link_text")} + + +
+ +
+
+ +

+ {t("enmarcha_announcement.install_title")} +

+
+ +
+
+

Android

+
+

{t("enmarcha_announcement.android_chrome")}

+

{t("enmarcha_announcement.android_firefox")}

+
+
+ +
+

iOS

+

+ {t("enmarcha_announcement.ios_safari")} +

+
+
+
+ + +
+
+
+ +
+ ); +}; diff --git a/src/frontend/app/components/layout/AppShell.tsx b/src/frontend/app/components/layout/AppShell.tsx index afc19f3..1088035 100644 --- a/src/frontend/app/components/layout/AppShell.tsx +++ b/src/frontend/app/components/layout/AppShell.tsx @@ -1,9 +1,11 @@ import React, { useState } from "react"; import { Outlet } from "react-router"; +import { useEnMarchaAnnouncement } from "~/hooks/useEnMarchaAnnouncement"; import { PageTitleProvider, usePageTitleContext, } from "~/contexts/PageTitleContext"; +import { EnMarchaAnnouncement } from "../EnMarchaAnnouncement"; import { ThemeColorManager } from "../ThemeColorManager"; import "./AppShell.css"; import { Drawer } from "./Drawer"; @@ -13,6 +15,7 @@ import NavBar from "./NavBar"; const AppShellContent: React.FC = () => { const { title } = usePageTitleContext(); const [isDrawerOpen, setIsDrawerOpen] = useState(false); + const { isOpen, closeAnnouncement } = useEnMarchaAnnouncement(); return (
@@ -31,6 +34,8 @@ const AppShellContent: React.FC = () => {
+ +
); }; diff --git a/src/frontend/app/hooks/useEnMarchaAnnouncement.ts b/src/frontend/app/hooks/useEnMarchaAnnouncement.ts new file mode 100644 index 0000000..d135465 --- /dev/null +++ b/src/frontend/app/hooks/useEnMarchaAnnouncement.ts @@ -0,0 +1,29 @@ +import { useEffect, useState } from "react"; + +export const useEnMarchaAnnouncement = () => { + const [isOpen, setIsOpen] = useState(false); + + useEffect(() => { + const lastShown = localStorage.getItem("enmarcha_announcement_last_shown"); + const today = new Date().toISOString().split("T")[0]; + + if (lastShown !== today) { + // Show after a short delay to not overwhelm the user immediately on load + const timer = setTimeout(() => { + setIsOpen(true); + }, 2000); + return () => clearTimeout(timer); + } + }, []); + + const closeAnnouncement = () => { + const today = new Date().toISOString().split("T")[0]; + localStorage.setItem("enmarcha_announcement_last_shown", today); + setIsOpen(false); + }; + + return { + isOpen, + closeAnnouncement, + }; +}; diff --git a/src/frontend/app/i18n/locales/en-GB.json b/src/frontend/app/i18n/locales/en-GB.json index 819329e..d8a3134 100644 --- a/src/frontend/app/i18n/locales/en-GB.json +++ b/src/frontend/app/i18n/locales/en-GB.json @@ -166,6 +166,23 @@ "lines": { "description": "Below is a list of Vigo urban bus lines with their respective routes and links to official timetables." }, + "enmarcha_announcement": { + "title": "Busurbano is now EnMarcha", + "description": "Busurbano is evolving into EnMarcha. An updated version with new features, UI improvements, and designed to guide you across Galicia.", + "discontinuation_notice": "Notice: Busurbano will be discontinued on January 31, 2026.", + "features_title": "What's new?", + "feature_planner": "Plan your journeys across Galicia: city buses (Vigo, Coruña, and soon Santiago), rail services, and Xunta interurban buses.", + "feature_realtime": "Real-time arrival estimates for Vigo, A Coruña, and Santiago (currently in development).", + "feature_operators": "Comprehensive transit data from multiple operators in a single app.", + "feature_ui": "A modern, fast, and polished interface built for your daily commute.", + "feature_more": "Exciting new features are already on the way.", + "link_text": "Try EnMarcha now", + "install_title": "How to install the app", + "android_chrome": "In Chrome (Android): Tap ⋮ and select \"Install app\".", + "android_firefox": "In Firefox (Android): Tap ⋮ and select \"Install\".", + "ios_safari": "In Safari (iOS): Tap the share button ⎋ and select \"Add to Home Screen\".", + "close": "Stay on Busurbano" + }, "stop_help": { "title": "Estimates guide", "realtime_ok": "Reliable real-time", diff --git a/src/frontend/app/i18n/locales/es-ES.json b/src/frontend/app/i18n/locales/es-ES.json index 1e67073..4b55733 100644 --- a/src/frontend/app/i18n/locales/es-ES.json +++ b/src/frontend/app/i18n/locales/es-ES.json @@ -166,6 +166,23 @@ "lines": { "description": "A continuación se muestra una lista de las líneas de autobús urbano de Vigo con sus respectivas rutas y enlaces a los horarios oficiales." }, + "enmarcha_announcement": { + "title": "Busurbano ahora es EnMarcha", + "description": "Busurbano evoluciona para convertirse en EnMarcha. Una versión actualizada con nuevas funciones, mejoras en la interfaz y diseñada para acompañarte en tus viajes por Galicia.", + "discontinuation_notice": "Aviso: Busurbano dejará de estar disponible el 31 de enero de 2026.", + "features_title": "¿Qué hay de nuevo?", + "feature_planner": "Planifica tus rutas por toda Galicia: buses urbanos (Vigo, Coruña y pronto Santiago), trenes y buses interurbanos de la Xunta.", + "feature_realtime": "Tiempos de llegada en tiempo real para Vigo, A Coruña y Santiago (en fase beta).", + "feature_operators": "Toda la información de transporte de múltiples operadores en un solo lugar.", + "feature_ui": "Una interfaz moderna, rápida y optimizada para tu día a día.", + "feature_more": "Nuevas funcionalidades en camino para mejorar tu movilidad.", + "link_text": "Probar EnMarcha ahora", + "install_title": "Cómo instalar la aplicación", + "android_chrome": "En Chrome (Android): Pulsa ⋮ y selecciona \"Instalar aplicación\".", + "android_firefox": "En Firefox (Android): Pulsa ⋮ y selecciona \"Instalar\".", + "ios_safari": "En Safari (iOS): Pulsa el botón compartir ⎋ y selecciona \"Añadir a la pantalla de inicio\".", + "close": "Seguir en Busurbano" + }, "stop_help": { "title": "Guía de estimaciones", "realtime_ok": "Tiempo real fiable", diff --git a/src/frontend/app/i18n/locales/gl-ES.json b/src/frontend/app/i18n/locales/gl-ES.json index 4148bfa..0cb238d 100644 --- a/src/frontend/app/i18n/locales/gl-ES.json +++ b/src/frontend/app/i18n/locales/gl-ES.json @@ -166,6 +166,23 @@ "lines": { "description": "A continuación móstrase unha lista das liñas de autobús urbano de Vigo coas súas respectivas rutas e ligazóns ós horarios oficiais." }, + "enmarcha_announcement": { + "title": "Busurbano agora é EnMarcha", + "description": "Busurbano evoluciona para converterse en EnMarcha. Unha versión actualizada con novas funcións, melloras na interface e deseñada para acompañarte nas túas viaxes por Galicia.", + "discontinuation_notice": "Aviso: Busurbano deixará de estar dispoñible o 31 de xaneiro de 2026.", + "features_title": "Que hai de novo?", + "feature_planner": "Planifica as túas rutas por toda Galicia: buses urbanos (Vigo, Coruña e pronto Santiago), trens e buses interurbanos da Xunta.", + "feature_realtime": "Tempos de chegada en tempo real para Vigo, A Coruña e Santiago (en desenvolvemento).", + "feature_operators": "Toda a información de transporte de múltiples operadores nun só lugar.", + "feature_ui": "Unha interface moderna, rápida e optimizada para o teu día a día.", + "feature_more": "Novas funcionalidades en camiño para mellorar a túa mobilidade.", + "link_text": "Probar EnMarcha agora", + "install_title": "Como instalar a aplicación", + "android_chrome": "En Chrome (Android): Preme ⋮ e selecciona \"Instalar aplicación\".", + "android_firefox": "En Firefox (Android): Preme ⋮ e selecciona \"Instalar\".", + "ios_safari": "En Safari (iOS): Preme o botón compartir ⎋ e selecciona \"Engadir á pantalla de inicio\".", + "close": "Seguir en Busurbano" + }, "stop_help": { "title": "Guía de estimacións", "realtime_ok": "Tempo real fiable", -- cgit v1.3