From f0eb706d82ea0bcb72296487e99cbc1ac71b56f4 Mon Sep 17 00:00:00 2001 From: null Date: Thu, 21 May 2026 21:02:03 -0500 Subject: [PATCH] fix(ui): top navbar --- .../src/app/settings/ai-providers/page.tsx | 265 +----------- .../organisms/ProviderNavbarStatus.tsx | 388 ++++++++++++++++++ .../components/templates/DashboardShell.tsx | 5 +- 3 files changed, 401 insertions(+), 257 deletions(-) create mode 100644 frontend/src/components/organisms/ProviderNavbarStatus.tsx diff --git a/frontend/src/app/settings/ai-providers/page.tsx b/frontend/src/app/settings/ai-providers/page.tsx index 0c17ff8..a720e8e 100644 --- a/frontend/src/app/settings/ai-providers/page.tsx +++ b/frontend/src/app/settings/ai-providers/page.tsx @@ -2,7 +2,7 @@ export const dynamic = "force-dynamic"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { Bot, CheckCircle2, @@ -29,7 +29,6 @@ import { useOrganizationMembership } from "@/lib/use-organization-membership"; import type { ProviderCredentialRead, ProviderUsageLiveRead, - SubscriptionWindowRead, } from "@/api/generated/model"; import { customFetch } from "@/api/mutator"; import { @@ -152,6 +151,10 @@ const PROVIDERS: ProviderConfig[] = [ }, ]; +function announceProviderCredentialsUpdated() { + window.dispatchEvent(new Event("provider-credentials-updated")); +} + // --------------------------------------------------------------------------- // Help toggle — collapsible inline instructions // --------------------------------------------------------------------------- @@ -816,194 +819,6 @@ function UsageStrip({ credentialId, provider }: { credentialId: string; provider ); } -// --------------------------------------------------------------------------- -// Navbar provider status — compact mirror of the active provider card -// --------------------------------------------------------------------------- - -function providerShortLabel(provider: string): string { - const config = PROVIDERS.find((item) => item.id === provider); - if (!config) return provider; - return config.label.split(" ")[0].replace("/", ""); -} - -function clampPct(pct: number): number { - return Math.max(0, Math.min(100, pct)); -} - -function remainingPct(window: SubscriptionWindowRead | null): number | null { - if (!window) return null; - return clampPct(100 - window.pct_used); -} - -function remainingColor(pct: number | null): string { - if (pct == null) return "bg-[color:var(--text-quiet)]"; - if (pct <= 10) return "bg-[color:var(--danger)]"; - if (pct <= 25) return "bg-[color:var(--warning)]"; - return "bg-[color:var(--success)]"; -} - -function findSessionWindow(usage: ProviderUsageLiveRead | null | undefined) { - const windows = usage?.subscription_windows ?? []; - return ( - windows.find((window) => { - const key = `${window.key} ${window.label}`.toLowerCase(); - return ( - key.includes("current") || - key.includes("session") || - key.includes("five") || - key.includes("hour") - ); - }) ?? - windows[0] ?? - null - ); -} - -function findModelsWindow( - usage: ProviderUsageLiveRead | null | undefined, - sessionWindow: SubscriptionWindowRead | null, -) { - const windows = usage?.subscription_windows ?? []; - return ( - windows.find((window) => { - if (window.key === sessionWindow?.key) return false; - const key = `${window.key} ${window.label}`.toLowerCase(); - return key.includes("all") || key.includes("model") || key.includes("week"); - }) ?? - windows.find((window) => window.key !== sessionWindow?.key) ?? - null - ); -} - -function resetLabel( - sessionWindow: SubscriptionWindowRead | null, - modelsWindow: SubscriptionWindowRead | null, -): string { - const resetInMs = sessionWindow?.reset_in_ms ?? modelsWindow?.reset_in_ms; - return resetInMs == null ? "—" : fmtResetMs(resetInMs); -} - -function keyLabel(cred: ProviderCredentialRead): string { - if (cred.has_api_key && cred.api_key_last_four) return `API ••••${cred.api_key_last_four}`; - if (cred.has_api_key) return "API set"; - if (cred.base_url) return "API local"; - return "API missing"; -} - -function tokenLabel( - cred: ProviderCredentialRead, - usage: ProviderUsageLiveRead | null | undefined, -): string { - if ((usage?.subscription_windows?.length ?? 0) > 0) return "Token connected"; - if (cred.has_session_key) return "Token set"; - return "Token auto"; -} - -function MiniRemainingBar({ - pct, - className = "w-10", -}: { - pct: number | null; - className?: string; -}) { - const width = pct == null ? 0 : clampPct(pct); - return ( -