First Commit

This commit is contained in:
2026-09-12 13:56:36 +01:00
commit 4d75af0418
426 changed files with 36452 additions and 0 deletions
@@ -0,0 +1,89 @@
import React from "react";
import { Menu, X } from "lucide-react";
import AdminAsideLinks from "./admin-aside-links-dict";
import Row from "@/src/components/twui/layout/Row";
import LogoIcon from "@/src/components/general/logo-icon";
import Divider from "@/src/components/twui/layout/Divider";
import { twMerge } from "tailwind-merge";
import Stack from "@/src/components/twui/layout/Stack";
export default function MobileNav() {
const [open, setOpen] = React.useState(false);
React.useEffect(() => {
if (!open) return;
const prev = document.body.style.overflow;
document.body.style.overflow = "hidden";
const onKey = (e: KeyboardEvent) => {
if (e.key === "Escape") setOpen(false);
};
document.addEventListener("keydown", onKey);
return () => {
document.body.style.overflow = prev;
document.removeEventListener("keydown", onKey);
};
}, [open]);
return (
<div className="flex xl:hidden">
<button
type="button"
aria-label="Open menu"
aria-expanded={open}
className="cursor-pointer p-1"
onClick={() => setOpen(true)}
>
<Menu size={28} />
</button>
{open ? (
<>
<div
className="fixed inset-0 z-200 bg-dark/50"
onClick={() => setOpen(false)}
aria-hidden
/>
<aside
className={twMerge(
"fixed top-0 left-0 bottom-0 z-210",
"w-[min(280px,85vw)] bg-background-light dark:bg-background-dark",
"flex flex-col shadow-xl",
)}
role="dialog"
aria-modal="true"
aria-label="Admin navigation"
>
<Row className="w-full justify-between items-center py-2 px-4 h-20 flex-nowrap">
<a href="/" onClick={() => setOpen(false)}>
<LogoIcon icon_size={60} />
</a>
<button
type="button"
aria-label="Close menu"
className="cursor-pointer p-1"
onClick={() => setOpen(false)}
>
<X size={28} />
</button>
</Row>
<Divider />
<Stack
className="w-full grow overflow-y-auto"
onClick={(e) => {
if ((e.target as HTMLElement).closest("a")) {
setOpen(false);
}
}}
>
<AdminAsideLinks />
</Stack>
</aside>
</>
) : null}
</div>
);
}
@@ -0,0 +1,66 @@
import type { TWUILink } from "@/src/components/twui/elements/LinkList";
import LinkList from "@/src/components/twui/elements/LinkList";
import Stack from "@/src/components/twui/layout/Stack";
import { AppContext } from "@/src/pages/__root";
import { useContext } from "react";
export default function AdminAsideLinks() {
const { pageProps } = useContext(AppContext);
const { user, user_types } = pageProps || {};
if (!user?.logged_in_status) {
return null;
}
const links: TWUILink[] = [
{
title: "Dashboard",
url: "/admin",
strict: true,
},
{
title: "People",
url: "/admin/people",
},
{
title: "Events",
url: "/admin/events",
},
{
title: "Media",
url: "/admin/media",
},
{
title: "Board",
url: "/admin/board",
},
{
title: "Locations",
url: "/admin/locations",
},
{
component: <div className="h-10"></div>,
},
{
title: "Settings",
url: "/admin/settings",
},
{
title: "Logout",
url: "/auth/logout",
},
];
return (
<Stack className="w-full items-stretch">
<LinkList
links={links}
className="gap-1 flex-col items-start"
linkProps={{
className: "px-4 py-3 w-full",
}}
divider
/>
</Stack>
);
}
+29
View File
@@ -0,0 +1,29 @@
import Row from "@/src/components/twui/layout/Row";
import Stack from "@/src/components/twui/layout/Stack";
import LogoIcon from "@/src/components/general/logo-icon";
import Divider from "@/src/components/twui/layout/Divider";
import AdminAsideLinks from "./admin-aside-links-dict";
import { twMerge } from "tailwind-merge";
type Props = {
className?: string;
};
export default function AdminAside({ className }: Props) {
return (
<aside className={twMerge("min-w-[180px] mb-20", className)}>
<Stack className="w-full items-stretch gap-0!">
<Row className="py-2 px-4 h-20">
<a href="/">
<LogoIcon icon_size={60} />
</a>
</Row>
<Divider />
<nav className="w-full">
<AdminAsideLinks />
</nav>
<Divider />
</Stack>
</aside>
);
}