From 80f6263516e307bcc6d887f6f91757bc73ae63f2 Mon Sep 17 00:00:00 2001
From: Copilot <198982749+Copilot@users.noreply.github.com>
Date: Fri, 14 Nov 2025 17:34:28 +0100
Subject: Add loading states, error handling, and refresh feedback to stops-$id
page (#89)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: arielcostas <94913521+arielcostas@users.noreply.github.com>
---
.../Stops/ConsolidatedCirculationListSkeleton.tsx | 45 ++++++++++++++++++++++
src/frontend/app/routes/estimates-$id.css | 25 ++++++++++++
src/frontend/app/routes/stops-$id.tsx | 36 ++++++++++++-----
3 files changed, 97 insertions(+), 9 deletions(-)
create mode 100644 src/frontend/app/components/Stops/ConsolidatedCirculationListSkeleton.tsx
(limited to 'src/frontend/app')
diff --git a/src/frontend/app/components/Stops/ConsolidatedCirculationListSkeleton.tsx b/src/frontend/app/components/Stops/ConsolidatedCirculationListSkeleton.tsx
new file mode 100644
index 0000000..43f02ca
--- /dev/null
+++ b/src/frontend/app/components/Stops/ConsolidatedCirculationListSkeleton.tsx
@@ -0,0 +1,45 @@
+import React from "react";
+import Skeleton, { SkeletonTheme } from "react-loading-skeleton";
+import "react-loading-skeleton/dist/skeleton.css";
+import "./ConsolidatedCirculationList.css";
+
+export const ConsolidatedCirculationListSkeleton: React.FC = () => {
+ return (
+
+
+
+
+
+
+
+ {[1, 2, 3, 4, 5].map((i) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+ );
+};
diff --git a/src/frontend/app/routes/estimates-$id.css b/src/frontend/app/routes/estimates-$id.css
index 0658156..81fba1d 100644
--- a/src/frontend/app/routes/estimates-$id.css
+++ b/src/frontend/app/routes/estimates-$id.css
@@ -268,3 +268,28 @@
[data-theme="dark"] .experimental-notice strong {
color: #ffd966;
}
+
+.refresh-status {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ justify-content: center;
+ padding: 0.75rem 1rem;
+ margin-bottom: 1rem;
+ background-color: rgba(0, 123, 255, 0.1);
+ border: 1px solid rgba(0, 123, 255, 0.2);
+ border-radius: 8px;
+ color: var(--primary-color);
+ font-size: 0.9rem;
+ font-weight: 500;
+}
+
+.refresh-status .refresh-icon {
+ width: 1rem;
+ height: 1rem;
+}
+
+[data-theme="dark"] .refresh-status {
+ background-color: rgba(0, 123, 255, 0.15);
+ border-color: rgba(0, 123, 255, 0.3);
+}
diff --git a/src/frontend/app/routes/stops-$id.tsx b/src/frontend/app/routes/stops-$id.tsx
index 7d533a5..86e74d9 100644
--- a/src/frontend/app/routes/stops-$id.tsx
+++ b/src/frontend/app/routes/stops-$id.tsx
@@ -11,6 +11,8 @@ import { type RegionId, getRegionConfig } from "~/data/RegionConfig";
import { StopAlert } from "~/components/StopAlert";
import LineIcon from "~/components/LineIcon";
import { ConsolidatedCirculationList } from "~/components/Stops/ConsolidatedCirculationList";
+import { ConsolidatedCirculationListSkeleton } from "~/components/Stops/ConsolidatedCirculationListSkeleton";
+import { ErrorDisplay } from "~/components/ErrorDisplay";
export interface ConsolidatedCirculation {
line: string;
@@ -197,7 +199,7 @@ export default function Estimates() {
- {/* TODO: Implement skeleton */}
+
@@ -255,17 +257,33 @@ export default function Estimates() {
+ {(isManualRefreshing || dataLoading) && (
+
+
+ {t("estimates.refreshing", "Actualizando datos...")}
+
+ )}
+
{stopData && }
- {data ? (
- <>
-
- >
+ {dataLoading ? (
+
+ ) : dataError ? (
+
+ ) : data ? (
+
) : null}
--
cgit v1.3