// Form modal: create / edit / delete tasks and events.
function Field({ label, children, hint }) {
return (
{label}
{children}
{hint &&
{hint}
}
);
}
function inputStyle() {
return {
width: "100%", padding: "12px 14px",
background: "var(--surface)", border: "1px solid var(--line-2)",
borderRadius: 12, fontSize: 16, color: "var(--ink)", outline: "none",
};
}
function Segmented({ options, value, onChange, color = "var(--terracotta)" }) {
return (
{options.map(opt => {
const active = opt.value === value;
return (
);
})}
);
}
function CustomDateChips({ days, onChange }) {
const [input, setInput] = React.useState(ymd(addDays(TODAY, 1)));
const sorted = [...(days || [])].sort();
return (
);
}
function TaskForm({ initial, onSave, onDelete, onClose }) {
const blank = {
id: "",
kind: "task",
title: "",
date: ymd(TODAY),
priority: "mid",
status: "todo",
recurrence: { kind: "none" },
notify: false,
notes: "",
overrides: {},
assignee: null,
};
const [draft, setDraft] = React.useState({ ...blank, ...initial });
const isNew = !initial?.id;
const set = (k, v) => setDraft(d => ({ ...d, [k]: v }));
const submit = (e) => {
e?.preventDefault?.();
if (!draft.title.trim()) return;
const id = draft.id || `i_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,6)}`;
onSave({ ...draft, id });
onClose();
};
return (
);
}
Object.assign(window, { TaskForm });