- Rename catalog: ingredient/* → product/* (canonical_name, barcode, nutrition per 100g)
- Rename pantry: product/* → userproduct/* (user-owned items with expiry)
- Squash migrations into single 001_initial_schema.sql (clean-db baseline)
- product_categories: add English canonical name column; fix COALESCE in queries
- Remove product_translations: product names are stored in their original language
- Add default_unit_name to product API responses via unit_translations JOIN
- Add cmd/importoff: bulk import from OpenFoodFacts JSONL dump (COPY + ON CONFLICT)
- Diary: support product_id entries alongside dish_id (CHECK num_nonnulls = 1)
- Home: getLoggedCalories joins both recipes and catalog products
- Flutter: rename models/providers/services to match backend rename
- Flutter: add barcode scan flow for diary (mobile_scanner, product_portion_sheet)
- Flutter: localise 6 new keys across 12 languages (barcode scan, portion weight)
- Routes: GET /products/search, GET /products/barcode/{barcode}, /user-products
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
115 lines
3.8 KiB
Plaintext
115 lines
3.8 KiB
Plaintext
{
|
|
"@@locale": "es",
|
|
"appTitle": "FoodAI",
|
|
"greetingMorning": "Buenos días",
|
|
"greetingAfternoon": "Buenas tardes",
|
|
"greetingEvening": "Buenas noches",
|
|
"caloriesUnit": "kcal",
|
|
"gramsUnit": "g",
|
|
"goalLabel": "meta:",
|
|
"consumed": "Consumido",
|
|
"remaining": "Restante",
|
|
"exceeded": "Excedido",
|
|
"proteinLabel": "Proteínas",
|
|
"fatLabel": "Grasas",
|
|
"carbsLabel": "Carbohidratos",
|
|
"today": "Hoy",
|
|
"yesterday": "Ayer",
|
|
"mealsSection": "Comidas",
|
|
"addDish": "Añadir plato",
|
|
"scanDish": "Escanear",
|
|
"menu": "Menú",
|
|
"dishHistory": "Historial de platos",
|
|
"recommendCook": "Recomendamos cocinar",
|
|
"camera": "Cámara",
|
|
"gallery": "Galería",
|
|
"analyzingPhoto": "Analizando foto...",
|
|
"inQueue": "Estás en la cola",
|
|
"queuePosition": "Posición {position}",
|
|
"@queuePosition": {
|
|
"placeholders": {
|
|
"position": {
|
|
"type": "int"
|
|
}
|
|
}
|
|
},
|
|
"processing": "Procesando...",
|
|
"upgradePrompt": "¿Saltar la cola? Actualiza →",
|
|
"recognitionFailed": "Reconocimiento fallido. Inténtalo de nuevo.",
|
|
"dishRecognition": "Reconocimiento de platos",
|
|
"all": "Todos",
|
|
"dishRecognized": "Plato reconocido",
|
|
"recognizing": "Reconociendo…",
|
|
"recognitionError": "Error de reconocimiento",
|
|
"dishResultTitle": "Plato reconocido",
|
|
"selectDish": "Selecciona un plato",
|
|
"dishNotRecognized": "Plato no reconocido",
|
|
"tryAgain": "Intentar de nuevo",
|
|
"nutritionApproximate": "Los valores nutricionales son aproximados — estimados a partir de la foto.",
|
|
"portion": "Porción",
|
|
"mealType": "Tipo de comida",
|
|
"dateLabel": "Fecha",
|
|
"addToJournal": "Añadir al diario",
|
|
"addFailed": "Error al añadir. Inténtalo de nuevo.",
|
|
"historyTitle": "Historial de reconocimientos",
|
|
"historyLoadError": "Error al cargar el historial",
|
|
"retry": "Reintentar",
|
|
"noHistory": "Sin reconocimientos aún",
|
|
"profileTitle": "Perfil",
|
|
"edit": "Editar",
|
|
"bodyParams": "PARÁMETROS CORPORALES",
|
|
"goalActivity": "OBJETIVO Y ACTIVIDAD",
|
|
"nutrition": "NUTRICIÓN",
|
|
"settings": "AJUSTES",
|
|
"height": "Altura",
|
|
"weight": "Peso",
|
|
"age": "Edad",
|
|
"gender": "Género",
|
|
"genderMale": "Masculino",
|
|
"genderFemale": "Femenino",
|
|
"goalLoss": "Pérdida de peso",
|
|
"goalMaintain": "Mantenimiento",
|
|
"goalGain": "Ganancia muscular",
|
|
"activityLow": "Baja",
|
|
"activityMedium": "Media",
|
|
"activityHigh": "Alta",
|
|
"calorieGoal": "Objetivo calórico",
|
|
"mealTypes": "Tipos de comida",
|
|
"formulaNote": "Calculado con la fórmula de Mifflin-St Jeor",
|
|
"language": "Idioma",
|
|
"notSet": "No establecido",
|
|
"calorieHint": "Introduce los parámetros corporales para calcular el objetivo calórico",
|
|
"logout": "Cerrar sesión",
|
|
"editProfile": "Editar perfil",
|
|
"cancel": "Cancelar",
|
|
"save": "Guardar",
|
|
"nameLabel": "Nombre",
|
|
"heightCm": "Altura (cm)",
|
|
"weightKg": "Peso (kg)",
|
|
"birthDate": "Fecha de nacimiento",
|
|
"nameRequired": "Introduce el nombre",
|
|
"profileUpdated": "Perfil actualizado",
|
|
"profileSaveFailed": "Error al guardar",
|
|
"mealTypeBreakfast": "Desayuno",
|
|
"mealTypeSecondBreakfast": "Segundo desayuno",
|
|
"mealTypeLunch": "Almuerzo",
|
|
"mealTypeAfternoonSnack": "Merienda",
|
|
"mealTypeDinner": "Cena",
|
|
"mealTypeSnack": "Aperitivo",
|
|
"navHome": "Inicio",
|
|
"navProducts": "Productos",
|
|
"navRecipes": "Recetas",
|
|
"addFromReceiptOrPhoto": "Añadir desde recibo o foto",
|
|
"chooseMethod": "Elegir método",
|
|
"photoReceipt": "Fotografiar recibo",
|
|
"photoReceiptSubtitle": "Reconocemos todos los productos del recibo",
|
|
"photoProducts": "Fotografiar productos",
|
|
"photoProductsSubtitle": "Nevera, mesa, estante — hasta 3 fotos",
|
|
"addPackagedFood": "Agregar alimento envasado",
|
|
"scanBarcode": "Escanear código de barras",
|
|
"portionWeightG": "Peso de la porción (g)",
|
|
"productNotFound": "Producto no encontrado",
|
|
"enterManually": "Ingresar manualmente",
|
|
"perHundredG": "por 100 g"
|
|
}
|