feat: zero-waste tips during cooking mode (#76)

This commit is contained in:
dadaloop82
2026-05-17 09:16:48 +00:00
parent 06f6d58fb5
commit a602726531
12 changed files with 169 additions and 10 deletions
+58
View File
@@ -6875,6 +6875,64 @@ body.cooking-mode-active .app-header {
opacity: 0.8;
}
/* ===== ZERO-WASTE TIP CARD (cooking mode) ===== */
.cooking-zerowaste-tip {
display: flex;
align-items: flex-start;
gap: 10px;
background: rgba(16, 185, 129, 0.10);
border: 1.5px solid rgba(16, 185, 129, 0.35);
border-radius: 12px;
padding: 12px 14px;
margin: 10px 16px 0;
position: relative;
animation: zwFadeIn 0.3s ease;
flex-direction: column;
}
@keyframes zwFadeIn {
from { opacity: 0; transform: translateY(6px); }
to { opacity: 1; transform: translateY(0); }
}
.cooking-zerowaste-label {
font-size: 0.7rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
color: #059669;
}
.cooking-zerowaste-scrap {
font-size: 0.85rem;
font-weight: 700;
color: #065f46;
margin-left: 4px;
}
.cooking-zerowaste-text {
font-size: 0.85rem;
color: var(--text);
margin: 4px 0 0;
line-height: 1.45;
}
.cooking-zerowaste-close {
position: absolute;
top: 8px;
right: 10px;
background: none;
border: none;
font-size: 0.85rem;
cursor: pointer;
color: #6b7280;
padding: 2px 4px;
line-height: 1;
}
.cooking-zerowaste-close:hover { color: #374151; }
[data-theme="dark"] .cooking-zerowaste-tip {
background: rgba(16, 185, 129, 0.08);
border-color: rgba(16, 185, 129, 0.25);
}
[data-theme="dark"] .cooking-zerowaste-scrap { color: #6ee7b7; }
[data-theme="dark"] .cooking-zerowaste-label { color: #34d399; }
[data-theme="dark"] .cooking-zerowaste-close { color: #9ca3af; }
/* ===== DARK MODE ===== */
[data-theme="dark"] {
--bg: #0f172a;
+40
View File
@@ -2538,6 +2538,9 @@ async function loadSettingsUI() {
// Dark mode setting
const dmEl = document.getElementById('setting-dark-mode');
if (dmEl) dmEl.value = s.dark_mode || 'auto';
// Zero-waste tips setting
const zwEl = document.getElementById('setting-zerowaste-tips');
if (zwEl) zwEl.checked = s.zerowaste_tips_enabled === true;
// Populate About section version
_loadAboutSection();
@@ -2864,6 +2867,9 @@ async function saveSettings() {
// Dark mode
const dmSaveEl = document.getElementById('setting-dark-mode');
if (dmSaveEl) { s.dark_mode = dmSaveEl.value; _applyTheme(); }
// Zero-waste tips
const zwSaveEl = document.getElementById('setting-zerowaste-tips');
if (zwSaveEl) s.zerowaste_tips_enabled = zwSaveEl.checked;
// Meal plan enabled toggle
const mpEnabledEl = document.getElementById('setting-meal-plan-enabled');
if (mpEnabledEl) s.meal_plan_enabled = mpEnabledEl.checked;
@@ -12429,6 +12435,7 @@ function startCookingMode() {
_cookingRecipe = JSON.parse(JSON.stringify(recipe));
_cookingStep = 0;
_cookingVisited = new Set();
_dismissedZeroWasteTips = new Set();
clearAllCookingTimers();
}
_cookingTTS = true;
@@ -12478,6 +12485,7 @@ function restartCookingMode() {
_cookingStep = 0;
_cookingWheelLastDelta = 0;
_cookingVisited = new Set();
_dismissedZeroWasteTips = new Set();
clearAllCookingTimers();
renderCookingStep();
}
@@ -12699,10 +12707,42 @@ function renderCookingStep() {
// Timer: detect duration in step text and show suggestion
setupCookingTimerSuggestion(cleanStep);
// Zero-waste tip for this step
_renderZeroWasteTip(_cookingStep);
// TTS: auto-speak is handled by navigateCookingStep() and startCookingMode() callers.
// Use replayCookingTTS() to re-read the current step manually ("Rileggi" button).
}
// ===== ZERO-WASTE TIPS =====
let _dismissedZeroWasteTips = new Set(); // dismissed tip indices for this cooking session
function _renderZeroWasteTip(stepIdx) {
const tipEl = document.getElementById('cooking-zerowaste-tip');
if (!tipEl) return;
// Check setting
const s = getSettings();
if (!s.zerowaste_tips_enabled) { tipEl.style.display = 'none'; return; }
// Already dismissed for this step in this session
if (_dismissedZeroWasteTips.has(stepIdx)) { tipEl.style.display = 'none'; return; }
// Find tip for current step
const tips = (_cookingRecipe && _cookingRecipe.zero_waste_tips) || [];
const tip = tips.find(t => t.step === stepIdx);
if (!tip) { tipEl.style.display = 'none'; return; }
// Populate and show
const scrapEl = document.getElementById('cooking-zerowaste-scrap');
const textEl = document.getElementById('cooking-zerowaste-text');
if (scrapEl) scrapEl.textContent = tip.scrap || '';
if (textEl) textEl.textContent = tip.tip || '';
tipEl.style.display = 'flex';
}
function _dismissZeroWasteTip() {
_dismissedZeroWasteTips.add(_cookingStep);
const tipEl = document.getElementById('cooking-zerowaste-tip');
if (tipEl) tipEl.style.display = 'none';
}
function _buildTtsRequest(text, s) {
const url = s.tts_url || '';
const method = s.tts_method || 'POST';