i18n: Translate all hardcoded Italian labels to English & German
- Convert LOCATIONS labels to use t('locations.*')
- Convert SHOPPING_SECTIONS labels to use t('shopping_sections.*')
- Convert CATEGORY_LABELS to use t('categories.*')
- Convert MEAL_PLAN_TYPES to use t('meal_plan_types.*')
- Convert WEEK_DAYS_SHORT to use t('days.*_short')
- Convert MEAL_TYPES to use t('meal_types.*')
- Convert MEAL_SUB_TYPES to use t('meal_sub.*')
- Convert meal-plan column headers to use translated meal_types
- Replace inline locLabels/LOC_LABELS with translated LOCATIONS object
- Fix shopping action buttons: bring_add_n, bring_add_selected, bring_adding, bring_added_*
- Fix recipe archive empty state
- Fix meal plan reset success toast
- Fix meal plan suggestion hint and screensaver display
- Fix settings save status messages (saved, saved_local, saved_local_error)
- Fix product edit form title
- Fix kiosk session phrases for screensaver counter
- Add cooking.expires_chip translation for expiry date format
- Add meal_plan section (reset_success, suggested_by)
- Add error.select_items for Bring shopping validation
- All strings now properly internationalized for EN/DE languages
This commit is contained in:
+95
-93
@@ -959,10 +959,10 @@ function changeLanguage(lang) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const LOCATIONS = {
|
const LOCATIONS = {
|
||||||
'dispensa': { icon: '🗄️', label: 'Dispensa' },
|
'dispensa': { icon: '🗄️', label: t('locations.dispensa') },
|
||||||
'frigo': { icon: '🧊', label: 'Frigo' },
|
'frigo': { icon: '🧊', label: t('locations.frigo') },
|
||||||
'freezer': { icon: '❄️', label: 'Freezer' },
|
'freezer': { icon: '❄️', label: t('locations.freezer') },
|
||||||
'altro': { icon: '📦', label: 'Altro' },
|
'altro': { icon: '📦', label: t('locations.altro') },
|
||||||
};
|
};
|
||||||
const CATEGORY_ICONS = {
|
const CATEGORY_ICONS = {
|
||||||
'latticini': '🥛', 'carne': '🥩', 'pesce': '🐟', 'frutta': '🍎',
|
'latticini': '🥛', 'carne': '🥩', 'pesce': '🐟', 'frutta': '🍎',
|
||||||
@@ -982,16 +982,16 @@ const CATEGORY_LOCATION = {
|
|||||||
|
|
||||||
// Shopping section (reparto) map — groups categories into grocery departments
|
// Shopping section (reparto) map — groups categories into grocery departments
|
||||||
const SHOPPING_SECTIONS = [
|
const SHOPPING_SECTIONS = [
|
||||||
{ key: 'frutta_verdura', icon: '🥬', label: 'Frutta & Verdura', cats: new Set(['frutta','verdura']) },
|
{ key: 'frutta_verdura', icon: '🥬', label: t('shopping_sections.frutta_verdura'), cats: new Set(['frutta','verdura']) },
|
||||||
{ key: 'carne_pesce', icon: '🥩', label: 'Carne & Pesce', cats: new Set(['carne','pesce']) },
|
{ key: 'carne_pesce', icon: '🥩', label: t('shopping_sections.carne_pesce'), cats: new Set(['carne','pesce']) },
|
||||||
{ key: 'latticini', icon: '🥛', label: 'Latticini & Fresco', cats: new Set(['latticini']) },
|
{ key: 'latticini', icon: '🥛', label: t('shopping_sections.latticini'), cats: new Set(['latticini']) },
|
||||||
{ key: 'pane_dolci', icon: '🍞', label: 'Pane & Dolci', cats: new Set(['pane','snack','cereali']) },
|
{ key: 'pane_dolci', icon: '🍞', label: t('shopping_sections.pane_dolci'), cats: new Set(['pane','snack','cereali']) },
|
||||||
{ key: 'pasta', icon: '🍝', label: 'Pasta & Cereali', cats: new Set(['pasta']) },
|
{ key: 'pasta', icon: '🍝', label: t('shopping_sections.pasta'), cats: new Set(['pasta']) },
|
||||||
{ key: 'conserve', icon: '🥫', label: 'Conserve & Salse', cats: new Set(['conserve','condimenti']) },
|
{ key: 'conserve', icon: '🥫', label: t('shopping_sections.conserve'), cats: new Set(['conserve','condimenti']) },
|
||||||
{ key: 'surgelati', icon: '❄️', label: 'Surgelati', cats: new Set(['surgelati']) },
|
{ key: 'surgelati', icon: '❄️', label: t('shopping_sections.surgelati'), cats: new Set(['surgelati']) },
|
||||||
{ key: 'bevande', icon: '🥤', label: 'Bevande', cats: new Set(['bevande']) },
|
{ key: 'bevande', icon: '🥤', label: t('shopping_sections.bevande'), cats: new Set(['bevande']) },
|
||||||
{ key: 'pulizia_igiene', icon: '🧴', label: 'Pulizia & Igiene', cats: new Set(['igiene','pulizia']) },
|
{ key: 'pulizia_igiene', icon: '🧴', label: t('shopping_sections.pulizia_igiene'), cats: new Set(['igiene','pulizia']) },
|
||||||
{ key: 'altro', icon: '📦', label: 'Altro', cats: new Set(['altro']) },
|
{ key: 'altro', icon: '📦', label: t('shopping_sections.altro'), cats: new Set(['altro']) },
|
||||||
];
|
];
|
||||||
|
|
||||||
function getItemSection(name) {
|
function getItemSection(name) {
|
||||||
@@ -1150,14 +1150,14 @@ function getExpiredSafety(item, daysExpired) {
|
|||||||
return { level: 'danger', icon: '🗑️', label: t('status.discard'), tip: t('status.tip_lowRisk_danger') };
|
return { level: 'danger', icon: '🗑️', label: t('status.discard'), tip: t('status.tip_lowRisk_danger') };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nice Italian labels for local categories
|
// Localized labels for local categories
|
||||||
const CATEGORY_LABELS = {
|
const CATEGORY_LABELS = {
|
||||||
'latticini': '🥛 Latticini', 'carne': '🥩 Carne', 'pesce': '🐟 Pesce',
|
'latticini': `🥛 ${t('categories.latticini')}`, 'carne': `🥩 ${t('categories.carne')}`, 'pesce': `🐟 ${t('categories.pesce')}`,
|
||||||
'frutta': '🍎 Frutta', 'verdura': '🥬 Verdura', 'pasta': '🍝 Pasta & Riso',
|
'frutta': `🍎 ${t('categories.frutta')}`, 'verdura': `🥬 ${t('categories.verdura')}`, 'pasta': `🍝 ${t('categories.pasta')}`,
|
||||||
'pane': '🍞 Pane & Forno', 'surgelati': '🧊 Surgelati', 'bevande': '🥤 Bevande',
|
'pane': `🍞 ${t('categories.pane')}`, 'surgelati': `🧊 ${t('categories.surgelati')}`, 'bevande': `🥤 ${t('categories.bevande')}`,
|
||||||
'condimenti': '🧂 Condimenti', 'snack': '🍪 Snack & Dolci', 'conserve': '🥫 Conserve',
|
'condimenti': `🧂 ${t('categories.condimenti')}`, 'snack': `🍪 ${t('categories.snack')}`, 'conserve': `🥫 ${t('categories.conserve')}`,
|
||||||
'cereali': '🌾 Cereali & Legumi', 'igiene': '🧴 Igiene', 'pulizia': '🧹 Pulizia',
|
'cereali': `🌾 ${t('categories.cereali')}`, 'igiene': `🧴 ${t('categories.igiene')}`, 'pulizia': `🧹 ${t('categories.pulizia')}`,
|
||||||
'altro': '📦 Altro'
|
'altro': `📦 ${t('categories.altro')}`
|
||||||
};
|
};
|
||||||
|
|
||||||
// Detect best unit/quantity from Open Food Facts quantity_info string
|
// Detect best unit/quantity from Open Food Facts quantity_info string
|
||||||
@@ -1946,17 +1946,17 @@ async function saveSettings() {
|
|||||||
const statusEl = document.getElementById('settings-status');
|
const statusEl = document.getElementById('settings-status');
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
statusEl.className = 'settings-status success';
|
statusEl.className = 'settings-status success';
|
||||||
statusEl.textContent = '✅ Configurazione salvata!';
|
statusEl.textContent = `✅ ${t('settings.saved')}`;
|
||||||
} else {
|
} else {
|
||||||
statusEl.className = 'settings-status error';
|
statusEl.className = 'settings-status error';
|
||||||
statusEl.textContent = '⚠️ Salvato localmente, errore server: ' + (result.error || '');
|
statusEl.textContent = `⚠️ ${t('settings.saved_local_error').replace('{error}', result.error || '')}`;
|
||||||
}
|
}
|
||||||
statusEl.style.display = 'block';
|
statusEl.style.display = 'block';
|
||||||
setTimeout(() => statusEl.style.display = 'none', 4000);
|
setTimeout(() => statusEl.style.display = 'none', 4000);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
const statusEl = document.getElementById('settings-status');
|
const statusEl = document.getElementById('settings-status');
|
||||||
statusEl.className = 'settings-status success';
|
statusEl.className = 'settings-status success';
|
||||||
statusEl.textContent = '✅ Configurazione salvata localmente';
|
statusEl.textContent = `✅ ${t('settings.saved_local')}`;
|
||||||
statusEl.style.display = 'block';
|
statusEl.style.display = 'block';
|
||||||
setTimeout(() => statusEl.style.display = 'none', 4000);
|
setTimeout(() => statusEl.style.display = 'none', 4000);
|
||||||
}
|
}
|
||||||
@@ -4653,7 +4653,7 @@ function editProductFromAction() {
|
|||||||
document.getElementById('pf-notes').value = currentProduct.notes || '';
|
document.getElementById('pf-notes').value = currentProduct.notes || '';
|
||||||
document.getElementById('pf-unit').value = currentProduct.unit || 'pz';
|
document.getElementById('pf-unit').value = currentProduct.unit || 'pz';
|
||||||
document.getElementById('pf-defqty').value = currentProduct.default_quantity || 1;
|
document.getElementById('pf-defqty').value = currentProduct.default_quantity || 1;
|
||||||
document.getElementById('product-form-title').textContent = 'Modifica Prodotto';
|
document.getElementById('product-form-title').textContent = t('product.title_edit');
|
||||||
const pfAiRow = document.getElementById('pf-ai-fill-row');
|
const pfAiRow = document.getElementById('pf-ai-fill-row');
|
||||||
if (pfAiRow) pfAiRow.style.display = 'none';
|
if (pfAiRow) pfAiRow.style.display = 'none';
|
||||||
// Keep barcode hint hidden in edit mode
|
// Keep barcode hint hidden in edit mode
|
||||||
@@ -7484,7 +7484,7 @@ async function migrateBringNames(btn) {
|
|||||||
async function addSmartToBring() {
|
async function addSmartToBring() {
|
||||||
const checks = document.querySelectorAll('.smart-check:checked');
|
const checks = document.querySelectorAll('.smart-check:checked');
|
||||||
if (checks.length === 0) {
|
if (checks.length === 0) {
|
||||||
showToast('Seleziona almeno un prodotto', 'info');
|
showToast(t('error.select_items'), 'info');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8156,21 +8156,23 @@ function updateSuggestionActionBtn() {
|
|||||||
const selected = suggestionItems.filter(s => s.selected);
|
const selected = suggestionItems.filter(s => s.selected);
|
||||||
const btn = document.querySelector('#suggestion-actions .btn-success');
|
const btn = document.querySelector('#suggestion-actions .btn-success');
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.textContent = `✅ Aggiungi ${selected.length} prodott${selected.length === 1 ? 'o' : 'i'} a Bring!`;
|
const nItems = selected.length;
|
||||||
btn.disabled = selected.length === 0;
|
const prodStr = nItems === 1 ? 'prodotto' : 'prodotti';
|
||||||
|
btn.textContent = `✅ ${t('shopping.bring_add_n').replace('{n}', nItems + ' ' + prodStr)}!`;
|
||||||
|
btn.disabled = nItems === 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addSelectedSuggestions() {
|
async function addSelectedSuggestions() {
|
||||||
const selected = suggestionItems.filter(s => s.selected);
|
const selected = suggestionItems.filter(s => s.selected);
|
||||||
if (selected.length === 0) {
|
if (selected.length === 0) {
|
||||||
showToast('Seleziona almeno un prodotto', 'error');
|
showToast(t('error.select_items'), 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const btn = document.querySelector('#suggestion-actions .btn-success');
|
const btn = document.querySelector('#suggestion-actions .btn-success');
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.innerHTML = '<div class="loading-spinner" style="display:inline-block;width:18px;height:18px;margin-right:8px;vertical-align:middle"></div> Aggiunta in corso...';
|
btn.innerHTML = `<div class="loading-spinner" style="display:inline-block;width:18px;height:18px;margin-right:8px;vertical-align:middle"></div> ${t('shopping.bring_adding')}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const items = selected.map(s => {
|
const items = selected.map(s => {
|
||||||
@@ -8180,8 +8182,8 @@ async function addSelectedSuggestions() {
|
|||||||
const data = await api('bring_add', {}, 'POST', { items, listUUID: shoppingListUUID });
|
const data = await api('bring_add', {}, 'POST', { items, listUUID: shoppingListUUID });
|
||||||
|
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
let msg = `${data.added} prodott${data.added === 1 ? 'o aggiunto' : 'i aggiunti'} a Bring!`;
|
let msg = data.added === 1 ? t('shopping.bring_added_one') : t('shopping.bring_added_many').replace('{n}', data.added);
|
||||||
if (data.skipped > 0) msg += ` (${data.skipped} già in lista)`;
|
if (data.skipped > 0) msg += ` ${t('shopping.bring_skipped').replace('{n}', data.skipped)}`;
|
||||||
showToast(msg, 'success');
|
showToast(msg, 'success');
|
||||||
// Refresh list
|
// Refresh list
|
||||||
await loadShoppingList();
|
await loadShoppingList();
|
||||||
@@ -8198,7 +8200,7 @@ async function addSelectedSuggestions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.innerHTML = '✅ Aggiungi selezionati a Bring!';
|
btn.innerHTML = `✅ ${t('shopping.bring_add_selected')}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== UTILITY FUNCTIONS =====
|
// ===== UTILITY FUNCTIONS =====
|
||||||
@@ -8515,28 +8517,28 @@ async function undoTransactionEntry(id, type, name) {
|
|||||||
* id must be URL-safe; icon + label shown in UI.
|
* id must be URL-safe; icon + label shown in UI.
|
||||||
*/
|
*/
|
||||||
const MEAL_PLAN_TYPES = [
|
const MEAL_PLAN_TYPES = [
|
||||||
{ id: 'pasta', icon: '🍝', label: 'Pasta' },
|
{ id: 'pasta', icon: '🍝', label: t('meal_plan_types.pasta') },
|
||||||
{ id: 'riso', icon: '🍚', label: 'Riso' },
|
{ id: 'riso', icon: '🍚', label: t('meal_plan_types.riso') },
|
||||||
{ id: 'carne', icon: '🥩', label: 'Carne' },
|
{ id: 'carne', icon: '🥩', label: t('meal_plan_types.carne') },
|
||||||
{ id: 'pesce', icon: '🐟', label: 'Pesce' },
|
{ id: 'pesce', icon: '🐟', label: t('meal_plan_types.pesce') },
|
||||||
{ id: 'legumi', icon: '🫘', label: 'Legumi' },
|
{ id: 'legumi', icon: '🫘', label: t('meal_plan_types.legumi') },
|
||||||
{ id: 'uova', icon: '🥚', label: 'Uova' },
|
{ id: 'uova', icon: '🥚', label: t('meal_plan_types.uova') },
|
||||||
{ id: 'formaggio', icon: '🧀', label: 'Formaggio' },
|
{ id: 'formaggio', icon: '🧀', label: t('meal_plan_types.formaggio') },
|
||||||
{ id: 'pizza', icon: '🍕', label: 'Pizza' },
|
{ id: 'pizza', icon: '🍕', label: t('meal_plan_types.pizza') },
|
||||||
{ id: 'affettati', icon: '🥓', label: 'Affettati' },
|
{ id: 'affettati', icon: '🥓', label: t('meal_plan_types.affettati') },
|
||||||
{ id: 'verdure', icon: '🥦', label: 'Verdure' },
|
{ id: 'verdure', icon: '🥦', label: t('meal_plan_types.verdure') },
|
||||||
{ id: 'zuppa', icon: '🍲', label: 'Zuppa' },
|
{ id: 'zuppa', icon: '🍲', label: t('meal_plan_types.zuppa') },
|
||||||
{ id: 'insalata', icon: '🥗', label: 'Insalata' },
|
{ id: 'insalata', icon: '🥗', label: t('meal_plan_types.insalata') },
|
||||||
{ id: 'pane', icon: '🥪', label: 'Pane/Sandwich' },
|
{ id: 'pane', icon: '🥪', label: t('meal_plan_types.pane') },
|
||||||
{ id: 'dolce', icon: '🍰', label: 'Dolce' },
|
{ id: 'dolce', icon: '🍰', label: t('meal_plan_types.dolce') },
|
||||||
{ id: 'libero', icon: '🎲', label: 'Libero' },
|
{ id: 'libero', icon: '🎲', label: t('meal_plan_types.libero') },
|
||||||
];
|
];
|
||||||
|
|
||||||
const MEAL_PLAN_TYPE_MAP = {};
|
const MEAL_PLAN_TYPE_MAP = {};
|
||||||
MEAL_PLAN_TYPES.forEach(t => { MEAL_PLAN_TYPE_MAP[t.id] = t; });
|
MEAL_PLAN_TYPES.forEach(mpt => { MEAL_PLAN_TYPE_MAP[mpt.id] = mpt; });
|
||||||
|
|
||||||
const WEEK_DAYS = [t('days.mon'),t('days.tue'),t('days.wed'),t('days.thu'),t('days.fri'),t('days.sat'),t('days.sun')];
|
const WEEK_DAYS = [t('days.mon'),t('days.tue'),t('days.wed'),t('days.thu'),t('days.fri'),t('days.sat'),t('days.sun')];
|
||||||
const WEEK_DAYS_SHORT = ['Lun','Mar','Mer','Gio','Ven','Sab','Dom'];
|
const WEEK_DAYS_SHORT = [t('days.mon_short'),t('days.tue_short'),t('days.wed_short'),t('days.thu_short'),t('days.fri_short'),t('days.sat_short'),t('days.sun_short')];
|
||||||
|
|
||||||
/** Default weekly plan as requested. */
|
/** Default weekly plan as requested. */
|
||||||
const DEFAULT_MEAL_PLAN = {
|
const DEFAULT_MEAL_PLAN = {
|
||||||
@@ -8590,8 +8592,8 @@ function renderMealPlanEditor() {
|
|||||||
const today = new Date().getDay();
|
const today = new Date().getDay();
|
||||||
|
|
||||||
const header = `<div class="mplan-header">
|
const header = `<div class="mplan-header">
|
||||||
<span class="mplan-col-header">🌤️ Pranzo</span>
|
<span class="mplan-col-header">🌤️ ${t('meal_types.pranzo')}</span>
|
||||||
<span class="mplan-col-header">🌙 Cena</span>
|
<span class="mplan-col-header">🌙 ${t('meal_types.cena')}</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
const rows = dayOrder.map((dow, i) => {
|
const rows = dayOrder.map((dow, i) => {
|
||||||
@@ -8660,33 +8662,33 @@ function resetMealPlan() {
|
|||||||
s.meal_plan = JSON.parse(JSON.stringify(DEFAULT_MEAL_PLAN));
|
s.meal_plan = JSON.parse(JSON.stringify(DEFAULT_MEAL_PLAN));
|
||||||
saveSettingsToStorage(s);
|
saveSettingsToStorage(s);
|
||||||
renderMealPlanEditor();
|
renderMealPlanEditor();
|
||||||
showToast('Piano settimanale ripristinato', 'success');
|
showToast(t('meal_plan.reset_success'), 'success');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== RECIPE GENERATION =====
|
// ===== RECIPE GENERATION =====
|
||||||
const MEAL_TYPES = [
|
const MEAL_TYPES = [
|
||||||
{ id: 'colazione', icon: '☀️', label: 'Colazione', from: 6, to: 11 },
|
{ id: 'colazione', icon: '☀️', label: t('meal_types.colazione'), from: 6, to: 11 },
|
||||||
{ id: 'pranzo', icon: '🍽️', label: 'Pranzo', from: 11, to: 14 },
|
{ id: 'pranzo', icon: '🍽️', label: t('meal_types.pranzo'), from: 11, to: 14 },
|
||||||
{ id: 'merenda', icon: '🍪', label: 'Merenda', from: 14, to: 17 },
|
{ id: 'merenda', icon: '🍪', label: t('meal_types.merenda'), from: 14, to: 17 },
|
||||||
{ id: 'cena', icon: '🌙', label: 'Cena', from: 17, to: 6 },
|
{ id: 'cena', icon: '🌙', label: t('meal_types.cena'), from: 17, to: 6 },
|
||||||
{ id: 'dolce', icon: '🍰', label: 'Dolce', from: -1, to: -1 },
|
{ id: 'dolce', icon: '🍰', label: t('meal_types.dolce'), from: -1, to: -1 },
|
||||||
{ id: 'succo', icon: '🧃', label: 'Succo di Frutta', from: -1, to: -1 },
|
{ id: 'succo', icon: '🧃', label: t('meal_types.succo'), from: -1, to: -1 },
|
||||||
];
|
];
|
||||||
|
|
||||||
const MEAL_SUB_TYPES = {
|
const MEAL_SUB_TYPES = {
|
||||||
dolce: [
|
dolce: [
|
||||||
{ id: 'torta', icon: '🎂', label: 'Torta' },
|
{ id: 'torta', icon: '🎂', label: t('meal_sub.dolce_torta') },
|
||||||
{ id: 'crema', icon: '🍮', label: 'Crema / Budino' },
|
{ id: 'crema', icon: '🍮', label: t('meal_sub.dolce_crema') },
|
||||||
{ id: 'crumble', icon: '🥧', label: 'Crumble / Crostata' },
|
{ id: 'crumble', icon: '🥧', label: t('meal_sub.dolce_crumble') },
|
||||||
{ id: 'biscotti', icon: '🍪', label: 'Biscotti / Pasticcini' },
|
{ id: 'biscotti', icon: '🍪', label: t('meal_sub.dolce_biscotti') },
|
||||||
{ id: 'frutta', icon: '🍓', label: 'Dolce alla Frutta' },
|
{ id: 'frutta', icon: '🍓', label: t('meal_sub.dolce_frutta') },
|
||||||
],
|
],
|
||||||
succo: [
|
succo: [
|
||||||
{ id: 'dolce', icon: '🍑', label: 'Dolce / Fruttato' },
|
{ id: 'dolce', icon: '🍑', label: t('meal_sub.succo_dolce') },
|
||||||
{ id: 'energizzante', icon: '⚡', label: 'Energizzante' },
|
{ id: 'energizzante', icon: '⚡', label: t('meal_sub.succo_energizzante') },
|
||||||
{ id: 'detox', icon: '🥬', label: 'Detox / Verde' },
|
{ id: 'detox', icon: '🥬', label: t('meal_sub.succo_detox') },
|
||||||
{ id: 'rinfrescante', icon: '🧊', label: 'Rinfrescante' },
|
{ id: 'rinfrescante', icon: '🧊', label: t('meal_sub.succo_rinfrescante') },
|
||||||
{ id: 'vitaminico', icon: '🍊', label: 'Vitaminico / Agrumi' },
|
{ id: 'vitaminico', icon: '🍊', label: t('meal_sub.succo_vitaminico') },
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -8749,7 +8751,7 @@ async function loadRecipeArchive() {
|
|||||||
_recipeArchiveEntries = archive;
|
_recipeArchiveEntries = archive;
|
||||||
|
|
||||||
if (archive.length === 0) {
|
if (archive.length === 0) {
|
||||||
container.innerHTML = '<div class="empty-state" style="padding:20px"><div class="empty-state-icon">🍳</div><p>Nessuna ricetta salvata.<br>Genera la tua prima ricetta!</p></div>';
|
container.innerHTML = `<div class="empty-state" style="padding:20px"><div class="empty-state-icon">🍳</div><p>${t('recipes.archive_empty')}</p></div>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9240,8 +9242,8 @@ function renderRecipe(r) {
|
|||||||
html += `<span class="recipe-ing-text"><strong>${ing.name}</strong>${ing.brand ? ' <em>(' + ing.brand + ')</em>' : ''}: ${ing.qty} ✅`;
|
html += `<span class="recipe-ing-text"><strong>${ing.name}</strong>${ing.brand ? ' <em>(' + ing.brand + ')</em>' : ''}: ${ing.qty} ✅`;
|
||||||
// Detail line: location + expiry
|
// Detail line: location + expiry
|
||||||
let details = [];
|
let details = [];
|
||||||
const locLabels = { 'frigo': '🧊 Frigo', 'freezer': '🧊 Freezer', 'dispensa': '🗄️ Dispensa' };
|
const ingredientLocLabels = Object.fromEntries(Object.entries(LOCATIONS).map(([k,v]) => [k, `${v.icon} ${v.label}`]));
|
||||||
details.push(locLabels[ing.location] || ('📍 ' + ing.location));
|
details.push(ingredientLocLabels[ing.location] || ('📍 ' + ing.location));
|
||||||
if (ing.expiry_date) {
|
if (ing.expiry_date) {
|
||||||
const exp = new Date(ing.expiry_date);
|
const exp = new Date(ing.expiry_date);
|
||||||
const now = new Date(); now.setHours(0,0,0,0);
|
const now = new Date(); now.setHours(0,0,0,0);
|
||||||
@@ -9362,19 +9364,19 @@ function renderCookingStep() {
|
|||||||
|
|
||||||
const ingsEl = document.getElementById('cooking-step-ings');
|
const ingsEl = document.getElementById('cooking-step-ings');
|
||||||
if (ings.length > 0) {
|
if (ings.length > 0) {
|
||||||
const LOC_LABELS = { dispensa: '🏠 Dispensa', frigo: '❄️ Frigo', freezer: '🧊 Freezer' };
|
const cookingLocLabels = Object.fromEntries(Object.entries(LOCATIONS).map(([k,v]) => [k, `${v.icon} ${v.label}`]));
|
||||||
ingsEl.innerHTML = ings.map(ing => {
|
ingsEl.innerHTML = ings.map(ing => {
|
||||||
const loc = (ing.location || 'dispensa').replace(/'/g, "\\'");
|
const loc = (ing.location || 'dispensa').replace(/'/g, "\\'");
|
||||||
const qtyNum = ing.qty_number || 0;
|
const qtyNum = ing.qty_number || 0;
|
||||||
// Build info chips: brand, location, expiry
|
// Build info chips: brand, location, expiry
|
||||||
const chips = [];
|
const chips = [];
|
||||||
if (ing.brand) chips.push(`<span class="cooking-ing-chip">${escapeHtml(ing.brand)}</span>`);
|
if (ing.brand) chips.push(`<span class="cooking-ing-chip">${escapeHtml(ing.brand)}</span>`);
|
||||||
const locLabel = LOC_LABELS[ing.location] || (ing.location ? `📍 ${ing.location}` : '🏠 Dispensa');
|
const locLabel = cookingLocLabels[ing.location] || (ing.location ? `📍 ${ing.location}` : `${LOCATIONS.dispensa.icon} ${LOCATIONS.dispensa.label}`);
|
||||||
chips.push(`<span class="cooking-ing-chip">${locLabel}</span>`);
|
chips.push(`<span class="cooking-ing-chip">${locLabel}</span>`);
|
||||||
if (ing.expiry_date) {
|
if (ing.expiry_date) {
|
||||||
const daysLeft = Math.round((new Date(ing.expiry_date) - new Date()) / 86400000);
|
const daysLeft = Math.round((new Date(ing.expiry_date) - new Date()) / 86400000);
|
||||||
const expClass = daysLeft <= 3 ? 'exp-soon' : daysLeft <= 7 ? 'exp-close' : '';
|
const expClass = daysLeft <= 3 ? 'exp-soon' : daysLeft <= 7 ? 'exp-close' : '';
|
||||||
chips.push(`<span class="cooking-ing-chip ${expClass}">📅 scade ${formatDate(ing.expiry_date)}</span>`);
|
chips.push(`<span class="cooking-ing-chip ${expClass}">📅 ${t('cooking.expires_chip').replace('{date}', formatDate(ing.expiry_date))}</span>`);
|
||||||
}
|
}
|
||||||
return `<div class="cooking-ing-row">
|
return `<div class="cooking-ing-row">
|
||||||
<div style="flex:1;min-width:0">
|
<div style="flex:1;min-width:0">
|
||||||
@@ -9942,26 +9944,26 @@ function _renderMealPlanHint(mealSlot) {
|
|||||||
if (chipWrap) chipWrap.style.display = 'none';
|
if (chipWrap) chipWrap.style.display = 'none';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const t = MEAL_PLAN_TYPE_MAP[typeId];
|
const mpt = MEAL_PLAN_TYPE_MAP[typeId];
|
||||||
if (!t) {
|
if (!mpt) {
|
||||||
if (el) el.style.display = 'none';
|
if (el) el.style.display = 'none';
|
||||||
if (banner) banner.style.display = 'none';
|
if (banner) banner.style.display = 'none';
|
||||||
if (chipWrap) chipWrap.style.display = 'none';
|
if (chipWrap) chipWrap.style.display = 'none';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (el) {
|
if (el) {
|
||||||
el.innerHTML = `<span class="mplan-hint-badge">${t.icon} ${t.label}</span> <span class="mplan-hint-label">suggerito dal piano settimanale</span>`;
|
el.innerHTML = `<span class="mplan-hint-badge">${mpt.icon} ${mpt.label}</span> <span class="mplan-hint-label">${t('meal_plan.suggested_by')}</span>`;
|
||||||
el.style.display = 'flex';
|
el.style.display = 'flex';
|
||||||
}
|
}
|
||||||
if (banner) {
|
if (banner) {
|
||||||
const slotLabel = mealSlot === 'pranzo' ? '🌤️ Pranzo' : '🌙 Cena';
|
const slotLabel = mealSlot === 'pranzo' ? '🌤️ ' + t('meal_types.pranzo') : '🌙 ' + t('meal_types.cena');
|
||||||
banner.innerHTML = `<span style="opacity:0.75;font-weight:500">${slotLabel}</span><span style="opacity:0.45">·</span><span>${t.icon} ${t.label}</span>`;
|
banner.innerHTML = `<span style="opacity:0.75;font-weight:500">${slotLabel}</span><span style="opacity:0.45">·</span><span>${mpt.icon} ${mpt.label}</span>`;
|
||||||
banner.style.display = 'flex';
|
banner.style.display = 'flex';
|
||||||
}
|
}
|
||||||
// Show the meal-plan chip (active by default, user can uncheck to ignore the plan)
|
// Show the meal-plan chip (active by default, user can uncheck to ignore the plan)
|
||||||
if (chipWrap) {
|
if (chipWrap) {
|
||||||
chipWrap.style.display = '';
|
chipWrap.style.display = '';
|
||||||
if (chipLabel) chipLabel.textContent = `${t.icon} ${t.label}`;
|
if (chipLabel) chipLabel.textContent = `${mpt.icon} ${mpt.label}`;
|
||||||
if (chipCb) chipCb.checked = true;
|
if (chipCb) chipCb.checked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10346,10 +10348,10 @@ function updateScreensaverMealPlan() {
|
|||||||
const slot = hour < 15 ? 'pranzo' : 'cena';
|
const slot = hour < 15 ? 'pranzo' : 'cena';
|
||||||
const typeId = getTodayMealPlanType(slot);
|
const typeId = getTodayMealPlanType(slot);
|
||||||
if (!typeId || typeId === 'libero') { el.style.display = 'none'; return; }
|
if (!typeId || typeId === 'libero') { el.style.display = 'none'; return; }
|
||||||
const t = MEAL_PLAN_TYPE_MAP[typeId];
|
const mpt = MEAL_PLAN_TYPE_MAP[typeId];
|
||||||
if (!t) { el.style.display = 'none'; return; }
|
if (!mpt) { el.style.display = 'none'; return; }
|
||||||
const slotLabel = slot === 'pranzo' ? '🌤️ Pranzo' : '🌙 Cena';
|
const slotLabel = slot === 'pranzo' ? '🌤️ ' + t('meal_types.pranzo') : '🌙 ' + t('meal_types.cena');
|
||||||
el.innerHTML = `<span class="screensaver-mealplan-badge">${slotLabel} · ${t.icon} ${t.label}</span>`;
|
el.innerHTML = `<span class="screensaver-mealplan-badge">${slotLabel} · ${mpt.icon} ${mpt.label}</span>`;
|
||||||
el.style.display = 'block';
|
el.style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10814,15 +10816,15 @@ function _spesaBannerStat() {
|
|||||||
const unique = [...new Set(names)];
|
const unique = [...new Set(names)];
|
||||||
const dupes = names.length - unique.length;
|
const dupes = names.length - unique.length;
|
||||||
const phrases = [
|
const phrases = [
|
||||||
n === 1 ? `Primo prodotto: ${_spesaSession[0].name}!` : null,
|
n === 1 ? t('kiosk_session.first_item').replace('{name}', _spesaSession[0].name) : null,
|
||||||
n >= 2 && n < 5 ? `${n} prodotti — stai scaldando i motori 🚀` : null,
|
n >= 2 && n < 5 ? t('kiosk_session.items_two_four').replace('{n}', n) : null,
|
||||||
n >= 5 && n < 10 ? `${n} prodotti — ottimo ritmo! 💪` : null,
|
n >= 5 && n < 10 ? t('kiosk_session.items_five_nine').replace('{n}', n) : null,
|
||||||
n >= 10 && n < 20 ? `${n} prodotti — quasi un recordman 🏆` : null,
|
n >= 10 && n < 20 ? t('kiosk_session.items_ten_twenty').replace('{n}', n) : null,
|
||||||
n >= 20 ? `${n} prodotti — spesa epica! 🛒🔥` : null,
|
n >= 20 ? t('kiosk_session.items_twenty_plus').replace('{n}', n) : null,
|
||||||
dupes > 0 ? `${dupes} bis ${dupes===1?'(stessa cosa due volte)':'(roba presa più volte)'}` : null,
|
dupes > 0 ? (dupes === 1 ? t('kiosk_session.duplicates_one') : t('kiosk_session.duplicates_many').replace('{n}', dupes)) : null,
|
||||||
topCat && topCat[1] > 1 ? `Categoria top: ${topCat[0]} (${topCat[1]}×)` : null,
|
topCat && topCat[1] > 1 ? t('kiosk_session.top_category').replace('{cat}', topCat[0]).replace('{count}', topCat[1]) : null,
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
return phrases[n % phrases.length] || `${n} prodott${n===1?'o':'i'} aggiunti`;
|
return phrases[n % phrases.length] || t('kiosk_session.items_fallback').replace('{n}', n).replace('{plural}', n===1?'o':'i');
|
||||||
}
|
}
|
||||||
|
|
||||||
function _initScreensaverShortcutBtn(btnId, targetPage, longPressFn) {
|
function _initScreensaverShortcutBtn(btnId, targetPage, longPressFn) {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"a_32_572":1776776330,"a_17_171":1776776404,"a_25_-777":1776776427,"a_7_-279":1776776434,"a_168_253":1777223925}
|
{"a_32_572":1776776330,"a_17_171":1776776404,"a_25_-777":1776776427,"a_7_-279":1776776434,"a_168_253":1777223925,"a_191_1":1777300414,"a_183_291":1777310462,"a_213_150":1777378506,"a_183_290":1777380000}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"ts":1777391782}
|
||||||
+70
-6
@@ -272,7 +272,8 @@
|
|||||||
},
|
},
|
||||||
"recipes": {
|
"recipes": {
|
||||||
"title": "🍳 Rezepte",
|
"title": "🍳 Rezepte",
|
||||||
"generate": "✨ Neues Rezept generieren"
|
"generate": "✨ Neues Rezept generieren",
|
||||||
|
"archive_empty": "Keine Rezepte gespeichert. Erstelle dein erstes Rezept!"
|
||||||
},
|
},
|
||||||
"shopping": {
|
"shopping": {
|
||||||
"title": "🛒 Einkaufsliste",
|
"title": "🛒 Einkaufsliste",
|
||||||
@@ -326,7 +327,13 @@
|
|||||||
"smart_already_predicted": "📊 Einkauf wird bereits vorhergesagt: <strong>{name}</strong>{urgency}.",
|
"smart_already_predicted": "📊 Einkauf wird bereits vorhergesagt: <strong>{name}</strong>{urgency}.",
|
||||||
"item_removed": "✅ {name} von der Liste entfernt!",
|
"item_removed": "✅ {name} von der Liste entfernt!",
|
||||||
"urgency_spec_critical": "⚡ Dringend",
|
"urgency_spec_critical": "⚡ Dringend",
|
||||||
"urgency_spec_high": "🟠 Bald"
|
"urgency_spec_high": "🟠 Bald",
|
||||||
|
"bring_add_n": "{n} zu Bring! hinzufügen",
|
||||||
|
"bring_add_selected": "Ausgewählte zu Bring! hinzufügen",
|
||||||
|
"bring_adding": "Wird hinzugefügt...",
|
||||||
|
"bring_added_one": "1 Produkt zu Bring! hinzugefügt",
|
||||||
|
"bring_added_many": "{n} Produkte zu Bring! hinzugefügt",
|
||||||
|
"bring_skipped": "({n} bereits in Liste)"
|
||||||
},
|
},
|
||||||
"ai": {
|
"ai": {
|
||||||
"title": "🤖 KI-Identifikation",
|
"title": "🤖 KI-Identifikation",
|
||||||
@@ -386,7 +393,8 @@
|
|||||||
"ingredient_deduct_title": "Von Vorrat abziehen",
|
"ingredient_deduct_title": "Von Vorrat abziehen",
|
||||||
"timer_expired_tts": "Timer {label} abgelaufen!",
|
"timer_expired_tts": "Timer {label} abgelaufen!",
|
||||||
"timer_warning_tts": "Achtung! {label}: noch 10 Sekunden!",
|
"timer_warning_tts": "Achtung! {label}: noch 10 Sekunden!",
|
||||||
"recipe_done_tts": "Rezept abgeschlossen! Guten Appetit!"
|
"recipe_done_tts": "Rezept abgeschlossen! Guten Appetit!",
|
||||||
|
"expires_chip": "läuft ab {date}"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"title": "⚙️ Einstellungen",
|
"title": "⚙️ Einstellungen",
|
||||||
@@ -610,7 +618,8 @@
|
|||||||
"not_in_inventory": "Produkt nicht im Bestand",
|
"not_in_inventory": "Produkt nicht im Bestand",
|
||||||
"appliance_exists": "Gerät bereits vorhanden",
|
"appliance_exists": "Gerät bereits vorhanden",
|
||||||
"already_exists": "Bereits vorhanden",
|
"already_exists": "Bereits vorhanden",
|
||||||
"network_retry": "Verbindungsfehler. Erneut versuchen."
|
"network_retry": "Verbindungsfehler. Erneut versuchen.",
|
||||||
|
"select_items": "Wähle mindestens ein Produkt aus"
|
||||||
},
|
},
|
||||||
"confirm": {
|
"confirm": {
|
||||||
"remove_item": "Möchtest du dieses Produkt wirklich aus dem Bestand entfernen?",
|
"remove_item": "Möchtest du dieses Produkt wirklich aus dem Bestand entfernen?",
|
||||||
@@ -632,11 +641,22 @@
|
|||||||
"thu": "Donnerstag",
|
"thu": "Donnerstag",
|
||||||
"fri": "Freitag",
|
"fri": "Freitag",
|
||||||
"sat": "Samstag",
|
"sat": "Samstag",
|
||||||
"sun": "Sonntag"
|
"sun": "Sonntag",
|
||||||
|
"mon_short": "Mo",
|
||||||
|
"tue_short": "Di",
|
||||||
|
"wed_short": "Mi",
|
||||||
|
"thu_short": "Do",
|
||||||
|
"fri_short": "Fr",
|
||||||
|
"sat_short": "Sa",
|
||||||
|
"sun_short": "So"
|
||||||
},
|
},
|
||||||
"meal_types": {
|
"meal_types": {
|
||||||
"lunch": "Mittagessen",
|
"lunch": "Mittagessen",
|
||||||
"dinner": "Abendessen"
|
"dinner": "Abendessen",
|
||||||
|
"colazione": "Frühstück",
|
||||||
|
"merenda": "Nachmittagssnack",
|
||||||
|
"dolce": "Dessert",
|
||||||
|
"succo": "Fruchtsaft"
|
||||||
},
|
},
|
||||||
"scale": {
|
"scale": {
|
||||||
"status_connected": "Waage verbunden",
|
"status_connected": "Waage verbunden",
|
||||||
@@ -709,5 +729,49 @@
|
|||||||
"2": "Kulinarische Zutat",
|
"2": "Kulinarische Zutat",
|
||||||
"3": "Verarbeitet",
|
"3": "Verarbeitet",
|
||||||
"4": "Hochverarbeitet"
|
"4": "Hochverarbeitet"
|
||||||
|
},
|
||||||
|
"meal_plan_types": {
|
||||||
|
"pasta": "Pasta",
|
||||||
|
"riso": "Reis",
|
||||||
|
"carne": "Fleisch",
|
||||||
|
"pesce": "Fisch",
|
||||||
|
"legumi": "Hülsenfrüchte",
|
||||||
|
"uova": "Eier",
|
||||||
|
"formaggio": "Käse",
|
||||||
|
"pizza": "Pizza",
|
||||||
|
"affettati": "Aufschnitt",
|
||||||
|
"verdure": "Gemüse",
|
||||||
|
"zuppa": "Suppe",
|
||||||
|
"insalata": "Salat",
|
||||||
|
"pane": "Brot/Sandwich",
|
||||||
|
"dolce": "Dessert",
|
||||||
|
"libero": "Frei"
|
||||||
|
},
|
||||||
|
"meal_sub": {
|
||||||
|
"dolce_torta": "Kuchen",
|
||||||
|
"dolce_crema": "Creme / Pudding",
|
||||||
|
"dolce_crumble": "Crumble / Tarte",
|
||||||
|
"dolce_biscotti": "Kekse / Gebäck",
|
||||||
|
"dolce_frutta": "Fruchtdessert",
|
||||||
|
"succo_dolce": "Süß / Fruchtig",
|
||||||
|
"succo_energizzante": "Energetisierend",
|
||||||
|
"succo_detox": "Detox / Grün",
|
||||||
|
"succo_rinfrescante": "Erfrischend",
|
||||||
|
"succo_vitaminico": "Vitamin / Zitrus"
|
||||||
|
},
|
||||||
|
"meal_plan": {
|
||||||
|
"reset_success": "Wochenplan zurückgesetzt",
|
||||||
|
"suggested_by": "vom Wochenplan vorgeschlagen"
|
||||||
|
},
|
||||||
|
"kiosk_session": {
|
||||||
|
"first_item": "Erstes Produkt: {name}!",
|
||||||
|
"items_two_four": "{n} Artikel — Trägheit überwinden 🚀",
|
||||||
|
"items_five_nine": "{n} Artikel — super Tempo! 💪",
|
||||||
|
"items_ten_twenty": "{n} Artikel — fast Rekord 🏆",
|
||||||
|
"items_twenty_plus": "{n} Artikel — epischer Einkauf! 🛒🔥",
|
||||||
|
"duplicates_one": "1 Duplikat (gleiches Produkt zweimal)",
|
||||||
|
"duplicates_many": "{n} Duplikate (mehrfach genommen)",
|
||||||
|
"top_category": "Top-Kategorie: {cat} ({count}×)",
|
||||||
|
"items_fallback": "{n} Artikel hinzugefügt"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+70
-6
@@ -272,7 +272,8 @@
|
|||||||
},
|
},
|
||||||
"recipes": {
|
"recipes": {
|
||||||
"title": "🍳 Recipes",
|
"title": "🍳 Recipes",
|
||||||
"generate": "✨ Generate new recipe"
|
"generate": "✨ Generate new recipe",
|
||||||
|
"archive_empty": "No recipes saved. Generate your first recipe!"
|
||||||
},
|
},
|
||||||
"shopping": {
|
"shopping": {
|
||||||
"title": "🛒 Shopping List",
|
"title": "🛒 Shopping List",
|
||||||
@@ -326,7 +327,13 @@
|
|||||||
"smart_already_predicted": "📊 Smart shopping already predicts <strong>{name}</strong>{urgency}.",
|
"smart_already_predicted": "📊 Smart shopping already predicts <strong>{name}</strong>{urgency}.",
|
||||||
"item_removed": "✅ {name} removed from list!",
|
"item_removed": "✅ {name} removed from list!",
|
||||||
"urgency_spec_critical": "⚡ Urgent",
|
"urgency_spec_critical": "⚡ Urgent",
|
||||||
"urgency_spec_high": "🟠 Soon"
|
"urgency_spec_high": "🟠 Soon",
|
||||||
|
"bring_add_n": "Add {n} to Bring!",
|
||||||
|
"bring_add_selected": "Add selected to Bring!",
|
||||||
|
"bring_adding": "Adding...",
|
||||||
|
"bring_added_one": "1 product added to Bring!",
|
||||||
|
"bring_added_many": "{n} products added to Bring!",
|
||||||
|
"bring_skipped": "({n} already in list)"
|
||||||
},
|
},
|
||||||
"ai": {
|
"ai": {
|
||||||
"title": "🤖 AI Identification",
|
"title": "🤖 AI Identification",
|
||||||
@@ -386,7 +393,8 @@
|
|||||||
"ingredient_deduct_title": "Deduct from pantry",
|
"ingredient_deduct_title": "Deduct from pantry",
|
||||||
"timer_expired_tts": "Timer {label} expired!",
|
"timer_expired_tts": "Timer {label} expired!",
|
||||||
"timer_warning_tts": "Heads up! {label}: 10 seconds left!",
|
"timer_warning_tts": "Heads up! {label}: 10 seconds left!",
|
||||||
"recipe_done_tts": "Recipe complete! Enjoy your meal!"
|
"recipe_done_tts": "Recipe complete! Enjoy your meal!",
|
||||||
|
"expires_chip": "exp. {date}"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"title": "⚙️ Settings",
|
"title": "⚙️ Settings",
|
||||||
@@ -610,7 +618,8 @@
|
|||||||
"not_in_inventory": "Product not in inventory",
|
"not_in_inventory": "Product not in inventory",
|
||||||
"appliance_exists": "Appliance already exists",
|
"appliance_exists": "Appliance already exists",
|
||||||
"already_exists": "Already exists",
|
"already_exists": "Already exists",
|
||||||
"network_retry": "Connection error. Try again."
|
"network_retry": "Connection error. Try again.",
|
||||||
|
"select_items": "Select at least one product"
|
||||||
},
|
},
|
||||||
"confirm": {
|
"confirm": {
|
||||||
"remove_item": "Do you really want to remove this product from inventory?",
|
"remove_item": "Do you really want to remove this product from inventory?",
|
||||||
@@ -632,11 +641,22 @@
|
|||||||
"thu": "Thursday",
|
"thu": "Thursday",
|
||||||
"fri": "Friday",
|
"fri": "Friday",
|
||||||
"sat": "Saturday",
|
"sat": "Saturday",
|
||||||
"sun": "Sunday"
|
"sun": "Sunday",
|
||||||
|
"mon_short": "Mon",
|
||||||
|
"tue_short": "Tue",
|
||||||
|
"wed_short": "Wed",
|
||||||
|
"thu_short": "Thu",
|
||||||
|
"fri_short": "Fri",
|
||||||
|
"sat_short": "Sat",
|
||||||
|
"sun_short": "Sun"
|
||||||
},
|
},
|
||||||
"meal_types": {
|
"meal_types": {
|
||||||
"lunch": "Lunch",
|
"lunch": "Lunch",
|
||||||
"dinner": "Dinner"
|
"dinner": "Dinner",
|
||||||
|
"colazione": "Breakfast",
|
||||||
|
"merenda": "Snack",
|
||||||
|
"dolce": "Dessert",
|
||||||
|
"succo": "Fruit Juice"
|
||||||
},
|
},
|
||||||
"scale": {
|
"scale": {
|
||||||
"status_connected": "Scale connected",
|
"status_connected": "Scale connected",
|
||||||
@@ -709,5 +729,49 @@
|
|||||||
"2": "Culinary ingredient",
|
"2": "Culinary ingredient",
|
||||||
"3": "Processed",
|
"3": "Processed",
|
||||||
"4": "Ultra-processed"
|
"4": "Ultra-processed"
|
||||||
|
},
|
||||||
|
"meal_plan_types": {
|
||||||
|
"pasta": "Pasta",
|
||||||
|
"riso": "Rice",
|
||||||
|
"carne": "Meat",
|
||||||
|
"pesce": "Fish",
|
||||||
|
"legumi": "Legumes",
|
||||||
|
"uova": "Eggs",
|
||||||
|
"formaggio": "Cheese",
|
||||||
|
"pizza": "Pizza",
|
||||||
|
"affettati": "Cold Cuts",
|
||||||
|
"verdure": "Veggies",
|
||||||
|
"zuppa": "Soup",
|
||||||
|
"insalata": "Salad",
|
||||||
|
"pane": "Bread/Sandwich",
|
||||||
|
"dolce": "Dessert",
|
||||||
|
"libero": "Free"
|
||||||
|
},
|
||||||
|
"meal_sub": {
|
||||||
|
"dolce_torta": "Cake",
|
||||||
|
"dolce_crema": "Cream / Pudding",
|
||||||
|
"dolce_crumble": "Crumble / Tart",
|
||||||
|
"dolce_biscotti": "Cookies / Pastries",
|
||||||
|
"dolce_frutta": "Fruit Dessert",
|
||||||
|
"succo_dolce": "Sweet / Fruity",
|
||||||
|
"succo_energizzante": "Energizing",
|
||||||
|
"succo_detox": "Detox / Green",
|
||||||
|
"succo_rinfrescante": "Refreshing",
|
||||||
|
"succo_vitaminico": "Vitamin / Citrus"
|
||||||
|
},
|
||||||
|
"meal_plan": {
|
||||||
|
"reset_success": "Weekly plan reset",
|
||||||
|
"suggested_by": "suggested by weekly plan"
|
||||||
|
},
|
||||||
|
"kiosk_session": {
|
||||||
|
"first_item": "First item: {name}!",
|
||||||
|
"items_two_four": "{n} items — warming up 🚀",
|
||||||
|
"items_five_nine": "{n} items — great pace! 💪",
|
||||||
|
"items_ten_twenty": "{n} items — almost a record 🏆",
|
||||||
|
"items_twenty_plus": "{n} items — epic shopping! 🛒🔥",
|
||||||
|
"duplicates_one": "1 duplicate (same thing twice)",
|
||||||
|
"duplicates_many": "{n} duplicates (picked multiple times)",
|
||||||
|
"top_category": "Top category: {cat} ({count}×)",
|
||||||
|
"items_fallback": "{n} item{plural} added"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+70
-6
@@ -272,7 +272,8 @@
|
|||||||
},
|
},
|
||||||
"recipes": {
|
"recipes": {
|
||||||
"title": "🍳 Ricette",
|
"title": "🍳 Ricette",
|
||||||
"generate": "✨ Genera nuova ricetta"
|
"generate": "✨ Genera nuova ricetta",
|
||||||
|
"archive_empty": "Nessuna ricetta salvata. Genera la tua prima ricetta!"
|
||||||
},
|
},
|
||||||
"shopping": {
|
"shopping": {
|
||||||
"title": "🛒 Lista della Spesa",
|
"title": "🛒 Lista della Spesa",
|
||||||
@@ -326,7 +327,13 @@
|
|||||||
"smart_already_predicted": "📊 La spesa intelligente prevede già <strong>{name}</strong>{urgency}.",
|
"smart_already_predicted": "📊 La spesa intelligente prevede già <strong>{name}</strong>{urgency}.",
|
||||||
"item_removed": "✅ {name} rimosso dalla lista!",
|
"item_removed": "✅ {name} rimosso dalla lista!",
|
||||||
"urgency_spec_critical": "⚡ Urgente",
|
"urgency_spec_critical": "⚡ Urgente",
|
||||||
"urgency_spec_high": "🟠 Presto"
|
"urgency_spec_high": "🟠 Presto",
|
||||||
|
"bring_add_n": "Aggiungi {n} a Bring!",
|
||||||
|
"bring_add_selected": "Aggiungi selezionati a Bring!",
|
||||||
|
"bring_adding": "Aggiunta in corso...",
|
||||||
|
"bring_added_one": "1 prodotto aggiunto a Bring!",
|
||||||
|
"bring_added_many": "{n} prodotti aggiunti a Bring!",
|
||||||
|
"bring_skipped": "({n} già in lista)"
|
||||||
},
|
},
|
||||||
"ai": {
|
"ai": {
|
||||||
"title": "🤖 Identificazione AI",
|
"title": "🤖 Identificazione AI",
|
||||||
@@ -386,7 +393,8 @@
|
|||||||
"ingredient_deduct_title": "Scala dalla dispensa",
|
"ingredient_deduct_title": "Scala dalla dispensa",
|
||||||
"timer_expired_tts": "Timer {label} scaduto!",
|
"timer_expired_tts": "Timer {label} scaduto!",
|
||||||
"timer_warning_tts": "Attenzione! {label}: mancano 10 secondi!",
|
"timer_warning_tts": "Attenzione! {label}: mancano 10 secondi!",
|
||||||
"recipe_done_tts": "Ricetta completata! Buon appetito!"
|
"recipe_done_tts": "Ricetta completata! Buon appetito!",
|
||||||
|
"expires_chip": "scade {date}"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"title": "⚙️ Configurazione",
|
"title": "⚙️ Configurazione",
|
||||||
@@ -610,7 +618,8 @@
|
|||||||
"not_in_inventory": "Prodotto non nell'inventario",
|
"not_in_inventory": "Prodotto non nell'inventario",
|
||||||
"appliance_exists": "Elettrodomestico già presente",
|
"appliance_exists": "Elettrodomestico già presente",
|
||||||
"already_exists": "Già presente",
|
"already_exists": "Già presente",
|
||||||
"network_retry": "Errore di connessione. Riprova."
|
"network_retry": "Errore di connessione. Riprova.",
|
||||||
|
"select_items": "Seleziona almeno un prodotto"
|
||||||
},
|
},
|
||||||
"confirm": {
|
"confirm": {
|
||||||
"remove_item": "Vuoi davvero rimuovere questo prodotto dall'inventario?",
|
"remove_item": "Vuoi davvero rimuovere questo prodotto dall'inventario?",
|
||||||
@@ -632,11 +641,22 @@
|
|||||||
"thu": "Giovedì",
|
"thu": "Giovedì",
|
||||||
"fri": "Venerdì",
|
"fri": "Venerdì",
|
||||||
"sat": "Sabato",
|
"sat": "Sabato",
|
||||||
"sun": "Domenica"
|
"sun": "Domenica",
|
||||||
|
"mon_short": "Lun",
|
||||||
|
"tue_short": "Mar",
|
||||||
|
"wed_short": "Mer",
|
||||||
|
"thu_short": "Gio",
|
||||||
|
"fri_short": "Ven",
|
||||||
|
"sat_short": "Sab",
|
||||||
|
"sun_short": "Dom"
|
||||||
},
|
},
|
||||||
"meal_types": {
|
"meal_types": {
|
||||||
"lunch": "Pranzo",
|
"lunch": "Pranzo",
|
||||||
"dinner": "Cena"
|
"dinner": "Cena",
|
||||||
|
"colazione": "Colazione",
|
||||||
|
"merenda": "Merenda",
|
||||||
|
"dolce": "Dolce",
|
||||||
|
"succo": "Succo di Frutta"
|
||||||
},
|
},
|
||||||
"scale": {
|
"scale": {
|
||||||
"status_connected": "Bilancia connessa",
|
"status_connected": "Bilancia connessa",
|
||||||
@@ -709,5 +729,49 @@
|
|||||||
"2": "Ingrediente culinario",
|
"2": "Ingrediente culinario",
|
||||||
"3": "Trasformato",
|
"3": "Trasformato",
|
||||||
"4": "Ultra-trasformato"
|
"4": "Ultra-trasformato"
|
||||||
|
},
|
||||||
|
"meal_plan_types": {
|
||||||
|
"pasta": "Pasta",
|
||||||
|
"riso": "Riso",
|
||||||
|
"carne": "Carne",
|
||||||
|
"pesce": "Pesce",
|
||||||
|
"legumi": "Legumi",
|
||||||
|
"uova": "Uova",
|
||||||
|
"formaggio": "Formaggio",
|
||||||
|
"pizza": "Pizza",
|
||||||
|
"affettati": "Affettati",
|
||||||
|
"verdure": "Verdure",
|
||||||
|
"zuppa": "Zuppa",
|
||||||
|
"insalata": "Insalata",
|
||||||
|
"pane": "Pane/Sandwich",
|
||||||
|
"dolce": "Dolce",
|
||||||
|
"libero": "Libero"
|
||||||
|
},
|
||||||
|
"meal_sub": {
|
||||||
|
"dolce_torta": "Torta",
|
||||||
|
"dolce_crema": "Crema / Budino",
|
||||||
|
"dolce_crumble": "Crumble / Crostata",
|
||||||
|
"dolce_biscotti": "Biscotti / Pasticcini",
|
||||||
|
"dolce_frutta": "Dolce alla Frutta",
|
||||||
|
"succo_dolce": "Dolce / Fruttato",
|
||||||
|
"succo_energizzante": "Energizzante",
|
||||||
|
"succo_detox": "Detox / Verde",
|
||||||
|
"succo_rinfrescante": "Rinfrescante",
|
||||||
|
"succo_vitaminico": "Vitaminico / Agrumi"
|
||||||
|
},
|
||||||
|
"meal_plan": {
|
||||||
|
"reset_success": "Piano settimanale ripristinato",
|
||||||
|
"suggested_by": "suggerito dal piano settimanale"
|
||||||
|
},
|
||||||
|
"kiosk_session": {
|
||||||
|
"first_item": "Primo prodotto: {name}!",
|
||||||
|
"items_two_four": "{n} prodotti — stai scaldando i motori 🚀",
|
||||||
|
"items_five_nine": "{n} prodotti — ottimo ritmo! 💪",
|
||||||
|
"items_ten_twenty": "{n} prodotti — quasi un recordman 🏆",
|
||||||
|
"items_twenty_plus": "{n} prodotti — spesa epica! 🛒🔥",
|
||||||
|
"duplicates_one": "1 bis (stessa cosa due volte)",
|
||||||
|
"duplicates_many": "{n} bis (roba presa più volte)",
|
||||||
|
"top_category": "Categoria top: {cat} ({count}×)",
|
||||||
|
"items_fallback": "{n} prodott{n} aggiunti"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user