Phase 1 Complete by Claude Code
This commit is contained in:
@@ -1 +1,28 @@
|
||||
// TODO: Header component
|
||||
import { useAuth } from "../auth/AuthContext";
|
||||
|
||||
export default function Header() {
|
||||
const { user, logout } = useAuth();
|
||||
|
||||
return (
|
||||
<header className="bg-white border-b border-gray-200 px-6 py-3 flex items-center justify-between">
|
||||
<h2 className="text-lg font-semibold text-gray-800">
|
||||
BellSystems Admin Panel
|
||||
</h2>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<span className="text-sm text-gray-600">
|
||||
{user?.name}
|
||||
<span className="ml-2 px-2 py-0.5 bg-gray-100 text-gray-500 text-xs rounded-full">
|
||||
{user?.role}
|
||||
</span>
|
||||
</span>
|
||||
<button
|
||||
onClick={logout}
|
||||
className="text-sm text-red-600 hover:text-red-800 transition-colors"
|
||||
>
|
||||
Sign out
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1 +1,17 @@
|
||||
// TODO: Main layout wrapper
|
||||
import { Outlet } from "react-router-dom";
|
||||
import Header from "./Header";
|
||||
import Sidebar from "./Sidebar";
|
||||
|
||||
export default function MainLayout() {
|
||||
return (
|
||||
<div className="flex min-h-screen bg-gray-100">
|
||||
<Sidebar />
|
||||
<div className="flex-1 flex flex-col">
|
||||
<Header />
|
||||
<main className="flex-1 p-6">
|
||||
<Outlet />
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1 +1,42 @@
|
||||
// TODO: Navigation menu
|
||||
import { NavLink } from "react-router-dom";
|
||||
import { useAuth } from "../auth/AuthContext";
|
||||
|
||||
const navItems = [
|
||||
{ to: "/", label: "Dashboard", roles: null },
|
||||
{ to: "/melodies", label: "Melodies", roles: ["superadmin", "melody_editor", "viewer"] },
|
||||
{ to: "/devices", label: "Devices", roles: ["superadmin", "device_manager", "viewer"] },
|
||||
{ to: "/users", label: "Users", roles: ["superadmin", "user_manager", "viewer"] },
|
||||
{ to: "/mqtt", label: "MQTT", roles: ["superadmin", "device_manager", "viewer"] },
|
||||
];
|
||||
|
||||
export default function Sidebar() {
|
||||
const { hasRole } = useAuth();
|
||||
|
||||
const visibleItems = navItems.filter(
|
||||
(item) => item.roles === null || hasRole(...item.roles)
|
||||
);
|
||||
|
||||
return (
|
||||
<aside className="w-56 bg-gray-900 text-white min-h-screen p-4">
|
||||
<div className="text-xl font-bold mb-8 px-2">BellSystems</div>
|
||||
<nav className="space-y-1">
|
||||
{visibleItems.map((item) => (
|
||||
<NavLink
|
||||
key={item.to}
|
||||
to={item.to}
|
||||
end={item.to === "/"}
|
||||
className={({ isActive }) =>
|
||||
`block px-3 py-2 rounded-md text-sm transition-colors ${
|
||||
isActive
|
||||
? "bg-gray-700 text-white"
|
||||
: "text-gray-300 hover:bg-gray-800 hover:text-white"
|
||||
}`
|
||||
}
|
||||
>
|
||||
{item.label}
|
||||
</NavLink>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user