feat: expired banner for opened products, AI model fallback, TTS cooking improvements

- Banner: detect expired opened-products via effective shelf-life (opened_at +
  estimateOpenedExpiryDays), not just raw expiry_date — fixes Fagioli/Panna case
- Banner: expired items show safety tip inline; danger-level items (fridge dairy,
  meat, fish) get red banner + 'L'ho buttato' as primary button, 'Usa comunque'
  demoted to grey; safety-ok/warning items keep original button order
- Banner: anomaly dismiss button now shows current inventory qty ('La quantità è
  giusta (2 pz)') so the action is unambiguous
- AI: add callGeminiWithFallback() helper — tries gemini-2.5-flash first (separate
  quota), falls back to gemini-2.0-flash; applied to all endpoints (expiry, chat,
  identify, recipe non-streaming, shopping name classifier)
- AI: show friendly 'Quota AI esaurita' message instead of raw Gemini error string
- Cooking TTS: fix auto-speak broken since 'auto-speak removed' comment — each step
  is now read automatically on navigate and on first step when entering cooking mode
- Cooking TTS: remove incorrect s.tts_enabled gate — _cookingTTS toggle is the only
  gate; browser Web Speech API used by default without requiring Settings config
- Cooking TTS: timer fires '10 secondi rimanenti' warning at T-10s
- Cooking TTS: announce recipe completion ('Buon appetito!') on last step confirm
- i18n: add timer_warning_tts, recipe_done_tts, error.ai_quota keys (IT/EN/DE)
- CSS: add banner-expired-danger, banner-safety-* styles for unsafe expired items
This commit is contained in:
dadaloop82
2026-04-28 12:46:00 +00:00
parent 8a16307b39
commit c3b19a6c48
7 changed files with 925 additions and 335 deletions
+33
View File
@@ -5679,3 +5679,36 @@ body {
background: #fee2e2;
color: #dc2626;
}
.alert-banner.banner-expired-danger {
background: linear-gradient(135deg, #fca5a5 0%, #f87171 100%);
border-color: #b91c1c;
border-width: 2px;
}
.banner-expired-danger .alert-banner-title {
color: #7f1d1d;
}
.banner-safety-tip {
display: inline-block;
font-size: 0.82em;
margin-top: 1px;
}
.banner-safety-danger {
color: #b91c1c;
font-weight: 600;
}
.banner-safety-warning {
color: #92400e;
}
.banner-safety-ok {
color: #166534;
}
.btn-banner-throw-primary {
background: #dc2626;
color: #fff;
font-weight: 600;
}
.btn-banner-use-danger {
background: #f3f4f6;
color: #9ca3af;
font-size: 0.8em;
}