Files
daily_console_web/src/features/console/consoleScope.ts
2026-09-03 12:31:07 +05:30

83 lines
2.9 KiB
TypeScript

/**
* 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,
};
}