Files
food-ai/client/lib/l10n/app_es.arb
dbastrikin 5096df2102 fix: fix menu generation errors and show planned meals on home screen
Backend fixes:
- migration 003: add 'menu' value to recipe_source enum (was causing SQLSTATE 22P02)
- migration 004: rename recipe_products→recipe_ingredients, product_id→ingredient_id (was causing SQLSTATE 42P01)
- dish/repository.go: fix INSERT INTO tags using $1/$1 for two columns → $1/$2 (was causing SQLSTATE 42P08)
- home/handler.go: replace non-existent saved_recipes table with correct joins (recipes→dishes→dish_translations, user_saved_recipes) so today's plan and recommendations load correctly
- reqlog: new slog.Handler wrapper that adds request_id and stack trace to ERROR-level logs
- all handlers: slog.Error→slog.ErrorContext so error logs include request context; writeError includes request_id in response body

Client:
- home_screen.dart: extend home screen to future dates, show planned meals as ghost entries
- l10n: add new localisation keys for home screen date navigation and planned meal UI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 00:35:11 +02:00

140 lines
4.6 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",
"searchFoodHint": "Buscar productos y platos...",
"recentlyUsedLabel": "Usados recientemente",
"productsSection": "Productos",
"dishesSection": "Platos",
"noResultsForQuery": "Nada encontrado para \"{query}\"",
"@noResultsForQuery": {
"placeholders": {
"query": { "type": "String" }
}
},
"servingsLabel": "Porciones",
"addToDiary": "Añadir al diario",
"scanDishPhoto": "Escanear foto",
"planningForDate": "",
"@planningForDate": {
"placeholders": {
"date": { "type": "String" }
}
},
"markAsEaten": "Marcar como comido",
"plannedMealLabel": "Planificado",
"generateWeekLabel": "Planificar la semana",
"generateWeekSubtitle": "La IA creará un menú con desayuno, comida y cena para toda la semana",
"generatingMenu": "Generando menú...",
"weekPlannedLabel": "Semana planificada"
}