feat: dynamic merchant sidebar with module-driven menus
Replace the hardcoded merchant sidebar with a dynamic menu system driven by module definitions, matching the existing admin frontend pattern. Modules declare FrontendType.MERCHANT menus in their definition.py, and a new API endpoint unions enabled modules across all platforms the merchant is subscribed to — so loyalty only appears when enabled. - Add MERCHANT menu definitions to core, billing, tenancy, loyalty modules - Extend MenuDiscoveryService with enabled_module_codes parameter - Create GET /merchants/core/menu/render/merchant endpoint - Update merchant Alpine.js with loadMenuConfig() and dynamic section state - Replace hardcoded sidebar.html with x-for rendering + loading skeleton + fallback - Add 36 unit and integration tests for menu discovery, service, and endpoint Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -165,6 +165,10 @@ billing_module = ModuleDefinition(
|
||||
"billing", # Store billing dashboard
|
||||
"invoices", # Store invoice history
|
||||
],
|
||||
FrontendType.MERCHANT: [
|
||||
"subscriptions", # Merchant subscriptions
|
||||
"invoices", # Merchant billing history
|
||||
],
|
||||
},
|
||||
# New module-driven menu definitions
|
||||
menus={
|
||||
@@ -199,6 +203,31 @@ billing_module = ModuleDefinition(
|
||||
],
|
||||
),
|
||||
],
|
||||
FrontendType.MERCHANT: [
|
||||
MenuSectionDefinition(
|
||||
id="billing",
|
||||
label_key="billing.menu.billing_subscriptions",
|
||||
icon="credit-card",
|
||||
order=50,
|
||||
items=[
|
||||
MenuItemDefinition(
|
||||
id="subscriptions",
|
||||
label_key="billing.menu.subscriptions",
|
||||
icon="clipboard-list",
|
||||
route="/merchants/billing/subscriptions",
|
||||
order=10,
|
||||
is_mandatory=True,
|
||||
),
|
||||
MenuItemDefinition(
|
||||
id="invoices",
|
||||
label_key="billing.menu.billing_history",
|
||||
icon="currency-euro",
|
||||
route="/merchants/billing/invoices",
|
||||
order=20,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
FrontendType.STORE: [
|
||||
MenuSectionDefinition(
|
||||
id="sales",
|
||||
|
||||
Reference in New Issue
Block a user