- Rename directory keep-notes -> memento-note with all code references - Prisma: SQLite -> PostgreSQL (both app and MCP server schemas) - Sync MCP schema with main app (add missing fields, relations, indexes) - Delete 17 SQLite migrations (clean slate for PostgreSQL) - Remove SQLite dependencies (@libsql/client, better-sqlite3, etc.) - Fix MCP server: hardcoded Windows DB paths -> DATABASE_URL env var - Fix MCP server: .dockerignore excluded index-sse.js (SSE mode broken) - MCP Dockerfile: node:20 -> node:22 - Docker Compose: add postgres service, remove SQLite volume - Generate favicon.ico, icon-192.png, icon-512.png, apple-icon.png - Update layout.tsx icons and manifest.json for PNG icons - Update all .env files for PostgreSQL - Rewrite README.md with updated sections - Remove mcp-server/node_modules and prisma/client-generated from git tracking Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
76 lines
1.8 KiB
TypeScript
76 lines
1.8 KiB
TypeScript
'use client'
|
|
|
|
import Link from 'next/link'
|
|
import { usePathname } from 'next/navigation'
|
|
import { LayoutDashboard, Users, Brain, Settings } from 'lucide-react'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
export interface AdminSidebarProps {
|
|
className?: string
|
|
}
|
|
|
|
export interface NavItem {
|
|
title: string
|
|
href: string
|
|
icon: React.ReactNode
|
|
}
|
|
|
|
const navItems: NavItem[] = [
|
|
{
|
|
title: 'Dashboard',
|
|
href: '/admin',
|
|
icon: <LayoutDashboard className="h-5 w-5" />,
|
|
},
|
|
{
|
|
title: 'Users',
|
|
href: '/admin/users',
|
|
icon: <Users className="h-5 w-5" />,
|
|
},
|
|
{
|
|
title: 'AI Management',
|
|
href: '/admin/ai',
|
|
icon: <Brain className="h-5 w-5" />,
|
|
},
|
|
{
|
|
title: 'Settings',
|
|
href: '/admin/settings',
|
|
icon: <Settings className="h-5 w-5" />,
|
|
},
|
|
]
|
|
|
|
export function AdminSidebar({ className }: AdminSidebarProps) {
|
|
const pathname = usePathname()
|
|
|
|
return (
|
|
<aside
|
|
className={cn(
|
|
'w-64 bg-white dark:bg-zinc-900 border-r border-gray-200 dark:border-gray-800 p-4',
|
|
className
|
|
)}
|
|
>
|
|
<nav className="space-y-1">
|
|
{navItems.map((item) => {
|
|
const isActive = pathname === item.href || (item.href !== '/admin' && pathname?.startsWith(item.href))
|
|
|
|
return (
|
|
<Link
|
|
key={item.href}
|
|
href={item.href}
|
|
className={cn(
|
|
'flex items-center gap-3 px-4 py-3 rounded-lg text-sm font-medium transition-colors',
|
|
'hover:bg-gray-100 dark:hover:bg-zinc-800',
|
|
isActive
|
|
? 'bg-gray-100 dark:bg-zinc-800 text-gray-900 dark:text-white font-semibold'
|
|
: 'text-gray-600 dark:text-gray-400'
|
|
)}
|
|
>
|
|
{item.icon}
|
|
<span>{item.title}</span>
|
|
</Link>
|
|
)
|
|
})}
|
|
</nav>
|
|
</aside>
|
|
)
|
|
}
|