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