Merge branch 'develop'

This commit is contained in:
dadaloop82
2026-04-29 06:19:38 +00:00
7 changed files with 73 additions and 18 deletions
+3 -1
View File
@@ -269,7 +269,9 @@ function estimateOpenedExpiryDaysPHP(string $name, string $category, string $loc
// ── F: Fridge — short-life perishables ──────────────────────────────
if (preg_match('/latte\s+(fresco|intero|parzial|scremato)/', $n)) return 3;
if (preg_match('/latte\s+(uht|a\s+lunga)/', $n)) return 5;
if (preg_match('/latte\s+(uht|a\s+lunga)/', $n)) return 7;
// Long-life mountain/brand milks stored in pantry before use (UHT)
if (preg_match('/latte.*(montagna|alta\s+qual|parmalat|granarolo|esselunga|conservaz|microfiltrat)/i', $n)) return 7;
if (preg_match('/\blatte\b/', $n)) return 4;
if (preg_match('/\byogurt\b/', $n)) return 5;
if (preg_match('/mozzarella|burrata|stracciatella/', $n)) return 3;
+1
View File
@@ -1529,6 +1529,7 @@ function getStats(PDO $db): void {
COALESCE(i.vacuum_sealed, 0) as vacuum_sealed
FROM inventory i JOIN products p ON i.product_id = p.id
WHERE i.expiry_date IS NOT NULL AND i.expiry_date >= date('now') AND i.quantity > 0
AND (i.opened_at IS NULL OR i.opened_at = '')
ORDER BY i.expiry_date ASC
LIMIT 4
")->fetchAll();
+21 -9
View File
@@ -378,8 +378,9 @@ body {
/* ── Anti-Waste Report Card ─────────────────────────────── */
#waste-chart-section {
background: var(--bg-card);
border: 1px solid var(--border);
background: linear-gradient(160deg, #f0fdf4 0%, var(--bg-card) 70%);
border: 2px solid #86efac;
border-left: 4px solid var(--success);
border-radius: var(--radius);
padding: 10px 12px;
margin-bottom: 10px;
@@ -498,16 +499,27 @@ body {
.aw-badge {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 8px;
border-radius: 999px;
font-size: 0.7rem;
gap: 5px;
padding: 4px 9px;
border-radius: 10px;
font-size: 0.72rem;
font-weight: 600;
border: 1px solid transparent;
}
.aw-badge-money { background: #fef9c3; color: #854d0e; border-color: #fde047; }
.aw-badge-meals { background: #f0fdf4; color: #166534; border-color: #86efac; }
.aw-badge-co2 { background: #eff6ff; color: #1e40af; border-color: #93c5fd; }
.aw-badge-icon { font-size: 0.85rem; flex-shrink: 0; }
.aw-badge-body {
display: flex;
flex-direction: column;
line-height: 1.2;
}
.aw-badge-body b { font-size: 0.78rem; }
.aw-badge-body small { font-size: 0.6rem; font-weight: 500; opacity: .75; }
.aw-badge-rate { background: #f5f3ff; color: #5b21b6; border-color: #c4b5fd; }
.aw-badge-money { background: #fef9c3; color: #854d0e; border-color: #fde047; }
.aw-badge-meals { background: #f0fdf4; color: #166534; border-color: #86efac; }
.aw-badge-co2 { background: #eff6ff; color: #1e40af; border-color: #93c5fd; }
.aw-badge-wasted { background: #fef2f2; color: #991b1b; border-color: #fca5a5; }
.aw-badge-better { background: #f0fdf4; color: #15803d; border-color: #4ade80; }
/* ── Trend mini-cards ───────────────────────────────────── */
.aw-trend-cards {
+30 -5
View File
@@ -1337,7 +1337,9 @@ function estimateOpenedExpiryDays(product, location) {
}
if (/latte\s+(fresco|intero|parzial|scremato)/.test(name)) return 3;
if (/latte\s+(uht|a\s+lunga)/.test(name)) return 5;
if (/latte\s+(uht|a\s+lunga)/.test(name)) return 7;
// Long-life mountain/brand milks stored in pantry before use (UHT)
if (/latte.*(montagna|alta\s+qual|parmalat|granarolo|esselunga|conservaz|microfiltrat)/i.test(name)) return 7;
if (/\blatte\b/.test(name)) return 4;
if (/\byogurt\b/.test(name)) return 5;
if (/mozzarella|burrata|stracciatella/.test(name)) return 3;
@@ -2234,11 +2236,34 @@ function _renderAntiWasteSection(used30, wasted30, usedP30, wastedP30, usedP60,
const arr2 = _awTrendArrow(rates[1], rates[2]);
const arrowHtml = a => a ? `<span class="aw-tc-arrow ${a.cls}">${a.sym}</span>` : '';
// Badges
// Badges — richer info chips
const diffPct = avgRate - myRate; // positive = you're better
const badges = [];
if (savedMoney > 0) badges.push(`<span class="aw-badge aw-badge-money">💰 ${bm.currency}${savedMoney}</span>`);
if (savedMeals > 0) badges.push(`<span class="aw-badge aw-badge-meals">🥗 ${savedMeals} ${t('antiwaste.meals')}</span>`);
if (savedCO2 > 0) badges.push(`<span class="aw-badge aw-badge-co2">🌍 ${savedCO2} kg CO₂</span>`);
// Always show your waste rate vs avg
badges.push(`<span class="aw-badge aw-badge-rate">
<span class="aw-badge-icon">📊</span>
<span class="aw-badge-body"><b>${myRate}%</b><small>${t('antiwaste.badge_rate')}</small></span>
</span>`);
if (savedMoney > 0) badges.push(`<span class="aw-badge aw-badge-money">
<span class="aw-badge-icon">💰</span>
<span class="aw-badge-body"><b>${bm.currency}${savedMoney}/m</b><small>${t('antiwaste.badge_saved_money')}</small></span>
</span>`);
if (savedMeals > 0) badges.push(`<span class="aw-badge aw-badge-meals">
<span class="aw-badge-icon">🥗</span>
<span class="aw-badge-body"><b>${savedMeals}</b><small>${t('antiwaste.badge_meals')}</small></span>
</span>`);
if (savedCO2 > 0) badges.push(`<span class="aw-badge aw-badge-co2">
<span class="aw-badge-icon">🌍</span>
<span class="aw-badge-body"><b>${savedCO2} kg</b><small>CO</small></span>
</span>`);
if (wasted30 > 0) badges.push(`<span class="aw-badge aw-badge-wasted">
<span class="aw-badge-icon">🗑</span>
<span class="aw-badge-body"><b>${wasted30}</b><small>${t('antiwaste.badge_wasted')}</small></span>
</span>`);
if (diffPct > 0) badges.push(`<span class="aw-badge aw-badge-better">
<span class="aw-badge-icon"></span>
<span class="aw-badge-body"><b>${diffPct}%</b><small>${t('antiwaste.badge_better')}</small></span>
</span>`);
// Random starting fact
const facts = AW_FACTS[_currentLang] || AW_FACTS['it'];
+6 -1
View File
@@ -696,7 +696,12 @@
"source": "Quellen: REDUCE, Eurostat, USDA 2021",
"live_on": "Live-Daten",
"live_off": "Offline",
"meals": "Mahlzeiten"
"meals": "Mahlzeiten",
"badge_rate": "Abfallquote",
"badge_saved_money": "gespart vs Ø",
"badge_meals": "Mahlzeiten gerettet",
"badge_wasted": "verschwendet",
"badge_better": "weniger als Ø"
},
"error": {
"generic": "Fehler",
+6 -1
View File
@@ -696,7 +696,12 @@
"source": "Sources: REDUCE, Eurostat, USDA 2021",
"live_on": "Live data",
"live_off": "Offline",
"meals": "meals"
"meals": "meals",
"badge_rate": "waste rate",
"badge_saved_money": "saved vs avg",
"badge_meals": "meals saved",
"badge_wasted": "items wasted",
"badge_better": "less than avg"
},
"error": {
"generic": "Error",
+6 -1
View File
@@ -696,7 +696,12 @@
"source": "Fonti: REDUCE, Eurostat, USDA 2021",
"live_on": "Dati in tempo reale",
"live_off": "Offline",
"meals": "pasti"
"meals": "pasti",
"badge_rate": "tasso spreco",
"badge_saved_money": "risparmio vs media",
"badge_meals": "pasti salvati",
"badge_wasted": "prod. sprecati",
"badge_better": "in meno vs media"
},
"error": {
"generic": "Errore",