From f8bfbc3ed2096da7867601c45d95d1b817254466 Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Wed, 14 Jan 2026 07:18:42 +1000 Subject: [PATCH] feat: improve API keys UX and navigation clarity - Reorganize sidebar into sections with headers (main items, Settings) - Rename "API Keys" to "AI Provider Keys" with clear description - Rename "TPMJS API Keys" to "Platform API Keys" - Add info banners explaining the difference: - AI Provider Keys: credentials for OpenAI, Anthropic, etc. - Platform API Keys: authentication for TPMJS platform (tpmjs_sk_...) - Update empty states with clearer messaging - Use distinct icons (puzzle for AI providers, key for platform) --- .../app/dashboard/settings/api-keys/page.tsx | 32 +++++-- .../settings/tpmjs-api-keys/page.tsx | 18 ++-- .../components/dashboard/DashboardLayout.tsx | 89 ++++++++++++------- 3 files changed, 90 insertions(+), 49 deletions(-) diff --git a/apps/web/src/app/dashboard/settings/api-keys/page.tsx b/apps/web/src/app/dashboard/settings/api-keys/page.tsx index 9f03f25..ed245ee 100644 --- a/apps/web/src/app/dashboard/settings/api-keys/page.tsx +++ b/apps/web/src/app/dashboard/settings/api-keys/page.tsx @@ -144,7 +144,7 @@ export default function ApiKeysPage(): React.ReactElement { if (error) { return ( - +

Error

@@ -157,8 +157,8 @@ export default function ApiKeysPage(): React.ReactElement { return ( 0 ? `${keys.length} key${keys.length !== 1 ? 's' : ''}` : undefined} + title="AI Provider Keys" + subtitle="Credentials for OpenAI, Anthropic, Google, and other AI services" actions={ !showAddForm && !showImport && ( @@ -175,6 +175,22 @@ export default function ApiKeysPage(): React.ReactElement { ) } > + {/* Info banner */} +
+
+ +
+

+ These are your AI service credentials +

+

+ Add API keys from providers like OpenAI, Anthropic, or Google. Your agents use these + keys to make AI calls. Keys are encrypted and never exposed to clients. +

+
+
+
+ {/* Import from .env */} {showImport && (
@@ -272,16 +288,16 @@ ANOTHER_SECRET=xyz789" - +
+
} - title="No API keys yet" - description="Add your AI provider API keys to enable agent functionality. Keys are encrypted and stored securely." + title="No AI provider keys yet" + description="Add your OpenAI, Anthropic, or other AI provider keys so your agents can make AI calls." action={ } /> diff --git a/apps/web/src/app/dashboard/settings/tpmjs-api-keys/page.tsx b/apps/web/src/app/dashboard/settings/tpmjs-api-keys/page.tsx index e959009..25cef8f 100644 --- a/apps/web/src/app/dashboard/settings/tpmjs-api-keys/page.tsx +++ b/apps/web/src/app/dashboard/settings/tpmjs-api-keys/page.tsx @@ -199,7 +199,7 @@ export default function TpmjsApiKeysPage(): React.ReactElement { if (error) { return ( - +

Error

@@ -212,8 +212,8 @@ export default function TpmjsApiKeysPage(): React.ReactElement { return ( 0 ? `${keys.length} key${keys.length !== 1 ? 's' : ''}` : undefined} + title="Platform API Keys" + subtitle="Authentication keys for accessing TPMJS programmatically" actions={ !showCreateForm && !newlyCreatedKey && ( @@ -230,11 +230,11 @@ export default function TpmjsApiKeysPage(): React.ReactElement {

- Use API keys to access TPMJS programmatically + These keys authenticate you to the TPMJS platform

- API keys allow you to call MCP endpoints, chat with agents, and connect via the bridge - without a browser session. Keep your keys secure and never share them. + Use platform API keys (tpmjs_sk_...) to access MCP servers, chat with agents from scripts, + or connect via the bridge. These are different from AI provider keys which power the AI calls themselves.

@@ -342,12 +342,12 @@ export default function TpmjsApiKeysPage(): React.ReactElement {
} - title="No API keys yet" - description="Create an API key to access TPMJS programmatically from your applications, scripts, or CI/CD pipelines." + title="No platform API keys yet" + description="Create a key to access your TPMJS collections and agents programmatically from scripts or CI/CD pipelines." action={ } /> diff --git a/apps/web/src/components/dashboard/DashboardLayout.tsx b/apps/web/src/components/dashboard/DashboardLayout.tsx index 6cd1a58..e01cd67 100644 --- a/apps/web/src/components/dashboard/DashboardLayout.tsx +++ b/apps/web/src/components/dashboard/DashboardLayout.tsx @@ -15,15 +15,29 @@ interface NavItem { badge?: number; } -const navItems: NavItem[] = [ - { href: '/dashboard', label: 'Overview', icon: 'home' }, - { href: '/dashboard/agents', label: 'Agents', icon: 'terminal' }, - { href: '/dashboard/collections', label: 'Collections', icon: 'folder' }, - { href: '/dashboard/usage', label: 'Usage', icon: 'globe' }, - { href: '/dashboard/settings/profile', label: 'Profile', icon: 'user' }, - { href: '/dashboard/settings/tpmjs-api-keys', label: 'TPMJS API Keys', icon: 'key' }, - { href: '/dashboard/settings/api-keys', label: 'Provider Keys', icon: 'edit' }, - { href: '/dashboard/settings/bridge', label: 'Bridge', icon: 'link' }, +interface NavSection { + title?: string; + items: NavItem[]; +} + +const navSections: NavSection[] = [ + { + items: [ + { href: '/dashboard', label: 'Overview', icon: 'home' }, + { href: '/dashboard/agents', label: 'Agents', icon: 'terminal' }, + { href: '/dashboard/collections', label: 'Collections', icon: 'folder' }, + ], + }, + { + title: 'Settings', + items: [ + { href: '/dashboard/settings/profile', label: 'Profile', icon: 'user' }, + { href: '/dashboard/settings/api-keys', label: 'AI Provider Keys', icon: 'puzzle' }, + { href: '/dashboard/settings/tpmjs-api-keys', label: 'Platform API Keys', icon: 'key' }, + { href: '/dashboard/settings/bridge', label: 'Bridge', icon: 'link' }, + { href: '/dashboard/usage', label: 'Usage', icon: 'globe' }, + ], + }, ]; const likesNavItems: NavItem[] = [ @@ -152,32 +166,43 @@ export function DashboardLayout({ ${sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'} `} > -