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:
@@ -91,6 +91,10 @@ tenancy_module = ModuleDefinition(
|
||||
FrontendType.STORE: [
|
||||
"team",
|
||||
],
|
||||
FrontendType.MERCHANT: [
|
||||
"stores",
|
||||
"profile",
|
||||
],
|
||||
},
|
||||
# New module-driven menu definitions
|
||||
menus={
|
||||
@@ -160,6 +164,30 @@ tenancy_module = ModuleDefinition(
|
||||
],
|
||||
),
|
||||
],
|
||||
FrontendType.MERCHANT: [
|
||||
MenuSectionDefinition(
|
||||
id="account",
|
||||
label_key="tenancy.menu.account",
|
||||
icon="cog",
|
||||
order=900,
|
||||
items=[
|
||||
MenuItemDefinition(
|
||||
id="stores",
|
||||
label_key="tenancy.menu.stores",
|
||||
icon="shopping-bag",
|
||||
route="/merchants/account/stores",
|
||||
order=10,
|
||||
),
|
||||
MenuItemDefinition(
|
||||
id="profile",
|
||||
label_key="tenancy.menu.profile",
|
||||
icon="user",
|
||||
route="/merchants/account/profile",
|
||||
order=20,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
FrontendType.STORE: [
|
||||
MenuSectionDefinition(
|
||||
id="account",
|
||||
|
||||
Reference in New Issue
Block a user