From cb2e70e42d1122e9c2e5420b095aeb1e55454c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elisi=C3=A1rio=20Couto?= Date: Mon, 8 Sep 2025 23:58:38 +0100 Subject: [PATCH] feat: implement dynamic API connection status - Move health endpoint from /health to /api/v1/health - Update frontend Dashboard to show real connection status - Add health check query that refreshes every 30 seconds - Display connected/disconnected status with appropriate icons - Show loading state while checking connection --- frontend/src/components/Dashboard.tsx | 32 ++++++++++++++++++++++++--- leggend/main.py | 27 ++++++++++++++++++++-- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/Dashboard.tsx b/frontend/src/components/Dashboard.tsx index ee2730e..1316f18 100644 --- a/frontend/src/components/Dashboard.tsx +++ b/frontend/src/components/Dashboard.tsx @@ -8,7 +8,9 @@ import { X, Home, List, - BarChart3 + BarChart3, + Wifi, + WifiOff } from 'lucide-react'; import { apiClient } from '../lib/api'; import AccountsOverview from './AccountsOverview'; @@ -28,6 +30,16 @@ export default function Dashboard() { queryFn: apiClient.getAccounts, }); + const { data: healthStatus, isLoading: healthLoading } = useQuery({ + queryKey: ['health'], + queryFn: async () => { + const response = await fetch(`${import.meta.env.VITE_API_URL || 'http://localhost:8000'}/api/v1/health`); + return response.json(); + }, + refetchInterval: 30000, // Check every 30 seconds + retry: 3, + }); + const navigation = [ { name: 'Overview', icon: Home, id: 'overview' as TabType }, { name: 'Transactions', icon: List, id: 'transactions' as TabType }, @@ -129,8 +141,22 @@ export default function Dashboard() {
- - Connected + {healthLoading ? ( + <> + + Checking... + + ) : healthStatus?.success ? ( + <> + + Connected + + ) : ( + <> + + Disconnected + + )}
diff --git a/leggend/main.py b/leggend/main.py index 24640e9..807d9fe 100644 --- a/leggend/main.py +++ b/leggend/main.py @@ -77,9 +77,32 @@ def create_app() -> FastAPI: version = "unknown" return {"message": "Leggend API is running", "version": version} - @app.get("/health") + @app.get("/api/v1/health") async def health(): - return {"status": "healthy", "config_loaded": config._config is not None} + """Health check endpoint for API connectivity""" + try: + from leggend.api.models.common import APIResponse + + config_loaded = config._config is not None + + return APIResponse( + success=True, + data={ + "status": "healthy", + "config_loaded": config_loaded, + "message": "API is running and responsive", + }, + message="Health check successful", + ) + except Exception as e: + logger.error(f"Health check failed: {e}") + from leggend.api.models.common import APIResponse + + return APIResponse( + success=False, + data={"status": "unhealthy", "error": str(e)}, + message="Health check failed", + ) return app