diff --git a/apps/ops/src/pages/EventsPage.vue b/apps/ops/src/pages/EventsPage.vue
index d6fe254..73c8807 100644
--- a/apps/ops/src/pages/EventsPage.vue
+++ b/apps/ops/src/pages/EventsPage.vue
@@ -371,15 +371,18 @@
-
-
- L'envoi réel (création de la campagne + envoi suivi) est la dernière étape à activer — rien n'est envoyé aux clients ici.
+
+
+
+ L'envoi crée une campagne : suivi ouvertures/clics (Mailjet), statut par destinataire et rapport dans Campagnes.
+
@@ -777,6 +780,29 @@ function clearList () {
catch (e) { $q.notify({ type: 'negative', message: e.message }) } finally { listBusy.value = false }
})
}
+function goCampaigns () { window.location.hash = '#/campaigns' }
+const sendingMass = ref(false)
+function confirmMassSend () {
+ const n = mainList.value.count
+ if (!n) return
+ const chan = sendChannel.value === 'gmail' ? 'Gmail' : 'Mailjet'
+ $q.dialog({
+ title: "Envoyer l'invitation",
+ message: `Envoyer un vrai courriel d'invitation à ${n} destinataire(s) via ${chan} ?
Chacun reçoit un lien RSVP personnel. Cette action est irréversible.`,
+ html: true,
+ cancel: { label: 'Annuler', flat: true, noCaps: true },
+ ok: { label: `Envoyer à ${n}`, color: 'negative', unelevated: true, noCaps: true },
+ persistent: true,
+ }).onOk(async () => {
+ sendingMass.value = true
+ try {
+ const r = await sendInvite(eventId.value, { mass: true, channel: sendChannel.value })
+ $q.notify({ type: 'positive', message: `Envoi lancé à ${r.count} destinataire(s)`, caption: 'Suivi dans Campagnes', icon: 'send', timeout: 7000, actions: [{ label: 'Ouvrir Campagnes', color: 'white', handler: goCampaigns }] })
+ showSend.value = false
+ load()
+ } catch (e) { $q.notify({ type: 'negative', message: 'Échec du lancement : ' + e.message }) } finally { sendingMass.value = false }
+ })
+}
async function sendTestNow () {
const em = (testEmail.value || '').trim()
if (!em) { $q.notify({ type: 'warning', message: 'Entrez un courriel de test' }); return }