feat(i18n): add bilingual support (Català / Castellano)
Run Tests on Branches / Detect Changes (push) Successful in 11s
Run Tests on Branches / Backend Tests (push) Has been skipped
Run Tests on Branches / Frontend Tests (push) Successful in 1m44s
Run Tests on Branches / Frontend Mobile Tests (push) Has been skipped
Run Tests on Branches / Parapharmacy API Tests (push) Has been skipped

Add lightweight i18n system using React Context + useTranslation hook.
No external dependencies. Language persisted in localStorage('ff-lang').

New files:
- src/i18n/locales/ca.js (~410 translation keys)
- src/i18n/locales/es.js (~410 translation keys)
- src/i18n/LanguageContext.jsx (Provider + t() function)
- src/i18n/useTranslation.js (hook)
- src/i18n/index.js (barrel export)

Modified 22 files:
- main.jsx: wrap App with LanguageProvider
- App.test.jsx: add LanguageProvider wrapper for tests
- 13 user components: BottomNav, HomeView, LoginModal, SearchView,
  ProfileView, AlertsView, ScannerView, PharmacyList, MedicineResults,
  ProductResults, SavedNotifications, ErrorBoundary, SearchBar
- 6 admin components: AdminView, LoginForm, PharmacyManagement,
  MedicineManagement, PharmacyMedicineLink, PharmacyProductLink

ProfileView includes language selector (globe icon + modal CA/ES)
placed next to the Theme selector.

