feat: show expiry + qty pills on use-page product hero card; redesign card with accent border
This commit is contained in:
+75
-4
@@ -3027,10 +3027,72 @@ body.server-offline .bottom-nav {
|
|||||||
gap: 14px;
|
gap: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-preview-small {
|
/* Use-page hero card: larger, accent border, more breathing room */
|
||||||
padding: 12px;
|
#page-use .product-preview-small {
|
||||||
|
padding: 14px 16px;
|
||||||
|
gap: 14px;
|
||||||
|
border-left: 4px solid var(--primary);
|
||||||
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.use-hero-icon {
|
||||||
|
font-size: 2.4rem;
|
||||||
|
width: 52px;
|
||||||
|
text-align: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
line-height: 1;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.use-hero-body {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.use-hero-name {
|
||||||
|
font-size: 1.05rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--text);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.use-hero-brand {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.use-hero-meta {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.use-meta-pill {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 3px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 3px 8px;
|
||||||
|
border-radius: 99px;
|
||||||
|
line-height: 1.3;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expiry pill colours */
|
||||||
|
.use-pill-ok { background: #dcfce7; color: #166534; }
|
||||||
|
.use-pill-warn { background: #fef9c3; color: #854d0e; }
|
||||||
|
.use-pill-soon { background: #fed7aa; color: #7c2d12; }
|
||||||
|
.use-pill-expired { background: #fee2e2; color: #991b1b; }
|
||||||
|
/* Quantity pill */
|
||||||
|
.use-pill-qty { background: #e0f2fe; color: #0c4a6e; }
|
||||||
|
|
||||||
.product-preview img, .product-preview-small img {
|
.product-preview img, .product-preview-small img {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
@@ -3040,8 +3102,11 @@ body.server-offline .bottom-nav {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.product-preview-small img {
|
.product-preview-small img {
|
||||||
width: 45px;
|
width: 52px;
|
||||||
height: 45px;
|
height: 52px;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
object-fit: cover;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.product-preview-emoji {
|
.product-preview-emoji {
|
||||||
@@ -7510,6 +7575,12 @@ body.cooking-mode-active .app-header {
|
|||||||
/* ── Use inventory info ── */
|
/* ── Use inventory info ── */
|
||||||
[data-theme="dark"] .use-inventory-info { background: #0c2a4e; color: #7dd3fc; }
|
[data-theme="dark"] .use-inventory-info { background: #0c2a4e; color: #7dd3fc; }
|
||||||
[data-theme="dark"] #use-expiry-hint { background: #2a1e00; border-color: #78350f; color: #fde68a; }
|
[data-theme="dark"] #use-expiry-hint { background: #2a1e00; border-color: #78350f; color: #fde68a; }
|
||||||
|
[data-theme="dark"] #page-use .product-preview-small { border-left-color: var(--primary); }
|
||||||
|
[data-theme="dark"] .use-pill-ok { background: #14532d; color: #86efac; }
|
||||||
|
[data-theme="dark"] .use-pill-warn { background: #422006; color: #fde68a; }
|
||||||
|
[data-theme="dark"] .use-pill-soon { background: #431407; color: #fdba74; }
|
||||||
|
[data-theme="dark"] .use-pill-expired { background: #450a0a; color: #fca5a5; }
|
||||||
|
[data-theme="dark"] .use-pill-qty { background: #0c2a4e; color: #7dd3fc; }
|
||||||
|
|
||||||
/* ── Recipe components ── */
|
/* ── Recipe components ── */
|
||||||
[data-theme="dark"] .recipe-expiry-note { background: #2a1e00; color: #fde68a; }
|
[data-theme="dark"] .recipe-expiry-note { background: #2a1e00; color: #fde68a; }
|
||||||
|
|||||||
+53
-7
@@ -8408,18 +8408,61 @@ function showUseForm() {
|
|||||||
|
|
||||||
function renderUsePreview() {
|
function renderUsePreview() {
|
||||||
const catIcon = CATEGORY_ICONS[mapToLocalCategory(currentProduct?.category, currentProduct?.name)] || '📦';
|
const catIcon = CATEGORY_ICONS[mapToLocalCategory(currentProduct?.category, currentProduct?.name)] || '📦';
|
||||||
|
const imgHtml = currentProduct?.image_url
|
||||||
|
? `<img src="${escapeHtml(currentProduct.image_url)}" alt="">`
|
||||||
|
: `<span class="use-hero-icon">${catIcon}</span>`;
|
||||||
document.getElementById('use-product-preview').innerHTML = `
|
document.getElementById('use-product-preview').innerHTML = `
|
||||||
${currentProduct?.image_url ?
|
${imgHtml}
|
||||||
`<img src="${escapeHtml(currentProduct.image_url)}" alt="">` :
|
<div class="use-hero-body">
|
||||||
`<span style="font-size:2rem">${catIcon}</span>`
|
<div class="use-hero-name">${escapeHtml(currentProduct?.name || '')}</div>
|
||||||
}
|
${currentProduct?.brand ? `<div class="use-hero-brand">${escapeHtml(currentProduct.brand)}</div>` : ''}
|
||||||
<div class="product-preview-info">
|
<div class="use-hero-meta" id="use-hero-meta"></div>
|
||||||
<h3>${escapeHtml(currentProduct?.name || '')}</h3>
|
|
||||||
<p>${currentProduct?.brand ? escapeHtml(currentProduct.brand) : ''}</p>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill the hero-card meta row with expiry badge + quantity pill.
|
||||||
|
* Called from loadUseInventoryInfo() once inventory data is available.
|
||||||
|
*/
|
||||||
|
function _updateUseHeroMeta(items) {
|
||||||
|
const metaEl = document.getElementById('use-hero-meta');
|
||||||
|
if (!metaEl) return;
|
||||||
|
const pills = [];
|
||||||
|
|
||||||
|
// ── Expiry badge ───────────────────────────────────────────────────
|
||||||
|
const withExpiry = items.filter(i => i.expiry_date && parseFloat(i.quantity) > 0.01);
|
||||||
|
if (withExpiry.length > 0) {
|
||||||
|
withExpiry.sort((a, b) => new Date(a.expiry_date + 'T12:00:00') - new Date(b.expiry_date + 'T12:00:00'));
|
||||||
|
const soonest = withExpiry[0];
|
||||||
|
const expDate = new Date(soonest.expiry_date + 'T12:00:00');
|
||||||
|
const today = new Date(); today.setHours(0,0,0,0);
|
||||||
|
const days = Math.round((expDate - today) / 86400000);
|
||||||
|
const locale = _currentLang === 'de' ? 'de-DE' : _currentLang === 'en' ? 'en-GB' : 'it-IT';
|
||||||
|
const dateStr = expDate.toLocaleDateString(locale, { day: '2-digit', month: '2-digit', year: '2-digit' });
|
||||||
|
|
||||||
|
let cls, label;
|
||||||
|
if (days < 0) { cls = 'use-pill-expired'; label = `${t('expiry.badge_expired_ago').replace('{n}', Math.abs(days))} (${dateStr})`; }
|
||||||
|
else if (days === 0){ cls = 'use-pill-soon'; label = t('expiry.badge_today'); }
|
||||||
|
else if (days <= 3) { cls = 'use-pill-soon'; label = `${t('expiry.badge_expiring_short').replace('{n}', days)} (${dateStr})`; }
|
||||||
|
else if (days <= 7) { cls = 'use-pill-warn'; label = `${t('expiry.badge_expiring_short').replace('{n}', days)} (${dateStr})`; }
|
||||||
|
else { cls = 'use-pill-ok'; label = `📅 ${dateStr}`; }
|
||||||
|
pills.push(`<span class="use-meta-pill ${cls}">${label}</span>`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Quantity + location count pill ────────────────────────────────
|
||||||
|
if (items.length > 0) {
|
||||||
|
const totalQty = items.reduce((s, i) => s + parseFloat(i.quantity || 0), 0);
|
||||||
|
const unit = items[0]?.unit;
|
||||||
|
const qtyStr = stripHtml(formatQuantity(totalQty, unit, items[0]?.default_quantity, items[0]?.package_unit));
|
||||||
|
const locCount = new Set(items.map(i => i.location)).size;
|
||||||
|
const locSuffix = locCount > 1 ? ` · ${locCount} ${t('use.locations_short') || 'posti'}` : '';
|
||||||
|
pills.push(`<span class="use-meta-pill use-pill-qty">📦 ${escapeHtml(qtyStr)}${locSuffix}</span>`);
|
||||||
|
}
|
||||||
|
|
||||||
|
metaEl.innerHTML = pills.join('');
|
||||||
|
}
|
||||||
|
|
||||||
// Conf-mode tracking for USE form
|
// Conf-mode tracking for USE form
|
||||||
let _useConfMode = null; // null = normal, { packageSize, packageUnit, totalSub, unit } = conf mode active
|
let _useConfMode = null; // null = normal, { packageSize, packageUnit, totalSub, unit } = conf mode active
|
||||||
let _useNormalUnit = 'pz'; // unit when not in conf mode
|
let _useNormalUnit = 'pz'; // unit when not in conf mode
|
||||||
@@ -8522,6 +8565,9 @@ async function loadUseInventoryInfo() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Hero card meta: expiry badge + qty pill ──────────────────
|
||||||
|
_updateUseHeroMeta(items);
|
||||||
|
|
||||||
// ── Suggerisci quale confezione usare per prima ──────────────────
|
// ── Suggerisci quale confezione usare per prima ──────────────────
|
||||||
_renderUseExpiryHint(items);
|
_renderUseExpiryHint(items);
|
||||||
// ─────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user