librelad 875a60f90f LibrePortal v0.1.0 — initial release
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>
2026-05-21 20:37:54 +01:00

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>
);
}