fix(loyalty): align menu item IDs with URL segments for sidebar highlight

The store and merchant init-alpine.js derive currentPage from the URL's
last segment (e.g., /loyalty/program -> 'program'). Loyalty menu items
used prefixed IDs like 'loyalty-program' which never matched, so sidebar
items never highlighted.

Fixed by renaming all store/merchant menu item IDs and JS currentPage
values to match URL segments: program, cards, analytics, transactions,
pins, settings — consistent with how every other module works.

Also reverted the init-alpine.js guard that broke storeCode extraction,
and added missing loyalty.common.contact_admin_setup translation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-23 18:32:50 +01:00
parent ce0caa5685
commit 1d90bfe044
20 changed files with 3497 additions and 3494 deletions

View File

@@ -65,16 +65,14 @@ function data() {
openSections: getStoreSidebarSectionsFromStorage(),
init() {
// Set current page from URL (only if not already set by child component)
if (!this.currentPage) {
const path = window.location.pathname;
const segments = path.split('/').filter(Boolean);
// For /store/ABC/orders/123 -> 'orders' (skip numeric IDs)
const last = segments[segments.length - 1] || 'dashboard';
this.currentPage = /^\d+$/.test(last) && segments.length > 2
? segments[segments.length - 2]
: last;
}
// Set current page from URL
const path = window.location.pathname;
const segments = path.split('/').filter(Boolean);
// For /store/ABC/orders/123 -> 'orders' (skip numeric IDs)
const last = segments[segments.length - 1] || 'dashboard';
this.currentPage = /^\d+$/.test(last) && segments.length > 2
? segments[segments.length - 2]
: last;
// Get store code from server-rendered value or URL fallback
this.storeCode = window.STORE_CODE || null;

View File

@@ -132,16 +132,17 @@ loyalty_module = ModuleDefinition(
FrontendType.STORE: [
"terminal", # Loyalty terminal
"cards", # Customer cards
"loyalty-program", # Program config
"loyalty-analytics", # Store analytics
"pins", # Staff PINs
"program", # Program config
"analytics", # Store analytics
],
FrontendType.MERCHANT: [
"loyalty-program", # Merchant loyalty program
"loyalty-cards", # Customer cards
"loyalty-analytics", # Merchant loyalty analytics
"loyalty-transactions", # Transaction feed
"loyalty-pins", # Staff PINs
"loyalty-settings", # Settings (read-only)
"program", # Merchant loyalty program
"cards", # Customer cards
"analytics", # Merchant loyalty analytics
"transactions", # Transaction feed
"pins", # Staff PINs
"settings", # Settings (read-only)
],
},
# New module-driven menu definitions
@@ -210,7 +211,7 @@ loyalty_module = ModuleDefinition(
requires_permission="loyalty.view_programs",
),
MenuItemDefinition(
id="loyalty-program",
id="program",
label_key="loyalty.menu.program",
icon="cog",
route="/store/{store_code}/loyalty/program",
@@ -218,7 +219,7 @@ loyalty_module = ModuleDefinition(
requires_permission="loyalty.view_programs",
),
MenuItemDefinition(
id="loyalty-analytics",
id="analytics",
label_key="loyalty.menu.analytics",
icon="chart-bar",
route="/store/{store_code}/loyalty/analytics",
@@ -236,42 +237,42 @@ loyalty_module = ModuleDefinition(
order=60,
items=[
MenuItemDefinition(
id="loyalty-program",
id="program",
label_key="loyalty.menu.program",
icon="gift",
route="/merchants/loyalty/program",
order=10,
),
MenuItemDefinition(
id="loyalty-cards",
id="cards",
label_key="loyalty.menu.customer_cards",
icon="identification",
route="/merchants/loyalty/cards",
order=15,
),
MenuItemDefinition(
id="loyalty-analytics",
id="analytics",
label_key="loyalty.menu.analytics",
icon="chart-bar",
route="/merchants/loyalty/analytics",
order=20,
),
MenuItemDefinition(
id="loyalty-transactions",
id="transactions",
label_key="loyalty.menu.transactions",
icon="clock",
route="/merchants/loyalty/transactions",
order=25,
),
MenuItemDefinition(
id="loyalty-pins",
id="pins",
label_key="loyalty.menu.staff_pins",
icon="key",
route="/merchants/loyalty/pins",
order=30,
),
MenuItemDefinition(
id="loyalty-settings",
id="settings",
label_key="loyalty.menu.settings",
icon="cog",
route="/merchants/loyalty/settings",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@ const loyaltyAnalyticsLog = window.LogConfig.loggers.loyaltyAnalytics || window.
function merchantLoyaltyAnalytics() {
return {
...data(),
currentPage: 'loyalty-analytics',
currentPage: 'analytics',
program: null,
locations: [],

View File

@@ -7,7 +7,7 @@ function merchantLoyaltyCardDetail() {
return loyaltyCardDetailView({
apiPrefix: '/merchants/loyalty',
backUrl: '/merchants/loyalty/cards',
currentPage: 'loyalty-cards',
currentPage: 'cards',
});
}

View File

@@ -8,7 +8,7 @@ function merchantLoyaltyCards() {
apiPrefix: '/merchants/loyalty',
baseUrl: '/merchants/loyalty/cards',
showStoreFilter: true,
currentPage: 'loyalty-cards',
currentPage: 'cards',
});
}

View File

@@ -6,7 +6,7 @@ const merchantSettingsViewLog = window.LogConfig.loggers.merchantSettingsView ||
function merchantLoyaltyMerchantSettings() {
return {
...data(),
currentPage: 'loyalty-settings',
currentPage: 'settings',
settings: null,
loading: false,

View File

@@ -8,7 +8,7 @@ function merchantLoyaltyPins() {
apiPrefix: '/merchants/loyalty',
showStoreFilter: true,
showCrud: true,
currentPage: 'loyalty-pins',
currentPage: 'pins',
});
}

View File

@@ -7,7 +7,7 @@ function merchantLoyaltySettings() {
return {
...data(),
...createProgramFormMixin(),
currentPage: 'loyalty-program',
currentPage: 'program',
loading: false,
error: null,

View File

@@ -7,7 +7,7 @@ function merchantLoyaltyTransactions() {
return loyaltyTransactionsList({
apiPrefix: '/merchants/loyalty',
showStoreFilter: true,
currentPage: 'loyalty-transactions',
currentPage: 'transactions',
});
}

View File

@@ -6,7 +6,7 @@ const loyaltyAnalyticsLog = window.LogConfig.loggers.loyaltyAnalytics || window.
function storeLoyaltyAnalytics() {
return {
...data(),
currentPage: 'loyalty-analytics',
currentPage: 'analytics',
program: null,

View File

@@ -6,7 +6,7 @@ const loyaltyCardDetailLog = window.LogConfig.loggers.loyaltyCardDetail || windo
function storeLoyaltyCardDetail() {
return {
...data(),
currentPage: 'loyalty-card-detail',
currentPage: 'cards',
cardId: null,
card: null,

View File

@@ -6,7 +6,7 @@ const loyaltyCardsLog = window.LogConfig.loggers.loyaltyCards || window.LogConfi
function storeLoyaltyCards() {
return {
...data(),
currentPage: 'loyalty-cards',
currentPage: 'cards',
// Data
cards: [],

View File

@@ -6,7 +6,7 @@ const loyaltyEnrollLog = window.LogConfig.loggers.loyaltyEnroll || window.LogCon
function storeLoyaltyEnroll() {
return {
...data(),
currentPage: 'loyalty-enroll',
currentPage: 'terminal',
program: null,
form: {

View File

@@ -13,7 +13,7 @@ function loyaltySettings() {
...createProgramFormMixin(),
// Page identifier
currentPage: 'loyalty-program',
currentPage: 'program',
// State
loading: false,

View File

@@ -13,7 +13,7 @@ function storeLoyaltyTerminal() {
...data(),
// Page identifier
currentPage: 'loyalty-terminal',
currentPage: 'terminal',
// Program state
program: null,

View File

@@ -61,7 +61,7 @@
function storeLoyaltyProgram() {
return {
...data(),
currentPage: 'loyalty-program',
currentPage: 'program',
program: null,
loading: false,