writekit/frontends/studio/src/components/layout/Sidebar.tsx
Josh bef5dd4437 refactor: move studio to frontends workspace
- Move studio from root to frontends/studio/
- Add owner-tools frontend for live blog admin UI
- Add shared ui component library
- Set up npm workspaces for frontends
- Add enhanced code block extension for editor

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 02:06:19 +02:00

102 lines
2.8 KiB
TypeScript

import { useStore } from '@nanostores/react'
import { $router } from '../../stores/router'
import { Icons, type IconComponent } from '../shared/Icons'
interface NavItem {
route: string
label: string
Icon: IconComponent
}
interface NavSection {
title: string
items: NavItem[]
}
const navigation: NavSection[] = [
{
title: '',
items: [
{ route: 'home', label: 'Home', Icon: Icons.Home },
],
},
{
title: 'Content',
items: [
{ route: 'posts', label: 'Posts', Icon: Icons.Posts },
{ route: 'analytics', label: 'Analytics', Icon: Icons.Analytics },
],
},
{
title: 'Site',
items: [
{ route: 'general', label: 'General', Icon: Icons.Settings },
{ route: 'design', label: 'Design', Icon: Icons.Design },
{ route: 'domain', label: 'Domain', Icon: Icons.Domain },
],
},
{
title: 'Readers',
items: [
{ route: 'engagement', label: 'Engagement', Icon: Icons.Engagement },
{ route: 'monetization', label: 'Monetization', Icon: Icons.Monetization },
],
},
{
title: 'Developer',
items: [
{ route: 'plugins', label: 'Plugins', Icon: Icons.Code },
{ route: 'api', label: 'API Keys', Icon: Icons.ApiKeys },
{ route: 'data', label: 'Data', Icon: Icons.Data },
],
},
{
title: 'Account',
items: [
{ route: 'billing', label: 'Billing', Icon: Icons.Billing },
],
},
]
export function Sidebar() {
const page = useStore($router)
const currentRoute = page?.route ?? 'posts'
return (
<aside className="w-56 h-screen bg-bg border-r border-border flex flex-col">
<div className="px-4 py-6">
<a href="/" className="block group">
<div className="text-[15px] font-bold tracking-tight text-text">
WriteKit
</div>
<div className="text-[11px] font-medium text-muted tracking-wide">
Studio
</div>
</a>
</div>
<nav className="flex-1 overflow-y-auto px-3">
{navigation.map((section, idx) => (
<div key={section.title || idx} className="mb-1">
{section.title && <div className="nav-section">{section.title}</div>}
<div className="space-y-0.5">
{section.items.map(item => {
const href = item.route === 'home' ? '/studio' : `/studio/${item.route}`
return (
<a
key={item.route}
href={href}
className={currentRoute === item.route ? 'nav-item-active' : 'nav-item'}
>
<item.Icon className={`text-sm ${currentRoute === item.route ? 'text-accent opacity-100' : 'opacity-50'}`} />
<span>{item.label}</span>
</a>
)
})}
</div>
</div>
))}
</nav>
</aside>
)
}