first commit

This commit is contained in:
2026-02-28 23:01:30 +08:00
commit 3956ee4806
415 changed files with 74538 additions and 0 deletions

94
components/Sidebar.tsx Normal file
View File

@@ -0,0 +1,94 @@
'use client';
import Link from 'next/link';
import { useState, useEffect } from 'react';
import { ThemeToggle } from './ThemeToggle';
interface SidebarItem {
title: string;
slug: string;
children?: SidebarItem[];
}
interface SidebarProps {
sidebarData: SidebarItem[];
currentSlug?: string;
}
export function Sidebar({ sidebarData, currentSlug }: SidebarProps) {
// Use a map to track open state of each section (by slug)
const [openSections, setOpenSections] = useState<Record<string, boolean>>({});
useEffect(() => {
// Automatically open the section that contains the current slug
if (currentSlug) {
const parentSection = sidebarData.find(item =>
item.children?.some(child => child.slug === currentSlug)
);
if (parentSection) {
setOpenSections(prev => ({ ...prev, [parentSection.slug]: true }));
}
}
}, [currentSlug, sidebarData]);
const toggleSection = (slug: string) => {
setOpenSections(prev => ({ ...prev, [slug]: !prev[slug] }));
};
return (
<aside className="sidebar">
<div className="sidebar-header">
<Link href="/" className="sidebar-logo">
<div className="sidebar-logo-icon">🦞</div>
<div className="sidebar-logo-text">
<span className="sidebar-logo-title">OpenClaw</span>
<span className="sidebar-logo-subtitle"></span>
</div>
</Link>
<ThemeToggle />
</div>
<nav className="sidebar-nav">
{sidebarData.map(item => {
if (item.children && item.children.length > 0) {
const isOpen = !!openSections[item.slug];
const hasActiveChild = item.children.some(c => c.slug === currentSlug);
return (
<div key={item.slug} className="sidebar-section">
<div
className={`sidebar-section-title ${hasActiveChild ? 'active' : ''}`}
onClick={() => toggleSection(item.slug)}
>
{item.title}
<span className={`sidebar-section-arrow ${isOpen ? 'open' : ''}`}></span>
</div>
{isOpen && (
<div className="sidebar-section-children">
{item.children.map(child => (
<Link
key={child.slug}
href={child.slug}
className={`sidebar-link ${child.slug === currentSlug ? 'active' : ''}`}
>
{child.title}
</Link>
))}
</div>
)}
</div>
);
}
return (
<Link
key={item.slug}
href={item.slug}
className={`sidebar-root-link ${item.slug === currentSlug ? 'active' : ''}`}
>
{item.title}
</Link>
);
})}
</nav>
</aside>
);
}