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 = {
|
||||
'dispensa': { icon: '🗄️', label: 'Dispensa' },
|
||||
'frigo': { icon: '🧊', label: 'Frigo' },
|
||||
'freezer': { icon: '❄️', label: 'Freezer' },
|
||||
'altro': { icon: '📦', label: 'Altro' },
|
||||
'dispensa': { icon: '🗄️', label: t('locations.dispensa') },
|
||||
'frigo': { icon: '🧊', label: t('locations.frigo') },
|
||||
'freezer': { icon: '❄️', label: t('locations.freezer') },
|
||||
'altro': { icon: '📦', label: t('locations.altro') },
|
||||
};
|
||||
const CATEGORY_ICONS = {
|
||||
'latticini': '🥛', 'carne': '🥩', 'pesce': '🐟', 'frutta': '🍎',
|
||||
@@ -982,16 +982,16 @@ const CATEGORY_LOCATION = {
|
||||
|
||||
// Shopping section (reparto) map — groups categories into grocery departments
|
||||
const SHOPPING_SECTIONS = [
|
||||
{ key: 'frutta_verdura', icon: '🥬', label: 'Frutta & Verdura', cats: new Set(['frutta','verdura']) },
|
||||
{ key: 'carne_pesce', icon: '🥩', label: 'Carne & Pesce', cats: new Set(['carne','pesce']) },
|
||||
{ key: 'latticini', icon: '🥛', label: 'Latticini & Fresco', cats: new Set(['latticini']) },
|
||||
{ key: 'pane_dolci', icon: '🍞', label: 'Pane & Dolci', cats: new Set(['pane','snack','cereali']) },
|
||||
{ key: 'pasta', icon: '🍝', label: 'Pasta & Cereali', cats: new Set(['pasta']) },
|
||||
{ key: 'conserve', icon: '🥫', label: 'Conserve & Salse', cats: new Set(['conserve','condimenti']) },
|
||||
{ key: 'surgelati', icon: '❄️', label: 'Surgelati', cats: new Set(['surgelati']) },
|
||||
{ key: 'bevande', icon: '🥤', label: 'Bevande', cats: new Set(['bevande']) },
|
||||
{ key: 'pulizia_igiene', icon: '🧴', label: 'Pulizia & Igiene', cats: new Set(['igiene','pulizia']) },
|
||||
{ key: 'altro', icon: '📦', label: 'Altro', cats: new Set(['altro']) },
|
||||
{ key: 'frutta_verdura', icon: '🥬', label: t('shopping_sections.frutta_verdura'), cats: new Set(['frutta','verdura']) },
|
||||
{ key: 'carne_pesce', icon: '🥩', label: t('shopping_sections.carne_pesce'), cats: new Set(['carne','pesce']) },
|
||||
{ key: 'latticini', icon: '🥛', label: t('shopping_sections.latticini'), cats: new Set(['latticini']) },
|
||||
{ key: 'pane_dolci', icon: '🍞', label: t('shopping_sections.pane_dolci'), cats: new Set(['pane','snack','cereali']) },
|
||||
{ key: 'pasta', icon: '🍝', label: t('shopping_sections.pasta'), cats: new Set(['pasta']) },
|
||||
{ key: 'conserve', icon: '🥫', label: t('shopping_sections.conserve'), cats: new Set(['conserve','condimenti']) },
|
||||
{ key: 'surgelati', icon: '❄️', label: t('shopping_sections.surgelati'), cats: new Set(['surgelati']) },
|
||||
{ key: 'bevande', icon: '🥤', label: t('shopping_sections.bevande'), cats: new Set(['bevande']) },
|
||||
{ key: 'pulizia_igiene', icon: '🧴', label: t('shopping_sections.pulizia_igiene'), cats: new Set(['igiene','pulizia']) },
|
||||
{ key: 'altro', icon: '📦', label: t('shopping_sections.altro'), cats: new Set(['altro']) },
|
||||
];
|
||||
|
||||
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') };
|
||||
}
|
||||
|
||||
// Nice Italian labels for local categories
|
||||
// Localized labels for local categories
|
||||
const CATEGORY_LABELS = {
|
||||
'latticini': '🥛 Latticini', 'carne': '🥩 Carne', 'pesce': '🐟 Pesce',
|
||||
'frutta': '🍎 Frutta', 'verdura': '🥬 Verdura', 'pasta': '🍝 Pasta & Riso',
|
||||
'pane': '🍞 Pane & Forno', 'surgelati': '🧊 Surgelati', 'bevande': '🥤 Bevande',
|
||||
'condimenti': '🧂 Condimenti', 'snack': '🍪 Snack & Dolci', 'conserve': '🥫 Conserve',
|
||||
'cereali': '🌾 Cereali & Legumi', 'igiene': '🧴 Igiene', 'pulizia': '🧹 Pulizia',
|
||||
'altro': '📦 Altro'
|
||||
'latticini': `🥛 ${t('categories.latticini')}`, 'carne': `🥩 ${t('categories.carne')}`, 'pesce': `🐟 ${t('categories.pesce')}`,
|
||||
'frutta': `🍎 ${t('categories.frutta')}`, 'verdura': `🥬 ${t('categories.verdura')}`, 'pasta': `🍝 ${t('categories.pasta')}`,
|
||||
'pane': `🍞 ${t('categories.pane')}`, 'surgelati': `🧊 ${t('categories.surgelati')}`, 'bevande': `🥤 ${t('categories.bevande')}`,
|
||||
'condimenti': `🧂 ${t('categories.condimenti')}`, 'snack': `🍪 ${t('categories.snack')}`, 'conserve': `🥫 ${t('categories.conserve')}`,
|
||||
'cereali': `🌾 ${t('categories.cereali')}`, 'igiene': `🧴 ${t('categories.igiene')}`, 'pulizia': `🧹 ${t('categories.pulizia')}`,
|
||||
'altro': `📦 ${t('categories.altro')}`
|
||||
};
|
||||
|
||||
// Detect best unit/quantity from Open Food Facts quantity_info string
|
||||
@@ -1946,17 +1946,17 @@ async function saveSettings() {
|
||||
const statusEl = document.getElementById('settings-status');
|
||||
if (result.success) {
|
||||
statusEl.className = 'settings-status success';
|
||||
statusEl.textContent = '✅ Configurazione salvata!';
|
||||
statusEl.textContent = `✅ ${t('settings.saved')}`;
|
||||
} else {
|
||||
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';
|
||||
setTimeout(() => statusEl.style.display = 'none', 4000);
|
||||
} catch(e) {
|
||||
const statusEl = document.getElementById('settings-status');
|
||||
statusEl.className = 'settings-status success';
|
||||
statusEl.textContent = '✅ Configurazione salvata localmente';
|
||||
statusEl.textContent = `✅ ${t('settings.saved_local')}`;
|
||||
statusEl.style.display = 'block';
|
||||
setTimeout(() => statusEl.style.display = 'none', 4000);
|
||||
}
|
||||
@@ -4653,7 +4653,7 @@ function editProductFromAction() {
|
||||
document.getElementById('pf-notes').value = currentProduct.notes || '';
|
||||
document.getElementById('pf-unit').value = currentProduct.unit || 'pz';
|
||||
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');
|
||||
if (pfAiRow) pfAiRow.style.display = 'none';
|
||||
// Keep barcode hint hidden in edit mode
|
||||
@@ -7484,7 +7484,7 @@ async function migrateBringNames(btn) {
|
||||
async function addSmartToBring() {
|
||||
const checks = document.querySelectorAll('.smart-check:checked');
|
||||
if (checks.length === 0) {
|
||||
showToast('Seleziona almeno un prodotto', 'info');
|
||||
showToast(t('error.select_items'), 'info');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8156,21 +8156,23 @@ function updateSuggestionActionBtn() {
|
||||
const selected = suggestionItems.filter(s => s.selected);
|
||||
const btn = document.querySelector('#suggestion-actions .btn-success');
|
||||
if (btn) {
|
||||
btn.textContent = `✅ Aggiungi ${selected.length} prodott${selected.length === 1 ? 'o' : 'i'} a Bring!`;
|
||||
btn.disabled = selected.length === 0;
|
||||
const nItems = selected.length;
|
||||
const prodStr = nItems === 1 ? 'prodotto' : 'prodotti';
|
||||
btn.textContent = `✅ ${t('shopping.bring_add_n').replace('{n}', nItems + ' ' + prodStr)}!`;
|
||||
btn.disabled = nItems === 0;
|
||||
}
|
||||
}
|
||||
|
||||
async function addSelectedSuggestions() {
|
||||
const selected = suggestionItems.filter(s => s.selected);
|
||||
if (selected.length === 0) {
|
||||
showToast('Seleziona almeno un prodotto', 'error');
|
||||
showToast(t('error.select_items'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const btn = document.querySelector('#suggestion-actions .btn-success');
|
||||
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 {
|
||||
const items = selected.map(s => {
|
||||
@@ -8180,8 +8182,8 @@ async function addSelectedSuggestions() {
|
||||
const data = await api('bring_add', {}, 'POST', { items, listUUID: shoppingListUUID });
|
||||
|
||||
if (data.success) {
|
||||
let msg = `${data.added} prodott${data.added === 1 ? 'o aggiunto' : 'i aggiunti'} a Bring!`;
|
||||
if (data.skipped > 0) msg += ` (${data.skipped} già in lista)`;
|
||||
let msg = data.added === 1 ? t('shopping.bring_added_one') : t('shopping.bring_added_many').replace('{n}', data.added);
|
||||
if (data.skipped > 0) msg += ` ${t('shopping.bring_skipped').replace('{n}', data.skipped)}`;
|
||||
showToast(msg, 'success');
|
||||
// Refresh list
|
||||
await loadShoppingList();
|
||||
@@ -8198,7 +8200,7 @@ async function addSelectedSuggestions() {
|
||||
}
|
||||
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '✅ Aggiungi selezionati a Bring!';
|
||||
btn.innerHTML = `✅ ${t('shopping.bring_add_selected')}`;
|
||||
}
|
||||
|
||||
// ===== UTILITY FUNCTIONS =====
|
||||
@@ -8515,28 +8517,28 @@ async function undoTransactionEntry(id, type, name) {
|
||||
* id must be URL-safe; icon + label shown in UI.
|
||||
*/
|
||||
const MEAL_PLAN_TYPES = [
|
||||
{ id: 'pasta', icon: '🍝', label: 'Pasta' },
|
||||
{ id: 'riso', icon: '🍚', label: 'Riso' },
|
||||
{ id: 'carne', icon: '🥩', label: 'Carne' },
|
||||
{ id: 'pesce', icon: '🐟', label: 'Pesce' },
|
||||
{ id: 'legumi', icon: '🫘', label: 'Legumi' },
|
||||
{ id: 'uova', icon: '🥚', label: 'Uova' },
|
||||
{ id: 'formaggio', icon: '🧀', label: 'Formaggio' },
|
||||
{ id: 'pizza', icon: '🍕', label: 'Pizza' },
|
||||
{ id: 'affettati', icon: '🥓', label: 'Affettati' },
|
||||
{ id: 'verdure', icon: '🥦', label: 'Verdure' },
|
||||
{ id: 'zuppa', icon: '🍲', label: 'Zuppa' },
|
||||
{ id: 'insalata', icon: '🥗', label: 'Insalata' },
|
||||
{ id: 'pane', icon: '🥪', label: 'Pane/Sandwich' },
|
||||
{ id: 'dolce', icon: '🍰', label: 'Dolce' },
|
||||
{ id: 'libero', icon: '🎲', label: 'Libero' },
|
||||
{ id: 'pasta', icon: '🍝', label: t('meal_plan_types.pasta') },
|
||||
{ id: 'riso', icon: '🍚', label: t('meal_plan_types.riso') },
|
||||
{ id: 'carne', icon: '🥩', label: t('meal_plan_types.carne') },
|
||||
{ id: 'pesce', icon: '🐟', label: t('meal_plan_types.pesce') },
|
||||
{ id: 'legumi', icon: '🫘', label: t('meal_plan_types.legumi') },
|
||||
{ id: 'uova', icon: '🥚', label: t('meal_plan_types.uova') },
|
||||
{ id: 'formaggio', icon: '🧀', label: t('meal_plan_types.formaggio') },
|
||||
{ id: 'pizza', icon: '🍕', label: t('meal_plan_types.pizza') },
|
||||
{ id: 'affettati', icon: '🥓', label: t('meal_plan_types.affettati') },
|
||||
{ id: 'verdure', icon: '🥦', label: t('meal_plan_types.verdure') },
|
||||
{ id: 'zuppa', icon: '🍲', label: t('meal_plan_types.zuppa') },
|
||||
{ id: 'insalata', icon: '🥗', label: t('meal_plan_types.insalata') },
|
||||
{ id: 'pane', icon: '🥪', label: t('meal_plan_types.pane') },
|
||||
{ id: 'dolce', icon: '🍰', label: t('meal_plan_types.dolce') },
|
||||
{ id: 'libero', icon: '🎲', label: t('meal_plan_types.libero') },
|
||||
];
|
||||
|
||||
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_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. */
|
||||
const DEFAULT_MEAL_PLAN = {
|
||||
@@ -8590,8 +8592,8 @@ function renderMealPlanEditor() {
|
||||
const today = new Date().getDay();
|
||||
|
||||
const header = `<div class="mplan-header">
|
||||
<span class="mplan-col-header">🌤️ Pranzo</span>
|
||||
<span class="mplan-col-header">🌙 Cena</span>
|
||||
<span class="mplan-col-header">🌤️ ${t('meal_types.pranzo')}</span>
|
||||
<span class="mplan-col-header">🌙 ${t('meal_types.cena')}</span>
|
||||
</div>`;
|
||||
|
||||
const rows = dayOrder.map((dow, i) => {
|
||||
@@ -8660,33 +8662,33 @@ function resetMealPlan() {
|
||||
s.meal_plan = JSON.parse(JSON.stringify(DEFAULT_MEAL_PLAN));
|
||||
saveSettingsToStorage(s);
|
||||
renderMealPlanEditor();
|
||||
showToast('Piano settimanale ripristinato', 'success');
|
||||
showToast(t('meal_plan.reset_success'), 'success');
|
||||
}
|
||||
|
||||
// ===== RECIPE GENERATION =====
|
||||
const MEAL_TYPES = [
|
||||
{ id: 'colazione', icon: '☀️', label: 'Colazione', from: 6, to: 11 },
|
||||
{ id: 'pranzo', icon: '🍽️', label: 'Pranzo', from: 11, to: 14 },
|
||||
{ id: 'merenda', icon: '🍪', label: 'Merenda', from: 14, to: 17 },
|
||||
{ id: 'cena', icon: '🌙', label: 'Cena', from: 17, to: 6 },
|
||||
{ id: 'dolce', icon: '🍰', label: 'Dolce', from: -1, to: -1 },
|
||||
{ id: 'succo', icon: '🧃', label: 'Succo di Frutta', from: -1, to: -1 },
|
||||
{ id: 'colazione', icon: '☀️', label: t('meal_types.colazione'), from: 6, to: 11 },
|
||||
{ id: 'pranzo', icon: '🍽️', label: t('meal_types.pranzo'), from: 11, to: 14 },
|
||||
{ id: 'merenda', icon: '🍪', label: t('meal_types.merenda'), from: 14, to: 17 },
|
||||
{ id: 'cena', icon: '🌙', label: t('meal_types.cena'), from: 17, to: 6 },
|
||||
{ id: 'dolce', icon: '🍰', label: t('meal_types.dolce'), from: -1, to: -1 },
|
||||
{ id: 'succo', icon: '🧃', label: t('meal_types.succo'), from: -1, to: -1 },
|
||||
];
|
||||
|
||||
const MEAL_SUB_TYPES = {
|
||||
dolce: [
|
||||
{ id: 'torta', icon: '🎂', label: 'Torta' },
|
||||
{ id: 'crema', icon: '🍮', label: 'Crema / Budino' },
|
||||
{ id: 'crumble', icon: '🥧', label: 'Crumble / Crostata' },
|
||||
{ id: 'biscotti', icon: '🍪', label: 'Biscotti / Pasticcini' },
|
||||
{ id: 'frutta', icon: '🍓', label: 'Dolce alla Frutta' },
|
||||
{ id: 'torta', icon: '🎂', label: t('meal_sub.dolce_torta') },
|
||||
{ id: 'crema', icon: '🍮', label: t('meal_sub.dolce_crema') },
|
||||
{ id: 'crumble', icon: '🥧', label: t('meal_sub.dolce_crumble') },
|
||||
{ id: 'biscotti', icon: '🍪', label: t('meal_sub.dolce_biscotti') },
|
||||
{ id: 'frutta', icon: '🍓', label: t('meal_sub.dolce_frutta') },
|
||||
],
|
||||
succo: [
|
||||
{ id: 'dolce', icon: '🍑', label: 'Dolce / Fruttato' },
|
||||
{ id: 'energizzante', icon: '⚡', label: 'Energizzante' },
|
||||
{ id: 'detox', icon: '🥬', label: 'Detox / Verde' },
|
||||
{ id: 'rinfrescante', icon: '🧊', label: 'Rinfrescante' },
|
||||
{ id: 'vitaminico', icon: '🍊', label: 'Vitaminico / Agrumi' },
|
||||
{ id: 'dolce', icon: '🍑', label: t('meal_sub.succo_dolce') },
|
||||
{ id: 'energizzante', icon: '⚡', label: t('meal_sub.succo_energizzante') },
|
||||
{ id: 'detox', icon: '🥬', label: t('meal_sub.succo_detox') },
|
||||
{ id: 'rinfrescante', icon: '🧊', label: t('meal_sub.succo_rinfrescante') },
|
||||
{ id: 'vitaminico', icon: '🍊', label: t('meal_sub.succo_vitaminico') },
|
||||
]
|
||||
};
|
||||
|
||||
@@ -8749,7 +8751,7 @@ async function loadRecipeArchive() {
|
||||
_recipeArchiveEntries = archive;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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} ✅`;
|
||||
// Detail line: location + expiry
|
||||
let details = [];
|
||||
const locLabels = { 'frigo': '🧊 Frigo', 'freezer': '🧊 Freezer', 'dispensa': '🗄️ Dispensa' };
|
||||
details.push(locLabels[ing.location] || ('📍 ' + ing.location));
|
||||
const ingredientLocLabels = Object.fromEntries(Object.entries(LOCATIONS).map(([k,v]) => [k, `${v.icon} ${v.label}`]));
|
||||
details.push(ingredientLocLabels[ing.location] || ('📍 ' + ing.location));
|
||||
if (ing.expiry_date) {
|
||||
const exp = new Date(ing.expiry_date);
|
||||
const now = new Date(); now.setHours(0,0,0,0);
|
||||
@@ -9362,19 +9364,19 @@ function renderCookingStep() {
|
||||
|
||||
const ingsEl = document.getElementById('cooking-step-ings');
|
||||
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 => {
|
||||
const loc = (ing.location || 'dispensa').replace(/'/g, "\\'");
|
||||
const qtyNum = ing.qty_number || 0;
|
||||
// Build info chips: brand, location, expiry
|
||||
const chips = [];
|
||||
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>`);
|
||||
if (ing.expiry_date) {
|
||||
const daysLeft = Math.round((new Date(ing.expiry_date) - new Date()) / 86400000);
|
||||
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">
|
||||
<div style="flex:1;min-width:0">
|
||||
@@ -9942,26 +9944,26 @@ function _renderMealPlanHint(mealSlot) {
|
||||
if (chipWrap) chipWrap.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
const t = MEAL_PLAN_TYPE_MAP[typeId];
|
||||
if (!t) {
|
||||
const mpt = MEAL_PLAN_TYPE_MAP[typeId];
|
||||
if (!mpt) {
|
||||
if (el) el.style.display = 'none';
|
||||
if (banner) banner.style.display = 'none';
|
||||
if (chipWrap) chipWrap.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
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';
|
||||
}
|
||||
if (banner) {
|
||||
const slotLabel = mealSlot === 'pranzo' ? '🌤️ Pranzo' : '🌙 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>`;
|
||||
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>${mpt.icon} ${mpt.label}</span>`;
|
||||
banner.style.display = 'flex';
|
||||
}
|
||||
// Show the meal-plan chip (active by default, user can uncheck to ignore the plan)
|
||||
if (chipWrap) {
|
||||
chipWrap.style.display = '';
|
||||
if (chipLabel) chipLabel.textContent = `${t.icon} ${t.label}`;
|
||||
if (chipLabel) chipLabel.textContent = `${mpt.icon} ${mpt.label}`;
|
||||
if (chipCb) chipCb.checked = true;
|
||||
}
|
||||
}
|
||||
@@ -10346,10 +10348,10 @@ function updateScreensaverMealPlan() {
|
||||
const slot = hour < 15 ? 'pranzo' : 'cena';
|
||||
const typeId = getTodayMealPlanType(slot);
|
||||
if (!typeId || typeId === 'libero') { el.style.display = 'none'; return; }
|
||||
const t = MEAL_PLAN_TYPE_MAP[typeId];
|
||||
if (!t) { el.style.display = 'none'; return; }
|
||||
const slotLabel = slot === 'pranzo' ? '🌤️ Pranzo' : '🌙 Cena';
|
||||
el.innerHTML = `<span class="screensaver-mealplan-badge">${slotLabel} · ${t.icon} ${t.label}</span>`;
|
||||
const mpt = MEAL_PLAN_TYPE_MAP[typeId];
|
||||
if (!mpt) { el.style.display = 'none'; return; }
|
||||
const slotLabel = slot === 'pranzo' ? '🌤️ ' + t('meal_types.pranzo') : '🌙 ' + t('meal_types.cena');
|
||||
el.innerHTML = `<span class="screensaver-mealplan-badge">${slotLabel} · ${mpt.icon} ${mpt.label}</span>`;
|
||||
el.style.display = 'block';
|
||||
}
|
||||
|
||||
@@ -10814,15 +10816,15 @@ function _spesaBannerStat() {
|
||||
const unique = [...new Set(names)];
|
||||
const dupes = names.length - unique.length;
|
||||
const phrases = [
|
||||
n === 1 ? `Primo prodotto: ${_spesaSession[0].name}!` : null,
|
||||
n >= 2 && n < 5 ? `${n} prodotti — stai scaldando i motori 🚀` : null,
|
||||
n >= 5 && n < 10 ? `${n} prodotti — ottimo ritmo! 💪` : null,
|
||||
n >= 10 && n < 20 ? `${n} prodotti — quasi un recordman 🏆` : null,
|
||||
n >= 20 ? `${n} prodotti — spesa epica! 🛒🔥` : null,
|
||||
dupes > 0 ? `${dupes} bis ${dupes===1?'(stessa cosa due volte)':'(roba presa più volte)'}` : null,
|
||||
topCat && topCat[1] > 1 ? `Categoria top: ${topCat[0]} (${topCat[1]}×)` : null,
|
||||
n === 1 ? t('kiosk_session.first_item').replace('{name}', _spesaSession[0].name) : null,
|
||||
n >= 2 && n < 5 ? t('kiosk_session.items_two_four').replace('{n}', n) : null,
|
||||
n >= 5 && n < 10 ? t('kiosk_session.items_five_nine').replace('{n}', n) : null,
|
||||
n >= 10 && n < 20 ? t('kiosk_session.items_ten_twenty').replace('{n}', n) : null,
|
||||
n >= 20 ? t('kiosk_session.items_twenty_plus').replace('{n}', n) : null,
|
||||
dupes > 0 ? (dupes === 1 ? t('kiosk_session.duplicates_one') : t('kiosk_session.duplicates_many').replace('{n}', dupes)) : null,
|
||||
topCat && topCat[1] > 1 ? t('kiosk_session.top_category').replace('{cat}', topCat[0]).replace('{count}', topCat[1]) : null,
|
||||
].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) {
|
||||
|
||||
@@ -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": {
|
||||
"title": "🍳 Rezepte",
|
||||
"generate": "✨ Neues Rezept generieren"
|
||||
"generate": "✨ Neues Rezept generieren",
|
||||
"archive_empty": "Keine Rezepte gespeichert. Erstelle dein erstes Rezept!"
|
||||
},
|
||||
"shopping": {
|
||||
"title": "🛒 Einkaufsliste",
|
||||
@@ -326,7 +327,13 @@
|
||||
"smart_already_predicted": "📊 Einkauf wird bereits vorhergesagt: <strong>{name}</strong>{urgency}.",
|
||||
"item_removed": "✅ {name} von der Liste entfernt!",
|
||||
"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": {
|
||||
"title": "🤖 KI-Identifikation",
|
||||
@@ -386,7 +393,8 @@
|
||||
"ingredient_deduct_title": "Von Vorrat abziehen",
|
||||
"timer_expired_tts": "Timer {label} abgelaufen!",
|
||||
"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": {
|
||||
"title": "⚙️ Einstellungen",
|
||||
@@ -610,7 +618,8 @@
|
||||
"not_in_inventory": "Produkt nicht im Bestand",
|
||||
"appliance_exists": "Gerät 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": {
|
||||
"remove_item": "Möchtest du dieses Produkt wirklich aus dem Bestand entfernen?",
|
||||
@@ -632,11 +641,22 @@
|
||||
"thu": "Donnerstag",
|
||||
"fri": "Freitag",
|
||||
"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": {
|
||||
"lunch": "Mittagessen",
|
||||
"dinner": "Abendessen"
|
||||
"dinner": "Abendessen",
|
||||
"colazione": "Frühstück",
|
||||
"merenda": "Nachmittagssnack",
|
||||
"dolce": "Dessert",
|
||||
"succo": "Fruchtsaft"
|
||||
},
|
||||
"scale": {
|
||||
"status_connected": "Waage verbunden",
|
||||
@@ -709,5 +729,49 @@
|
||||
"2": "Kulinarische Zutat",
|
||||
"3": "Verarbeitet",
|
||||
"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": {
|
||||
"title": "🍳 Recipes",
|
||||
"generate": "✨ Generate new recipe"
|
||||
"generate": "✨ Generate new recipe",
|
||||
"archive_empty": "No recipes saved. Generate your first recipe!"
|
||||
},
|
||||
"shopping": {
|
||||
"title": "🛒 Shopping List",
|
||||
@@ -326,7 +327,13 @@
|
||||
"smart_already_predicted": "📊 Smart shopping already predicts <strong>{name}</strong>{urgency}.",
|
||||
"item_removed": "✅ {name} removed from list!",
|
||||
"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": {
|
||||
"title": "🤖 AI Identification",
|
||||
@@ -386,7 +393,8 @@
|
||||
"ingredient_deduct_title": "Deduct from pantry",
|
||||
"timer_expired_tts": "Timer {label} expired!",
|
||||
"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": {
|
||||
"title": "⚙️ Settings",
|
||||
@@ -610,7 +618,8 @@
|
||||
"not_in_inventory": "Product not in inventory",
|
||||
"appliance_exists": "Appliance 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": {
|
||||
"remove_item": "Do you really want to remove this product from inventory?",
|
||||
@@ -632,11 +641,22 @@
|
||||
"thu": "Thursday",
|
||||
"fri": "Friday",
|
||||
"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": {
|
||||
"lunch": "Lunch",
|
||||
"dinner": "Dinner"
|
||||
"dinner": "Dinner",
|
||||
"colazione": "Breakfast",
|
||||
"merenda": "Snack",
|
||||
"dolce": "Dessert",
|
||||
"succo": "Fruit Juice"
|
||||
},
|
||||
"scale": {
|
||||
"status_connected": "Scale connected",
|
||||
@@ -709,5 +729,49 @@
|
||||
"2": "Culinary ingredient",
|
||||
"3": "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": {
|
||||
"title": "🍳 Ricette",
|
||||
"generate": "✨ Genera nuova ricetta"
|
||||
"generate": "✨ Genera nuova ricetta",
|
||||
"archive_empty": "Nessuna ricetta salvata. Genera la tua prima ricetta!"
|
||||
},
|
||||
"shopping": {
|
||||
"title": "🛒 Lista della Spesa",
|
||||
@@ -326,7 +327,13 @@
|
||||
"smart_already_predicted": "📊 La spesa intelligente prevede già <strong>{name}</strong>{urgency}.",
|
||||
"item_removed": "✅ {name} rimosso dalla lista!",
|
||||
"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": {
|
||||
"title": "🤖 Identificazione AI",
|
||||
@@ -386,7 +393,8 @@
|
||||
"ingredient_deduct_title": "Scala dalla dispensa",
|
||||
"timer_expired_tts": "Timer {label} scaduto!",
|
||||
"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": {
|
||||
"title": "⚙️ Configurazione",
|
||||
@@ -610,7 +618,8 @@
|
||||
"not_in_inventory": "Prodotto non nell'inventario",
|
||||
"appliance_exists": "Elettrodomestico 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": {
|
||||
"remove_item": "Vuoi davvero rimuovere questo prodotto dall'inventario?",
|
||||
@@ -632,11 +641,22 @@
|
||||
"thu": "Giovedì",
|
||||
"fri": "Venerdì",
|
||||
"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": {
|
||||
"lunch": "Pranzo",
|
||||
"dinner": "Cena"
|
||||
"dinner": "Cena",
|
||||
"colazione": "Colazione",
|
||||
"merenda": "Merenda",
|
||||
"dolce": "Dolce",
|
||||
"succo": "Succo di Frutta"
|
||||
},
|
||||
"scale": {
|
||||
"status_connected": "Bilancia connessa",
|
||||
@@ -709,5 +729,49 @@
|
||||
"2": "Ingrediente culinario",
|
||||
"3": "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