Skip to content

(SP:3) feat(i18n): add UA and PL translations for shop/admin pages#225

Merged
ViktorSvertoka merged 2 commits into
developfrom
feat/translate-shop
Jan 29, 2026
Merged

(SP:3) feat(i18n): add UA and PL translations for shop/admin pages#225
ViktorSvertoka merged 2 commits into
developfrom
feat/translate-shop

Conversation

@TiZorii
Copy link
Copy Markdown
Collaborator

@TiZorii TiZorii commented Jan 28, 2026

Add comprehensive i18n support for shop and admin sections in 3 languages (en, uk,
pl).

Translation coverage:

  • Shop pages: main page, products, cart, checkout, orders
  • Admin pages: dashboard, products management, orders management
  • Navigation: header, mobile menu, category links
  • Product components: cards, filters, sort, badges (NEW/SALE)
  • Category names: Apparel, Lifestyle, Collectibles
  • All UI buttons, labels, and actions

Key changes:

  • Added ~250+ translation keys to messages/en.json, messages/uk.json, messages/pl.json
  • Updated 20+ components to use useTranslations() and getTranslations()
  • Implemented color translation in cart and product detail pages
  • Translated hero message
  • Added badge translations

Summary by CodeRabbit

  • New Features
    • Added comprehensive localization across the shop (product browse, cart, checkout, orders, admin, catalog, toolbar, filters, and UI labels) with English, Polish, and Ukrainian translations.
  • Bug Fixes / Accessibility
    • Enhanced accessible labels and ARIA attributes with localized strings for better screen-reader support.
  • Chores
    • Homepage hero content removed from the public content payload (affects displayed hero).

✏️ Tip: You can customize this high-level summary in your review settings.

Add comprehensive i18n support for shop and admin sections in 3 languages (en, uk,
  pl).

  Translation coverage:
  - Shop pages: main page, products, cart, checkout, orders
  - Admin pages: dashboard, products management, orders management
  - Navigation: header, mobile menu, category links
  - Product components: cards, filters, sort, badges (NEW/SALE)
  - Category names: Apparel, Lifestyle, Collectibles
  - All UI buttons, labels, and actions

  Key changes:
  - Added ~250+ translation keys to messages/en.json, messages/uk.json,
  messages/pl.json
  - Updated 20+ components to use useTranslations() and getTranslations()
  - Implemented color translation in cart and product detail pages
  - Translated hero message
  - Added badge translations
@netlify
Copy link
Copy Markdown

netlify Bot commented Jan 28, 2026

Deploy Preview for develop-devlovers ready!

Name Link
🔨 Latest commit 240be52
🔍 Latest deploy log https://app.netlify.com/projects/develop-devlovers/deploys/697a6a6113cf11000851ef62
😎 Deploy Preview https://deploy-preview-225--develop-devlovers.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jan 28, 2026

📝 Walkthrough

Walkthrough

Adds comprehensive internationalization across the shop frontend: imports next-intl, replaces hard-coded UI strings with translation lookups, adds/updates locale JSONs, and converts several components to async or updated signatures to fetch server-side translations.

Changes

