aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/app
diff options
context:
space:
mode:
authorAriel Costas Guerrero <ariel@costas.dev>2026-01-02 01:08:41 +0100
committerAriel Costas Guerrero <ariel@costas.dev>2026-01-02 01:08:41 +0100
commita3eb2d0441ae18f75604a4bee64db18391469837 (patch)
tree8994c1987afdd9436ba0699236439d3eb6c3f04d /src/frontend/app
parentdd544d713a2af4713c61ae0d2050f2861cc0892a (diff)
feat: Integrate Geoapify geocoding service and update configuration
Diffstat (limited to 'src/frontend/app')
-rw-r--r--src/frontend/app/components/PlannerOverlay.tsx26
-rw-r--r--src/frontend/app/config/constants.ts5
-rw-r--r--src/frontend/app/contexts/PageTitleContext.tsx3
-rw-r--r--src/frontend/app/routes/planner.tsx10
-rw-r--r--src/frontend/app/tailwind-full.css54
-rw-r--r--src/frontend/app/tailwind.css54
6 files changed, 101 insertions, 51 deletions
diff --git a/src/frontend/app/components/PlannerOverlay.tsx b/src/frontend/app/components/PlannerOverlay.tsx
index cbb4ac1..facf6f9 100644
--- a/src/frontend/app/components/PlannerOverlay.tsx
+++ b/src/frontend/app/components/PlannerOverlay.tsx
@@ -147,24 +147,8 @@ export const PlannerOverlay: React.FC<PlannerOverlayProps> = ({
const sortedRemoteResults = useMemo(() => {
const order: Record<string, number> = { venue: 0, address: 1, street: 2 };
- const q = pickerQuery.trim().toLowerCase();
- const base = q
- ? remoteResults.filter(
- (s) =>
- (s.name || "").toLowerCase().includes(q) ||
- (s.label || "").toLowerCase().includes(q)
- )
- : remoteResults;
- return [...base].sort((a, b) => {
- const oa = order[a.layer || ""] ?? 99;
- const ob = order[b.layer || ""] ?? 99;
- if (oa !== ob) return oa - ob;
- // Secondary: shorter label first, then name alpha
- const la = (a.label || "").length;
- const lb = (b.label || "").length;
- if (la !== lb) return la - lb;
- return (a.name || "").localeCompare(b.name || "");
- });
+
+ return remoteResults;
}, [remoteResults, pickerQuery]);
const openPicker = (field: PickerField) => {
@@ -251,7 +235,7 @@ export const PlannerOverlay: React.FC<PlannerOverlayProps> = ({
console.error("[PlannerOverlay] Geolocation error:", err);
setLocationLoading(false);
},
- { enableHighAccuracy: true, timeout: 10000 }
+ { enableHighAccuracy: false, maximumAge: 60000, timeout: 10000 }
);
},
[setOrigin, t]
@@ -282,7 +266,7 @@ export const PlannerOverlay: React.FC<PlannerOverlayProps> = ({
} finally {
if (!cancelled) setRemoteLoading(false);
}
- }, 250);
+ }, 400);
return () => {
cancelled = true;
@@ -564,7 +548,7 @@ export const PlannerOverlay: React.FC<PlannerOverlayProps> = ({
<button
type="button"
className="flex w-full items-center justify-between px-4 py-3 text-left hover:bg-slate-50 dark:hover:bg-slate-800 disabled:opacity-50 transition-colors duration-200"
- onClick={setOriginFromCurrentLocation}
+ onClick={() => setOriginFromCurrentLocation}
disabled={locationLoading}
>
<div className="flex items-center gap-2">
diff --git a/src/frontend/app/config/constants.ts b/src/frontend/app/config/constants.ts
index a130f87..3cbb37c 100644
--- a/src/frontend/app/config/constants.ts
+++ b/src/frontend/app/config/constants.ts
@@ -1,12 +1,7 @@
import type { LngLatLike } from "maplibre-gl";
-export type RegionId = "vigo";
-
export const APP_CONSTANTS = {
id: "vigo",
-
- consolidatedCirculationsEndpoint: "/api/vigo/GetConsolidatedCirculations",
- shapeEndpoint: "/api/vigo/GetShape",
defaultCenter: {
lat: 42.229188855975046,
lng: -8.72246955783102,
diff --git a/src/frontend/app/contexts/PageTitleContext.tsx b/src/frontend/app/contexts/PageTitleContext.tsx
index a7a3ad4..a6bf348 100644
--- a/src/frontend/app/contexts/PageTitleContext.tsx
+++ b/src/frontend/app/contexts/PageTitleContext.tsx
@@ -38,7 +38,6 @@ export const usePageTitle = (title: string) => {
setTitle(title);
document.title = `${title} - EnMarcha`;
- return () => {
- };
+ return () => {};
}, [title, setTitle]);
};
diff --git a/src/frontend/app/routes/planner.tsx b/src/frontend/app/routes/planner.tsx
index b71d211..32c37c0 100644
--- a/src/frontend/app/routes/planner.tsx
+++ b/src/frontend/app/routes/planner.tsx
@@ -312,14 +312,14 @@ const ItineraryDetail = ({
const stopKey = leg.from.name || leg.from.stopId;
if (!arrivalsByStop[stopKey]) {
try {
+ //TODO: Allow multiple stops one request
const resp = await fetch(
- `${APP_CONSTANTS.consolidatedCirculationsEndpoint}?stopId=${encodeURIComponent(leg.from.stopCode || leg.from.stopId)}`,
+ `/api/stops/arrivals?id=${encodeURIComponent(leg.from.stopId)}`,
{ headers: { Accept: "application/json" } }
);
if (resp.ok) {
- const data: ConsolidatedCirculation[] = await resp.json();
- arrivalsByStop[stopKey] = data;
+ arrivalsByStop[stopKey] = await resp.json() satisfies ConsolidatedCirculation[];
}
} catch (err) {
console.warn(
@@ -574,8 +574,8 @@ const ItineraryDetail = ({
linesToShow.push(previousLine);
}
- return nextArrivals[leg.from.name || leg.from.stopId]
- .filter((circ) => linesToShow.includes(circ.line))
+ return nextArrivals[leg.from.stopId]
+ ?.filter((circ) => linesToShow.includes(circ.line))
.slice(0, 3)
.map((circ, idx) => {
const minutes =
diff --git a/src/frontend/app/tailwind-full.css b/src/frontend/app/tailwind-full.css
index e7c4dd3..9b7da06 100644
--- a/src/frontend/app/tailwind-full.css
+++ b/src/frontend/app/tailwind-full.css
@@ -16,16 +16,52 @@
--color-accent: var(--button-background-color);
/* Generated-like palette using color-mix for flexibility */
- --color-primary-50: color-mix(in oklab, var(--button-background-color) 5%, white);
- --color-primary-100: color-mix(in oklab, var(--button-background-color) 10%, white);
- --color-primary-200: color-mix(in oklab, var(--button-background-color) 20%, white);
- --color-primary-300: color-mix(in oklab, var(--button-background-color) 40%, white);
- --color-primary-400: color-mix(in oklab, var(--button-background-color) 60%, white);
+ --color-primary-50: color-mix(
+ in oklab,
+ var(--button-background-color) 5%,
+ white
+ );
+ --color-primary-100: color-mix(
+ in oklab,
+ var(--button-background-color) 10%,
+ white
+ );
+ --color-primary-200: color-mix(
+ in oklab,
+ var(--button-background-color) 20%,
+ white
+ );
+ --color-primary-300: color-mix(
+ in oklab,
+ var(--button-background-color) 40%,
+ white
+ );
+ --color-primary-400: color-mix(
+ in oklab,
+ var(--button-background-color) 60%,
+ white
+ );
--color-primary-500: var(--button-background-color);
- --color-primary-600: color-mix(in oklab, var(--button-background-color) 80%, black);
- --color-primary-700: color-mix(in oklab, var(--button-background-color) 60%, black);
- --color-primary-800: color-mix(in oklab, var(--button-background-color) 40%, black);
- --color-primary-900: color-mix(in oklab, var(--button-background-color) 20%, black);
+ --color-primary-600: color-mix(
+ in oklab,
+ var(--button-background-color) 80%,
+ black
+ );
+ --color-primary-700: color-mix(
+ in oklab,
+ var(--button-background-color) 60%,
+ black
+ );
+ --color-primary-800: color-mix(
+ in oklab,
+ var(--button-background-color) 40%,
+ black
+ );
+ --color-primary-900: color-mix(
+ in oklab,
+ var(--button-background-color) 20%,
+ black
+ );
}
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
diff --git a/src/frontend/app/tailwind.css b/src/frontend/app/tailwind.css
index 7438ac7..9359f44 100644
--- a/src/frontend/app/tailwind.css
+++ b/src/frontend/app/tailwind.css
@@ -19,16 +19,52 @@
--color-accent: var(--button-background-color);
/* Generated-like palette using color-mix for flexibility */
- --color-primary-50: color-mix(in oklab, var(--button-background-color) 5%, white);
- --color-primary-100: color-mix(in oklab, var(--button-background-color) 10%, white);
- --color-primary-200: color-mix(in oklab, var(--button-background-color) 20%, white);
- --color-primary-300: color-mix(in oklab, var(--button-background-color) 40%, white);
- --color-primary-400: color-mix(in oklab, var(--button-background-color) 60%, white);
+ --color-primary-50: color-mix(
+ in oklab,
+ var(--button-background-color) 5%,
+ white
+ );
+ --color-primary-100: color-mix(
+ in oklab,
+ var(--button-background-color) 10%,
+ white
+ );
+ --color-primary-200: color-mix(
+ in oklab,
+ var(--button-background-color) 20%,
+ white
+ );
+ --color-primary-300: color-mix(
+ in oklab,
+ var(--button-background-color) 40%,
+ white
+ );
+ --color-primary-400: color-mix(
+ in oklab,
+ var(--button-background-color) 60%,
+ white
+ );
--color-primary-500: var(--button-background-color);
- --color-primary-600: color-mix(in oklab, var(--button-background-color) 80%, black);
- --color-primary-700: color-mix(in oklab, var(--button-background-color) 60%, black);
- --color-primary-800: color-mix(in oklab, var(--button-background-color) 40%, black);
- --color-primary-900: color-mix(in oklab, var(--button-background-color) 20%, black);
+ --color-primary-600: color-mix(
+ in oklab,
+ var(--button-background-color) 80%,
+ black
+ );
+ --color-primary-700: color-mix(
+ in oklab,
+ var(--button-background-color) 60%,
+ black
+ );
+ --color-primary-800: color-mix(
+ in oklab,
+ var(--button-background-color) 40%,
+ black
+ );
+ --color-primary-900: color-mix(
+ in oklab,
+ var(--button-background-color) 20%,
+ black
+ );
}
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));