// Auto-rezerwacja — CRUD zadań const { useState: uSA, useEffect: uEA, useMemo: uMA } = React; function AutoTaskForm({ initial, words, onSave, onCancel, saving }) { const [form, setForm] = uSA(initial || { name: "", active: true, category: "A", exam_type: "praktyka", date_from: new Date().toISOString().slice(0, 10), date_to: new Date(Date.now() + 45 * 86400_000).toISOString().slice(0, 10), check_interval_s: 60, word_ids: [], }); const [voivFilter, setVoivFilter] = uSA(""); const voivs = uMA(() => ["", ...Array.from(new Set(words.map(w => w.voivodeship))).sort()], [words]); const wordList = uMA(() => voivFilter ? words.filter(w => w.voivodeship === voivFilter) : words , [words, voivFilter]); const toggle = (id) => { setForm(f => ({ ...f, word_ids: f.word_ids.includes(id) ? f.word_ids.filter(x => x !== id) : [...f.word_ids, id], })); }; const submit = (e) => { e.preventDefault(); onSave(form); }; return (
); } function AutoTasksView({ toast }) { const [tasks, setTasks] = uSA([]); const [words, setWords] = uSA([]); const [loading, setLoading] = uSA(true); const [editing, setEditing] = uSA(null); // null | "new" | task obj const [saving, setSaving] = uSA(false); const load = async () => { setLoading(true); try { const [t, w] = await Promise.all([ window.ZlapApi.listAutoTasks(), window.ZlapApi.listWords(), ]); setTasks(t); setWords(w); } catch (e) { toast(`Błąd: ${e.message}`, "err"); } finally { setLoading(false); } }; uEA(() => { load(); }, []); const save = async (form) => { setSaving(true); try { if (editing && editing.id) { await window.ZlapApi.updateAutoTask(editing.id, form); toast("Zaktualizowano zadanie", "ok"); } else { await window.ZlapApi.createAutoTask(form); toast("Utworzono zadanie", "ok"); } setEditing(null); await load(); } catch (e) { toast(`Błąd: ${e.message}`, "err"); } finally { setSaving(false); } }; const toggleActive = async (task) => { try { await window.ZlapApi.updateAutoTask(task.id, { active: !task.active }); await load(); } catch (e) { toast(`Błąd: ${e.message}`, "err"); } }; const del = async (task) => { if (!confirm(`Usunąć zadanie „${task.name}"?`)) return; try { await window.ZlapApi.deleteAutoTask(task.id); toast("Usunięto", "ok"); await load(); } catch (e) { toast(`Błąd: ${e.message}`, "err"); } }; const wordName = (id) => words.find(w => w.id === id)?.name || `#${id}`; return (