Cohort / File(s) Summary
Shop pages (customer & admin)
frontend/app/[locale]/shop/page.tsx, frontend/app/[locale]/shop/products/page.tsx, frontend/app/[locale]/shop/products/[slug]/page.tsx, frontend/app/[locale]/shop/cart/page.tsx, frontend/app/[locale]/shop/checkout/error/page.tsx, frontend/app/[locale]/shop/checkout/success/page.tsx, frontend/app/[locale]/shop/checkout/payment/[orderId]/page.tsx, frontend/app/[locale]/shop/orders/page.tsx, frontend/app/[locale]/shop/orders/[id]/page.tsx, frontend/app/[locale]/shop/admin/page.tsx, frontend/app/[locale]/shop/admin/orders/page.tsx, frontend/app/[locale]/shop/admin/products/page.tsx, frontend/app/[locale]/shop/admin/orders/[id]/RefundButton.tsx
Added getTranslations/useTranslations and replaced static titles, buttons, headings, aria-labels and status text with t(...) lookups. Note: buildStatusMessage changed to async in payment page and some pages now await translations before render.
Header / navigation / mobile menu
frontend/components/header/AppMobileMenu.tsx, frontend/components/shop/header/nav-links.tsx
Replaced static NAV_LINKS and hard-coded labels with translation-driven shopLinks/navLinks; updated aria labels and active-link logic; removed exported NAV_LINKS.
Shop components (catalog, product, cart UI)
frontend/components/shop/add-to-cart-button.tsx, frontend/components/shop/catalog-load-more.tsx, frontend/components/shop/catalog-products-client.tsx, frontend/components/shop/category-tile.tsx, frontend/components/shop/product-card.tsx, frontend/components/shop/product-filters.tsx, frontend/components/shop/product-sort.tsx, frontend/components/shop/products-toolbar.tsx, frontend/components/shop/products-toolbar.tsx
Introduced useTranslations, replaced UI copy, labels, badges and empty-state text with translations; added helpers (e.g., translateColor, getOptionLabel); category-tile converted to async.
Admin UI components
frontend/components/shop/admin/admin-pagination.tsx, frontend/components/shop/admin/admin-product-delete-button.tsx, frontend/components/shop/admin/admin-product-status-toggle.tsx, frontend/components/shop/admin/shop-admin-topbar.tsx
Converted some components to async to fetch server translations (notably AdminPagination and ShopAdminTopbar), replaced static labels and error messages with t(...) lookups; watch for signature/usage changes.
Shared / small components
frontend/components/shared/OnlineCounterPopup.tsx, frontend/components/shop/catalog-load-more.tsx, frontend/components/shop/catalog-products-client.tsx
Added translations for pluralized copy, error messages and aria-labels; preserved existing control flow.
Data / types
frontend/lib/shop/data.ts
Removed hero property from HomepageContent and stopped returning hero data from getHomepageContent(); hero content moved to translations in pages. Verify callers expecting hero.
Translation bundles
frontend/messages/en.json, frontend/messages/pl.json, frontend/messages/uk.json
Added large mobileMenu, shop and onlineCounter trees (extensive nested keys) for each locale — substantial additive translation payloads.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

UI

Suggested reviewers

  • AM1007
  • ViktorSvertoka

Poem

🐰✨ I hopped through strings both near and far,
Replaced each label, badge, and aria star.
Now carts and pages speak in tongues anew —
A multilingual hop, from me to you! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding Ukrainian and Polish translations for shop/admin pages, which aligns with the extensive i18n work across the entire changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
frontend/app/[locale]/shop/products/[slug]/page.tsx (1)

58-61: Badge in unavailable block is not translated.

