A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys, Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun VPN routing, and a web dashboard to manage it all. Free & open forever to self-host; optional paid hosted services fund it. See PROMISE.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
62 lines
2.0 KiB
TypeScript
62 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { usePathname } from "next/navigation";
|
|
import {
|
|
LayoutDashboard,
|
|
ListOrdered,
|
|
Repeat,
|
|
Target,
|
|
TrendingUp,
|
|
Upload,
|
|
Settings,
|
|
Wallet,
|
|
} from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
const NAV = [
|
|
{ href: "/", label: "Dashboard", icon: LayoutDashboard },
|
|
{ href: "/ledger", label: "Ledger", icon: ListOrdered },
|
|
{ href: "/recurring", label: "Recurring", icon: Repeat },
|
|
{ href: "/budgets", label: "Budgets", icon: Wallet },
|
|
{ href: "/goals", label: "Goals", icon: Target },
|
|
{ href: "/forecast", label: "Forecast", icon: TrendingUp },
|
|
{ href: "/import", label: "Import", icon: Upload },
|
|
{ href: "/settings", label: "Settings", icon: Settings },
|
|
];
|
|
|
|
export function Sidebar() {
|
|
const pathname = usePathname();
|
|
return (
|
|
<aside className="hidden md:flex md:w-60 shrink-0 flex-col gap-2 border-r border-border/60 bg-sidebar/80 px-3 py-5">
|
|
<div className="px-2 pb-3 flex items-center gap-2">
|
|
<div className="size-8 rounded-md bg-primary/20 grid place-items-center">
|
|
<span className="text-primary font-bold">£</span>
|
|
</div>
|
|
<span className="font-semibold tracking-tight">MoneyApp</span>
|
|
</div>
|
|
<nav className="flex flex-col gap-0.5">
|
|
{NAV.map((item) => {
|
|
const active = pathname === item.href || (item.href !== "/" && pathname.startsWith(item.href));
|
|
const Icon = item.icon;
|
|
return (
|
|
<Link
|
|
key={item.href}
|
|
href={item.href}
|
|
className={cn(
|
|
"flex items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors",
|
|
active
|
|
? "bg-sidebar-accent text-sidebar-accent-foreground font-medium"
|
|
: "text-sidebar-foreground/80 hover:bg-sidebar-accent/60 hover:text-sidebar-foreground",
|
|
)}
|
|
>
|
|
<Icon className="size-4" />
|
|
<span>{item.label}</span>
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
</aside>
|
|
);
|
|
}
|