fix: improve dashboard UX and fix dark mode
- Replace hardcoded bg-white with bg-surface across all dashboard pages - Add welcome banner with quick actions on dashboard overview - Improve quick action cards with better hover states and icons - Enhance profile section with avatar initial and edit button - Fix dark mode support in collections, executor config, and playground
This commit is contained in:
parent
faf4b622c7
commit
e73b7955a3
9 changed files with 114 additions and 64 deletions
|
|
@ -93,7 +93,7 @@ function McpUrlSection({ username, slug }: { username: string; slug: string }) {
|
|||
<span className="text-xs text-foreground-tertiary">(recommended)</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex-1 px-3 py-2 bg-white border border-border rounded-lg font-mono text-sm text-foreground-secondary overflow-x-auto">
|
||||
<div className="flex-1 px-3 py-2 bg-surface border border-border rounded-lg font-mono text-sm text-foreground-secondary overflow-x-auto">
|
||||
{httpUrl}
|
||||
</div>
|
||||
<Button
|
||||
|
|
@ -117,7 +117,7 @@ function McpUrlSection({ username, slug }: { username: string; slug: string }) {
|
|||
<span className="text-xs text-foreground-tertiary">(streaming)</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex-1 px-3 py-2 bg-white border border-border rounded-lg font-mono text-sm text-foreground-secondary overflow-x-auto">
|
||||
<div className="flex-1 px-3 py-2 bg-surface border border-border rounded-lg font-mono text-sm text-foreground-secondary overflow-x-auto">
|
||||
{sseUrl}
|
||||
</div>
|
||||
<Button
|
||||
|
|
@ -146,7 +146,7 @@ function McpUrlSection({ username, slug }: { username: string; slug: string }) {
|
|||
|
||||
{showConfig && (
|
||||
<div className="mt-3 relative">
|
||||
<pre className="p-4 bg-white border border-border rounded-lg text-xs font-mono text-foreground-secondary overflow-x-auto">
|
||||
<pre className="p-4 bg-surface border border-border rounded-lg text-xs font-mono text-foreground-secondary overflow-x-auto">
|
||||
{configSnippet}
|
||||
</pre>
|
||||
<Button
|
||||
|
|
@ -320,7 +320,7 @@ export default function PublicCollectionDetailPage(): React.ReactElement {
|
|||
<h2 className="text-lg font-semibold text-foreground mb-4">Tools in this Collection</h2>
|
||||
|
||||
{collection.tools.length === 0 ? (
|
||||
<div className="text-center py-12 bg-white border border-border rounded-lg">
|
||||
<div className="text-center py-12 bg-surface border border-border rounded-lg">
|
||||
<Icon icon="puzzle" size="lg" className="mx-auto text-foreground-tertiary mb-2" />
|
||||
<p className="text-foreground-secondary">No tools in this collection yet</p>
|
||||
</div>
|
||||
|
|
@ -329,7 +329,7 @@ export default function PublicCollectionDetailPage(): React.ReactElement {
|
|||
{collection.tools.map((ct) => (
|
||||
<div
|
||||
key={ct.id}
|
||||
className="bg-white border border-border rounded-lg p-4 hover:border-foreground/20 hover:shadow-sm transition-all"
|
||||
className="bg-surface border border-border rounded-lg p-4 hover:border-foreground/20 hover:shadow-sm transition-all"
|
||||
>
|
||||
<div className="flex items-start justify-between mb-2">
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ export default function AgentsPage(): React.ReactElement {
|
|||
</Link>
|
||||
}
|
||||
>
|
||||
<div className="bg-white border border-border rounded-lg overflow-hidden">
|
||||
<div className="bg-surface border border-border rounded-lg overflow-hidden">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ function McpUrlSection({ username, slug }: { username: string; slug: string }) {
|
|||
<span className="text-xs text-foreground-tertiary">(recommended)</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex-1 px-3 py-2 bg-white border border-border rounded-lg font-mono text-sm text-foreground-secondary overflow-x-auto">
|
||||
<div className="flex-1 px-3 py-2 bg-surface border border-border rounded-lg font-mono text-sm text-foreground-secondary overflow-x-auto">
|
||||
{httpUrl}
|
||||
</div>
|
||||
<Button
|
||||
|
|
@ -88,7 +88,7 @@ function McpUrlSection({ username, slug }: { username: string; slug: string }) {
|
|||
<span className="text-xs text-foreground-tertiary">(streaming)</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex-1 px-3 py-2 bg-white border border-border rounded-lg font-mono text-sm text-foreground-secondary overflow-x-auto">
|
||||
<div className="flex-1 px-3 py-2 bg-surface border border-border rounded-lg font-mono text-sm text-foreground-secondary overflow-x-auto">
|
||||
{sseUrl}
|
||||
</div>
|
||||
<Button
|
||||
|
|
@ -117,7 +117,7 @@ function McpUrlSection({ username, slug }: { username: string; slug: string }) {
|
|||
|
||||
{showConfig && (
|
||||
<div className="mt-3 relative">
|
||||
<pre className="p-4 bg-white border border-border rounded-lg text-xs font-mono text-foreground-secondary overflow-x-auto">
|
||||
<pre className="p-4 bg-surface border border-border rounded-lg text-xs font-mono text-foreground-secondary overflow-x-auto">
|
||||
{configSnippet}
|
||||
</pre>
|
||||
<Button
|
||||
|
|
@ -480,7 +480,7 @@ export default function CollectionDetailPage(): React.ReactElement {
|
|||
>
|
||||
{/* Edit Form */}
|
||||
{isEditing && (
|
||||
<div className="bg-white border border-border rounded-lg p-6 mb-8">
|
||||
<div className="bg-surface border border-border rounded-lg p-6 mb-8">
|
||||
<CollectionForm
|
||||
initialData={{
|
||||
name: collection.name,
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ export default function CollectionsPage(): React.ReactElement {
|
|||
>
|
||||
{/* Create Form */}
|
||||
{showCreateForm && (
|
||||
<div className="bg-white border border-border rounded-lg p-6 mb-6">
|
||||
<div className="bg-surface border border-border rounded-lg p-6 mb-6">
|
||||
<h2 className="text-lg font-medium text-foreground mb-4">Create New Collection</h2>
|
||||
<CollectionForm
|
||||
onSubmit={handleCreate}
|
||||
|
|
@ -178,7 +178,7 @@ export default function CollectionsPage(): React.ReactElement {
|
|||
)}
|
||||
|
||||
{/* Collections Table */}
|
||||
<div className="bg-white border border-border rounded-lg overflow-hidden">
|
||||
<div className="bg-surface border border-border rounded-lg overflow-hidden">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ export default function LikedAgentsPage(): React.ReactElement {
|
|||
{isLoading ? (
|
||||
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{[1, 2, 3, 4, 5, 6].map((i) => (
|
||||
<div key={i} className="bg-white border border-border rounded-lg p-4 animate-pulse">
|
||||
<div key={i} className="bg-surface border border-border rounded-lg p-4 animate-pulse">
|
||||
<div className="h-5 bg-surface-secondary rounded w-3/4 mb-2" />
|
||||
<div className="h-4 bg-surface-secondary rounded w-full mb-1" />
|
||||
<div className="h-4 bg-surface-secondary rounded w-2/3" />
|
||||
|
|
@ -121,7 +121,7 @@ export default function LikedAgentsPage(): React.ReactElement {
|
|||
{agents.map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className="bg-white border border-border rounded-lg p-4 hover:border-foreground/20 hover:shadow-sm transition-all"
|
||||
className="bg-surface border border-border rounded-lg p-4 hover:border-foreground/20 hover:shadow-sm transition-all"
|
||||
>
|
||||
<div className="flex items-start justify-between mb-2">
|
||||
<Link
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ export default function LikedCollectionsPage(): React.ReactElement {
|
|||
{isLoading ? (
|
||||
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{[1, 2, 3, 4, 5, 6].map((i) => (
|
||||
<div key={i} className="bg-white border border-border rounded-lg p-4 animate-pulse">
|
||||
<div key={i} className="bg-surface border border-border rounded-lg p-4 animate-pulse">
|
||||
<div className="h-5 bg-surface-secondary rounded w-3/4 mb-2" />
|
||||
<div className="h-4 bg-surface-secondary rounded w-full mb-1" />
|
||||
<div className="h-4 bg-surface-secondary rounded w-2/3" />
|
||||
|
|
@ -123,7 +123,7 @@ export default function LikedCollectionsPage(): React.ReactElement {
|
|||
{collections.map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className="bg-white border border-border rounded-lg p-4 hover:border-foreground/20 hover:shadow-sm transition-all"
|
||||
className="bg-surface border border-border rounded-lg p-4 hover:border-foreground/20 hover:shadow-sm transition-all"
|
||||
>
|
||||
<div className="flex items-start justify-between mb-2">
|
||||
<Link
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ export default function LikesOverviewPage(): React.ReactElement {
|
|||
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{sections.map((section) => (
|
||||
<Link key={section.href} href={section.href} className="block">
|
||||
<div className="bg-white border border-border rounded-lg p-6 hover:border-foreground/20 hover:shadow-sm transition-all group h-full">
|
||||
<div className="bg-surface border border-border rounded-lg p-6 hover:border-foreground/20 hover:shadow-sm transition-all group h-full">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-12 h-12 rounded-lg bg-primary/10 flex items-center justify-center group-hover:bg-primary/20 transition-colors">
|
||||
<Icon icon={section.icon} size="md" className="text-primary" />
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ export default function LikedToolsPage(): React.ReactElement {
|
|||
{isLoading ? (
|
||||
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{[1, 2, 3, 4, 5, 6].map((i) => (
|
||||
<div key={i} className="bg-white border border-border rounded-lg p-4 animate-pulse">
|
||||
<div key={i} className="bg-surface border border-border rounded-lg p-4 animate-pulse">
|
||||
<div className="h-5 bg-surface-secondary rounded w-3/4 mb-2" />
|
||||
<div className="h-4 bg-surface-secondary rounded w-full mb-1" />
|
||||
<div className="h-4 bg-surface-secondary rounded w-2/3" />
|
||||
|
|
@ -116,7 +116,7 @@ export default function LikedToolsPage(): React.ReactElement {
|
|||
{tools.map((item) => (
|
||||
<div
|
||||
key={item.id}
|
||||
className="bg-white border border-border rounded-lg p-4 hover:border-foreground/20 hover:shadow-sm transition-all"
|
||||
className="bg-surface border border-border rounded-lg p-4 hover:border-foreground/20 hover:shadow-sm transition-all"
|
||||
>
|
||||
<div className="flex items-start justify-between mb-2">
|
||||
<Link
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
'use client';
|
||||
|
||||
import { useSession } from '@/lib/auth-client';
|
||||
import { Button } from '@tpmjs/ui/Button/Button';
|
||||
import { Icon } from '@tpmjs/ui/Icon/Icon';
|
||||
import Link from 'next/link';
|
||||
import { DashboardActivityStream } from '~/components/DashboardActivityStream';
|
||||
|
|
@ -11,51 +12,86 @@ export default function DashboardPage(): React.ReactElement {
|
|||
|
||||
return (
|
||||
<DashboardLayout title="Overview">
|
||||
{/* Welcome Banner */}
|
||||
<div className="mb-8 p-6 rounded-lg bg-gradient-to-r from-primary/10 via-primary/5 to-transparent border border-primary/20">
|
||||
<h2 className="text-xl font-semibold text-foreground mb-2">
|
||||
Welcome back{session?.user?.name ? `, ${session.user.name.split(' ')[0]}` : ''}!
|
||||
</h2>
|
||||
<p className="text-foreground-secondary mb-4">
|
||||
Build AI agents, organize tools into collections, and connect them to your workflows.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Link href="/dashboard/agents/new">
|
||||
<Button size="sm">
|
||||
<Icon icon="plus" size="xs" className="mr-1" />
|
||||
Create Agent
|
||||
</Button>
|
||||
</Link>
|
||||
<Link href="/tool/tool-search">
|
||||
<Button size="sm" variant="outline">
|
||||
<Icon icon="search" size="xs" className="mr-1" />
|
||||
Browse Tools
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Actions */}
|
||||
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 mb-8">
|
||||
<Link href="/dashboard/agents" className="block">
|
||||
<div className="bg-white border border-border rounded-lg p-6 hover:border-foreground/20 hover:shadow-sm transition-all group">
|
||||
<div className="flex items-center gap-4">
|
||||
<Link href="/dashboard/agents" className="block group">
|
||||
<div className="bg-surface border border-border rounded-lg p-6 hover:border-primary/50 hover:shadow-md transition-all h-full">
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div className="w-12 h-12 rounded-lg bg-primary/10 flex items-center justify-center group-hover:bg-primary/20 transition-colors">
|
||||
<Icon icon="terminal" size="md" className="text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-lg font-medium text-foreground">My Agents</h2>
|
||||
<p className="text-sm text-foreground-secondary">
|
||||
Create and manage AI agents with tools
|
||||
</p>
|
||||
</div>
|
||||
<Icon
|
||||
icon="chevronRight"
|
||||
size="sm"
|
||||
className="text-foreground-tertiary group-hover:text-primary group-hover:translate-x-1 transition-all"
|
||||
/>
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-foreground mb-1">Agents</h3>
|
||||
<p className="text-sm text-foreground-secondary">
|
||||
Create AI agents with custom tools and system prompts
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link href="/dashboard/collections" className="block">
|
||||
<div className="bg-white border border-border rounded-lg p-6 hover:border-foreground/20 hover:shadow-sm transition-all group">
|
||||
<div className="flex items-center gap-4">
|
||||
<Link href="/dashboard/collections" className="block group">
|
||||
<div className="bg-surface border border-border rounded-lg p-6 hover:border-primary/50 hover:shadow-md transition-all h-full">
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div className="w-12 h-12 rounded-lg bg-primary/10 flex items-center justify-center group-hover:bg-primary/20 transition-colors">
|
||||
<Icon icon="folder" size="md" className="text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-lg font-medium text-foreground">My Collections</h2>
|
||||
<p className="text-sm text-foreground-secondary">
|
||||
Organize and share your favorite tools
|
||||
</p>
|
||||
</div>
|
||||
<Icon
|
||||
icon="chevronRight"
|
||||
size="sm"
|
||||
className="text-foreground-tertiary group-hover:text-primary group-hover:translate-x-1 transition-all"
|
||||
/>
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-foreground mb-1">Collections</h3>
|
||||
<p className="text-sm text-foreground-secondary">
|
||||
Group tools together and share them as MCP servers
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link href="/dashboard/settings/api-keys" className="block">
|
||||
<div className="bg-white border border-border rounded-lg p-6 hover:border-foreground/20 hover:shadow-sm transition-all group">
|
||||
<div className="flex items-center gap-4">
|
||||
<Link href="/dashboard/settings/tpmjs-api-keys" className="block group">
|
||||
<div className="bg-surface border border-border rounded-lg p-6 hover:border-primary/50 hover:shadow-md transition-all h-full">
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div className="w-12 h-12 rounded-lg bg-primary/10 flex items-center justify-center group-hover:bg-primary/20 transition-colors">
|
||||
<Icon icon="key" size="md" className="text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-lg font-medium text-foreground">API Keys</h2>
|
||||
<p className="text-sm text-foreground-secondary">Manage AI provider credentials</p>
|
||||
</div>
|
||||
<Icon
|
||||
icon="chevronRight"
|
||||
size="sm"
|
||||
className="text-foreground-tertiary group-hover:text-primary group-hover:translate-x-1 transition-all"
|
||||
/>
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-foreground mb-1">API Keys</h3>
|
||||
<p className="text-sm text-foreground-secondary">
|
||||
Generate keys for programmatic API access
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
|
|
@ -63,35 +99,49 @@ export default function DashboardPage(): React.ReactElement {
|
|||
{/* Two-column layout for Profile and Activity */}
|
||||
<div className="grid gap-6 lg:grid-cols-2">
|
||||
{/* Profile Section */}
|
||||
<div className="bg-white border border-border rounded-lg p-6">
|
||||
<h2 className="text-lg font-medium text-foreground mb-4">Profile</h2>
|
||||
<div className="bg-surface border border-border rounded-lg p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h2 className="text-lg font-medium text-foreground">Profile</h2>
|
||||
<Link href="/dashboard/settings/profile">
|
||||
<Button size="sm" variant="ghost">
|
||||
<Icon icon="edit" size="xs" className="mr-1" />
|
||||
Edit
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<span className="block text-sm text-foreground-secondary">Name</span>
|
||||
<p className="text-foreground font-medium">{session?.user?.name || 'User'}</p>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-16 h-16 rounded-full bg-primary/10 flex items-center justify-center">
|
||||
<span className="text-2xl font-bold text-primary">
|
||||
{session?.user?.name?.[0]?.toUpperCase() || 'U'}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-lg font-medium text-foreground">
|
||||
{session?.user?.name || 'User'}
|
||||
</p>
|
||||
<p className="text-sm text-foreground-secondary">{session?.user?.email}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="block text-sm text-foreground-secondary">Email</span>
|
||||
<p className="text-foreground font-medium">{session?.user?.email}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="block text-sm text-foreground-secondary">Email Verified</span>
|
||||
<p className="text-foreground font-medium">
|
||||
{session?.user?.emailVerified ? (
|
||||
<span className="text-success">Verified</span>
|
||||
) : (
|
||||
<span className="text-warning">Not verified</span>
|
||||
)}
|
||||
</p>
|
||||
<div className="pt-4 border-t border-border">
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<Icon
|
||||
icon={session?.user?.emailVerified ? 'check' : 'alertCircle'}
|
||||
size="xs"
|
||||
className={session?.user?.emailVerified ? 'text-success' : 'text-warning'}
|
||||
/>
|
||||
<span className="text-foreground-secondary">
|
||||
{session?.user?.emailVerified ? 'Email verified' : 'Email not verified'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Activity Stream Section */}
|
||||
<div className="bg-white border border-border rounded-lg p-6">
|
||||
<div className="bg-surface border border-border rounded-lg p-6">
|
||||
<h2 className="text-lg font-medium text-foreground mb-4">Recent Activity</h2>
|
||||
<DashboardActivityStream autoRefreshInterval={30000} />
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue