From a4a870cda3a7b15327207ce47df22ea573b2d5e0 Mon Sep 17 00:00:00 2001 From: oyi77 Date: Sun, 17 May 2026 07:56:22 +0700 Subject: [PATCH] feat(ui): add newbie-friendly UX improvements across dashboard - Providers page: empty state with guided 'Add your first provider' card - Providers page: home page shows only configured providers by default - Settings: add intro text to Routing, Resilience, and AI tabs - i18n: fix 'Api Key Mgmt' to 'API Key Management', remove duplicate key - i18n: add keys for empty state, settings intros, free-only filter --- .../(dashboard)/dashboard/HomePageClient.tsx | 33 +++++++++++++----- .../(dashboard)/dashboard/providers/page.tsx | 34 +++++++++++++++++++ .../(dashboard)/dashboard/settings/page.tsx | 18 +++++++++- src/i18n/messages/en.json | 15 ++++++-- 4 files changed, 88 insertions(+), 12 deletions(-) diff --git a/src/app/(dashboard)/dashboard/HomePageClient.tsx b/src/app/(dashboard)/dashboard/HomePageClient.tsx index c9b4d06e34..2c39d93630 100644 --- a/src/app/(dashboard)/dashboard/HomePageClient.tsx +++ b/src/app/(dashboard)/dashboard/HomePageClient.tsx @@ -787,14 +787,31 @@ export default function HomePageClient({ machineId }: HomePageClientProps) {
- {providerStats.map((item) => ( - setSelectedProvider(item)} - /> - ))} + {providerStats + .filter((item) => item.total > 0) + .map((item) => ( + setSelectedProvider(item)} + /> + ))} + {providerStats.filter((item) => item.total > 0).length === 0 && ( +
+ dns +

+ {t("noProvidersConfigured") || "No providers configured yet"} +

+ + {t("addProvider") || "Add a provider"}{" "} + arrow_forward + +
+ )}
diff --git a/src/app/(dashboard)/dashboard/providers/page.tsx b/src/app/(dashboard)/dashboard/providers/page.tsx index 4c752a757c..2cad07fd78 100644 --- a/src/app/(dashboard)/dashboard/providers/page.tsx +++ b/src/app/(dashboard)/dashboard/providers/page.tsx @@ -541,6 +541,40 @@ export default function ProvidersPage() { ); } + const totalConfigured = + oauthProviderEntriesAll.filter((e) => Number(e.stats?.total || 0) > 0).length + + apiKeyProviderEntriesAll.filter((e) => Number(e.stats?.total || 0) > 0).length + + webCookieProviderEntriesAll.filter((e) => Number(e.stats?.total || 0) > 0).length + + localProviderEntriesAll.filter((e) => Number(e.stats?.total || 0) > 0).length; + + if (totalConfigured === 0 && !searchQuery) { + return ( +
+
+ dns +
+

+ {t("addFirstProvider") || "Add your first provider"} +

+

+ {t("addFirstProviderDesc") || + "Connect an AI provider to start routing requests through OmniRoute. You can use free providers, API keys, or OAuth accounts."} +

+
+ + help + {t("learnMore") || "Learn more"} + +
+
+ ); + } + return (
{/* Search Bar */} diff --git a/src/app/(dashboard)/dashboard/settings/page.tsx b/src/app/(dashboard)/dashboard/settings/page.tsx index ecc54f1133..aa4cdb90cc 100644 --- a/src/app/(dashboard)/dashboard/settings/page.tsx +++ b/src/app/(dashboard)/dashboard/settings/page.tsx @@ -93,6 +93,10 @@ export default function SettingsPage() { {activeTab === "ai" && (
+

+ {t("aiSettingsIntro") || + "AI-specific settings for thinking budget, model behavior, and compression."} +

+

+ {t("routingSettingsIntro") || + "Controls how your requests are routed, transformed, and sent to AI providers."} +

@@ -132,7 +140,15 @@ export default function SettingsPage() {
)} - {activeTab === "resilience" && } + {activeTab === "resilience" && ( +
+

+ {t("resilienceSettingsIntro") || + "Automatic retry, cooldown, and fallback when providers fail."} +

+ +
+ )} {activeTab === "advanced" && (
diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 69d9652f50..efe8a5e14e 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -365,6 +365,10 @@ "apiKeyForCheck": "Api Key For Check", "cloudRequestTimeout": "Cloud Request Timeout", "showConfiguredOnly": "Show Configured Only", + "showFreeOnly": "Free only", + "addFirstProvider": "Add your first provider", + "addFirstProviderDesc": "Connect an AI provider to start routing requests through OmniRoute. You can use free providers, API keys, or OAuth accounts.", + "learnMore": "Learn more", "includeDomains": "Include Domains", "promptCache": "Prompt Cache", "cloudConnected": "Cloud Connected", @@ -405,7 +409,7 @@ "expirationBannerExpiringSoonDesc": "Expiration Banner Expiring Soon Desc", "source": "Source", "failed": "Failed", - "apiKeyMgmt": "Api Key Mgmt", + "apiKeyMgmt": "API Key Management", "mcpQuickStartStep1": "Mcp Quick Start Step1", "runTest": "Run Test", "loadingFallbackChains": "Loading Fallback Chains", @@ -905,6 +909,8 @@ "providersOverview": "Providers Overview", "configuredOf": "{configured} configured of {total} available providers", "noModelsAvailable": "No models available for this provider.", + "noProvidersConfigured": "No providers configured yet", + "addProvider": "Add a provider", "configureFirst": "Configure a connection first in {providers}", "configureProvider": "Configure Provider", "modelAvailable": "{count} model available", @@ -2618,7 +2624,6 @@ "welcomeDesc": "OmniRoute is your local AI API proxy. It routes requests to multiple AI providers with load balancing, failover, and usage tracking.", "multiProvider": "Multi-Provider", "usageTracking": "Usage Tracking", - "apiKeyMgmt": "API Key Mgmt", "securityDesc": "Set a password to protect your dashboard, or skip for now.", "providerDesc": "Connect your first AI provider. You can add more later.", "apiKeyRequired": "API Key (required)", @@ -2637,7 +2642,8 @@ "failedSetPassword": "Failed to set password. Try again.", "failedAddProvider": "Failed to add provider. Try again.", "connectionError": "Connection error. Please try again.", - "provider": "Provider" + "provider": "Provider", + "apiKeyHelp": "An API key is a password for AI services. Get one from your provider's website (e.g., platform.openai.com, console.anthropic.com)." }, "providers": { "title": "Providers", @@ -3148,6 +3154,9 @@ "routing": "Routing", "cache": "Cache", "resilience": "Resilience", + "routingSettingsIntro": "Controls how your requests are routed, transformed, and sent to AI providers.", + "resilienceSettingsIntro": "Automatic retry, cooldown, and fallback when providers fail.", + "aiSettingsIntro": "AI-specific settings for thinking budget, model behavior, and compression.", "systemPrompt": "System Prompt", "thinkingBudget": "Thinking Budget", "proxy": "Proxy",