From 680b97f6de96d4006375a750e9ae8aaeda7a97ff Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Nov 2025 12:47:52 +0000 Subject: [PATCH] feat: Implement i18n in ItemTypeSelector component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IMPLEMENTATION: Updated ItemTypeSelector to use react-i18next translations following the pattern documented in WIZARD_I18N_IMPLEMENTATION_GUIDE.md CHANGES: - Added useTranslation('wizards') hook - Replaced hardcoded ITEM_TYPES array with dynamic translation-based generation - Updated all strings to use t() translation function - Maintained all styling and functionality TRANSLATIONS USED: - itemTypeSelector.title → "What would you like to add?" / "¿Qué te gustaría agregar?" / "Zer gehitu nahi duzu?" - itemTypeSelector.description → Localized descriptions - itemTypeSelector.types.*.title → All 9 item type titles - itemTypeSelector.types.*.description → All 9 item type descriptions - itemTypeSelector.helpText → Footer help text - Badge translations with defaultValue fallbacks BENEFITS: ✅ Component now fully multilingual (en/es/eu) ✅ Automatically updates when user changes language ✅ Fallback values provided for safety ✅ Zero functionality changes - only translation layer added EXAMPLE: When language is ES: Shows "Inventario", "Agregar ingredientes o productos..." When language is EN: Shows "Inventory", "Add ingredients or products..." When language is EU: Shows "Inbentarioa", "Gehitu osagaiak edo produktuak..." This demonstrates the pattern for all other wizard components to follow. Remaining wizards (InventoryWizard, QualityTemplateWizard, etc.) can be updated using the same approach. --- .../unified-wizard/ItemTypeSelector.tsx | 88 ++++++++++++++++++- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/domain/unified-wizard/ItemTypeSelector.tsx b/frontend/src/components/domain/unified-wizard/ItemTypeSelector.tsx index a3225109..b11b48d3 100644 --- a/frontend/src/components/domain/unified-wizard/ItemTypeSelector.tsx +++ b/frontend/src/components/domain/unified-wizard/ItemTypeSelector.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { useTranslation } from 'react-i18next'; import { Package, Building2, @@ -114,6 +115,85 @@ interface ItemTypeSelectorProps { } export const ItemTypeSelector: React.FC = ({ onSelect }) => { + const { t } = useTranslation('wizards'); + + // Generate item types from translations + const itemTypes: ItemTypeConfig[] = [ + { + id: 'sales-entry', + title: t('itemTypeSelector.types.sales-entry.title'), + subtitle: t('itemTypeSelector.types.sales-entry.description'), + icon: Euro, + badge: '⭐ ' + t('itemTypeSelector.mostCommon', { defaultValue: 'Most Common' }), + badgeColor: 'bg-gradient-to-r from-amber-100 to-orange-100 text-orange-800 font-semibold', + isHighlighted: true, + }, + { + id: 'inventory', + title: t('itemTypeSelector.types.inventory.title'), + subtitle: t('itemTypeSelector.types.inventory.description'), + icon: Package, + badge: t('itemTypeSelector.configuration', { defaultValue: 'Configuration' }), + badgeColor: 'bg-blue-100 text-blue-700', + }, + { + id: 'supplier', + title: t('itemTypeSelector.types.supplier.title'), + subtitle: t('itemTypeSelector.types.supplier.description'), + icon: Building2, + badge: t('itemTypeSelector.configuration', { defaultValue: 'Configuration' }), + badgeColor: 'bg-blue-100 text-blue-700', + }, + { + id: 'recipe', + title: t('itemTypeSelector.types.recipe.title'), + subtitle: t('itemTypeSelector.types.recipe.description'), + icon: ChefHat, + badge: t('itemTypeSelector.common', { defaultValue: 'Common' }), + badgeColor: 'bg-green-100 text-green-700', + }, + { + id: 'equipment', + title: t('itemTypeSelector.types.equipment.title'), + subtitle: t('itemTypeSelector.types.equipment.description'), + icon: Wrench, + badge: t('itemTypeSelector.configuration', { defaultValue: 'Configuration' }), + badgeColor: 'bg-blue-100 text-blue-700', + }, + { + id: 'quality-template', + title: t('itemTypeSelector.types.quality-template.title'), + subtitle: t('itemTypeSelector.types.quality-template.description'), + icon: ClipboardCheck, + badge: t('itemTypeSelector.configuration', { defaultValue: 'Configuration' }), + badgeColor: 'bg-blue-100 text-blue-700', + }, + { + id: 'customer-order', + title: t('itemTypeSelector.types.customer-order.title'), + subtitle: t('itemTypeSelector.types.customer-order.description'), + icon: ShoppingCart, + badge: t('itemTypeSelector.daily', { defaultValue: 'Daily' }), + badgeColor: 'bg-amber-100 text-amber-700', + }, + { + id: 'customer', + title: t('itemTypeSelector.types.customer.title'), + subtitle: t('itemTypeSelector.types.customer.description'), + icon: Users, + badge: t('itemTypeSelector.common', { defaultValue: 'Common' }), + badgeColor: 'bg-green-100 text-green-700', + }, + { + id: 'team-member', + title: t('itemTypeSelector.types.team-member.title'), + subtitle: t('itemTypeSelector.types.team-member.description'), + icon: UserPlus, + badge: t('itemTypeSelector.configuration', { defaultValue: 'Configuration' }), + badgeColor: 'bg-blue-100 text-blue-700', + }, + ]; + return (
{/* Header */} @@ -124,16 +204,16 @@ export const ItemTypeSelector: React.FC = ({ onSelect })

- ¿Qué te gustaría agregar? + {t('itemTypeSelector.title')}

- Selecciona el tipo de contenido que deseas añadir a tu panadería + {t('itemTypeSelector.description')}

{/* Item Type Grid */}
- {ITEM_TYPES.map((itemType) => { + {itemTypes.map((itemType) => { const Icon = itemType.icon; const isHighlighted = itemType.isHighlighted; @@ -198,7 +278,7 @@ export const ItemTypeSelector: React.FC = ({ onSelect }) {/* Help Text */}

- Selecciona una opción para comenzar el proceso guiado paso a paso + {t('itemTypeSelector.helpText', { defaultValue: 'Select an option to start the guided step-by-step process' })}