From 7302db69f7cd64c21523a99045daf897f354f95f Mon Sep 17 00:00:00 2001 From: ramvignesh-b Date: Mon, 11 May 2026 13:59:36 +0530 Subject: [PATCH] feat: add last updated timestamp to provider tokens in dashboard and API --- src/core/TokenManager.ts | 1 + src/routes/api.ts | 3 ++- src/views/dashboard.html | 35 ++++++++++++++++++++++++++++------- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/core/TokenManager.ts b/src/core/TokenManager.ts index 7097b3a..a5c30fb 100644 --- a/src/core/TokenManager.ts +++ b/src/core/TokenManager.ts @@ -39,5 +39,6 @@ export class TokenManager { tokens.expiresIn, ); await this.redis.set(`provider:${providerName}:refresh_token`, tokens.refreshToken); + await this.redis.set(`provider:${providerName}:last_updated`, new Date().toISOString()); } } diff --git a/src/routes/api.ts b/src/routes/api.ts index c426303..dc3991a 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -17,7 +17,8 @@ apiRoutes.get("/status", async (c) => { for (const provider of Object.keys(providers)) { const accessToken = await redis.get(`provider:${provider}:access_token`); const refreshToken = await redis.get(`provider:${provider}:refresh_token`); - status[provider] = { accessToken, refreshToken }; + const lastUpdated = await redis.get(`provider:${provider}:last_updated`); + status[provider] = { accessToken, refreshToken, lastUpdated } as any; } return c.json(status); diff --git a/src/views/dashboard.html b/src/views/dashboard.html index a124de1..10b10f9 100644 --- a/src/views/dashboard.html +++ b/src/views/dashboard.html @@ -140,13 +140,14 @@
-
@@ -193,12 +194,17 @@ Provider - Access + + Access Token - Refresh + + Refresh Token + class="font-bold uppercase tracking-wider text-[10px] opacity-60 px-6 whitespace-nowrap"> + Last Updated + Actions @@ -291,17 +297,29 @@ } } + function formatTimeAgo(dateString) { + if (!dateString) return 'Never'; + const date = new Date(dateString); + const now = new Date(); + const diffInSeconds = Math.floor((now - date) / 1000); + + if (diffInSeconds < 60) return 'Just now'; + if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)}m ago`; + if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)}h ago`; + return date.toLocaleDateString(); + } + function renderTable() { providerTableBody.innerHTML = ''; const entries = Object.entries(providerData); if (entries.length === 0) { - providerTableBody.innerHTML = 'No providers configured yet.'; + providerTableBody.innerHTML = 'No providers configured yet.'; return; } for (const [name, config] of entries) { - const status = tokenStatus[name] || { accessToken: null, refreshToken: null }; + const status = tokenStatus[name] || { accessToken: null, refreshToken: null, lastUpdated: null }; const row = document.createElement('tr'); row.className = "hover:bg-base-200/30 transition-colors group"; @@ -314,6 +332,9 @@ ${renderTokenCell(name, 'access', status.accessToken)} ${renderTokenCell(name, 'refresh', status.refreshToken)} + + ${formatTimeAgo(status.lastUpdated)} +