mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
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
This commit is contained in:
@@ -787,14 +787,31 @@ export default function HomePageClient({ machineId }: HomePageClientProps) {
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-3">
|
||||
{providerStats.map((item) => (
|
||||
<ProviderOverviewCard
|
||||
key={item.id}
|
||||
item={item}
|
||||
metrics={providerMetrics[item.provider.alias] || providerMetrics[item.id]}
|
||||
onClick={() => setSelectedProvider(item)}
|
||||
/>
|
||||
))}
|
||||
{providerStats
|
||||
.filter((item) => item.total > 0)
|
||||
.map((item) => (
|
||||
<ProviderOverviewCard
|
||||
key={item.id}
|
||||
item={item}
|
||||
metrics={providerMetrics[item.provider.alias] || providerMetrics[item.id]}
|
||||
onClick={() => setSelectedProvider(item)}
|
||||
/>
|
||||
))}
|
||||
{providerStats.filter((item) => item.total > 0).length === 0 && (
|
||||
<div className="col-span-full py-8 text-center">
|
||||
<span className="material-symbols-outlined text-[32px] text-text-muted/40">dns</span>
|
||||
<p className="text-sm text-text-muted mt-2">
|
||||
{t("noProvidersConfigured") || "No providers configured yet"}
|
||||
</p>
|
||||
<Link
|
||||
href="/dashboard/providers"
|
||||
className="inline-flex items-center gap-1 mt-2 text-xs text-primary hover:underline"
|
||||
>
|
||||
{t("addProvider") || "Add a provider"}{" "}
|
||||
<span className="material-symbols-outlined text-[14px]">arrow_forward</span>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
|
||||
@@ -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 (
|
||||
<div className="flex flex-col items-center justify-center py-20 text-center">
|
||||
<div className="flex items-center justify-center size-16 rounded-full bg-primary/10 mb-4">
|
||||
<span className="material-symbols-outlined text-[32px] text-primary">dns</span>
|
||||
</div>
|
||||
<h2 className="text-xl font-semibold text-text-main">
|
||||
{t("addFirstProvider") || "Add your first provider"}
|
||||
</h2>
|
||||
<p className="text-sm text-text-muted mt-2 max-w-md">
|
||||
{t("addFirstProviderDesc") ||
|
||||
"Connect an AI provider to start routing requests through OmniRoute. You can use free providers, API keys, or OAuth accounts."}
|
||||
</p>
|
||||
<div className="flex items-center gap-3 mt-4">
|
||||
<a
|
||||
href="https://docs.omniroute.io/providers"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-1.5 px-4 py-2 text-sm font-medium rounded-lg border border-border text-text-muted hover:text-text-main hover:bg-bg-subtle transition-colors"
|
||||
>
|
||||
<span className="material-symbols-outlined text-[16px]">help</span>
|
||||
{t("learnMore") || "Learn more"}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6">
|
||||
{/* Search Bar */}
|
||||
|
||||
@@ -93,6 +93,10 @@ export default function SettingsPage() {
|
||||
|
||||
{activeTab === "ai" && (
|
||||
<div className="flex flex-col gap-6">
|
||||
<p className="text-sm text-text-muted">
|
||||
{t("aiSettingsIntro") ||
|
||||
"AI-specific settings for thinking budget, model behavior, and compression."}
|
||||
</p>
|
||||
<ThinkingBudgetTab />
|
||||
<Link
|
||||
href="/dashboard/context/caveman"
|
||||
@@ -124,6 +128,10 @@ export default function SettingsPage() {
|
||||
|
||||
{activeTab === "routing" && (
|
||||
<div className="flex flex-col gap-6">
|
||||
<p className="text-sm text-text-muted">
|
||||
{t("routingSettingsIntro") ||
|
||||
"Controls how your requests are routed, transformed, and sent to AI providers."}
|
||||
</p>
|
||||
<RoutingTab />
|
||||
<ModelRoutingSection />
|
||||
<ComboDefaultsTab />
|
||||
@@ -132,7 +140,15 @@ export default function SettingsPage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === "resilience" && <ResilienceTab />}
|
||||
{activeTab === "resilience" && (
|
||||
<div className="flex flex-col gap-6">
|
||||
<p className="text-sm text-text-muted">
|
||||
{t("resilienceSettingsIntro") ||
|
||||
"Automatic retry, cooldown, and fallback when providers fail."}
|
||||
</p>
|
||||
<ResilienceTab />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === "advanced" && (
|
||||
<div className="flex flex-col gap-6">
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user