6: const d = await GET("/recipients/lists");
19:
21:
22:
30: const d = await GET(`/recipients/list?list_id=${list.id}&q=${encodeURIComponent($("#recSearch").value)}&page=${state.page}&limit=${state.pageSize}`);
41:
|
104: if (!file.files[0]) { toast("Choose a file first", "err"); return; }
106: toast("Note: only valid, non-duplicate rows will be imported", "warn");
115: toast(`Imported ${added} recipients (${dup} dup, ${bad} invalid, ${sup} suppressed)`, "ok");
117: } catch (err) { toast("Import failed: " + err.message, "err"); }
136: try { if (cf.value.trim()) custom = JSON.parse(cf.value); } catch { toast("Custom fields must be valid JSON","err"); return; }
137: const d = await POST("/recipients/manual", { list_id: listId, recipient: {
140: if (d.ok) { toast("Recipient added", "ok"); close(); await loadLists(); if (state.cur) await loadRecs(); }
147: toast(`Rejected: ${why}`, "err");
153: $("#btnNewList").addEventListener("click", () => {
158: await POST("/recipients/lists", { name: nm.value, description: ds.value });
159: toast("List created", "ok"); close(); await loadLists();
163: $("#btnImport").addEventListener("click", () => {
164: if (!state.lists.length) { toast("Create a list first", "warn"); return; }
170: $("#btnManual").addEventListener("click", () => {
171: if (!state.lists.length) { toast("Create a list first", "warn"); return; }
184: await POST(`/recipients/lists/${id}/clear`); toast("List cleared", "ok"); await loadLists(); if (state.cur) await loadRecs();
187: await api(`/recipients/lists/${id}`, { method:"DELETE" }); toast("List deleted", "ok");
195: toast("Recipient deleted", "ok"); await loadRecs(); await loadLists();
===
204 /workspace/bulkmailer/static/js/pages/recipients.js