Family board: add to shopping, tasks, checklists and the Family calendar; record who added each
build-container / build (push) Successful in 4m27s
build-container / build (push) Successful in 4m27s
- + button on each board card: write it, tap your name (PIN unless a child), it is added as you - Tasks, events, checklist items and shopping items remember who added them - Names shown on the board and in Tasks, Notes and Calendar - Tests and README updated Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
472e7bec7e
commit
f87a218eea
13 files changed
+86
-27
No files matched your search
@@ -35,6 +35,11 @@ function identify(t, pin, req) {
|
||||
if (!hasPin(t.id)) throw fail(403, 'Set a PIN first (Settings, on your own device), or sign in with your passkey');
|
||||
if (!checkPin(t.id, pin)) { audit.log('family device: wrong PIN', { who: t.name }, req); throw fail(401, 'That PIN is not right'); }
|
||||
}
|
||||
function eventFields(title, b) {
|
||||
const day = /^\d{4}-\d{2}-\d{2}$/.test(b.date || '') ? b.date : new Date().toISOString().slice(0, 10), time = /^\d{2}:\d{2}$/.test(b.time || '') ? b.time : '';
|
||||
if (!time) return { title, allDay: true, start: day, end: day };
|
||||
const end = String((+time.slice(0, 2) + 1) % 24).padStart(2, '0') + time.slice(2); return { title, allDay: false, start: day + 'T' + time, end: +time.slice(0, 2) === 23 ? day + 'T23:59' : day + 'T' + end, tz: b.tz || 'UTC' };
|
||||
}
|
||||
async function board(day) {
|
||||
const t1 = chores.addDays(day, 1), from = new Date(day + 'T00:00:00').getTime() - 864e5, to = new Date(t1 + 'T23:59:59').getTime() + 864e5;
|
||||
let events = []; try { events = cal.familyEvents({ from, to, fd: day, td: t1 }); } catch {}
|
||||
@@ -52,6 +57,18 @@ 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/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');
|
||||
const plan = { shopping: ['recipes', recipes, '/api/recipes/shopping/add', { text }],
|
||||
task: ['tasks', tasks, '/api/tasks', { list: 'local:family', fields: { title: text, due: /^\d{4}-\d{2}-\d{2}$/.test(b.due || '') ? b.due : '' } }],
|
||||
item: ['notes', notes, '/api/notes/' + String(b.note || '') + '/items', { text }],
|
||||
event: ['calendar', cal, '/api/cal/event', { cal: 'family~local', fields: eventFields(text, b) }] }[b.kind];
|
||||
if (!plan) throw fail(400, 'Unknown list'); if (!users.can(t, plan[0])) throw fail(403, 'That part of the hub is not turned on for ' + t.name);
|
||||
if (b.kind === 'item') { const n = notes.familyNotes().find(x => x.id === String(b.note) && x.type === 'list'); if (!n) throw fail(404, 'That list is not shared with the family'); }
|
||||
identify(t, b.pin, req); const r = Readable.from([Buffer.from(JSON.stringify(plan[3]))]); r.url = plan[2]; r.method = 'POST'; r.headers = {};
|
||||
return users.runAs(t, () => plan[1].handle(r, res)); // (as that person, so that person's own rules apply)
|
||||
}
|
||||
if (p === '/api/board/switch' && req.method === 'POST') {
|
||||
if (!dev) throw fail(403, 'This is not a family device'); const b = JSON.parse(await readBody(req, 5e3) || '{}'), t = users.get(String(b.uid));
|
||||
if (!t || !onBoard(t)) throw fail(404, 'Person not found');
|
||||
|
||||
Reference in new issue
Block a user