No routes changed. No API calls affected. No navigation changes.
This commit is contained in:
Antoni Nuñez Romeu
2026-07-17 09:43:45 +02:00
parent 41d3e5cd9a
commit 38374341ed
26 changed files with 1371 additions and 384 deletions
+414
View File
@@ -0,0 +1,414 @@
const ca = {
// BottomNav
'nav.home': 'Inici',
'nav.search': 'Cercar',
'nav.scan': 'Escanejar',
'nav.alerts': 'Alertes',
'nav.profile': 'Usuari',
// HomeView
'home.description': 'Trobeu els vostres medicaments a farmàcies properes',
'home.searchMedicine': 'Cercar Medicament',
'home.scanTSI': 'Escanejar TSI',
// SearchBar
'search.placeholder': 'Escriviu el nom del medicament',
'search.clear': 'Netejar cerca',
// SearchView
'search.suggestions': 'Suggeriments',
'search.recentResults': 'Resultats Recents',
'search.findNearby': 'Cerca a prop teu',
'search.resultsFound': 'resultats trobats',
'search.parapharmacy': 'Parafarmàcia',
'search.activeIngredient': 'Principi Actiu',
'search.dosage': 'Dosificació',
'search.form': 'Forma',
'search.backToSearch': '← Tornar a la cerca',
'search.sortByDistance': '📍 Ordenar per distància',
'search.sortBySavedLocation': '📍 Ordenar per ubicació desada',
'search.sortedByDistance': '📍 Ordenat per distància · Restablir',
'search.locating': '📍 Localitzant…',
'search.usingSavedAddress': 'Usant la vostra adreça desada',
'search.usingRecentLocation': 'Usant ubicació recent',
'search.retry': 'Tornar a provar',
'search.locationDenied': 'Permís d\'ubicació denegat. Permeteu l\'accés a la ubicació al vostre navegador.',
'search.locationUnavailable': 'Ubicació no disponible. Verifiqueu que el GPS estigui activat.',
'search.locationTimeout': 'L\'ubicació ha trigat massa. Torneu-ho a provar o verifiqueu la vostra connexió.',
'search.locationError': 'No s\'ha pogut obtenir la vostra ubicació',
'search.searching': 'Cercant...',
// MedicineResults
'medicine.noResults': 'No s\'han trobat medicaments per a',
'medicine.principioActivo': 'Principi Actiu:',
'medicine.dosis': 'Dosificació:',
'medicine.forma': 'Forma:',
'medicine.viewPharmacies': 'Veure farmàcies →',
'medicine.loginForNotifications': 'Inicieu sessió per activar notificacions',
'medicine.disableNotifications': 'Desactivar notificacions per a aquest medicament',
'medicine.enableNotifications': 'Notificar-me quan estigui disponible',
'medicine.notificationsActivated': 'Notificacions activades — clic per desactivar',
'medicine.notifyWhenAvailable': 'Notificar-me quan aquest medicament estigui a una farmàcia',
'medicine.subscriptionError': 'No s\'ha pogut actualitzar la subscripció',
// PharmacyList
'pharmacy.loading': 'Carregant farmàcies...',
'pharmacy.notFound': 'No s\'han trobat farmàcies amb aquest medicament',
'pharmacy.availableAt': 'Disponible a',
'pharmacy.pharmacy': 'farmàcia',
'pharmacy.pharmacies': 'farmàcies',
'pharmacy.howToGet': 'Com arribar',
'pharmacy.inStock': '✓ En Estoc',
'pharmacy.lowStock': '⚠ Estoc Baix',
'pharmacy.outOfStock': '✗ Sense Estoc',
'pharmacy.loginForNotifications': 'Inicieu sessió per activar notificacions',
'pharmacy.disableNotificationsPharmacy': 'Desactivar notificacions per a aquesta farmàcia',
'pharmacy.notifyWhenArrives': 'Notificar-me quan arribi a aquesta farmàcia',
'pharmacy.notificationsActivatedPharmacy': 'Notificacions activades per a aquesta farmàcia — clic per desactivar',
'pharmacy.notificationsRequired': 'Les notificacions requereixen iOS 16.4+ i aquest lloc instal·lat com a app (Compartir → Afegir a Pantalla d\'Inici).',
// ProductResults
'product.sinReceta': 'Sense Recepta',
'product.parapharmacy': 'Parafarmàcia',
'product.dermocosmetica': 'Dermocosmètica',
'product.formulasLacteas': 'Fórmules Làctees',
'product.vitamins': 'Vitamines',
'product.analgesics': 'Analgèsics',
'product.noResults': 'No s\'han trobat productes',
'product.brand': 'Marca:',
'product.price': 'Preu:',
'product.activeIngredient': 'Principi Actiu:',
'product.dosage': 'Dosificació:',
'product.viewDetails': 'Veure detalls →',
// LoginModal
'login.login': 'Iniciar sessió',
'login.register': 'Crear compte',
'login.welcomeBack': 'Benvingut de nou',
'login.createAccount': 'Crea el teu compte',
'login.registerDescription': 'Desa la teva adreça i rep notificacions quan arribin medicaments.',
'login.loginDescription': 'Inicia sessió per gestionar el teu perfil i notificacions.',
'login.username': 'Usuari',
'login.usernameHint': '3–32 caràcters: lletres, dígits o guió baix.',
'login.password': 'Contrasenya',
'login.passwordHint': 'Almenys 8 caràcters.',
'login.cancel': 'Cancel·lar',
'login.creating': 'Creant…',
'login.loggingIn': 'Iniciant sessió…',
'login.createAccountBtn': 'Crear compte',
'login.loginBtn': 'Iniciar sessió',
'login.passwordError': 'La contrasenya ha de tenir almenys 8 caràcters',
'login.registerError': 'No s\'ha pogut crear el compte',
'login.loginError': 'Error d\'inici de sessió',
'login.networkError': 'Error de xarxa — torneu-ho a provar',
// AlertsView
'alerts.title': 'Les Meves Alertes',
'alerts.subtitle': 'Mantingueu-vos al dia amb els vostres medicaments.',
'alerts.loading': 'Carregant alertes...',
'alerts.loginRequired': 'Si us plau, inicieu sessió per veure les vostres alertes.',
'alerts.loadError': 'No s\'han pogut carregar les alertes.',
'alerts.availability': 'Disponibilitat',
'alerts.noSubscriptions': 'No teniu subscripcions de disponibilitat.',
'alerts.notifyWhenAvailable': 'Notificar-me quan estigui disponible',
'alerts.deleteError': 'No s\'ha pogut eliminar l\'alerta de disponibilitat.',
'alerts.pharmacy': 'Farmàcia',
// ScannerView
'scanner.title': 'Escanejar TSI',
'scanner.description': 'Escanegeu el codi de barres de la vostra targeta sanitària per veure les vostres receptes actives',
'scanner.openCamera': 'Obrir càmera',
'scanner.orUploadPhoto': 'O pugeu una foto de la vostra TSI',
'scanner.takePhoto': 'Fer foto',
'scanner.uploadFromGallery': 'Pujar de galeria',
'scanner.scanImage': 'Escanejar imatge',
'scanner.discard': 'Descartar',
'scanner.enterCIP': 'O introduïu el codi CIP manualment',
'scanner.cipPlaceholder': 'Codi CIP de 16 dígits',
'scanner.search': 'Cercar',
'scanner.scanning': 'Apunteu al codi de barres',
'scanner.openingCamera': 'Obrint càmera…',
'scanner.processingImage': 'Processant imatge…',
'scanner.tsiScanned': 'TSI Escanejada',
'scanner.activePrescriptions': 'Receptes Actives',
'scanner.tapToFind': 'Toqueu un medicament per veure disponibilitat a farmàcies properes.',
'scanner.loadingPrescriptions': 'Carregant receptes…',
'scanner.noPrescriptions': 'No s\'han trobat receptes actives per a aquesta targeta.',
'scanner.scanAnother': 'Escanejar una altra targeta',
'scanner.tryAgain': 'Tornar a provar',
'scanner.scannerUnavailable': 'L\'escàner no està disponible en aquest dispositiu.',
'scanner.cameraPermissionDenied': 'Permís de càmera denegat. Activeu-lo a la configuració o introduïu el codi CIP manualment.',
'scanner.invalidBarcode': 'Codi de barres invàlid. Torneu-ho a provar o introduïu el CIP manualment.',
'scanner.cameraNotAvailable': 'Càmera no disponible en aquest navegador.',
'scanner.invalidCIP': 'Format CIP invàlid. Ha de tenir 16 caràcters alfanumèrics.',
'scanner.enterCIPError': 'Introduïu un codi CIP.',
'scanner.cameraPermissionWeb': 'Permís de càmera denegat. Permeteu l\'accés i torneu-ho a provar.',
'scanner.noCamera': 'No s\'ha detectat cap càmera. Introduïu el codi CIP manualment.',
'scanner.imageReadError': 'No s\'ha pogut llegir la imatge. Proveu amb una altra foto.',
'scanner.invalidCIPDetected': 'CIP detectat no té format vàlid. Introduïu el codi manualment.',
'scanner.scanError': 'Error en escanejar:',
'scanner.unknownError': 'Error desconegut',
'scanner.cameraError': 'Error de càmera:',
'scanner.imageProcessError': 'Error en processar la imatge:',
// ProfileView
'profile.name': 'Nom',
'profile.lastName': 'Cognoms',
'profile.config': 'Configuració',
'profile.myAddresses': 'Les Meves Adreces',
'profile.theme': 'Tema',
'profile.themeAuto': 'Automàtic',
'profile.themeLight': 'Clar',
'profile.themeDark': 'Fosc',
'profile.admin': 'Panell d\'Administració',
'profile.logout': 'Tancar Sessió',
'profile.uploadingPhoto': 'Pujant foto...',
'profile.recentSearches': 'Les vostres cerques recents:',
'profile.delete': 'Eliminar',
'profile.changeAvatar': 'Canviar Avatar',
'profile.presetAvatar': 'Predissenyat',
'profile.colors': 'Colors',
'profile.upload': 'Pujar',
'profile.chooseFromGallery': 'Trieu de galeria',
'profile.selectExistingImage': 'Seleccioneu una imatge existent',
'profile.imageTooBig': 'La imatge no pot superar els 5 MB',
'profile.imageSaveError': 'Error en desar la imatge. Proveu amb una altra foto.',
'profile.imageConnectionError': 'Error de connexió en desar la imatge.',
'profile.imageProcessError': 'Error en processar la imatge.',
'profile.configTitle': 'Configuració',
'profile.firstName': 'Nom',
'profile.firstNamePlaceholder': 'El vostre nom',
'profile.lastNamePlaceholder': 'Els vostres cognoms',
'profile.email': 'Correu electrònic',
'profile.emailPlaceholder': 'el_vostre@email.com',
'profile.city': 'Ciutat',
'profile.cityPlaceholder': 'La vostra ciutat',
'profile.address': 'Adreça',
'profile.addressPlaceholder': 'Carrer Major 1, Barcelona',
'profile.cancel': 'Cancel·lar',
'profile.saving': 'Desant...',
'profile.save': 'Desar',
'profile.profileSaved': 'Perfil desat.',
'profile.saveError': 'Error en desar',
'profile.addressesTitle': 'Les Meves Adreces',
'profile.addressLabel': 'Adreça',
'profile.addressOptional': 'Etiqueta (opcional)',
'profile.addressLabelPlaceholder': 'Ex: Casa, Treball, Segona residència',
'profile.defaultAddress': 'Adreça predeterminada',
'profile.add': 'Afegir',
'profile.update': 'Actualitzar',
'profile.loadingAddresses': 'Carregant adreces...',
'profile.mainAddress': 'Adreça principal',
'profile.default': 'Predeterminada',
'profile.setDefault': 'Establir com a predeterminada',
'profile.addMore': 'Afegir més',
'profile.addressRequired': 'L\'adreça és obligatòria',
'profile.addressSaveError': 'Error en desar l\'adreça',
'profile.themeTitle': 'Tema de visualització',
'profile.themeDescription': 'Trieu com es veu l\'aplicació. En mode automàtic, s\'adapta al tema del vostre dispositiu.',
'profile.themeAutoDesc': 'Seguir sistema',
'profile.themeLightDesc': 'Sempre clar',
'profile.themeDarkDesc': 'Sempre fosc',
'profile.language': 'Idioma',
'profile.languageTitle': 'Idioma de l\'aplicació',
'profile.languageCatalan': 'Català',
'profile.languageSpanish': 'Castellà',
// SavedNotifications
'savedNotifications.title': '🔔 Notificacions Desades',
'savedNotifications.close': 'Tancar',
'savedNotifications.loading': 'Carregant…',
'savedNotifications.empty': 'Encara no hi ha notificacions desades. Toqueu la campana 🔕 a una farmàcia sense estoc per rebre notificacions quan es reposi.',
'savedNotifications.anyPharmacy': 'Qualsevol farmàcia',
'savedNotifications.delete': 'Eliminar notificació',
'savedNotifications.loadError': 'No s\'han pogut carregar les notificacions desades',
'savedNotifications.deleteError': 'No s\'ha pogut eliminar la notificació',
// ErrorBoundary
'error.title': 'Alguna cosa ha fallat',
'error.description': 'Ha ocorregut un error inesperat. Si us plau, recarregueu la pàgina.',
'error.reload': 'Recarregar',
// AdminView
'admin.title': '⚙️ Panell d\'Administració',
'admin.authRequired': 'Autenticació requerida',
'admin.managePharmacies': 'Gestioneu farmàcies i medicaments',
'admin.logout': 'Tancar sessió',
'admin.checkingAuth': 'Comprovant autenticació...',
'admin.pharmacies': '🏥 Farmàcies',
'admin.medicines': '💊 Medicaments',
'admin.linkMedicine': '🔗 Vincular Medicament a Farmàcia',
'admin.linkProduct': '🍎 Vincular Producte a Farmàcia',
// LoginForm
'admin.login.title': '🔐 Accés Administració',
'admin.login.description': 'Introduïu les vostres credencials per accedir al panell d\'administració',
'admin.login.username': 'Usuari',
'admin.login.usernamePlaceholder': 'Introduïu usuari',
'admin.login.password': 'Contrasenya',
'admin.login.passwordPlaceholder': 'Introduïu contrasenya',
'admin.login.loggingIn': 'Iniciant sessió...',
'admin.login.loginBtn': 'Iniciar sessió',
'admin.login.defaultCredentials': 'Credencials per defecte:',
'admin.login.changePasswordWarning': '⚠️ Canvieu la contrasenya per defecte després del primer inici de sessió!',
'admin.login.failed': 'Error d\'inici de sessió',
'admin.login.invalidCredentials': 'Usuari o contrasenya invàlids',
// PharmacyManagement
'admin.pharmacy.title': 'Gestionar Farmàcies',
'admin.pharmacy.addNew': '+ Afegir Nova Farmàcia',
'admin.pharmacy.edit': 'Editar Farmàcia',
'admin.pharmacy.add': 'Afegir Nova Farmàcia',
'admin.pharmacy.name': 'Nom *',
'admin.pharmacy.address': 'Adreça *',
'admin.pharmacy.phone': 'Telèfon',
'admin.pharmacy.latitude': 'Latitud',
'admin.pharmacy.longitude': 'Longitud',
'admin.pharmacy.openingHours': 'Horari d\'obertura',
'admin.pharmacy.closed': 'Tancat',
'admin.pharmacy.opensAt': 'obre a les',
'admin.pharmacy.closesAt': 'tanca a les',
'admin.pharmacy.saving': 'Desant...',
'admin.pharmacy.update': 'Actualitzar',
'admin.pharmacy.create': 'Afegir',
'admin.pharmacy.cancel': 'Cancel·lar',
'admin.pharmacy.loading': 'Carregant farmàcies...',
'admin.pharmacy.showing': 'Mostrant',
'admin.pharmacy.of': 'de',
'admin.pharmacy.withinRadio': '(dins del radi)',
'admin.pharmacy.empty': 'Encara no hi ha farmàcies. Importeu des de webhook o afegiu-ne una manualment.',
'admin.pharmacy.noResults': 'No hi ha farmàcies en aquest radi amb coordenades. Amplieu el radi, cerqueu una altra ciutat o desactiveu el filtre de regió.',
'admin.pharmacy.editBtn': 'Editar',
'admin.pharmacy.deleteBtn': 'Eliminar',
'admin.pharmacy.deleteConfirm': 'Esteu segur que voleu eliminar aquesta farmàcia?',
'admin.pharmacy.updated': 'Farmàcia actualitzada!',
'admin.pharmacy.created': 'Farmàcia afegida!',
'admin.pharmacy.deleted': 'Farmàcia eliminada!',
'admin.pharmacy.loadError': 'Error en carregar farmàcies',
'admin.pharmacy.updateError': 'Error en actualitzar farmàcia',
'admin.pharmacy.createError': 'Error en crear farmàcia',
'admin.pharmacy.deleteError': 'Error en eliminar farmàcia',
'admin.pharmacy.citySearch': 'Ciutat, regió i importació',
'admin.pharmacy.searchCity': 'Cercar ciutat',
'admin.pharmacy.chooseOne': 'Trieu-ne una',
'admin.pharmacy.openDataUrl': 'URL de dades obertes',
'admin.pharmacy.cityPlaceholder': 'Ex: Rubí, Madrid, València…',
'admin.pharmacy.searching': 'Cercant…',
'admin.pharmacy.areaPreset': 'Preset d\'àrea',
'admin.pharmacy.customCoordinates': 'Coordenades personalitzades',
'admin.pharmacy.areaExample': 'Exemple: Àrea de Rubí (1,5 km)',
'admin.pharmacy.enterCity': 'Introduïu una ciutat o lloc.',
'admin.pharmacy.setCoordinates': 'Establiu latitud, longitud i radi (useu Cercar ciutat o un preset).',
'admin.pharmacy.dataSource': 'Font de dades',
'admin.pharmacy.webhookLegacy': 'n8n webhook (heretat)',
'admin.pharmacy.openDataJson': 'URL de dades obertes JSON',
'admin.pharmacy.jsonUrl': 'URL JSON',
'admin.pharmacy.importing': 'Important…',
'admin.pharmacy.importWebhook': 'Importar des de webhook',
'admin.pharmacy.importUrl': 'Importar des d\'URL',
'admin.pharmacy.importFrom': 'Importar des de',
'admin.pharmacy.showWithinRadio': 'Mostrar només farmàcies dins del radi',
'admin.pharmacy.sessionExpired': 'Sessió expirada o no heu iniciat sessió. Inicieu sessió de nou al panell Admin i torneu-ho a provar.',
'admin.pharmacy.apiNotFound': 'L\'app no ha pogut connectar amb l\'API (404). Useu http://localhost:3000 amb frontend i backend actius.',
'admin.pharmacy.geocodificationNotFound': 'Servei de geocodificació no trobat. Actualitzeu el backend i reinicieu-lo.',
'admin.pharmacy.searchFailed': 'Cerca fallida (HTTP',
'admin.pharmacy.dayClosed': 'Marqueu un dia com a Tancat si la farmàcia no obre aquest dia.',
'admin.pharmacy.saveError': 'Error en desar farmàcia',
'admin.pharmacy.radius': 'Radi (m)',
// MedicineManagement
'admin.medicine.title': 'Cercar Medicaments (API CIMA)',
'admin.medicine.description': 'Els medicaments s\'obtenen directament de la',
'admin.medicine.cimaApi': 'API de CIMA',
'admin.medicine.cimaDescription': '(Agència Espanyola de Medicaments i Productes Sanitaris).',
'admin.medicine.linkDescription': 'Cerqueu medicaments per vincular-los a farmàcies a la pestanya "Link Medicine".',
'admin.medicine.search': 'Cercar medicaments',
'admin.medicine.searchPlaceholder': 'Escriviu el nom d\'un medicament...',
'admin.medicine.searching': 'Cercant a API CIMA...',
'admin.medicine.found': 'S\'han trobat',
'admin.medicine.medications': 'medicaments',
'admin.medicine.activeIngredient': 'Principi Actiu:',
'admin.medicine.dosage': 'Dosificació:',
'admin.medicine.form': 'Forma:',
'admin.medicine.laboratory': 'Laboratori:',
'admin.medicine.registrationNumber': 'Nº Registre:',
'admin.medicine.generic': 'Genèric',
'admin.medicine.brand': 'Marca',
'admin.medicine.noResults': 'No s\'han trobat medicaments amb aquest nom.',
'admin.medicine.loadError': 'Error en cercar medicaments a l\'API CIMA',
// PharmacyMedicineLink
'admin.linkMedicine.title': 'Vincular Medicament a Farmàcia',
'admin.linkMedicine.pharmacy': 'Farmàcia *',
'admin.linkMedicine.searchPharmacy': 'Cercar entre',
'admin.linkMedicine.pharmacies': 'farmàcies per nom o adreça…',
'admin.linkMedicine.loadingPharmacies': 'Carregant farmàcies…',
'admin.linkMedicine.noPharmacies': 'No hi ha farmàcies que coincideixin amb',
'admin.linkMedicine.changePharmacy': 'Canviar farmàcia',
'admin.linkMedicine.medicine': 'Cercar Medicament (API CIMA) *',
'admin.linkMedicine.searchMedicine': 'Escriviu per cercar medicaments a CIMA...',
'admin.linkMedicine.searching': 'Cercant...',
'admin.linkMedicine.activeIngredient': 'Principi actiu:',
'admin.linkMedicine.dosage': 'Dosificació:',
'admin.linkMedicine.registrationNumber': 'Nº Registre:',
'admin.linkMedicine.changeMedicine': 'Canviar medicament',
'admin.linkMedicine.price': 'Preu (€)',
'admin.linkMedicine.stock': 'Estoc',
'admin.linkMedicine.linkBtn': 'Vincular Medicament',
'admin.linkMedicine.reset': 'Restablir',
'admin.linkMedicine.medicationsIn': 'Medicaments a',
'admin.linkMedicine.loading': 'Carregant...',
'admin.linkMedicine.empty': 'Encara no hi ha medicaments vinculats a aquesta farmàcia.',
'admin.linkMedicine.priceLabel': 'Preu:',
'admin.linkMedicine.undefined': 'No definit',
'admin.linkMedicine.newPrice': 'Introduïu nou preu:',
'admin.linkMedicine.newStock': 'Introduïu nou estoc:',
'admin.linkMedicine.update': 'Actualitzar',
'admin.linkMedicine.delete': 'Eliminar',
'admin.linkMedicine.selectMedicineFirst': 'Si us plau, seleccioneu un medicament primer',
'admin.linkMedicine.linkSuccess': 'Medicament vinculat a la farmàcia correctament!',
'admin.linkMedicine.linkError': 'Error en vincular medicament a farmàcia',
'admin.linkMedicine.updateSuccess': 'Actualitzat correctament!',
'admin.linkMedicine.updateError': 'Error en actualitzar',
'admin.linkMedicine.deleteConfirm': 'Eliminar aquest medicament de la farmàcia?',
'admin.linkMedicine.deleteSuccess': 'Medicament eliminat de la farmàcia!',
'admin.linkMedicine.deleteError': 'Error en eliminar medicament',
// PharmacyProductLink
'admin.linkProduct.title': 'Vincular Producte a Farmàcia',
'admin.linkProduct.pharmacy': 'Farmàcia *',
'admin.linkProduct.searchPharmacy': 'Cercar entre',
'admin.linkProduct.pharmacies': 'farmàcies per nom o adreça…',
'admin.linkProduct.loadingPharmacies': 'Carregant farmàcies…',
'admin.linkProduct.noPharmacies': 'No hi ha farmàcies que coincideixin amb',
'admin.linkProduct.changePharmacy': 'Canviar farmàcia',
'admin.linkProduct.product': 'Cercar Producte (CIMA / Parafarmàcia) *',
'admin.linkProduct.searchProduct': 'Escriviu per cercar medicaments o productes de parafarmàcia...',
'admin.linkProduct.searching': 'Cercant...',
'admin.linkProduct.brand': 'Marca:',
'admin.linkProduct.price': 'Preu:',
'admin.linkProduct.changeProduct': 'Canviar producte',
'admin.linkProduct.priceInput': 'Preu (€)',
'admin.linkProduct.stock': 'Estoc',
'admin.linkProduct.linkBtn': 'Vincular Producte',
'admin.linkProduct.reset': 'Restablir',
'admin.linkProduct.productsIn': 'Productes a',
'admin.linkProduct.loading': 'Carregant...',
'admin.linkProduct.empty': 'Encara no hi ha productes vinculats a aquesta farmàcia.',
'admin.linkProduct.priceLabel': 'Preu:',
'admin.linkProduct.undefined': 'No definit',
'admin.linkProduct.newPrice': 'Introduïu nou preu:',
'admin.linkProduct.newStock': 'Introduïu nou estoc:',
'admin.linkProduct.update': 'Actualitzar',
'admin.linkProduct.delete': 'Eliminar',
'admin.linkProduct.selectProductFirst': 'Si us plau, seleccioneu un producte primer',
'admin.linkProduct.linkSuccess': 'Producte vinculat a la farmàcia correctament!',
'admin.linkProduct.linkError': 'Error en vincular producte a farmàcia',
'admin.linkProduct.updateSuccess': 'Actualitzat correctament!',
'admin.linkProduct.updateError': 'Error en actualitzar',
'admin.linkProduct.deleteConfirm': 'Eliminar aquest producte de la farmàcia?',
'admin.linkProduct.deleteSuccess': 'Producte eliminat de la farmàcia!',
'admin.linkProduct.deleteError': 'Error en eliminar producte',
};
export default ca;