import {SETTINGS_NAV} from '@/features/settings/config/settingsNav'; import {ICONS} from '@/shared/utils/icons'; import type {IconType} from '@astryxdesign/core/Icon'; /** * The account menu, as a two-level cascade rather than a flat list. * * Panel one is identity plus four branches and a way out. Every branch opens a * SECOND panel beside the first — it never navigates. Only a leaf navigates, * and leaves only exist in panel two (and on the sign-out row, which ends the * session instead). * * That distinction is the whole shape of the file: `AccountBranch` carries a * `panel`, `AccountLeaf` carries a destination or an `action`, and nothing * carries both. A row cannot accidentally do both things because there is no * type that permits it. */ export type AccountPanelId = 'settings' | 'profile' | 'language' | 'help'; /** * Rows that resolve to something. `href` routes, `externalHref` opens a tab, * `action` is handled by the menu itself. */ export interface AccountLeaf { label: string; icon?: IconType; /** Shown under the label. Use it for a live value, not for decoration. */ description?: string; /** Internal destination. */ href?: string; /** Opens in a new tab instead of routing. Mutually exclusive with href. */ externalHref?: string; /** Non-navigational rows: the session, and the two help surfaces. */ action?: 'signOut' | 'shortcuts' | 'about'; /** Only sign-out may carry semantic colour — see the monochrome rule. */ tone?: 'danger'; } /** Rows that open panel two. The one thing they must never do is navigate. */ export interface AccountBranch { label: string; icon: IconType; panel: AccountPanelId; description?: string; } export type AccountRowSpec = AccountLeaf | AccountBranch; export function isBranch(row: AccountRowSpec): row is AccountBranch { return 'panel' in row; } /** * Panel one, as two groups separated by a divider. * * Four branches and sign-out — deliberately short. Everything that used to sit * here as a flat list of twelve destinations now lives one level down, where * it is grouped by what it is rather than stacked by what fit. */ export const ACCOUNT_ROOT_GROUPS: AccountRowSpec[][] = [ // Flat: every row is a destination that exists. The cascading panels below // are unreachable from here and kept only until the menu is simplified. [ {label: 'Account & devices', icon: ICONS.profile, href: '/settings'}, {label: 'Team', icon: ICONS.staff, href: '/settings/team'}, {label: 'Keyboard shortcuts', icon: ICONS.keyboard, action: 'shortcuts'}, ], [ { label: 'Log out', icon: ICONS.signOut, action: 'signOut', tone: 'danger', }, ], ]; export interface AccountPanel { title: string; rows: AccountLeaf[]; } /** * The locales the workspace offers, in the order PreferencesForm lists them. * * Display only: there is no locale provider yet, so selecting one marks the * row and nothing else. The row that actually persists a choice is the * "Language settings" leaf at the bottom of that panel, which routes to * Preferences where the Selector writes it. */ export interface LocaleOption { code: 'en' | 'hi' | 'kn' | 'ta'; label: string; } export const LOCALE_OPTIONS: LocaleOption[] = [ {code: 'en', label: 'English (US & India)'}, {code: 'hi', label: 'Hindi (हिंदी)'}, {code: 'kn', label: 'Kannada (ಕನ್ನಡ)'}, {code: 'ta', label: 'Tamil (தமிழ்)'}, ]; /** The shipped default in PreferencesForm. */ export const DEFAULT_LOCALE: LocaleOption['code'] = 'en'; /** * Panel two, keyed by the branch that opens it. * * `settings` is DERIVED from SETTINGS_NAV rather than restated: the settings * sub-nav and this panel are the same eleven destinations, and a copy here is * a copy that goes stale the first time a section is added. * * `language` holds only its trailing leaf — the locale rows are stateful and * come from LOCALE_OPTIONS at render time. */ export const ACCOUNT_PANELS: Record = { settings: { title: 'Settings', rows: SETTINGS_NAV.map(({label, href, icon}) => ({label, href, icon})), }, profile: { title: 'Profile', rows: [ {label: 'Account & devices', icon: ICONS.profile, href: '/settings'}, ], }, language: { title: 'Language', rows: [ { label: 'Language settings', icon: ICONS.preferences, href: '/settings', }, ], }, help: { title: 'Help', rows: [ // Placeholder URLs on the brand's own domain — point them at the real // docs and support hosts when there are any. { label: 'Documentation', icon: ICONS.docs, externalHref: 'https://loyaly.ai/docs', }, {label: 'Keyboard Shortcuts', icon: ICONS.keyboard, action: 'shortcuts'}, { label: 'Report Bug', icon: ICONS.alert, externalHref: 'https://loyaly.ai/support/bug', }, { label: 'Contact Support', icon: ICONS.chat, externalHref: 'https://loyaly.ai/support', }, {label: 'About Loyaly', icon: ICONS.info, action: 'about'}, ], }, };