From 5f359283bcfd2beb04cac3c79e7597dd827dba79 Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Fri, 29 May 2026 20:45:46 +0200 Subject: [PATCH] fix(storefront-i18n): dashboard widgets translate + correct customer-module key paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two bugs from Test 5.1 on FR storefront dashboard: 1. Loyalty + Orders dashboard cards (`StorefrontDashboardCard.title`/ `subtitle`/`value_label`) were hardcoded English. Added `language` to `WidgetContext`; customer dashboard route passes `request.state.language` through; loyalty and orders widget providers now call `translate(..., context.language)` with new `widget.*` i18n keys × 4 locales each. 2. Customer-module locale JSON has redundant top-level `customers` wrapper, so after the module-locale loader auto-namespaces under module code `customers`, the actual key path is `customers.customers.customer_number` (matches the existing `loyalty.loyalty.wallet.apple` pattern). My earlier sweep used the single-prefix path for 8 references — fixed all to double-prefix. Both bugs were visible end-of-day yesterday after the api container recreate landed `1bade6e6`. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/modules/contracts/widgets.py | 2 ++ .../customers/routes/pages/storefront.py | 4 ++++ .../customers/storefront/addresses.html | 4 ++-- .../customers/storefront/dashboard.html | 2 +- .../customers/storefront/profile.html | 10 +++++----- app/modules/loyalty/locales/de.json | 8 ++++++++ app/modules/loyalty/locales/en.json | 8 ++++++++ app/modules/loyalty/locales/fr.json | 8 ++++++++ app/modules/loyalty/locales/lb.json | 8 ++++++++ .../loyalty/services/loyalty_widgets.py | 18 ++++++++++++++---- app/modules/orders/locales/de.json | 7 +++++++ app/modules/orders/locales/en.json | 7 +++++++ app/modules/orders/locales/fr.json | 7 +++++++ app/modules/orders/locales/lb.json | 7 +++++++ app/modules/orders/services/order_widgets.py | 8 +++++--- 15 files changed, 93 insertions(+), 15 deletions(-) diff --git a/app/modules/contracts/widgets.py b/app/modules/contracts/widgets.py index 2fc24bc9..a83d53b6 100644 --- a/app/modules/contracts/widgets.py +++ b/app/modules/contracts/widgets.py @@ -72,12 +72,14 @@ class WidgetContext: date_to: End of date range filter limit: Maximum number of items for list widgets include_details: Whether to include extra details (may be expensive) + language: Storefront/dashboard locale (e.g. "fr") for i18n of card strings """ date_from: datetime | None = None date_to: datetime | None = None limit: int = 5 include_details: bool = False + language: str | None = None # ============================================================================= diff --git a/app/modules/customers/routes/pages/storefront.py b/app/modules/customers/routes/pages/storefront.py index a731f969..4c434484 100644 --- a/app/modules/customers/routes/pages/storefront.py +++ b/app/modules/customers/routes/pages/storefront.py @@ -196,6 +196,7 @@ async def shop_account_dashboard_page( ) # Collect dashboard cards from enabled modules via widget protocol + from app.modules.contracts.widgets import WidgetContext from app.modules.core.services.widget_aggregator import widget_aggregator store = getattr(request.state, "store", None) @@ -207,6 +208,9 @@ async def shop_account_dashboard_page( store_id=store.id, customer_id=current_customer.id, platform_id=platform.id, + context=WidgetContext( + language=getattr(request.state, "language", None) + ), ) return templates.TemplateResponse( diff --git a/app/modules/customers/templates/customers/storefront/addresses.html b/app/modules/customers/templates/customers/storefront/addresses.html index 53499b3b..f91c37f2 100644 --- a/app/modules/customers/templates/customers/storefront/addresses.html +++ b/app/modules/customers/templates/customers/storefront/addresses.html @@ -156,12 +156,12 @@
- +
- +
diff --git a/app/modules/customers/templates/customers/storefront/dashboard.html b/app/modules/customers/templates/customers/storefront/dashboard.html index bd8ff102..b52b1d80 100644 --- a/app/modules/customers/templates/customers/storefront/dashboard.html +++ b/app/modules/customers/templates/customers/storefront/dashboard.html @@ -105,7 +105,7 @@

{{ user.created_at.strftime('%B %Y') }}

-

{{ _('customers.customer_number') }}

+

{{ _('customers.customers.customer_number') }}

{{ user.customer_number }}

diff --git a/app/modules/customers/templates/customers/storefront/profile.html b/app/modules/customers/templates/customers/storefront/profile.html index 065cd29d..93b4a3d4 100644 --- a/app/modules/customers/templates/customers/storefront/profile.html +++ b/app/modules/customers/templates/customers/storefront/profile.html @@ -66,7 +66,7 @@
- {{ _('customers.last_name') }} * + {{ _('customers.customers.last_name') }} * {{ _('customers.storefront.pages.profile.account_info') }}
-
{{ _('customers.customer_number') }}
+
{{ _('customers.customers.customer_number') }}
@@ -271,11 +271,11 @@
-
{{ _('customers.total_orders') }}
+
{{ _('customers.customers.total_orders') }}
-
{{ _('customers.total_spent') }}
+
{{ _('customers.customers.total_spent') }}
diff --git a/app/modules/loyalty/locales/de.json b/app/modules/loyalty/locales/de.json index 770d5448..10075be8 100644 --- a/app/modules/loyalty/locales/de.json +++ b/app/modules/loyalty/locales/de.json @@ -1,4 +1,12 @@ { + "widget": { + "rewards": { + "title": "Treueprogramm", + "subtitle_member": "Punkte und Prämien anzeigen", + "subtitle_join": "Unserem Treueprogramm beitreten", + "value_label": "Punktestand" + } + }, "loyalty": { "module": { "name": "Treueprogramme", diff --git a/app/modules/loyalty/locales/en.json b/app/modules/loyalty/locales/en.json index 0bbe8ff6..82c5dabc 100644 --- a/app/modules/loyalty/locales/en.json +++ b/app/modules/loyalty/locales/en.json @@ -1,4 +1,12 @@ { + "widget": { + "rewards": { + "title": "Loyalty Rewards", + "subtitle_member": "View your points & rewards", + "subtitle_join": "Join our rewards program", + "value_label": "Points Balance" + } + }, "loyalty": { "module": { "name": "Loyalty Programs", diff --git a/app/modules/loyalty/locales/fr.json b/app/modules/loyalty/locales/fr.json index 749adeb2..8f9eaa32 100644 --- a/app/modules/loyalty/locales/fr.json +++ b/app/modules/loyalty/locales/fr.json @@ -1,4 +1,12 @@ { + "widget": { + "rewards": { + "title": "Programme de fidélité", + "subtitle_member": "Voir vos points et récompenses", + "subtitle_join": "Rejoindre notre programme de fidélité", + "value_label": "Solde de points" + } + }, "loyalty": { "module": { "name": "Programmes de Fidélité", diff --git a/app/modules/loyalty/locales/lb.json b/app/modules/loyalty/locales/lb.json index ef2ff7ff..7f46fd1d 100644 --- a/app/modules/loyalty/locales/lb.json +++ b/app/modules/loyalty/locales/lb.json @@ -1,4 +1,12 @@ { + "widget": { + "rewards": { + "title": "Treieprogramm", + "subtitle_member": "Är Punkten a Belounungen kucken", + "subtitle_join": "Eisem Treieprogramm bäitrieden", + "value_label": "Punktenzuel" + } + }, "loyalty": { "module": { "name": "Treieprogrammer", diff --git a/app/modules/loyalty/services/loyalty_widgets.py b/app/modules/loyalty/services/loyalty_widgets.py index 00e8f5b6..8c4e7f1d 100644 --- a/app/modules/loyalty/services/loyalty_widgets.py +++ b/app/modules/loyalty/services/loyalty_widgets.py @@ -51,6 +51,7 @@ class LoyaltyWidgetProvider: ) -> list[StorefrontDashboardCard]: """Provide the Loyalty Rewards card for the customer dashboard.""" from app.modules.loyalty.models.loyalty_card import LoyaltyCard + from app.utils.i18n import translate card = ( db.query(LoyaltyCard) @@ -62,17 +63,26 @@ class LoyaltyWidgetProvider: ) points = card.points_balance if card else None - subtitle = "View your points & rewards" if card else "Join our rewards program" + lang = context.language if context else None + subtitle_key = ( + "loyalty.widget.rewards.subtitle_member" + if card + else "loyalty.widget.rewards.subtitle_join" + ) return [ StorefrontDashboardCard( key="loyalty.rewards", icon="gift", - title="Loyalty Rewards", - subtitle=subtitle, + title=translate("loyalty.widget.rewards.title", lang), + subtitle=translate(subtitle_key, lang), route="account/loyalty", value=points, - value_label="Points Balance" if points is not None else None, + value_label=( + translate("loyalty.widget.rewards.value_label", lang) + if points is not None + else None + ), order=30, ), ] diff --git a/app/modules/orders/locales/de.json b/app/modules/orders/locales/de.json index fc9498f5..2e78a72f 100644 --- a/app/modules/orders/locales/de.json +++ b/app/modules/orders/locales/de.json @@ -1,4 +1,11 @@ { + "widget": { + "summary": { + "title": "Bestellungen", + "subtitle": "Bestellverlauf anzeigen", + "value_label": "Bestellungen gesamt" + } + }, "orders": { "title": "Bestellungen", "order": "Bestellung", diff --git a/app/modules/orders/locales/en.json b/app/modules/orders/locales/en.json index f7035bce..ad44201a 100644 --- a/app/modules/orders/locales/en.json +++ b/app/modules/orders/locales/en.json @@ -1,4 +1,11 @@ { + "widget": { + "summary": { + "title": "Orders", + "subtitle": "View order history", + "value_label": "Total Orders" + } + }, "orders": { "title": "Orders", "order": "Order", diff --git a/app/modules/orders/locales/fr.json b/app/modules/orders/locales/fr.json index 5432d125..4938062b 100644 --- a/app/modules/orders/locales/fr.json +++ b/app/modules/orders/locales/fr.json @@ -1,4 +1,11 @@ { + "widget": { + "summary": { + "title": "Commandes", + "subtitle": "Voir l'historique des commandes", + "value_label": "Total des commandes" + } + }, "orders": { "title": "Commandes", "order": "Commande", diff --git a/app/modules/orders/locales/lb.json b/app/modules/orders/locales/lb.json index 2592e042..94b9b9c7 100644 --- a/app/modules/orders/locales/lb.json +++ b/app/modules/orders/locales/lb.json @@ -1,4 +1,11 @@ { + "widget": { + "summary": { + "title": "Bestellungen", + "subtitle": "Bestellhistorik kucken", + "value_label": "Bestellunge gesamt" + } + }, "orders": { "title": "Bestellungen", "order": "Bestellung", diff --git a/app/modules/orders/services/order_widgets.py b/app/modules/orders/services/order_widgets.py index 1ed255a7..b38afe0f 100644 --- a/app/modules/orders/services/order_widgets.py +++ b/app/modules/orders/services/order_widgets.py @@ -51,6 +51,7 @@ class OrderWidgetProvider: ) -> list[StorefrontDashboardCard]: """Provide the Orders card for the customer dashboard.""" from app.modules.orders.models.customer_order_stats import CustomerOrderStats + from app.utils.i18n import translate stats = ( db.query(CustomerOrderStats) @@ -62,16 +63,17 @@ class OrderWidgetProvider: ) total_orders = stats.total_orders if stats else 0 + lang = context.language if context else None return [ StorefrontDashboardCard( key="orders.summary", icon="shopping-bag", - title="Orders", - subtitle="View order history", + title=translate("orders.widget.summary.title", lang), + subtitle=translate("orders.widget.summary.subtitle", lang), route="account/orders", value=total_orders, - value_label="Total Orders", + value_label=translate("orders.widget.summary.value_label", lang), order=10, ), ]