ui: add protected dashboard CRUD screens and assignment docs
This commit is contained in:
parent
bf42037619
commit
cb0d4d7809
24 changed files with 2662 additions and 101 deletions
123
apps/web/src/components/dashboard-shell.tsx
Normal file
123
apps/web/src/components/dashboard-shell.tsx
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
import { Button } from "@minmon/ui/components/button";
|
||||
import { cn } from "@minmon/ui/lib/utils";
|
||||
import { Link, Outlet, useRouterState } from "@tanstack/react-router";
|
||||
import { Activity, BookText, Globe, LayoutGrid, Server, Wrench } from "lucide-react";
|
||||
|
||||
const dashboardLinks = [
|
||||
{
|
||||
to: "/dashboard",
|
||||
label: "Overview",
|
||||
description: "Health, alerts, and recent checks",
|
||||
icon: LayoutGrid,
|
||||
},
|
||||
{
|
||||
to: "/dashboard/servers",
|
||||
label: "Servers",
|
||||
description: "Inventory and host details",
|
||||
icon: Server,
|
||||
},
|
||||
{
|
||||
to: "/dashboard/services",
|
||||
label: "Services",
|
||||
description: "Processes and uptime targets",
|
||||
icon: Wrench,
|
||||
},
|
||||
{
|
||||
to: "/dashboard/domains",
|
||||
label: "Domains",
|
||||
description: "DNS, SSL, and expiry status",
|
||||
icon: Globe,
|
||||
},
|
||||
{
|
||||
to: "/dashboard/notes",
|
||||
label: "Notes",
|
||||
description: "Runbooks and operational handover",
|
||||
icon: BookText,
|
||||
},
|
||||
] as const;
|
||||
|
||||
export function DashboardShell({
|
||||
userName,
|
||||
userEmail,
|
||||
}: {
|
||||
userName?: string | null;
|
||||
userEmail?: string | null;
|
||||
}) {
|
||||
const pathname = useRouterState({
|
||||
select: (state) => state.location.pathname,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="min-h-full bg-muted/20">
|
||||
<div className="mx-auto flex w-full max-w-7xl flex-col gap-6 px-4 py-6 lg:px-6">
|
||||
<section className="border bg-card">
|
||||
<div className="grid gap-4 px-5 py-5 lg:grid-cols-[1.4fr_0.6fr] lg:px-6">
|
||||
<div className="space-y-2">
|
||||
<p className="text-[11px] uppercase tracking-[0.24em] text-muted-foreground">
|
||||
Server Management Dashboard
|
||||
</p>
|
||||
<h1 className="text-2xl font-semibold tracking-tight">Operations overview for demos and day-to-day admin tasks</h1>
|
||||
<p className="max-w-2xl text-sm text-muted-foreground">
|
||||
Use this area to review monitored assets, inspect detail states, and stage CRUD forms that can connect to tRPC routers as they are added.
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid gap-3 border-l-0 border-t pt-4 lg:border-l lg:border-t-0 lg:pl-6 lg:pt-0">
|
||||
<div>
|
||||
<p className="text-[11px] uppercase tracking-[0.16em] text-muted-foreground">Signed in as</p>
|
||||
<p className="mt-1 text-sm font-medium">{userName ?? "Administrator"}</p>
|
||||
<p className="text-xs text-muted-foreground">{userEmail ?? "admin@minmon.local"}</p>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Link to="/dashboard/servers/new">
|
||||
<Button size="sm">Add server</Button>
|
||||
</Link>
|
||||
<Link to="/dashboard/notes/new">
|
||||
<Button size="sm" variant="outline">
|
||||
New note
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="grid gap-6 lg:grid-cols-[240px_minmax(0,1fr)]">
|
||||
<aside className="h-fit border bg-card">
|
||||
<div className="border-b px-4 py-3">
|
||||
<div className="flex items-center gap-2 text-sm font-medium">
|
||||
<Activity className="size-4" />
|
||||
Navigation
|
||||
</div>
|
||||
</div>
|
||||
<nav className="grid gap-1 p-2">
|
||||
{dashboardLinks.map(({ to, label, description, icon: Icon }) => {
|
||||
const active = pathname === to || pathname.startsWith(`${to}/`);
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={to}
|
||||
to={to}
|
||||
className={cn(
|
||||
"grid gap-0.5 border px-3 py-2 text-left transition-colors",
|
||||
active ? "border-foreground/20 bg-muted" : "border-transparent hover:border-border hover:bg-muted/40",
|
||||
)}
|
||||
>
|
||||
<span className="flex items-center gap-2 text-sm font-medium">
|
||||
<Icon className="size-4" />
|
||||
{label}
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">{description}</span>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<main className="min-w-0">
|
||||
<Outlet />
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue