Staff / Owner

Merged staff and owner settings
This commit is contained in:
Stefan Lazic committed 2026-08-05 16:35:52 +01:00
1 parent cf3a28f3cd
commit 3300045d9e
23 files changed
+693 -236

No files matched your search

@@ -0,0 +1,79 @@
import { describe, expect, it } from "vitest";
import { getNavItems, resolveActiveHref } from "../nav-config";
describe("getNavItems", () => {
it("gives a barber exactly Calendar/Now/Clients/Settings", () => {
const labels = getNavItems("staff").map((i) => i.label);
expect(labels).toEqual(["Calendar", "Now", "Clients", "Settings"]);
});
it("gives an owner Calendar/Now/Clients/Manage/Settings — barber tools and business tools in one menu", () => {
const labels = getNavItems("owner").map((i) => i.label);
expect(labels).toEqual(["Calendar", "Now", "Clients", "Manage", "Settings"]);
});
it("gives a Super Administrator no 'Now' tab — there is no personal barber schedule to show", () => {
const labels = getNavItems("superadmin").map((i) => i.label);
expect(labels).toEqual(["Calendar", "Clients", "Manage", "Settings"]);
expect(labels).not.toContain("Now");
});
it("points owner's Now/Clients/Settings at the same routes a barber uses — no duplicate business-wide pages", () => {
const owner = getNavItems("owner");
const staff = getNavItems("staff");
expect(owner.find((i) => i.label === "Now")?.href).toBe(staff.find((i) => i.label === "Now")?.href);
expect(owner.find((i) => i.label === "Clients")?.href).toBe(staff.find((i) => i.label === "Clients")?.href);
expect(owner.find((i) => i.label === "Settings")?.href).toBe(staff.find((i) => i.label === "Settings")?.href);
});
it("gives owner and super-admin a business-wide Calendar, distinct from the barber's personal one", () => {
expect(getNavItems("owner").find((i) => i.label === "Calendar")?.href).toBe("/owner/calendar");
expect(getNavItems("superadmin").find((i) => i.label === "Calendar")?.href).toBe("/owner/calendar");
expect(getNavItems("staff").find((i) => i.label === "Calendar")?.href).toBe("/staff");
});
it("caps every role's nav at 5 items", () => {
for (const role of ["staff", "owner", "superadmin"] as const) {
expect(getNavItems(role).length).toBeLessThanOrEqual(5);
}
});
});
describe("resolveActiveHref", () => {
const staffItems = getNavItems("staff");
const ownerItems = getNavItems("owner");
it("activates Calendar for the barber's own calendar root", () => {
expect(resolveActiveHref("/staff", staffItems)).toBe("/staff");
});
it("activates Now for /staff/current, not Calendar — the classic longest-prefix trap", () => {
expect(resolveActiveHref("/staff/current", staffItems)).toBe("/staff/current");
});
it("activates Clients for a nested client detail route", () => {
expect(resolveActiveHref("/staff/clients/abc123", staffItems)).toBe("/staff/clients");
});
it("activates Settings for a nested personal-settings route", () => {
expect(resolveActiveHref("/staff/settings/calendar", staffItems)).toBe("/staff/settings");
});
it("activates Manage for every /owner/* business-management route", () => {
expect(resolveActiveHref("/owner/team", ownerItems)).toBe("/owner");
expect(resolveActiveHref("/owner/services", ownerItems)).toBe("/owner");
expect(resolveActiveHref("/owner/settings/loyalty", ownerItems)).toBe("/owner");
});
it("activates the business-wide Calendar for /owner/calendar, not Manage", () => {
expect(resolveActiveHref("/owner/calendar", ownerItems)).toBe("/owner/calendar");
});
it("activates Now for /staff/current even from the owner nav (shared personal route)", () => {
expect(resolveActiveHref("/staff/current", ownerItems)).toBe("/staff/current");
});
it("returns null for a route no item covers", () => {
expect(resolveActiveHref("/sign-in", staffItems)).toBeNull();
});
});