Analyzing diff...
plans/oksana/weeks-15/index.html+55 −23
index 37cf1c1..0ba1217 100644 @@ -183,7 +183,7 @@ .session { position: relative; margin: 10px 0; - padding: 14px 48px 14px 14px; + padding: 14px; border: 1px solid var(--line); border-radius: 16px; background: #fff; @@ -198,19 +198,28 @@ color: var(--muted); margin-top: 4px; } - .session input { - position: absolute; - right: 15px; - top: 17px; + .workout-completion { + display: flex; + align-items: center; + gap: 10px; + margin: 14px 0 4px; + padding: 13px; + border: 1px solid #b9d5c7; + border-radius: 15px; + background: #edf7f1; + font-weight: 800; + } + .workout-completion input { width: 22px; height: 22px; accent-color: var(--green); } - .session.done { - opacity: 0.62; - } - .session.done a { - text-decoration: line-through; + .workout-guidance { + margin: 14px 0 4px; + padding: 13px 15px; + border-radius: 15px; + background: var(--peach2); + color: #654d40; } .note { width: 100%; @@ -414,14 +423,14 @@ </header> <div class="progress"> <div class="progress-row"> - <span>Прогресс недели</span><span id="count">0 из 54</span> + <span>Прогресс недели</span><span id="count">0 из 46</span> </div> <div class="track" role="progressbar" aria-label="Прогресс недели" aria-valuemin="0" - aria-valuemax="54" + aria-valuemax="46" aria-valuenow="0" > <div class="fill" id="fill"></div> @@ -439,6 +448,11 @@ Листайте дни стрелками или свайпом. Под тренировками можно отметить ежедневный МТД и утреннюю часовую прогулку. </p> + <p class="workout-guidance"> + Учитывая восстановление после болезни, выполняйте одну тренировку + блока — любую, которая откликнется по времени, нагрузке и + самочувствию. + </p> <div class="days-nav"> <button class="navbtn" id="prev" aria-label="Предыдущий день"> ← @@ -625,7 +639,15 @@ } catch (e) {} const save = () => localStorage.setItem(STORE, JSON.stringify(state)); const key = (d, i) => `d${d}-s${i}`; + const workoutKey = (d) => `d${d}-workout`; const hkey = (d, i) => `d${d}-h${i}`; + days.forEach((d, di) => { + const newKey = workoutKey(di); + if (!(newKey in state.checks) && d.items.some((x, i) => state.checks[key(di, i)])) { + state.checks[newKey] = true; + } + }); + save(); function mins(meta) { const m = meta.match(/(\d{2}):(\d{2})/); return m ? +m[1] + +m[2] / 60 : 0; @@ -653,20 +675,23 @@ let items = d.items .map( (x, i) => - `<div class="session ${state.checks[key(state.day, i)] ? "done" : ""}"><a href="${x[1]}" target="_blank" rel="noopener">${x[0]}</a><small>${x[2]}</small><input type="checkbox" data-check="${key(state.day, i)}" ${state.checks[key(state.day, i)] ? "checked" : ""} aria-label="Отметить ${x[0]}"></div>`, + `<div class="session" data-role="workout-option" data-item-id="d${state.day}-option-${i}"><a href="${x[1]}" target="_blank" rel="noopener">${x[0]}</a><small>${x[2]}</small></div>`, ) .join(""); + const completion = d.items.length + ? `<label class="workout-completion" data-role="completion"><input type="checkbox" data-check="${workoutKey(state.day)}" ${state.checks[workoutKey(state.day)] ? "checked" : ""}> Выполнила одну тренировку блока</label>` + : ""; let habits = state.day < 6 ? daily .map( (x, i) => - `<label class="habit"><input type="checkbox" data-check="${hkey(state.day, i)}" ${state.checks[hkey(state.day, i)] ? "checked" : ""}> ${x[1] ? `<a href="${x[1]}" target="_blank" rel="noopener">${x[0]}</a>` : x[0]}</label>`, + `<label class="habit" data-role="daily-support" data-item-id="d${state.day}-support-${i}"><input type="checkbox" data-check="${hkey(state.day, i)}" ${state.checks[hkey(state.day, i)] ? "checked" : ""}> ${x[1] ? `<a href="${x[1]}" target="_blank" rel="noopener">${x[0]}</a>` : x[0]}</label>`, ) .join("") : ""; document.getElementById("day").innerHTML = - `<article class="day-card"><div class="day-head"><div><h2>${d.name}</h2><div>${d.theme}</div></div>${d.items.length ? `<span class="total">${fmt(total(d))}</span>` : ""}</div>${items}${habits}<textarea class="note" data-note="${state.day}" placeholder="Комментарий к дню">${state.notes[state.day] || ""}</textarea></article>`; + `<article class="day-card" data-day-card="${state.day}"><div class="day-head"><div><h2>${d.name}</h2><div>${d.theme}</div></div>${d.items.length ? `<span class="total">выберите 1</span>` : ""}</div>${items}${completion}${habits}<textarea class="note" data-note="${state.day}" placeholder="Комментарий к дню">${state.notes[state.day] || ""}</textarea></article>`; bind(); progress(); } @@ -693,11 +718,20 @@ }; } function progress() { - const planned = 14 + 12 + 28; + const workoutKeys = days + .map((d, di) => (d.items.length ? workoutKey(di) : null)) + .filter(Boolean); + const supportKeys = days.flatMap((d, di) => + di < 6 ? daily.map((x, i) => hkey(di, i)) : [], + ); + const mealKeys = days.flatMap((d, di) => + foodItems.map(([id]) => foodKey(di, id)), + ); + const planned = workoutKeys.length + supportKeys.length + mealKeys.length; const done = - Object.values(state.checks).filter(Boolean).length + - Object.entries(state.food).filter(([k, v]) => k.includes("-") && v) - .length; + workoutKeys.filter((k) => state.checks[k]).length + + supportKeys.filter((k) => state.checks[k]).length + + mealKeys.filter((k) => state.food[k]).length; document.getElementById("count").textContent = `${done} из ${planned}`; document.getElementById("fill").style.width = `${Math.min((done / planned) * 100, 100)}%`; @@ -757,13 +791,11 @@ function report() { let out = ["Итоги 15-й недели Оксаны", ""]; days.slice(0, 6).forEach((d, di) => { - const done = d.items - .filter((x, i) => state.checks[key(di, i)]) - .map((x) => x[0]); + const workout = state.checks[workoutKey(di)] ? "выполнена" : "нет отметки"; const mt = state.checks[hkey(di, 0)] ? "да" : "нет"; const walk = state.checks[hkey(di, 1)] ? "да" : "нет"; out.push( - `${d.name}: тренировки — ${done.length ? done.join(", ") : "нет отметок"}; МТД — ${mt}; прогулка — ${walk}.`, + `${d.name}: одна тренировка блока — ${workout}; МТД — ${mt}; прогулка — ${walk}.`, ); if (state.notes[di]) out.push(`Комментарий: ${state.notes[di]}`); });