From 7b8594debceb93a1fa400d48fe1dcff943bd5af6 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Jun 2025 23:44:25 +0200 Subject: Implement stop sheet modal for map stop interactions (#27) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: arielcostas <94913521+arielcostas@users.noreply.github.com> Co-authored-by: Ariel Costas Guerrero --- src/frontend/app/AppContext.tsx | 124 ++++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 55 deletions(-) (limited to 'src/frontend/app/AppContext.tsx') diff --git a/src/frontend/app/AppContext.tsx b/src/frontend/app/AppContext.tsx index d8db66d..e6d8971 100644 --- a/src/frontend/app/AppContext.tsx +++ b/src/frontend/app/AppContext.tsx @@ -1,10 +1,16 @@ /* eslint-disable react-refresh/only-export-components */ -import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'; -import { type LngLatLike } from 'maplibre-gl'; - -type Theme = 'light' | 'dark'; -type TableStyle = 'regular'|'grouped'; -type MapPositionMode = 'gps' | 'last'; +import { + createContext, + useContext, + useEffect, + useState, + type ReactNode, +} from "react"; +import { type LngLatLike } from "maplibre-gl"; + +type Theme = "light" | "dark"; +type TableStyle = "regular" | "grouped"; +type MapPositionMode = "gps" | "last"; interface MapState { center: LngLatLike; @@ -42,56 +48,62 @@ const AppContext = createContext(undefined); export const AppProvider = ({ children }: { children: ReactNode }) => { //#region Theme const [theme, setTheme] = useState(() => { - const savedTheme = localStorage.getItem('theme'); + const savedTheme = localStorage.getItem("theme"); if (savedTheme) { return savedTheme as Theme; } - const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; - return prefersDark ? 'dark' : 'light'; + const prefersDark = + window.matchMedia && + window.matchMedia("(prefers-color-scheme: dark)").matches; + return prefersDark ? "dark" : "light"; }); const toggleTheme = () => { - setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light')); + setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light")); }; useEffect(() => { - document.documentElement.setAttribute('data-theme', theme); - localStorage.setItem('theme', theme); + document.documentElement.setAttribute("data-theme", theme); + localStorage.setItem("theme", theme); }, [theme]); //#endregion //#region Table Style const [tableStyle, setTableStyle] = useState(() => { - const savedTableStyle = localStorage.getItem('tableStyle'); + const savedTableStyle = localStorage.getItem("tableStyle"); if (savedTableStyle) { return savedTableStyle as TableStyle; } - return 'regular'; + return "regular"; }); const toggleTableStyle = () => { - setTableStyle((prevTableStyle) => (prevTableStyle === 'regular' ? 'grouped' : 'regular')); - } + setTableStyle((prevTableStyle) => + prevTableStyle === "regular" ? "grouped" : "regular", + ); + }; useEffect(() => { - localStorage.setItem('tableStyle', tableStyle); + localStorage.setItem("tableStyle", tableStyle); }, [tableStyle]); //#endregion //#region Map Position Mode - const [mapPositionMode, setMapPositionMode] = useState(() => { - const saved = localStorage.getItem('mapPositionMode'); - return saved === 'last' ? 'last' : 'gps'; - }); + const [mapPositionMode, setMapPositionMode] = useState( + () => { + const saved = localStorage.getItem("mapPositionMode"); + return saved === "last" ? "last" : "gps"; + }, + ); useEffect(() => { - localStorage.setItem('mapPositionMode', mapPositionMode); + localStorage.setItem("mapPositionMode", mapPositionMode); }, [mapPositionMode]); //#endregion //#region Map State const [mapState, setMapState] = useState(() => { - const savedMapState = localStorage.getItem('mapState'); + const savedMapState = localStorage.getItem("mapState"); if (savedMapState) { try { const parsed = JSON.parse(savedMapState); @@ -99,56 +111,56 @@ export const AppProvider = ({ children }: { children: ReactNode }) => { center: parsed.center || DEFAULT_CENTER, zoom: parsed.zoom || DEFAULT_ZOOM, userLocation: parsed.userLocation || null, - hasLocationPermission: parsed.hasLocationPermission || false + hasLocationPermission: parsed.hasLocationPermission || false, }; } catch (e) { - console.error('Error parsing saved map state', e); + console.error("Error parsing saved map state", e); } } return { center: DEFAULT_CENTER, zoom: DEFAULT_ZOOM, userLocation: null, - hasLocationPermission: false + hasLocationPermission: false, }; }); const setMapCenter = (center: LngLatLike) => { - setMapState(prev => { + setMapState((prev) => { const newState = { ...prev, center }; - localStorage.setItem('mapState', JSON.stringify(newState)); + localStorage.setItem("mapState", JSON.stringify(newState)); return newState; }); }; const setMapZoom = (zoom: number) => { - setMapState(prev => { + setMapState((prev) => { const newState = { ...prev, zoom }; - localStorage.setItem('mapState', JSON.stringify(newState)); + localStorage.setItem("mapState", JSON.stringify(newState)); return newState; }); }; const setUserLocation = (userLocation: LngLatLike | null) => { - setMapState(prev => { + setMapState((prev) => { const newState = { ...prev, userLocation }; - localStorage.setItem('mapState', JSON.stringify(newState)); + localStorage.setItem("mapState", JSON.stringify(newState)); return newState; }); }; const setLocationPermission = (hasLocationPermission: boolean) => { - setMapState(prev => { + setMapState((prev) => { const newState = { ...prev, hasLocationPermission }; - localStorage.setItem('mapState', JSON.stringify(newState)); + localStorage.setItem("mapState", JSON.stringify(newState)); return newState; }); }; const updateMapState = (center: LngLatLike, zoom: number) => { - setMapState(prev => { + setMapState((prev) => { const newState = { ...prev, center, zoom }; - localStorage.setItem('mapState', JSON.stringify(newState)); + localStorage.setItem("mapState", JSON.stringify(newState)); return newState; }); }; @@ -164,31 +176,33 @@ export const AppProvider = ({ children }: { children: ReactNode }) => { setUserLocation([latitude, longitude]); }, (error) => { - console.error('Error getting location:', error); + console.error("Error getting location:", error); setLocationPermission(false); - } + }, ); } } }, [mapState.hasLocationPermission, mapState.userLocation]); return ( - + {children} ); @@ -197,7 +211,7 @@ export const AppProvider = ({ children }: { children: ReactNode }) => { export const useApp = () => { const context = useContext(AppContext); if (!context) { - throw new Error('useApp must be used within a AppProvider'); + throw new Error("useApp must be used within a AppProvider"); } return context; }; -- cgit v1.3