diff --git a/board.js b/board.js
index 22fc98c..ee9599b 100644
--- a/board.js
+++ b/board.js
@@ -62,6 +62,12 @@ async function handle(req, res) {
const body = JSON.stringify({ chore: b.chore, date: ymdOk(b.date) ? b.date : undefined, undo: b.action === 'unclaim' || b.action === 'undo' || undefined }), r = Readable.from([Buffer.from(body)]); r.url = path; r.method = 'POST'; r.headers = {};
return users.runAs(t, () => chores.handle(r, res)); // (as that person: all of the chore rules apply to them)
}
+ if (p === '/api/board/goal' && req.method === 'POST') { // a child chooses the reward they are aiming for this week, from the shared screen
+ if (!dev) throw fail(403, 'This is not a family device'); const b = JSON.parse(await readBody(req, 2e3) || '{}'), t = users.get(String(b.uid));
+ if (!t || !onBoard(t)) throw fail(404, 'Person not found'); if (!users.can(t, 'chores')) throw fail(403, 'Chores are not turned on for that person'); identify(t, b.pin);
+ const r = Readable.from([Buffer.from(JSON.stringify({ reward: String(b.reward || ''), date: ymdOk(b.date) ? b.date : undefined }))]); r.url = '/api/chores/goal'; r.method = 'POST'; r.headers = {};
+ return users.runAs(t, () => chores.handle(r, res)); // (as that person: the same rules as choosing it in Chores)
+ }
if (p === '/api/board/add' && req.method === 'POST') { // put something on one of the family's lists from the shared screen, as the person who picked their name
if (!dev) throw fail(403, 'This is not a family device'); const b = JSON.parse(await readBody(req, 8e3) || '{}'), t = users.get(String(b.uid));
if (!t || !onBoard(t)) throw fail(404, 'Person not found'); const text = String(b.text || '').replace(/\s+/g, ' ').trim().slice(0, 200); if (!text) throw fail(400, 'Write something first');
diff --git a/public/board.js b/public/board.js
index 2c4fa27..c50bcfd 100644
--- a/public/board.js
+++ b/public/board.js
@@ -9,7 +9,20 @@ function clock() { const d = new Date(); $('#clock').textContent = d.toLocaleTim
const card = (t, body, add, cls) => `
`; }).join('');
+}
+// ---- Choose a reward to aim for: pick it from a pop-up, then PIN (unless a child with no PIN), and it is set as that person
+function goalFlow(pid) {
+ const p = data.people.find(x => x.id === pid), w = data.week; if (!p || !w) return; const mine = w.tiers.filter(t => ((w.people.find(x => x.id === pid) || {}).tiers || []).includes(t.id));
+ const { box, close } = sheet(`
${esc(p.name.split(' ')[0])}, what are you aiming for?
Pick one reward for this week.
${mine.map(t => ``).join('')}
`);
+ box.querySelector('#no').onclick = close;
+ const send = async (reward, pin) => { const r = await fetch('/api/board/goal', { method: 'POST', body: JSON.stringify({ uid: p.id, pin, reward, date: ymd(new Date()) }) }), j = await r.json().catch(() => ({})); if (!r.ok) throw new Error(j.error || 'That did not work'); close(); await load(); toast('Goal chosen'); };
+ box.querySelectorAll('[data-g]').forEach(b => b.onclick = () => { const reward = b.dataset.g;
+ if (p.kid && !p.pin) return send(reward).catch(e => { box.querySelector('#e').textContent = e.message; });
+ if (!p.pin) { box.querySelector('#e').textContent = p.name + ' has not set a PIN yet. Set one in Settings on your own device.'; return; }
+ let pin = ''; box.innerHTML = `