feat: multi-module improvements across merchant, store, i18n, and customer systems
All checks were successful
CI / ruff (push) Successful in 12s
CI / pytest (push) Successful in 50m57s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 29s
CI / docs (push) Successful in 40s
CI / deploy (push) Successful in 51s

- Fix platform-grouped merchant sidebar menu with core items at root level
- Add merchant store management (detail page, create store, team page)
- Fix store settings 500 error by removing dead stripe/API tab
- Move onboarding translations to module-owned locale files
- Fix onboarding banner i18n with server-side rendering + context inheritance
- Refactor login language selectors to use languageSelector() function (LANG-002)
- Move HTTPException handling to global exception handler in merchant routes (API-003)
- Add language selector to all login pages and portal headers
- Fix customer module: drop order stats from customer model, add to orders module
- Fix admin menu config visibility for super admin platform context
- Fix storefront auth and layout issues
- Add missing i18n translations for onboarding steps (en/fr/de/lb)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 23:48:25 +01:00
parent f141cc4e6a
commit a77a8a3a98
113 changed files with 3741 additions and 2923 deletions

View File

@@ -18,6 +18,7 @@ from app.modules.core.utils.page_context import get_admin_context
from app.modules.enums import FrontendType
from app.modules.tenancy.models import User
from app.templates_config import templates
from app.utils.i18n import get_jinja2_globals
router = APIRouter()
@@ -57,10 +58,13 @@ async def admin_login_page(
if current_user:
return RedirectResponse(url="/admin/dashboard", status_code=302)
return templates.TemplateResponse("tenancy/admin/login.html", {
language = getattr(request.state, "language", "en")
context = {
"request": request,
"current_language": getattr(request.state, "language", "en"),
})
"current_language": language,
**get_jinja2_globals(language),
}
return templates.TemplateResponse("tenancy/admin/login.html", context)
@router.get("/select-platform", response_class=HTMLResponse, include_in_schema=False)
@@ -69,18 +73,15 @@ async def admin_select_platform_page(
current_user: User | None = Depends(get_current_admin_optional),
):
"""
Render platform selection page for platform admins.
Render platform selection page for admins.
Platform admins with access to multiple platforms must select
which platform they want to manage before accessing the dashboard.
Super admins are redirected to dashboard (they have global access).
Super admins can optionally select a platform to scope their view.
"""
if not current_user:
return RedirectResponse(url="/admin/login", status_code=302)
if current_user.is_super_admin:
return RedirectResponse(url="/admin/dashboard", status_code=302)
return templates.TemplateResponse(
"tenancy/admin/select-platform.html",
{"request": request, "user": current_user},
@@ -124,26 +125,6 @@ async def admin_settings_page(
)
@router.get("/my-menu", response_class=HTMLResponse, include_in_schema=False)
async def admin_my_menu_config(
request: Request,
current_user: User = Depends(require_menu_access("my-menu", FrontendType.ADMIN)),
db: Session = Depends(get_db),
):
"""
Render personal menu configuration page for super admins.
Allows super admins to customize their own sidebar menu.
"""
# Only super admins can configure their own menu
if not current_user.is_super_admin:
return RedirectResponse(url="/admin/settings", status_code=302)
return templates.TemplateResponse(
"core/admin/my-menu-config.html",
get_admin_context(request, db, current_user),
)
@router.get("/features", response_class=HTMLResponse, include_in_schema=False)
async def admin_features_page(
request: Request,

View File

@@ -24,6 +24,7 @@ from app.modules.core.utils.page_context import get_context_for_frontend
from app.modules.enums import FrontendType
from app.modules.tenancy.schemas.auth import UserContext
from app.templates_config import templates
from app.utils.i18n import get_jinja2_globals
ROUTE_CONFIG = {
"prefix": "",
@@ -67,10 +68,13 @@ async def merchant_login_page(
if current_user:
return RedirectResponse(url="/merchants/dashboard", status_code=302)
return templates.TemplateResponse("tenancy/merchant/login.html", {
language = getattr(request.state, "language", "fr")
context = {
"request": request,
"current_language": getattr(request.state, "language", "fr"),
})
"current_language": language,
**get_jinja2_globals(language),
}
return templates.TemplateResponse("tenancy/merchant/login.html", context)
# ============================================================================