Chores: weekly points and rewards are for child accounts only
build-container / build (push) Successful in 5m0s
build-container / build (push) Successful in 5m0s
- The weekly board, reward tiers and the board's This week card only include children - Rewards can be for all children or chosen children, not adults - Tests and README updated Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
15ddc68cf0
commit
e88b9dedf0
5 files changed
+15
-10
No files matched your search
@@ -36,8 +36,8 @@ async function viewChores() {
|
||||
${others.length ? `<h2>The family</h2><div class="crgrid">${others.map(person).join('')}</div>` : ''}
|
||||
<div class="ptop"><h2 style="margin:18px 0 6px">Weekly goals</h2><span class="pspace grow"></span></div>
|
||||
<div class="bar" style="justify-content:flex-start;margin:0 0 8px"><button class="ibtn" id="wkprev" aria-label="Previous week">${icon('back')}</button><b style="min-width:170px;text-align:center">${esc(crWeekLabel(cr.week))}</b><button class="ibtn" id="wknext" aria-label="Next week" style="transform:scaleX(-1)">${icon('back')}</button>${cr.week.from !== crMonday(crYmd(new Date())) ? '<button class="btn ghost" id="wktoday">This week</button>' : ''}</div>
|
||||
${cr.week.tiers.length ? `<p class="sub" style="margin:0 0 8px">${cr.week.tiers.map(t => esc(t.points) + ' pts: ' + esc(t.title) + (Array.isArray(t.for) ? ' (' + esc(t.for.map(id => (cr.data.people.find(p => p.id === id) || { name: '?' }).name).join(', ')) + ')' : '')).join(' · ')}. Points start again every Monday.</p>` : (d.me.admin ? '<p class="sub">Add rewards in Manage (for example 20 points: pick the movie) and everyone works toward them each week.</p>' : '')}
|
||||
<div class="crcard">${cr.week.people.map(crWeekPerson).join('') || '<p class="empty">No chores yet.</p>'}</div></div>`;
|
||||
${cr.week.tiers.length ? `<p class="sub" style="margin:0 0 8px">${cr.week.tiers.map(t => esc(t.points) + ' pts: ' + esc(t.title) + (Array.isArray(t.for) ? ' (' + esc(t.for.map(id => (cr.data.people.find(p => p.id === id) || { name: '?' }).name).join(', ')) + ')' : '')).join(' · ')}. Points start again every Monday.</p>` : (d.me.admin ? '<p class="sub">Add rewards in Manage (for example 20 points: pick the movie) and the children work toward them each week.</p>' : '')}
|
||||
<div class="crcard">${cr.week.people.map(crWeekPerson).join('') || '<p class="empty">No child accounts yet. Points and rewards are for children: turn on <b>This is a child</b> for a person in Settings.</p>'}</div></div>`;
|
||||
v.querySelectorAll('.crclaim').forEach(b => b.onclick = async e => { e.preventDefault(); try { await crPost('/claim', { chore: b.dataset.c, date: cr.day, undo: !!b.dataset.undo }); if (!b.dataset.undo) toast('It is yours'); viewChores(); } catch (x) { toast(x.message); viewChores(); } });
|
||||
v.querySelectorAll('.critem input').forEach(c => c.onchange = async () => { try { await crPost('/done', { chore: c.dataset.c, date: cr.day, user: c.dataset.u || undefined, undo: !c.checked }); if (c.checked) toast('Nice work!'); viewChores(); } catch (e) { toast(e.message); c.checked = !c.checked; } });
|
||||
$('#crprev').onclick = () => { cr.day = crShift(cr.day, -1); viewChores(); }; $('#crnext').onclick = () => { cr.day = crShift(cr.day, 1); viewChores(); }; if ($('#crtoday')) $('#crtoday').onclick = () => { cr.day = crYmd(new Date()); viewChores(); };
|
||||
@@ -52,7 +52,7 @@ function crManage() {
|
||||
const when = c => CR_REPEAT[c.repeat] + (c.repeat === 'weekly' && c.days && c.days.length ? ' · ' + c.days.map(x => CR_DAYS[x]).join(' ') : '') + (c.repeat === 'monthly' ? ' · day ' + (c.dom || 1) : '') + (c.repeat === 'once' ? ' · ' + c.date : '');
|
||||
const el = openSheet('Manage chores', 'Make jobs for the family and choose who does them', `<div class="list" style="max-height:52dvh;overflow:auto">${d.chores.map(c => `<button class="row" data-e="${esc(c.id)}"><span class="grow"><b>${esc(c.title)}${c.active ? '' : ' (paused)'}</b><small style="white-space:normal">${esc(when(c))} · ${esc(who(c))}${c.points ? ' · ' + c.points + ' pts' : ''}</small></span>${icon('chev', 'chev')}</button>`).join('') || '<p class="empty">No chores yet.</p>'}</div>
|
||||
<div class="bar"><button class="btn" id="crnew" style="width:100%;justify-content:center">${icon('plus')}New chore</button></div>
|
||||
<h2 style="margin:14px 0 6px">Weekly rewards</h2><div class="list">${d.rewards.map(r => `<button class="row" data-rw="${esc(r.id)}"><span class="grow"><b>${esc(r.title)}</b><small>${r.points} points in a week · ${Array.isArray(r.for) ? esc(r.for.map(id => (d.people.find(p => p.id === id) || { name: '?' }).name).join(', ')) : 'everyone'}</small></span>${icon('chev', 'chev')}</button>`).join('') || '<p class="empty" style="margin:6px 0">No rewards yet.</p>'}</div>
|
||||
<h2 style="margin:14px 0 6px">Weekly rewards</h2><div class="list">${d.rewards.map(r => `<button class="row" data-rw="${esc(r.id)}"><span class="grow"><b>${esc(r.title)}</b><small>${r.points} points in a week · ${Array.isArray(r.for) ? esc(r.for.map(id => (d.people.find(p => p.id === id) || { name: '?' }).name).join(', ')) : 'all children'}</small></span>${icon('chev', 'chev')}</button>`).join('') || '<p class="empty" style="margin:6px 0">No rewards yet.</p>'}</div>
|
||||
<div class="bar"><button class="btn ghost" id="rwnew" style="width:100%;justify-content:center">${icon('plus')}New reward</button></div>`);
|
||||
el.querySelector('#rwnew').onclick = () => { closeSheet(); crReward(null); }; el.querySelectorAll('[data-rw]').forEach(b => b.onclick = () => { closeSheet(); crReward(d.rewards.find(r => r.id === b.dataset.rw)); });
|
||||
el.querySelector('#crnew').onclick = () => { closeSheet(); crEdit(null); };
|
||||
@@ -60,7 +60,7 @@ function crManage() {
|
||||
}
|
||||
function crReward(r) {
|
||||
const el = openSheet(r ? 'Edit reward' : 'New reward', 'Anyone who reaches the points in a week earns it. Points start again each Monday.', `<form id="rwf"><label for="rwt">The reward</label><input type="text" id="rwt" value="${esc(r ? r.title : '')}" maxlength="80" required autocomplete="off" placeholder="Pick the movie, ice cream, $5..."><label for="rwp">Points needed in a week</label><input type="number" id="rwp" min="1" max="1000" value="${r ? r.points : 20}" required>
|
||||
<label>Who is it for?</label><div class="list"><label class="row" style="cursor:pointer"><input type="checkbox" id="rwall"${!r || !Array.isArray(r.for) ? ' checked' : ''}><span class="grow"><b>Everyone</b></span></label></div><div class="list" id="rwpp">${cr.data.people.map(p => `<label class="row" style="cursor:pointer"><input type="checkbox" data-p="${esc(p.id)}"${r && Array.isArray(r.for) && r.for.includes(p.id) ? ' checked' : ''}><span class="grow"><b>${esc(p.name)}</b></span></label>`).join('')}</div><div class="err" id="rwe"></div>
|
||||
<label>Who is it for? (child accounts)</label><div class="list"><label class="row" style="cursor:pointer"><input type="checkbox" id="rwall"${!r || !Array.isArray(r.for) ? ' checked' : ''}><span class="grow"><b>All children</b></span></label></div><div class="list" id="rwpp">${cr.data.people.filter(p => p.kid).map(p => `<label class="row" style="cursor:pointer"><input type="checkbox" data-p="${esc(p.id)}"${r && Array.isArray(r.for) && r.for.includes(p.id) ? ' checked' : ''}><span class="grow"><b>${esc(p.name)}</b></span></label>`).join('')}</div><div class="err" id="rwe"></div>
|
||||
<div class="bar">${r ? '<button type="button" class="btn danger" id="rwdel">Delete</button>' : ''}<button type="button" class="btn ghost" id="rwx" style="flex:1;justify-content:center">Cancel</button><button class="btn" style="flex:1;justify-content:center">Save</button></div></form>`);
|
||||
const rsync = () => { el.querySelector('#rwpp').hidden = el.querySelector('#rwall').checked; }; el.querySelector('#rwall').onchange = rsync; rsync();
|
||||
el.querySelector('#rwx').onclick = closeSheet; if (r) el.querySelector('#rwdel').onclick = async () => { try { await crPost('/reward', { id: r.id, remove: true }); closeSheet(); crRefresh(); } catch (e) { toast(e.message); } };
|
||||
|
||||
Reference in new issue
Block a user