Refine help UX and monthly close layout

This commit is contained in:
michael committed 2026-08-05 15:56:09 +02:00
1 parent 3b6f35e31a
commit f8574e5f39
5 files changed
+396 -214

No files matched your search

+41 -19
View File
@@ -69,6 +69,19 @@ import { TimerPage } from "./views/TimerPage";
import type { AuthUser, PeriodType } from "./types";
import type { Dispatch, SetStateAction } from "react";
type NavMenuEntry =
| {
type: "item";
href: string;
label: string;
icon: typeof Timer;
active: boolean;
}
| {
type: "separator";
key: string;
};
function routeFromPath(pathname: string) {
const periodTicketMatch = pathname.match(/^\/analysis\/(month|day)\/([^/]+)\/tickets\/(\d+)$/);
@@ -518,17 +531,20 @@ export function App() {
return <LoginPage onLogin={setCurrentUser} />;
}
const navItems = [
{ href: "/timer", label: "Timer", icon: Timer, active: path.startsWith("/timer") || path === "/" },
{ href: "/analysis", label: "Auswertung", icon: BarChart3, active: path.startsWith("/analysis") },
{ href: "/monthly-close", label: "Monatsabschluss", icon: ClipboardCheck, active: path.startsWith("/monthly-close") },
{ href: "/statistics", label: "Statistiken", icon: ChartNoAxesCombined, active: path.startsWith("/statistics") },
{ href: "/recurring", label: "Fixe Abrechnung", icon: Repeat, active: path.startsWith("/recurring") },
{ href: "/faq", label: "FAQ", icon: CircleHelp, active: path.startsWith("/faq") },
{ href: "/profile", label: "Profil", icon: UserCog, active: path.startsWith("/profile") },
const navItems: NavMenuEntry[] = [
{ type: "item", href: "/timer", label: "Timer", icon: Timer, active: path.startsWith("/timer") || path === "/" },
{ type: "item", href: "/analysis", label: "Auswertung", icon: BarChart3, active: path.startsWith("/analysis") },
{ type: "separator", key: "after-analysis" },
{ type: "item", href: "/monthly-close", label: "Monatsabschluss", icon: ClipboardCheck, active: path.startsWith("/monthly-close") },
{ type: "separator", key: "after-monthly-close" },
{ type: "item", href: "/statistics", label: "Statistiken", icon: ChartNoAxesCombined, active: path.startsWith("/statistics") },
{ type: "item", href: "/recurring", label: "Fixe Abrechnung", icon: Repeat, active: path.startsWith("/recurring") },
{ type: "item", href: "/profile", label: "Profil", icon: UserCog, active: path.startsWith("/profile") },
...(currentUser.role === "admin"
? [{ href: "/admin/users", label: "Benutzer", icon: Shield, active: path.startsWith("/admin/users") }]
? [{ type: "item" as const, href: "/admin/users", label: "Benutzer", icon: Shield, active: path.startsWith("/admin/users") }]
: []),
{ type: "separator", key: "before-faq" },
{ type: "item", href: "/faq", label: "FAQ", icon: CircleHelp, active: path.startsWith("/faq") },
];
const runningTimer = timers.find((timer) => timer.phase === "running") ?? null;
const runningElapsedSeconds = runningTimer ? Math.floor(activeElapsedMs(runningTimer, tick) / 1000) : 0;
@@ -589,16 +605,22 @@ export function App() {
<SidebarGroupLabel>Workflows</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{navItems.map((item) => (
<SidebarMenuItem key={item.href}>
<SidebarMenuButton asChild tooltip={item.label} isActive={item.active}>
<a href={item.href} onClick={navHandler(item.href)}>
<item.icon />
<span>{item.label}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
))}
{navItems.map((item) =>
item.type === "separator" ? (
<SidebarMenuItem key={item.key} className="py-1 group-data-[collapsible=icon]:hidden">
<Separator />
</SidebarMenuItem>
) : (
<SidebarMenuItem key={item.href}>
<SidebarMenuButton asChild tooltip={item.label} isActive={item.active}>
<a href={item.href} onClick={navHandler(item.href)}>
<item.icon />
<span>{item.label}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
)
)}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>