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

View File

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

View File

@@ -168,7 +168,8 @@
"saving": "Speichern...", "saving": "Speichern...",
"total": "GESAMT", "total": "GESAMT",
"view": "Anzeigen", "view": "Anzeigen",
"yes": "Ja" "yes": "Ja",
"contact_admin_setup": "Kontaktieren Sie Ihren Administrator um das Treueprogramm einzurichten"
}, },
"transactions": { "transactions": {
"card_created": "Angemeldet", "card_created": "Angemeldet",

View File

@@ -168,7 +168,8 @@
"saving": "Saving...", "saving": "Saving...",
"total": "TOTAL", "total": "TOTAL",
"view": "View", "view": "View",
"yes": "Yes" "yes": "Yes",
"contact_admin_setup": "Contact your administrator to set up the loyalty program"
}, },
"transactions": { "transactions": {
"card_created": "Enrolled", "card_created": "Enrolled",

View File

@@ -168,7 +168,8 @@
"saving": "Enregistrement...", "saving": "Enregistrement...",
"total": "TOTAL", "total": "TOTAL",
"view": "Voir", "view": "Voir",
"yes": "Oui" "yes": "Oui",
"contact_admin_setup": "Contactez votre administrateur pour configurer le programme fidélité"
}, },
"transactions": { "transactions": {
"card_created": "Inscrit", "card_created": "Inscrit",

View File

@@ -168,7 +168,8 @@
"saving": "Späicheren...", "saving": "Späicheren...",
"total": "TOTAL", "total": "TOTAL",
"view": "Kucken", "view": "Kucken",
"yes": "Jo" "yes": "Jo",
"contact_admin_setup": "Kontaktéiert Ären Administrator fir d'Treieprogramm anzeriichten"
}, },
"transactions": { "transactions": {
"card_created": "Ageschriwwen", "card_created": "Ageschriwwen",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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