69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { Link, useParams } from "react-router-dom";
|
|
import { listProjects } from "../../lib/api";
|
|
import type { Project } from "../../lib/types";
|
|
|
|
export default function Sidebar() {
|
|
const [projects, setProjects] = useState<Project[]>([]);
|
|
const { projectId } = useParams();
|
|
|
|
useEffect(() => {
|
|
listProjects().then(setProjects);
|
|
}, []);
|
|
|
|
// Expose a refresh function via custom event
|
|
useEffect(() => {
|
|
const handler = () => {
|
|
listProjects().then(setProjects);
|
|
};
|
|
window.addEventListener("orchai:refresh-projects", handler);
|
|
return () => window.removeEventListener("orchai:refresh-projects", handler);
|
|
}, []);
|
|
|
|
return (
|
|
<aside className="w-64 bg-gray-900 text-gray-100 flex flex-col h-screen">
|
|
<div className="p-4 border-b border-gray-700">
|
|
<h1 className="text-lg font-bold">Orchai</h1>
|
|
</div>
|
|
|
|
<nav className="flex-1 overflow-y-auto p-2">
|
|
<div className="flex items-center justify-between px-2 py-1 mb-1">
|
|
<span className="text-xs font-semibold text-gray-400 uppercase tracking-wider">
|
|
Projects
|
|
</span>
|
|
<Link
|
|
to="/projects/new"
|
|
className="text-gray-400 hover:text-white text-lg leading-none"
|
|
title="Add project"
|
|
>
|
|
+
|
|
</Link>
|
|
</div>
|
|
|
|
{projects.map((project) => (
|
|
<Link
|
|
key={project.id}
|
|
to={`/projects/${project.id}`}
|
|
className={`block px-3 py-2 rounded text-sm ${
|
|
projectId === project.id
|
|
? "bg-gray-700 text-white"
|
|
: "text-gray-300 hover:bg-gray-800 hover:text-white"
|
|
}`}
|
|
>
|
|
{project.name}
|
|
</Link>
|
|
))}
|
|
|
|
{projects.length === 0 && (
|
|
<p className="px-3 py-2 text-sm text-gray-500">No projects yet</p>
|
|
)}
|
|
</nav>
|
|
|
|
<div className="p-2 border-t border-gray-700">
|
|
<Link to="/settings" className="block px-3 py-2 rounded text-sm text-gray-300 hover:bg-gray-800 hover:text-white">
|
|
Settings
|
|
</Link>
|
|
</div>
|
|
</aside>
|
|
);
|
|
}
|