From d0e304cdab98a5dc90e83985ef6e57d3ef2921de Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Wed, 7 Jan 2026 19:03:45 +1000 Subject: [PATCH] feat: update dashboard and API keys pages to use DashboardLayout - Convert dashboard overview to use DashboardLayout with sidebar - Update API keys page with DashboardLayout and table layout - Add upload icon to icon library - Consistent sidebar navigation across all dashboard pages --- apps/web/src/app/dashboard/page.tsx | 155 +++++----- .../app/dashboard/settings/api-keys/page.tsx | 275 +++++++++++------- packages/ui/src/Icon/icons.ts | 4 + 3 files changed, 246 insertions(+), 188 deletions(-) diff --git a/apps/web/src/app/dashboard/page.tsx b/apps/web/src/app/dashboard/page.tsx index 61b7a47..791e08c 100644 --- a/apps/web/src/app/dashboard/page.tsx +++ b/apps/web/src/app/dashboard/page.tsx @@ -1,108 +1,91 @@ -import { AppHeader } from '@/components/AppHeader'; -import { SignOutButton } from '@/components/auth/SignOutButton'; -import { auth } from '@/lib/auth'; +'use client'; + +import { useSession } from '@/lib/auth-client'; import { Icon } from '@tpmjs/ui/Icon/Icon'; -import { headers } from 'next/headers'; import Link from 'next/link'; -import { redirect } from 'next/navigation'; +import { DashboardLayout } from '~/components/dashboard/DashboardLayout'; -export default async function DashboardPage() { - const session = await auth.api.getSession({ - headers: await headers(), - }); - - if (!session) { - redirect('/sign-in'); - } +export default function DashboardPage(): React.ReactElement { + const { data: session } = useSession(); return ( -
- -
-
-

Dashboard

- -
- - {/* Quick Actions */} -
- -
-
-
- -
-
-

My Agents

-

- Create and manage AI agents with tools -

-
+ + {/* Quick Actions */} +
+ +
+
+
+ +
+
+

My Agents

+

+ Create and manage AI agents with tools +

- +
+ - -
-
-
- -
-
-

My Collections

-

- Organize and share your favorite tools -

-
+ +
+
+
+ +
+
+

My Collections

+

+ Organize and share your favorite tools +

- +
+ - -
-
-
- -
-
-

API Keys

-

- Manage AI provider credentials -

-
+ +
+
+
+ +
+
+

API Keys

+

Manage AI provider credentials

- -
+
+ +
- {/* Profile Section */} -
-

Profile

+ {/* Profile Section */} +
+

Profile

-
-
- Name -

{session.user.name}

-
+
+
+ Name +

{session?.user?.name || 'User'}

+
-
- Email -

{session.user.email}

-
+
+ Email +

{session?.user?.email}

+
-
- Email Verified -

- {session.user.emailVerified ? ( - Verified - ) : ( - Not verified - )} -

-
+
+ Email Verified +

+ {session?.user?.emailVerified ? ( + Verified + ) : ( + Not verified + )} +

-
+ ); } 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 64445a9..e2a0293 100644 --- a/apps/web/src/app/dashboard/settings/api-keys/page.tsx +++ b/apps/web/src/app/dashboard/settings/api-keys/page.tsx @@ -2,10 +2,18 @@ import { Button } from '@tpmjs/ui/Button/Button'; import { Icon } from '@tpmjs/ui/Icon/Icon'; -import Link from 'next/link'; +import { + Table, + TableBody, + TableCell, + TableEmpty, + TableHead, + TableHeader, + TableRow, +} from '@tpmjs/ui/Table/Table'; import { useRouter } from 'next/navigation'; import { useCallback, useEffect, useState } from 'react'; -import { AppHeader } from '~/components/AppHeader'; +import { DashboardLayout } from '~/components/dashboard/DashboardLayout'; interface ApiKeyInfo { id: string; @@ -15,6 +23,15 @@ interface ApiKeyInfo { updatedAt: string; } +function formatDate(dateString: string): string { + const date = new Date(dateString); + return date.toLocaleDateString('en-US', { + month: 'short', + day: 'numeric', + year: 'numeric', + }); +} + export default function ApiKeysPage(): React.ReactElement { const router = useRouter(); const [keys, setKeys] = useState([]); @@ -22,6 +39,7 @@ export default function ApiKeysPage(): React.ReactElement { const [error, setError] = useState(null); // Add new key form + const [showAddForm, setShowAddForm] = useState(false); const [newKeyName, setNewKeyName] = useState(''); const [newKeyValue, setNewKeyValue] = useState(''); const [saving, setSaving] = useState(false); @@ -80,6 +98,7 @@ export default function ApiKeysPage(): React.ReactElement { if (result.success) { setNewKeyName(''); setNewKeyValue(''); + setShowAddForm(false); fetchKeys(); } else { setSaveError(result.error || 'Failed to save'); @@ -88,7 +107,8 @@ export default function ApiKeysPage(): React.ReactElement { setSaving(false); }, [newKeyName, newKeyValue, saveKey, fetchKeys]); - const handleDelete = useCallback(async (keyName: string, id: string) => { + const handleDelete = useCallback(async (keyName: string, id: string, e: React.MouseEvent) => { + e.stopPropagation(); if (!confirm(`Delete ${keyName}?`)) return; setDeletingId(id); @@ -135,137 +155,188 @@ export default function ApiKeysPage(): React.ReactElement { fetchKeys(); }, [envText, saveKey, fetchKeys]); - if (isLoading) { - return ( -
- -
-
-
-
-
-
-
- ); - } - if (error) { return ( -
- -
-

{error}

- + +
+ +

Error

+

{error}

+
-
+ ); } return ( -
- -
-
-
- - - -

Environment Variables

-
- -
- - {/* Import from .env */} - {showImport && ( -
-