The badge in the unavailable product view (line 60) renders {p.badge} directly, while the available product view at line 119 uses the translated version {tProduct(\badges.${product.badge}`)}`. This creates an inconsistent user experience across locales.

Proposed fix
          {p.badge && p.badge !== 'NONE' && (
            <span className="absolute left-4 top-4 z-10 rounded bg-foreground px-2 py-1 text-xs font-semibold uppercase text-background">
-              {p.badge}
+              {tProduct(`badges.${p.badge}`)}
            </span>
          )}
frontend/app/[locale]/shop/admin/page.tsx (1)

27-35: Translate the "Admin sections" aria-label.

This label is still hard-coded in English; consider using the page namespace (e.g., t('sectionsLabel')) and add the key to messages.

💡 Suggested tweak
-        <section className="mt-6" aria-label="Admin sections">
+        <section className="mt-6" aria-label={t('sectionsLabel')}>
frontend/app/[locale]/shop/orders/[id]/page.tsx (1)

321-343: Visible prefixes still hard-coded in English.
The Qty, Unit, and Line prefixes should be localized to avoid mixed-language UI.

💡 Suggested fix
-                    <dd className="text-sm">Qty: {it.quantity}</dd>
+                    <dd className="text-sm">
+                      {t('quantity')}: {it.quantity}
+                    </dd>
...
-                    <dd className="text-sm opacity-80">
-                      Unit:{' '}
-                      {safeFormatMoneyMajor(it.unitPrice, currency, locale)}
-                    </dd>
+                    <dd className="text-sm opacity-80">
+                      {t('unitPrice')}: {safeFormatMoneyMajor(it.unitPrice, currency, locale)}
+                    </dd>
...
-                    <dd className="text-sm font-medium">
-                      Line:{' '}
-                      {safeFormatMoneyMajor(it.lineTotal, currency, locale)}
-                    </dd>
+                    <dd className="text-sm font-medium">
+                      {t('lineTotal')}: {safeFormatMoneyMajor(it.lineTotal, currency, locale)}
+                    </dd>
🤖 Fix all issues with AI agents
In `@frontend/app/`[locale]/shop/checkout/error/page.tsx:
- Around line 101-105: The translation key errors.orderNotFoundDescription used
in the JSX (t('errors.orderNotFoundDescription')) is missing; either add that
key to your locale JSONs with the appropriate copy or change the call to use the
existing key notFoundOrder.message instead—update the JSX reference accordingly
so it matches an existing translation key.
- Around line 57-61: The page references non-existent or mis-namespaced
translation keys; update the component (page.tsx) to use the correct existing
keys and add the missing keys to all locale files (en.json, uk.json, pl.json).
Specifically: replace errors.unableToLoadOrder with errors.unableToLoad and
replace actions.retryPayment with error.retryPayment in the component; add the
four missing description keys errors.missingOrderIdDescription,
errors.orderNotFoundDescription, error.paymentFailedDescription,
error.paymentUnclearDescription to each locale and add the three label keys
error.orderLabel, error.totalLabel, error.statusLabel to each locale (using the
corresponding existing values for missing keys where appropriate). Ensure
namespaces match (errors.* and error.*) and that the component uses the exact
keys added to the locale files.

In `@frontend/app/`[locale]/shop/checkout/success/page.tsx:
- Around line 167-172: Replace the confusing translation key t('error.order')
used in the success page heading with a semantically appropriate key (e.g.,
t('success.orderLabel')): update the call in the checkout success page (the h1
that uses order.id.slice(0, 8)) to use the new key, add the corresponding
key/value to your locale files for all supported locales, and run your i18n
extraction/validation (or update any translation tests) so the new key is
present and the old error.order key is not wrongly reused here.

In `@frontend/app/`[locale]/shop/orders/[id]/page.tsx:
- Around line 285-288: The code renders a raw boolean (order.stockRestored ?
'true' : 'false') which leaks English; update the UI to output a localized
string by mapping the boolean to translation keys via the existing i18n helper t
— e.g. replace the ternary with a call that returns t('yes') when
order.stockRestored is truthy and t('no') when falsy (or add a small helper like
mapBooleanToTranslation used in this component), ensuring you use the same
translation namespace as t('stockRestored').

In `@frontend/app/`[locale]/shop/orders/page.tsx:
- Around line 111-117: The redirect for unauthenticated users in the route using
params and getCurrentUser currently drops locale and uses the wrong query key;
change the redirect call in the page component so it builds a locale-aware path
(include the resolved locale variable) and pass the return URL using the
returnTo query parameter (e.g., returnTo=<encoded path>) instead of next; update
the analogous redirect in the order detail page as well to use the same
locale-aware path and returnTo parameter so post-login navigation returns to the
correct localized page.

In `@frontend/components/header/AppMobileMenu.tsx`:
- Around line 61-72: The shop category links (shopLinks) are never marked active
because pathname ignores the ?category=... query; update the component to read
the current category using Next.js useSearchParams() and adjust the active-check
in the shop variant rendering logic (where variant === 'shop' determines active
state) to return active when pathname matches '/shop/products' AND the search
param 'category' equals the link's category value (extract category from each
shopLinks.href or store it alongside href/label), falling back to active when no
category is set for the base products page; ensure you reference
useSearchParams(), shopLinks, links and the variant-based active state to
implement the comparison.

In `@frontend/messages/uk.json`:
- Around line 454-469: The checkout.errors block is missing two translation keys
used by the error page: add "missingOrderIdDescription" and
"orderNotFoundDescription" under the existing "checkout.errors" object in
frontend/messages/uk.json; populate them with appropriate Ukrainian text that
complements "missingOrderId" and "orderNotFound" (e.g., short sentences
explaining next steps or guidance) so components referencing
checkout.errors.missingOrderIdDescription and
checkout.errors.orderNotFoundDescription can read localized strings.
🧹 Nitpick comments (7)
frontend/components/shop/product-sort.tsx (1)

31-39: Consider deriving translation keys to reduce maintenance burden.

The keyMap duplicates sort values that likely exist in SORT_OPTIONS. If new sort options are added to the config, this mapping must be manually updated—otherwise options silently fall back to 'featured'.

♻️ Suggested refactor: derive keys programmatically
  const getOptionLabel = (value: string) => {
-   const keyMap: Record<string, string> = {
-     'featured': 'featured',
-     'price-asc': 'priceAsc',
-     'price-desc': 'priceDesc',
-     'newest': 'newest',
-   };
-   return tOptions(keyMap[value] || 'featured');
+   // Convert 'price-asc' → 'priceAsc', 'featured' → 'featured', etc.
+   const key = value.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
+   return tOptions(key);
  };

Alternatively, store translation keys directly in SORT_OPTIONS config to keep them co-located with the values.

frontend/components/shop/header/nav-links.tsx (1)

35-44: Consider using a more appropriate translation namespace.

The component uses shop.admin.navigation for shopNav and home translations, but this is the public shop navigation (not admin). While functional, this could cause confusion during maintenance. Consider either:

  1. Moving these keys to a shared/common namespace like shop.navigation
  2. Or renaming the namespace to clarify it's shared
frontend/app/[locale]/shop/checkout/payment/[orderId]/page.tsx (1)

196-223: Consider reusing buildStatusMessage for consistency.

The paid status block at line 201 directly accesses t('payment.statusMessages.alreadyPaid') while buildStatusMessage already handles the 'paid' case. This creates slight duplication. Consider using buildStatusMessage(order.paymentStatus) here for consistency, or extract the status message keys to a shared constant.

frontend/components/shop/category-tile.tsx (1)

11-13: Parallelize translation loading to reduce latency.

These namespaces can be fetched concurrently.

♻️ Proposed refactor
-  const t = await getTranslations('shop.products');
-  const tCategories = await getTranslations('shop.catalog.categories');
-  const tCategoryTile = await getTranslations('shop.categoryTile');
+  const [t, tCategories, tCategoryTile] = await Promise.all([
+    getTranslations('shop.products'),
+    getTranslations('shop.catalog.categories'),
+    getTranslations('shop.categoryTile'),
+  ]);
frontend/components/shop/product-filters.tsx (1)

64-65: Consider simplifying the nested ternary for category keys.
It’s readable now but will get unwieldy as more special slugs appear.

♻️ Optional refactor
+  const categoryKeyMap: Record<string, string> = {
+    'new-arrivals': 'newArrivals',
+    'best-sellers': 'bestSellers',
+  };
...
-                {tCategories(cat.slug === 'new-arrivals' ? 'newArrivals' : cat.slug === 'best-sellers' ? 'bestSellers' : cat.slug)}
+                {tCategories(categoryKeyMap[cat.slug] ?? cat.slug)}
frontend/components/shop/add-to-cart-button.tsx (1)

28-35: Normalize color slugs for better translation coverage.
Lowercasing alone can miss multi-word or symbol colors (e.g., “Light Blue”).

♻️ Optional refactor
-  const translateColor = (color: string): string => {
-    const colorSlug = color.toLowerCase();
+  const translateColor = (color: string): string => {
+    const colorSlug = color
+      .toLowerCase()
+      .trim()
+      .replace(/\s+/g, '-')
+      .replace(/[^a-z0-9-]/g, '');
     try {
       return tColors(colorSlug);
     } catch {
       return color; 
     }
   };
frontend/app/[locale]/shop/products/page.tsx (1)

89-92: Consider localizing the SR-only “Product results” heading.
Keeps screen-reader text consistent across locales.

♻️ Suggested tweak
-          <h2 id="results-heading" className="sr-only">
-            Product results
-          </h2>
+          <h2 id="results-heading" className="sr-only">
+            {t('resultsHeading')}
+          </h2>

Remember to add resultsHeading in the locale message files.

Comment on lines +57 to 61
{t('errors.missingOrderId')}
</h1>
<p className="mt-2 text-sm text-muted-foreground">
We couldn’t identify your order.
{t('errors.missingOrderIdDescription')}
</p>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, search for the translation key across all JSON files
echo "=== Searching for 'missingOrderIdDescription' in JSON files ==="
rg -n "missingOrderIdDescription" --glob "*.json"
echo ""

# Also search for similar keys
echo "=== Searching for 'missingOrderId' (without Description) ==="
rg -n "missingOrderId" --glob "*.json"
echo ""

# List translation files to understand structure
echo "=== Translation files available ==="
fd -e json . | grep -E "(translations|locales|i18n|messages)" | head -20

Repository: DevLoversTeam/devlovers.net

Length of output: 571


🏁 Script executed:

# Examine the errors section in translation files
echo "=== Errors section in en.json ==="
rg -A 20 '"errors":\s*{' frontend/messages/en.json | head -40
echo ""

# Check the page.tsx file to see what keys are being used
echo "=== Translation keys in page.tsx ==="
rg "t\(['\"]" frontend/app/\[locale\]/shop/checkout/error/page.tsx | head -20

Repository: DevLoversTeam/devlovers.net

Length of output: 1249


🏁 Script executed:

# Let's examine the structure more carefully
echo "=== All 'error' and 'errors' related keys in en.json ==="
rg "\"error" frontend/messages/en.json | head -30
echo ""

# Check if there are any "Description" keys pattern
echo "=== All keys with 'Description' in en.json ==="
rg "Description" frontend/messages/en.json

Repository: DevLoversTeam/devlovers.net

Length of output: 916


🏁 Script executed:

# Get the full errors and error sections with better formatting
echo "=== Full shop.checkout errors section from en.json ==="
jq '.shop.checkout.errors' frontend/messages/en.json
echo ""

echo "=== Full shop.checkout error section from en.json ==="
jq '.shop.checkout.error' frontend/messages/en.json

Repository: DevLoversTeam/devlovers.net

Length of output: 979


🏁 Script executed:

# Verify all the translation keys being used in page.tsx against what exists
echo "=== Checking all translation key usages in page.tsx ==="
cat frontend/app/\[locale\]/shop/checkout/error/page.tsx | rg "t\(['\"]" -o | sort | uniq

echo ""
echo "=== Confirming which keys are missing from translations ==="
# The missing keys identified
jq '.shop.checkout | keys' frontend/messages/en.json

Repository: DevLoversTeam/devlovers.net

Length of output: 293


🏁 Script executed:

# Get the exact content to see all translation calls clearly
echo "=== All t() calls in page.tsx ==="
cat frontend/app/\[locale\]/shop/checkout/error/page.tsx | grep -oP "t\('[^']+'" | sort | uniq

echo ""
echo "=== Compare with available keys in shop.checkout sections ==="
echo "Available errors keys:"
jq '.shop.checkout.errors | keys' frontend/messages/en.json
echo ""
echo "Available error keys:"
jq '.shop.checkout.error | keys' frontend/messages/en.json
echo ""
echo "Available actions keys:"
jq '.shop.checkout.actions | keys' frontend/messages/en.json

Repository: DevLoversTeam/devlovers.net

Length of output: 1084


Multiple missing and incorrectly referenced translation keys in error page.

The code references several translation keys that don't exist or use incorrect namespaces:

Missing description keys:

  • errors.missingOrderIdDescription (only missingOrderId exists)
  • errors.orderNotFoundDescription (only orderNotFound exists)
  • error.paymentFailedDescription (only paymentFailed exists)
  • error.paymentUnclearDescription (only paymentUnclear exists)

Missing label keys:

  • error.orderLabel (only order exists)
  • error.totalLabel (only total exists)
  • error.statusLabel (only status exists)

Incorrect key references:

  • Line 63: errors.unableToLoadOrder should be errors.unableToLoad
  • actions.retryPayment should be error.retryPayment (retryPayment is defined under error, not actions)

Add the missing keys to all translation files (en.json, uk.json, pl.json) and fix the namespace/key references in the code.

🤖 Prompt for AI Agents
In `@frontend/app/`[locale]/shop/checkout/error/page.tsx around lines 57 - 61, The
page references non-existent or mis-namespaced translation keys; update the
component (page.tsx) to use the correct existing keys and add the missing keys
to all locale files (en.json, uk.json, pl.json). Specifically: replace
errors.unableToLoadOrder with errors.unableToLoad and replace
actions.retryPayment with error.retryPayment in the component; add the four
missing description keys errors.missingOrderIdDescription,
errors.orderNotFoundDescription, error.paymentFailedDescription,
error.paymentUnclearDescription to each locale and add the three label keys
error.orderLabel, error.totalLabel, error.statusLabel to each locale (using the
corresponding existing values for missing keys where appropriate). Ensure
namespaces match (errors.* and error.*) and that the component uses the exact
keys added to the locale files.

Comment on lines +101 to 105
{t('errors.orderNotFound')}
</h1>
<p className="mt-2 text-sm text-muted-foreground">
We couldn’t find this order.
{t('errors.orderNotFoundDescription')}
</p>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing translation key: errors.orderNotFoundDescription.

Similarly, errors.orderNotFoundDescription (line 104) doesn't exist in the translation files. Only errors.orderNotFound is defined.

Consider using notFoundOrder.message (line 468 in uk.json) or adding the missing key.

🤖 Prompt for AI Agents
In `@frontend/app/`[locale]/shop/checkout/error/page.tsx around lines 101 - 105,
The translation key errors.orderNotFoundDescription used in the JSX
(t('errors.orderNotFoundDescription')) is missing; either add that key to your
locale JSONs with the appropriate copy or change the call to use the existing
key notFoundOrder.message instead—update the JSX reference accordingly so it
matches an existing translation key.

Comment thread frontend/app/[locale]/shop/checkout/success/page.tsx
Comment thread frontend/app/[locale]/shop/orders/[id]/page.tsx
Comment thread frontend/app/[locale]/shop/orders/page.tsx
Comment thread frontend/components/header/AppMobileMenu.tsx
Comment thread frontend/messages/uk.json
  - Replace confusing error.order with success.orderLabel in checkout success page
  heading
  - Localize boolean stockRestored display (yes/no instead of true/false) in order
  details
  - Fix active state detection for shop category links in mobile menu using search
  params
  - Add missing translation keys (orderLabel, yes, no) to all locales (en, uk, pl)
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/app/[locale]/shop/orders/[id]/page.tsx (1)

328-343: Localize visible item labels (“Qty/Unit/Line”).
The visible prefixes remain hard‑coded English even though the SR-only labels are translated.

✅ Suggested fix
-                    <dd className="text-sm">Qty: {it.quantity}</dd>
+                    <dd className="text-sm">{t('quantity')}: {it.quantity}</dd>
...
-                    <dd className="text-sm opacity-80">
-                      Unit:{' '}
-                      {safeFormatMoneyMajor(it.unitPrice, currency, locale)}
-                    </dd>
+                    <dd className="text-sm opacity-80">
+                      {t('unitPrice')}: {safeFormatMoneyMajor(it.unitPrice, currency, locale)}
+                    </dd>
...
-                    <dd className="text-sm font-medium">
-                      Line:{' '}
-                      {safeFormatMoneyMajor(it.lineTotal, currency, locale)}
-                    </dd>
+                    <dd className="text-sm font-medium">
+                      {t('lineTotal')}: {safeFormatMoneyMajor(it.lineTotal, currency, locale)}
+                    </dd>
🧹 Nitpick comments (1)
frontend/app/[locale]/shop/checkout/success/page.tsx (1)

164-183: Localize the payment status value, not just its label.
Right now the status value shows raw enum text (e.g., paid, pending), which will stay English in non‑EN locales. Consider mapping it to localized labels with a fallback.

♻️ Suggested mapping (adjust keys to match your status enum)
   const totalMinor = order.totalAmountMinor;
   const itemsCount = order.items.reduce((sum, item) => sum + item.quantity, 0);
+  const paymentStatusLabel =
+    {
+      paid: t('success.paymentStatus.paid'),
+      pending: t('success.paymentStatus.pending'),
+      processing: t('success.paymentStatus.processing'),
+    }[order.paymentStatus] ?? order.paymentStatus;

 ...
-                <dd className="font-semibold capitalize text-foreground">
-                  {order.paymentStatus}
-                </dd>
+                <dd className="font-semibold capitalize text-foreground">
+                  {paymentStatusLabel}
+                </dd>

Also applies to: 193-210, 224-230

@ViktorSvertoka ViktorSvertoka merged commit b6c666b into develop Jan 29, 2026
8 checks passed
@ViktorSvertoka ViktorSvertoka deleted the feat/translate-shop branch January 29, 2026 15:36
@coderabbitai coderabbitai Bot mentioned this pull request Jan 31, 2026
20 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants