// Aufgaben: ansehen, abhaken, neue anlegen. import { h, clear, icon, toast, errText } from '../lib/dom.js'; import { apiCall, parseServerTime } from '../lib/core.js'; import { spinner, showError } from '../lib/ui.js'; const FILTERS = [['my', 'Meine'], ['open', 'Alle offenen'], ['done', 'Erledigt']]; const memory = { filter: 'my' }; const dueText = (s) => { const d = parseServerTime(s); return d ? d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' }) + ' ' + d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }) : ''; }; export async function renderTasks(host, ctx) { const list = h('div'); const chips = h('div', { class: 'chips' }); const form = h('div'); const drawChips = () => chips.replaceChildren(...FILTERS.map(([k, l]) => h('button', { type: 'button', class: `chip${memory.filter === k ? ' on' : ''}`, onclick: () => { memory.filter = k; drawChips(); load(); } }, l))); async function load() { clear(list).append(spinner()); try { const { data } = await apiCall('tasks.php', { query: { filter: memory.filter } }); ctx.taskStaff = data.staffOptions || []; clear(list); if (!data.items.length) return list.append(h('div', { class: 'empty' }, memory.filter === 'done' ? 'Keine erledigten Aufgaben.' : 'Keine Aufgaben. Schön!')); list.append(h('div', { class: 'stack' }, data.items.map((it) => { const done = it.status === 'done'; const box = h('input', { type: 'checkbox', checked: done, 'aria-label': 'Erledigt', onchange: async () => { try { await apiCall('tasks.php', { method: 'POST', body: { action: 'update_status', id: it.id, status: box.checked ? 'done' : 'open' } }); toast(box.checked ? 'Erledigt' : 'Wieder geöffnet'); load(); } catch (e) { box.checked = !box.checked; toast(errText(e), 'err'); } } }); return h('div', { class: `card task${done ? ' done' : ''}` }, box, h('div', { class: 'grow' }, h('div', { class: 'tt', style: { fontWeight: 650 } }, it.title), it.description ? h('div', { class: 'muted' }, it.description) : null, h('div', { class: 'muted', style: { marginTop: '3px' } }, [it.dueAt ? `fällig ${dueText(it.dueAt)}` : null, it.assignedName ? `für ${it.assignedName}` : null].filter(Boolean).join(' · ')), it.ticketNumber ? h('button', { class: 'btn small', style: { marginTop: '6px' }, onclick: () => ctx.go('ticket', { number: it.ticketNumber }) }, `#${it.ticketNumber}`) : null), h('button', { class: 'iconbtn', title: 'Aufgabe löschen', onclick: async () => { if (!confirm('Aufgabe löschen?')) return; try { await apiCall('tasks.php', { method: 'POST', body: { action: 'delete', id: it.id } }); load(); } catch (e) { toast(errText(e), 'err'); } } }, icon('x', 16))); }))); } catch (e) { showError(ctx, list, e); } } function drawForm(open) { if (!open) { form.replaceChildren(h('button', { class: 'btn', onclick: () => drawForm(true) }, icon('plus', 15), 'Neue Aufgabe')); return; } const title = h('input', { type: 'text', required: true, maxlength: '200', placeholder: 'Was ist zu tun?' }); const due = h('input', { type: 'datetime-local' }); const ticket = h('input', { type: 'text', placeholder: 'Ticketnummer (optional)' }); const who = h('select', {}, h('option', { value: '' }, 'Niemand'), (ctx.taskStaff || []).map((s) => h('option', { value: s.id, selected: s.id === ctx.session.staff?.id ? '' : undefined }, s.name))); form.replaceChildren(h('form', { class: 'sheet', onsubmit: async (ev) => { ev.preventDefault(); try { await apiCall('tasks.php', { method: 'POST', body: { action: 'create', title: title.value.trim(), dueAt: due.value ? due.value.replace('T', ' ') + ':00' : '', ticketNumber: ticket.value.trim(), assignedToId: who.value ? Number(who.value) : null } }); toast('Aufgabe angelegt'); drawForm(false); load(); } catch (e) { toast(errText(e), 'err'); } } }, h('label', {}, 'Titel', title), h('div', { class: 'row2' }, h('label', {}, 'Fällig', due), h('label', {}, 'Für', who)), h('label', {}, 'Ticket', ticket), h('div', { class: 'actions' }, h('button', { class: 'btn primary', type: 'submit' }, 'Anlegen'), h('button', { class: 'btn', type: 'button', onclick: () => drawForm(false) }, 'Abbrechen')))); title.focus(); } host.append(h('div', { class: 'stack' }, form, chips, list)); drawChips(); drawForm(false); load(); }