Voeg Module 1 Projecten toe met project plan, Rikx calculatie en Rikx rondes
- Projectenpagina met pipeline (standaard) en tabelweergave, filters op status, Rikx Ronde en zoeken - Projectpagina in stappen: Project plan (velden uit de Rikx-aanvraag) en Rikx calculatie achter een schuif, live berekend volgens de rekenmethode - Rikx rondes beheren (label, Rikx waarde, Rikx prijs) en koppelen aan projecten - Oranje Rikx-menubalk met menu per module, gedeeld door alle pagina's - Oude offerte-tabellen opgeruimd: leeg wordt verwijderd, met data hernoemd naar legacy_* - CLAUDE.md bijgewerkt naar de huidige stand Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import Link from "next/link";
|
||||
import { logout } from "./tenants/logout";
|
||||
|
||||
type MenuItem = { label: string; href?: string };
|
||||
type NavItem = { label: string; section: string; href?: string; items?: MenuItem[] };
|
||||
|
||||
// Menu volgens de Rikx-modules. Items zonder href bestaan nog niet en tonen "binnenkort".
|
||||
const NAV_ITEMS: NavItem[] = [
|
||||
{ label: "Dashboard", section: "dashboard" },
|
||||
{
|
||||
label: "Projecten",
|
||||
section: "projecten",
|
||||
items: [
|
||||
{ label: "Overzicht", href: "/projecten" },
|
||||
{ label: "Project toevoegen", href: "/projecten/nieuw" },
|
||||
{ label: "Rikx rondes", href: "/rondes" },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Investeringen",
|
||||
section: "investeringen",
|
||||
items: [{ label: "Overzicht" }],
|
||||
},
|
||||
{
|
||||
label: "CRM",
|
||||
section: "crm",
|
||||
items: [{ label: "Sociaal ondernemers", href: "/tenants" }, { label: "Investeerders" }, { label: "Beoordelaars" }],
|
||||
},
|
||||
{ label: "Publieke Website", section: "website" },
|
||||
];
|
||||
|
||||
function Caret() {
|
||||
return (
|
||||
<svg viewBox="0 0 10 6" aria-hidden className="w-2.5 h-2.5 fill-current opacity-80">
|
||||
<path d="M0 0h10L5 6z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function linkClass(isActive: boolean) {
|
||||
return isActive
|
||||
? "text-rikx-purple"
|
||||
: "text-white hover:text-rikx-maroon transition-colors";
|
||||
}
|
||||
|
||||
export function AppHeader({ email, active }: { email: string; active?: string }) {
|
||||
return (
|
||||
<header className="bg-rikx-orange">
|
||||
<div className="max-w-[96rem] mx-auto px-4 sm:px-6 py-3 flex flex-wrap items-center gap-x-8 gap-y-2">
|
||||
<Link href="/projecten" className="text-white text-4xl font-extrabold tracking-tight leading-none">
|
||||
Rikx
|
||||
</Link>
|
||||
|
||||
<nav className="order-3 lg:order-none w-full lg:w-auto lg:flex-1 flex flex-wrap items-center lg:justify-center gap-x-6 gap-y-1 text-base sm:text-lg font-semibold">
|
||||
{NAV_ITEMS.map((item) => {
|
||||
const isActive = active === item.section;
|
||||
if (!item.items) {
|
||||
return item.href ? (
|
||||
<Link key={item.label} href={item.href} className={linkClass(isActive)}>
|
||||
{item.label}
|
||||
</Link>
|
||||
) : (
|
||||
<span key={item.label} title="Binnenkort" className="text-white/60 cursor-default">
|
||||
{item.label}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div key={item.label} className="relative group">
|
||||
<button
|
||||
type="button"
|
||||
className={`flex items-center gap-1.5 py-1 ${linkClass(isActive)}`}
|
||||
aria-haspopup="true"
|
||||
>
|
||||
{item.label}
|
||||
<Caret />
|
||||
</button>
|
||||
<div className="absolute left-0 top-full z-20 hidden group-hover:block group-focus-within:block pt-1">
|
||||
<ul className="min-w-52 rounded-lg bg-white dark:bg-zinc-900 shadow-lg ring-1 ring-black/5 py-1 text-sm font-medium">
|
||||
{item.items.map((sub) => (
|
||||
<li key={sub.label}>
|
||||
{sub.href ? (
|
||||
<Link
|
||||
href={sub.href}
|
||||
className="block px-4 py-2 text-zinc-800 dark:text-zinc-200 hover:bg-orange-50 dark:hover:bg-zinc-800 hover:text-rikx-orange-dark"
|
||||
>
|
||||
{sub.label}
|
||||
</Link>
|
||||
) : (
|
||||
<span className="flex items-center justify-between gap-3 px-4 py-2 text-zinc-400 cursor-default">
|
||||
{sub.label}
|
||||
<span className="text-xs font-normal">binnenkort</span>
|
||||
</span>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
|
||||
<div className="relative group ml-auto">
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Account"
|
||||
aria-haspopup="true"
|
||||
className="flex items-center justify-center w-10 h-10 rounded-full bg-white/90 text-zinc-400 hover:bg-white"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" aria-hidden className="w-7 h-7 fill-current">
|
||||
<path d="M12 12a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9Zm0 2c-4.4 0-8 2.2-8 5v1h16v-1c0-2.8-3.6-5-8-5Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div className="absolute right-0 top-full z-20 hidden group-hover:block group-focus-within:block pt-1">
|
||||
<div className="min-w-56 rounded-lg bg-white dark:bg-zinc-900 shadow-lg ring-1 ring-black/5 py-1 text-sm">
|
||||
<p className="px-4 py-2 text-zinc-500 truncate">{email}</p>
|
||||
<form action={logout}>
|
||||
<button className="w-full text-left px-4 py-2 text-zinc-800 dark:text-zinc-200 hover:bg-orange-50 dark:hover:bg-zinc-800">
|
||||
Uitloggen
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user