integratedhub/islands/WelcomeBar/navigationConfig.ts
2026-02-14 06:10:15 +00:00

249 lines
6.6 KiB
TypeScript

import { NavigationGroup, NavigationItem } from "./welcome-types.ts";
export type NavigationContext = "calendar" | "landlord" | "tenant" | "default";
function normalizePath(path: string): string {
if (!path) return "/";
const [pathname] = path.split(/[?#]/);
if (!pathname || pathname === "/") return "/";
return pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
}
function getCurrentFinancialCalendarPath(date = new Date()): string {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
return `/calendar/financial-calendar/${year}/${month}`;
}
export function resolveNavigationContext(
currentRoute: string,
): NavigationContext {
const route = normalizePath(currentRoute);
if (route.startsWith("/calendar/")) return "calendar";
if (route.startsWith("/landlord/")) return "landlord";
if (route.startsWith("/tenant/")) return "tenant";
return "default";
}
export function isNavigationItemActive(
item: NavigationItem,
currentRoute: string,
): boolean {
if (item.isForm) return false;
const route = normalizePath(currentRoute);
const itemPath = normalizePath(item.path);
if (route === itemPath) {
return true;
}
if (item.matchPrefixes && item.matchPrefixes.length > 0) {
return item.matchPrefixes.some((prefix) => {
const normalizedPrefix = normalizePath(prefix);
return route === normalizedPrefix ||
route.startsWith(`${normalizedPrefix}/`);
});
}
return false;
}
/**
* Default navigation groups configuration.
* Groups are filtered by current route context (calendar / landlord / tenant / default).
*/
export const defaultNavigationGroups: NavigationGroup[] = [
{
id: "auth",
label: "Session",
items: [
{
path: "/auth/login",
label: "Sign In",
requiresAuth: false,
isForm: true,
formAction: "/auth/login",
formMethod: "get",
},
{
path: "/auth/logout",
label: "Logout",
requiresAuth: true,
isForm: true,
formAction: "/auth/logout",
formMethod: "post",
onClick: () => {
localStorage.setItem("lastClickedButton", "logout");
},
},
],
},
{
id: "apps",
label: "App Switch",
items: [
{
path: getCurrentFinancialCalendarPath(),
label: "Calendar",
requiresAuth: true,
matchPrefixes: ["/calendar/financial-calendar"],
},
{
path: "/landlord/dashboard",
label: "Landlord",
requiresAuth: true,
},
{
path: "/tenant/dashboard",
label: "Tenant",
requiresAuth: true,
},
],
},
{
id: "calendar",
label: "Calendar",
items: [
{
path: getCurrentFinancialCalendarPath(),
label: "Financial Calendar",
requiresAuth: true,
matchPrefixes: ["/calendar/financial-calendar"],
},
{
path: "/calendar/every-income",
label: "Every Income",
requiresAuth: true,
},
{
path: "/calendar/budget-obligations",
label: "Budget Obligations",
requiresAuth: true,
},
],
},
{
id: "landlord",
label: "Landlord",
items: [
{ path: "/landlord/dashboard", label: "Dashboard", requiresAuth: true },
{ path: "/landlord/properties", label: "Properties", requiresAuth: true },
{ path: "/landlord/leases", label: "Leases", requiresAuth: true },
{ path: "/landlord/payments", label: "Payments", requiresAuth: true },
{
path: "/landlord/maintenance",
label: "Maintenance",
requiresAuth: true,
},
{
path: "/landlord/applications",
label: "Applications",
requiresAuth: true,
},
{ path: "/landlord/messages", label: "Messages", requiresAuth: true },
{ path: "/landlord/reminders", label: "Reminders", requiresAuth: true },
{ path: "/landlord/documents", label: "Documents", requiresAuth: true },
],
},
{
id: "tenant",
label: "Tenant",
items: [
{ path: "/tenant/dashboard", label: "Dashboard", requiresAuth: true },
{ path: "/tenant/property", label: "Property", requiresAuth: true },
{ path: "/tenant/payments", label: "Payments", requiresAuth: true },
{
path: "/tenant/payment-methods",
label: "Payment Methods",
requiresAuth: true,
},
{ path: "/tenant/maintenance", label: "Maintenance", requiresAuth: true },
{ path: "/tenant/messages", label: "Messages", requiresAuth: true },
{
path: "/tenant/applications",
label: "Applications",
requiresAuth: true,
},
{ path: "/tenant/reminders", label: "Reminders", requiresAuth: true },
{ path: "/tenant/documents", label: "Documents", requiresAuth: true },
{ path: "/tenant/settings", label: "Settings", requiresAuth: true },
],
},
{
id: "general",
label: "General",
items: [
{
path: "/",
label: "Home",
requiresAuth: false,
},
{
path: "/user-profile",
label: "Profile",
requiresAuth: true,
},
],
},
];
const contextGroupOrder: Record<NavigationContext, string[]> = {
default: ["auth", "apps", "general"],
calendar: ["auth", "calendar", "apps", "general"],
landlord: ["auth", "landlord", "apps", "general"],
tenant: ["auth", "tenant", "apps", "general"],
};
/**
* Get navigation groups filtered by authentication status and current route context.
*/
export function getNavigationGroups(
isLoggedIn: boolean,
currentRoute: string,
customGroups?: NavigationGroup[],
): NavigationGroup[] {
const groups = customGroups || defaultNavigationGroups;
const route = normalizePath(currentRoute);
const context = resolveNavigationContext(route);
const orderedGroupIds = contextGroupOrder[context];
return groups
.filter((group) => {
if (customGroups) return true;
return orderedGroupIds.includes(group.id);
})
.sort((a, b) => {
if (customGroups) return 0;
return orderedGroupIds.indexOf(a.id) - orderedGroupIds.indexOf(b.id);
})
.map((group) => ({
...group,
items: group.items.filter((item) => {
if (item.requiresAuth && !isLoggedIn) {
return false;
}
if (group.id === "auth") {
if (item.path === "/auth/login" && isLoggedIn) {
return false;
}
if (item.path === "/auth/logout" && !isLoggedIn) {
return false;
}
}
if (isNavigationItemActive(item, route)) {
return false;
}
return true;
}),
}))
.filter((group) => group.items.length > 0);
}