/** * What this Console is showing, and to whom. * * One component serves three situations — an admin across every branch, an * admin looking at one, and a store user who has exactly one. The differences * are almost entirely in the words and in which sections appear, so they are * decided here as data rather than scattered through the layout as `isPinned &&` * conditions that drift apart. * * Pure on purpose. The rules about what a store user may see are the kind that * get quietly broken by a later refactor, so they are tested rather than * inspected. */ export type ConsoleRole = 'admin' | 'store-user'; export interface ConsoleScopeInput { role: ConsoleRole; /** The branch in view. `null` means every branch the user may see. */ selected: number | null; /** Branch name when one is selected. */ branchName?: string | undefined; /** How many branches this user is authorised for. */ branchCount: number; } export interface ConsoleScope { /** True only for an admin looking across more than their own single branch. */ isAggregate: boolean; /** Sits beside the "Console" title. */ countLabel: string; /** The sentence under the title. */ blurb: string; /** What Nearle Buddy says it is answering about. */ buddyContext: string; /** Admin-only, and only across branches. */ showBranchOverview: boolean; /** "Your shop" reads as a lie when several are in view. */ shopSectionTitle: string; /** Whether a per-branch column earns its width. */ showBranchColumn: boolean; } export function consoleScope({ role, selected, branchName, branchCount, }: ConsoleScopeInput): ConsoleScope { // A store user is pinned to one outlet, so "all branches" is not a state they // can reach — and if a stray null ever arrives here it must not be read as // permission to aggregate. const isAggregate = role === 'admin' && selected === null; if (isAggregate) { return { isAggregate: true, countLabel: `${branchCount} ${branchCount === 1 ? 'branch' : 'branches'}`, blurb: 'Everything trading right now — across your branches, and what needs your attention.', buddyContext: 'Across your branches', showBranchOverview: true, // Naming it "Your shop" while thirteen are in view invites a merchant to // read one shop's numbers as the whole business. shopSectionTitle: 'Branch performance', showBranchColumn: true, }; } const name = branchName?.trim() || 'your store'; return { isAggregate: false, countLabel: name, blurb: `Everything trading right now — for ${name}.`, buddyContext: name, showBranchOverview: false, shopSectionTitle: role === 'store-user' ? 'Your shop' : 'Branch', // A store user already knows which branch they are in; an admin who chose // one branch does too. Neither needs it repeated in every table row. showBranchColumn: false, }; }