forked from farhoodlabs/paperclip
Add React UI with Vite
Dashboard, agents, goals, issues, and projects pages with sidebar navigation. API client layer, custom hooks, and shared layout components. Built with Vite and TypeScript. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { Sidebar } from "./Sidebar";
|
||||
|
||||
export function Layout() {
|
||||
return (
|
||||
<div className="flex h-screen bg-gray-50 text-gray-900">
|
||||
<Sidebar />
|
||||
<main className="flex-1 overflow-auto p-8">
|
||||
<Outlet />
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { NavLink } from "react-router-dom";
|
||||
import { cn } from "../lib/utils";
|
||||
|
||||
const links = [
|
||||
{ to: "/", label: "Dashboard" },
|
||||
{ to: "/agents", label: "Agents" },
|
||||
{ to: "/projects", label: "Projects" },
|
||||
{ to: "/issues", label: "Issues" },
|
||||
{ to: "/goals", label: "Goals" },
|
||||
];
|
||||
|
||||
export function Sidebar() {
|
||||
return (
|
||||
<aside className="w-56 border-r border-gray-200 bg-white p-4 flex flex-col gap-1">
|
||||
<h1 className="text-lg font-bold mb-6 px-3">Paperclip</h1>
|
||||
<nav className="flex flex-col gap-1">
|
||||
{links.map((link) => (
|
||||
<NavLink
|
||||
key={link.to}
|
||||
to={link.to}
|
||||
end={link.to === "/"}
|
||||
className={({ isActive }) =>
|
||||
cn(
|
||||
"px-3 py-2 rounded-md text-sm font-medium transition-colors",
|
||||
isActive
|
||||
? "bg-gray-100 text-gray-900"
|
||||
: "text-gray-600 hover:bg-gray-50 hover:text-gray-900"
|
||||
)
|
||||
}
|
||||
>
|
||||
{link.label}
|
||||
</NavLink>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { cn } from "../lib/utils";
|
||||
|
||||
const statusColors: Record<string, string> = {
|
||||
active: "bg-green-100 text-green-800",
|
||||
idle: "bg-yellow-100 text-yellow-800",
|
||||
offline: "bg-gray-100 text-gray-600",
|
||||
error: "bg-red-100 text-red-800",
|
||||
backlog: "bg-gray-100 text-gray-600",
|
||||
todo: "bg-blue-100 text-blue-800",
|
||||
in_progress: "bg-indigo-100 text-indigo-800",
|
||||
in_review: "bg-purple-100 text-purple-800",
|
||||
done: "bg-green-100 text-green-800",
|
||||
cancelled: "bg-gray-100 text-gray-500",
|
||||
};
|
||||
|
||||
export function StatusBadge({ status }: { status: string }) {
|
||||
return (
|
||||
<span
|
||||
className={cn(
|
||||
"inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium",
|
||||
statusColors[status] ?? "bg-gray-100 text-gray-600"
|
||||
)}
|
||||
>
|
||||
{status.replace("_", " ")}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user