{mismatched.length} selected attendee(s) have a notification preference that doesn't include{" "}
{channel === "whatsapp" ? "WhatsApp" : "email"}. They will still receive the message, but it may not be their preferred channel.
{" "}
);
}
// ─── WhatsApp Automations Panel ───────────────────────────────────────────────
function WAAutomationsPanel({ events, token, onInfo, onError }: { events: any[]; token?: string | null; onInfo: (s: string) => void; onError: (s: string) => void }) {
const [autoEventId, setAutoEventId] = React.useState("");
const currentEvent = React.useMemo(() => (events || []).find((e: any) => e.id === autoEventId), [events, autoEventId]);
const preWeekDefault = `Hi {{name}}\n\nJust a friendly reminder that {{event.title}} is one week away!\n\nEvent details: {{event.link}}`;
const finalDefault = `Hi {{name}}\n\nFinal reminder for {{event.title}}.\nPlease have your QR code/ticket ready at entry.\n\nEvent details: {{event.link}}`;
const thanksDefault = `Hi {{name}}\n\nThank you for joining us at {{event.title}}!\nWe hope you had a great time. See you next time!`;
const promoDefault = `Hi {{name}}\n\nWe'd love to see you at our next event: {{promo.title}}.\nFind out more and register here: {{promo.link}}`;
const [enablePre, setEnablePre] = React.useState(true);
const [enableFinal, setEnableFinal] = React.useState(true);
const [enableThanks, setEnableThanks] = React.useState(true);
const [enablePromo, setEnablePromo] = React.useState(false);
const [preBody, setPreBody] = React.useState(preWeekDefault);
const [finalBody, setFinalBody] = React.useState(finalDefault);
const [thanksBody, setThanksBody] = React.useState(thanksDefault);
const [promoBody, setPromoBody] = React.useState(promoDefault);
const [finalHours, setFinalHours] = React.useState<"24" | "48">("24");
const [preWhen, setPreWhen] = React.useState("");
const [finalWhen, setFinalWhen] = React.useState("");
const [thanksWhen, setThanksWhen] = React.useState("");
const [promoWhen, setPromoWhen] = React.useState("");
const [promoEventId, setPromoEventId] = React.useState("");
React.useEffect(() => {
if (!currentEvent) { setPreWhen(""); setFinalWhen(""); setThanksWhen(""); setPromoWhen(""); return; }
try {
const start = new Date(currentEvent.startDate);
const end = new Date(currentEvent.endDate || currentEvent.startDate);
const pre = new Date(start); pre.setDate(pre.getDate() - 7); pre.setHours(9, 0, 0, 0);
setPreWhen(toLocalInputValue(pre));
const fin = new Date(start); fin.setHours(fin.getHours() - (finalHours === "48" ? 48 : 24));
setFinalWhen(toLocalInputValue(fin));
const ty = new Date(end); ty.setDate(ty.getDate() + 1); ty.setHours(9, 0, 0, 0);
setThanksWhen(toLocalInputValue(ty));
const pr = new Date(end); pr.setDate(pr.getDate() + 3); pr.setHours(9, 0, 0, 0);
setPromoWhen(toLocalInputValue(pr));
} catch {}
}, [currentEvent, finalHours]);
const onSchedule = async () => {
try {
onError(null as any); onInfo(null as any);
if (!token) { onError("Not authenticated"); return; }
if (!autoEventId) { onError("Please select an event"); return; }
const jobs: any[] = [];
if (enablePre && preBody.trim() && preWhen) jobs.push({ message: preBody, scheduledAt: new Date(preWhen).toISOString() });
if (enableFinal && finalBody.trim() && finalWhen) jobs.push({ message: finalBody, scheduledAt: new Date(finalWhen).toISOString() });
if (enableThanks && thanksBody.trim() && thanksWhen) jobs.push({ message: thanksBody, scheduledAt: new Date(thanksWhen).toISOString() });
if (enablePromo && promoBody.trim() && promoWhen) jobs.push({ message: promoBody, scheduledAt: new Date(promoWhen).toISOString(), promoEventId: promoEventId || undefined });
if (jobs.length === 0) { onError("Please enable at least one automation and fill in details"); return; }
let scheduled = 0;
for (const job of jobs) {
await apiFetch(`/api/events/${encodeURIComponent(autoEventId)}/whatsapp-attendees/schedule`, {
method: "POST", authToken: token,
body: { message: job.message, scheduledAt: job.scheduledAt, filter: { status: "paid" } },
});
scheduled++;
}
onInfo(`Scheduled ${scheduled} WhatsApp automation(s).`);
} catch (e: any) {
onError(e?.message || "Failed to schedule automations");
}
};
return (