feat: Navbar with server-fetched categories

This commit is contained in:
achmad
2026-05-28 22:26:34 +07:00
parent 1ab153c94f
commit dcae4824c6
2 changed files with 67 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
import { getAllCategories } from '@/lib/directus'
import NavbarClient from './NavbarClient'
export default async function Navbar() {
const categories = await getAllCategories()
return <NavbarClient categories={categories} />
}
+60
View File
@@ -0,0 +1,60 @@
'use client'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { Search } from 'lucide-react'
import type { Category } from '@/lib/types'
interface Props {
categories: Category[]
}
export default function NavbarClient({ categories }: Props) {
const pathname = usePathname()
function openSearch() {
window.dispatchEvent(new CustomEvent('kotobane:open-search'))
}
return (
<nav className="bg-bg-elevated border-b border-border sticky top-0 z-40">
<div className="max-w-[1200px] mx-auto px-6 h-14 flex items-center gap-6">
<Link href="/" className="text-lg font-black text-accent tracking-[3px] shrink-0">
</Link>
<div className="w-px h-4 bg-border shrink-0" />
<div className="flex items-center gap-1 overflow-x-auto">
{categories.map((cat) => {
const isActive = pathname.startsWith(`/${cat.slug}`)
return (
<Link
key={cat.slug}
href={`/${cat.slug}`}
className={`text-xs font-medium px-3 py-1 rounded-sm whitespace-nowrap transition-colors ${
isActive
? 'text-accent'
: 'text-text-muted hover:text-text-secondary'
}`}
>
{cat.name}
</Link>
)
})}
</div>
<button
onClick={openSearch}
className="ml-auto flex items-center gap-2 text-text-muted hover:text-text-secondary transition-colors shrink-0"
aria-label="Open search"
>
<Search size={16} />
<kbd className="hidden sm:inline-flex bg-bg-card border border-border rounded px-1.5 py-0.5 text-[10px] font-mono">
K
</kbd>
</button>
</div>
</nav>
)
}