feat: banner opened items show 'aperto da X giorni in frigo' instead of 'scaduto'
When inventory item has opened_at set, the expired banner now shows: - Title: '[Nome] — Aperto da troppo tempo!' (instead of '— Scaduto!') - Detail: 'Aperto da N giorni in [icon] [location] · hai ancora X' Also removed hardcoded Italian 'scade il' string from non-opened expired detail.
This commit is contained in:
+43
-13
@@ -3746,10 +3746,32 @@ function renderBannerItem() {
|
||||
if (entry.type === 'expired') {
|
||||
const item = entry.data;
|
||||
const qtyDisplay = formatQuantity(item.quantity, item.unit, item.default_quantity, item.package_unit);
|
||||
const daysText = item.days_expired === 0
|
||||
? t('expiry.expired_today_long')
|
||||
: t('expiry.expired_ago_long').replace('{n}', item.days_expired);
|
||||
const isOpenedExpiry = !!item.opened_at;
|
||||
const safety = getExpiredSafety(item, item.days_expired);
|
||||
|
||||
let daysText, suffix;
|
||||
if (isOpenedExpiry) {
|
||||
const todayMs = new Date(); todayMs.setHours(0, 0, 0, 0);
|
||||
const daysSinceOpened = Math.round((todayMs - new Date(item.opened_at)) / 86400000);
|
||||
daysText = daysSinceOpened === 0
|
||||
? t('expiry.opened_today_long')
|
||||
: t('expiry.opened_ago_long').replace('{n}', daysSinceOpened);
|
||||
suffix = safety.level === 'ok'
|
||||
? t('expiry.opened_suffix_ok')
|
||||
: safety.level === 'warning'
|
||||
? t('expiry.opened_suffix_warning')
|
||||
: t('expiry.opened_suffix');
|
||||
} else {
|
||||
daysText = item.days_expired === 0
|
||||
? t('expiry.expired_today_long')
|
||||
: t('expiry.expired_ago_long').replace('{n}', item.days_expired);
|
||||
suffix = safety.level === 'ok'
|
||||
? t('expiry.expired_suffix_ok')
|
||||
: safety.level === 'warning'
|
||||
? t('expiry.expired_suffix_warning')
|
||||
: t('expiry.expired_suffix');
|
||||
}
|
||||
|
||||
if (safety.level === 'danger') {
|
||||
banner.className = 'alert-banner banner-expired banner-expired-danger';
|
||||
iconEl.textContent = '🚫';
|
||||
@@ -3760,16 +3782,24 @@ function renderBannerItem() {
|
||||
banner.className = 'alert-banner banner-expired banner-expired-ok';
|
||||
iconEl.textContent = '✅';
|
||||
}
|
||||
const expiredSuffix = safety.level === 'ok'
|
||||
? t('expiry.expired_suffix_ok')
|
||||
: safety.level === 'warning'
|
||||
? t('expiry.expired_suffix_warning')
|
||||
: t('expiry.expired_suffix');
|
||||
titleEl.textContent = `${item.name}${item.brand ? ' (' + item.brand + ')' : ''} ${expiredSuffix}`;
|
||||
const baseDetail = t('dashboard.banner_expired_detail').replace('{when}', daysText).replace('{qty}', qtyDisplay);
|
||||
const locationTag = item.location ? ` · <strong>${escapeHtml(item.location)}</strong>` : '';
|
||||
const expiryTag = item.expiry_date ? ` · scade il <strong>${escapeHtml(item.expiry_date)}</strong>` : '';
|
||||
detailEl.innerHTML = `${baseDetail}${locationTag}${expiryTag} <span class="banner-safety-tip banner-safety-${safety.level}">${safety.icon} ${safety.tip}</span>`;
|
||||
titleEl.textContent = `${item.name}${item.brand ? ' (' + item.brand + ')' : ''} ${suffix}`;
|
||||
|
||||
let baseDetail;
|
||||
if (isOpenedExpiry) {
|
||||
const locLabel = (LOCATIONS[item.location]
|
||||
? LOCATIONS[item.location].icon + ' ' + LOCATIONS[item.location].label
|
||||
: (item.location || ''));
|
||||
baseDetail = t('dashboard.banner_opened_detail')
|
||||
.replace('{when}', daysText)
|
||||
.replace('{location}', escapeHtml(locLabel))
|
||||
.replace('{qty}', qtyDisplay);
|
||||
} else {
|
||||
baseDetail = t('dashboard.banner_expired_detail').replace('{when}', daysText).replace('{qty}', qtyDisplay);
|
||||
const locationTag = item.location ? ` · <strong>${escapeHtml(item.location)}</strong>` : '';
|
||||
const expiryTag = item.expiry_date ? ` · ${escapeHtml(item.expiry_date)}` : '';
|
||||
baseDetail += locationTag + expiryTag;
|
||||
}
|
||||
detailEl.innerHTML = `${baseDetail} <span class="banner-safety-tip banner-safety-${safety.level}">${safety.icon} ${safety.tip}</span>`;
|
||||
let btns = '';
|
||||
if (safety.level !== 'danger') {
|
||||
btns += `<button class="btn-banner btn-banner-use" onclick="bannerQuickUse()">${t('dashboard.banner_expired_action_use')}</button>`;
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@
|
||||
<title>EverShelf</title>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="icon" type="image/png" href="assets/img/logo/logo_icon.png">
|
||||
<link rel="stylesheet" href="assets/css/style.css?v=20260511e">
|
||||
<link rel="stylesheet" href="assets/css/style.css?v=20260511f">
|
||||
<!-- QuaggaJS for barcode scanning -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2@1.8.4/dist/quagga.min.js"></script>
|
||||
<!-- @xenova/transformers: ES-module bootstrap that exposes a lazy category-classifier as window._categoryPipelinePromise -->
|
||||
@@ -1469,6 +1469,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="assets/js/app.js?v=20260511e"></script>
|
||||
<script src="assets/js/app.js?v=20260511f"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
"wasted": "Weggeworfen: {n} ({pct}%)",
|
||||
"more_opened": "und {n} weitere geöffnet...",
|
||||
"banner_expired_detail": "{when} · du hast noch <strong>{qty}</strong>.",
|
||||
"banner_opened_detail": "{when} in {location} · du hast noch <strong>{qty}</strong>.",
|
||||
"banner_explain_title": "Gemini um eine Erklärung bitten",
|
||||
"banner_explain_btn": "Erklären",
|
||||
"banner_analyzing": "🤖 Analysiere…"
|
||||
@@ -693,6 +694,11 @@
|
||||
"expired_suffix": "— Abgelaufen!",
|
||||
"expired_suffix_ok": "— Abgelaufen (noch ok)",
|
||||
"expired_suffix_warning": "— Abgelaufen (erst prüfen)",
|
||||
"opened_ago_long": "Seit {n} Tagen geöffnet",
|
||||
"opened_today_long": "Heute geöffnet",
|
||||
"opened_suffix": "— Zu lange geöffnet!",
|
||||
"opened_suffix_ok": "— Geöffnet (noch ok)",
|
||||
"opened_suffix_warning": "— Geöffnet (erst prüfen)",
|
||||
"days_compact": "{n}T"
|
||||
},
|
||||
"status": {
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
"wasted": "Wasted: {n} ({pct}%)",
|
||||
"more_opened": "and {n} more opened...",
|
||||
"banner_expired_detail": "{when} · you still have <strong>{qty}</strong>.",
|
||||
"banner_opened_detail": "{when} in {location} · you still have <strong>{qty}</strong>.",
|
||||
"banner_explain_title": "Ask Gemini for an explanation",
|
||||
"banner_explain_btn": "Explain",
|
||||
"banner_analyzing": "🤖 Analyzing…"
|
||||
@@ -693,6 +694,11 @@
|
||||
"expired_suffix": "— Expired!",
|
||||
"expired_suffix_ok": "— Expired (still ok)",
|
||||
"expired_suffix_warning": "— Expired (check first)",
|
||||
"opened_ago_long": "Opened {n} days ago",
|
||||
"opened_today_long": "Opened today",
|
||||
"opened_suffix": "— Opened too long!",
|
||||
"opened_suffix_ok": "— Opened (still ok)",
|
||||
"opened_suffix_warning": "— Opened (check first)",
|
||||
"days_compact": "{n}d"
|
||||
},
|
||||
"status": {
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
"wasted": "Buttati: {n} ({pct}%)",
|
||||
"more_opened": "e altri {n} prodotti aperti...",
|
||||
"banner_expired_detail": "{when} · hai ancora <strong>{qty}</strong>.",
|
||||
"banner_opened_detail": "{when} in {location} · hai ancora <strong>{qty}</strong>.",
|
||||
"banner_explain_title": "Chiedi a Gemini una spiegazione",
|
||||
"banner_explain_btn": "Spiega",
|
||||
"banner_analyzing": "🤖 Analizzo…"
|
||||
@@ -693,6 +694,11 @@
|
||||
"expired_suffix": "— Scaduto!",
|
||||
"expired_suffix_ok": "— Scaduto (ancora ok)",
|
||||
"expired_suffix_warning": "— Scaduto (controlla)",
|
||||
"opened_ago_long": "Aperto da {n} giorni",
|
||||
"opened_today_long": "Aperto oggi",
|
||||
"opened_suffix": "— Aperto da troppo tempo!",
|
||||
"opened_suffix_ok": "— Aperto (ancora ok)",
|
||||
"opened_suffix_warning": "— Aperto (controlla)",
|
||||
"days_compact": "{n}gg"
|
||||
},
|
||||
"status": {
|
||||
|
||||
Reference in New Issue
Block a user