From afd3df123f2941bf0bf23440b52978b70ce8aa3f Mon Sep 17 00:00:00 2001 From: isUnknown Date: Tue, 28 Jan 2025 14:55:10 +0100 Subject: [PATCH] send email v1 --- site/blueprints/pages/email.yml | 14 +- site/blueprints/pages/newsletter.yml | 3 +- site/config/config.php | 4 +- site/config/routes/send-newsletter.php | 48 +++--- site/plugins/send-button/index.css | 12 ++ site/plugins/send-button/index.js | 92 ++++++++++-- site/plugins/send-button/index.php | 3 + .../src/components/SendButtonField.vue | 142 ++++++++++++++++-- site/templates/emails/newsletter.html.php | 3 + 9 files changed, 258 insertions(+), 63 deletions(-) create mode 100644 site/templates/emails/newsletter.html.php diff --git a/site/blueprints/pages/email.yml b/site/blueprints/pages/email.yml index f3acc68..2021140 100644 --- a/site/blueprints/pages/email.yml +++ b/site/blueprints/pages/email.yml @@ -6,21 +6,13 @@ image: back: black color: white icon: email -options: - changeStatus: false tabs: contentTab: fields: - month: - label: Mois - type: date - display: "MM/YYYY" - default: today - width: 1/4 + body: + label: Contenu + type: writer sendBtn: type: send-button width: 1/4 - content: - label: Contenu - type: writer diff --git a/site/blueprints/pages/newsletter.yml b/site/blueprints/pages/newsletter.yml index 39c5083..56a28a7 100644 --- a/site/blueprints/pages/newsletter.yml +++ b/site/blueprints/pages/newsletter.yml @@ -21,5 +21,4 @@ tabs: label: Emails type: pages template: email - info: "{{ page.month.toDate('M Y') }}" - sortBy: month desc + info: "{{ page.status == 'listed' ? 'envoyé' : 'brouillon' }}" diff --git a/site/config/config.php b/site/config/config.php index 35cddd0..730c5a4 100644 --- a/site/config/config.php +++ b/site/config/config.php @@ -11,7 +11,9 @@ return array( 'type' => 'smtp', 'host' => 'mail.infomaniak.com', 'port' => 465, - 'security' => true + 'auth' => true, + 'username' => 'info@actuel-inactuel.fr', + 'password' => 'v!Vr$#JH7quJ35' ] ], 'routes' => array( diff --git a/site/config/routes/send-newsletter.php b/site/config/routes/send-newsletter.php index 7cb0550..69e4f72 100644 --- a/site/config/routes/send-newsletter.php +++ b/site/config/routes/send-newsletter.php @@ -1,35 +1,43 @@ '/send-newsletter.json', - 'method' => 'POST', - 'action' => function () { - $jsonRequest = file_get_contents("php://input"); - $data = json_decode($jsonRequest); + 'pattern' => '/send-newsletter.json', + 'method' => 'POST', + 'action' => function () { + $jsonRequest = file_get_contents("php://input"); + $data = json_decode($jsonRequest); - $kirby = kirby(); + $kirby = kirby(); + $emailPage = page("inscription")->childrenAndDrafts()->find($data->pageUri); - $emailPage = page($data->uri); - $content = $emailPage->content()->kt(); - - try { + $to = $data->isTest ? $kirby->users() : page("inscription")->subscribers()->toStructure()->pluck("email", true, true); + $subject = $data->isTest ? "[TEST] - " . (string) $emailPage->title() : (string) $emailPage->title(); + + try { if ($kirby->email([ 'from' => "info@actuel-inactuel.fr", - 'to' => page("inscription")->toStructure()->pluck("email"), - 'subject' => $data->subject, - 'body' => [ - "html" => $emailPage->content() - ], + 'to' => $to, + 'cc' => 'contact@adrien-payet.fr', + 'subject' => $subject, + 'template' => 'newsletter', + 'data' => [ + "body" => $emailPage->body() + ] ])->isSent()) { - return json_encode(['status' => 'success', 'message' => 'Email envoyé avec succès.']); + $emailPage->changeStatus("listed"); + return json_encode([ + 'status' => 'success', + 'message' => + 'Email envoyé avec succès.' + ]); } else { return json_encode([ "status" => "error", "message" => "Erreur lors de l'envoi de l'email.", ]); } - } catch (Exception $error) { - return json_encode(['status' => 'error', 'message' => $error->getMessage()]); - } - } + } catch (Exception $error) { + return json_encode(['status' => 'error', 'message' => $error->getMessage()]); + } + } ]; diff --git a/site/plugins/send-button/index.css b/site/plugins/send-button/index.css index f96ab1a..3f2e526 100644 --- a/site/plugins/send-button/index.css +++ b/site/plugins/send-button/index.css @@ -1,4 +1,16 @@ +.wrapper[data-v-4847e765] { + display: flex; + gap: 10vw; +} +.k-field-footer[data-v-4847e765] { + width: 15rem; +} +@media screen and (max-width: 800px) { +.k-field-footer[data-v-4847e765] { + width: 9rem; +} +} @media screen and (min-width: 533px) { button[data-v-4847e765] { margin-top: 2.15rem; diff --git a/site/plugins/send-button/index.js b/site/plugins/send-button/index.js index c89a1bc..e6345e3 100644 --- a/site/plugins/send-button/index.js +++ b/site/plugins/send-button/index.js @@ -2,7 +2,7 @@ "use strict"; function normalizeComponent(scriptExports, render, staticRenderFns, functionalTemplate, injectStyles, scopeId, moduleIdentifier, shadowMode) { var options = typeof scriptExports === "function" ? scriptExports.options : scriptExports; - if (render) { + { options.render = render; options.staticRenderFns = staticRenderFns; options._compiled = true; @@ -18,31 +18,93 @@ const _sfc_main = { __name: "SendButtonField", props: { - pageUri: String + pageUri: String, + pageStatus: String }, setup(__props) { const { pageUri } = __props; - const text = Vue.ref("Envoyer"); - const headers = { - method: "POST", - body: JSON.stringify({ - pageUri - }) - }; - function send(event) { + const testBtnState = Vue.ref({ + icon: "plane", + text: "Tester", + theme: "blue", + error: null + }); + const sendBtnState = Vue.ref({ + icon: "plane", + text: "Envoyer", + theme: "aqua", + error: null + }); + async function send(event, isTest = false) { event.preventDefault(); - fetch("/send-newsletter.json", headers).then((res) => res.json()).then((json) => console.log(json)); + const currentBtnState = isTest ? testBtnState : sendBtnState; + currentBtnState.value = { + theme: "orange", + text: "En cours…", + icon: "loader", + error: null + }; + const headers = { + method: "POST", + body: JSON.stringify({ + pageUri, + isTest + }) + }; + try { + const response = await fetch("/send-newsletter.json", headers); + const data = await response.json(); + if (data.status === "success") { + currentBtnState.value = { + theme: "green", + icon: "check", + text: isTest ? "Test envoyé" : "Envoi réussi", + error: null + }; + if (!isTest) { + setTimeout(() => { + location.href = location.href; + }, 2e3); + } else { + currentBtnState.value = { + icon: "plane", + text: "Re-tester", + theme: "blue", + error: null + }; + } + } else { + throw new Error(data.message || "Erreur inconnue"); + } + } catch (error) { + currentBtnState.value = { + theme: "red", + icon: "alert", + text: isTest ? "Échec du test" : "Erreur", + error: error.message + }; + } } - return { __sfc: true, text, headers, send }; + return { __sfc: true, testBtnState, sendBtnState, send }; } }; var _sfc_render = function render() { var _vm = this, _c = _vm._self._c, _setup = _vm._self._setupProxy; - return _c("k-button", { attrs: { "variant": "filled", "icon": "plane" }, on: { "click": function($event) { + return _vm.pageStatus === "draft" ? _c("div", { staticClass: "wrapper" }, [_c("div", { staticClass: "test-wrapper" }, [_c("k-button", { staticStyle: { "width": "max-content" }, attrs: { "variant": "filled", "help": "test", "theme": _setup.testBtnState.theme, "icon": _setup.testBtnState.icon }, on: { "click": function($event) { + return _setup.send($event, true); + } } }, [_vm._v(_vm._s(_setup.testBtnState.text))]), _vm._m(0), _setup.testBtnState.error ? _c("k-box", { staticStyle: { "margin-top": "var(--spacing-1)" }, attrs: { "theme": "error" } }, [_vm._v(_vm._s(_setup.testBtnState.error))]) : _vm._e()], 1), _c("div", { staticClass: "send-wrapper" }, [_c("k-button", { attrs: { "variant": "filled", "theme": _setup.sendBtnState.theme, "icon": _setup.sendBtnState.icon }, on: { "click": function($event) { return _setup.send($event); - } } }, [_vm._v(_vm._s(_setup.text))]); + } } }, [_vm._v(_vm._s(_setup.sendBtnState.text))]), _setup.sendBtnState.error ? _c("k-box", { staticStyle: { "margin-top": "var(--spacing-1)" }, attrs: { "theme": "error" } }, [_vm._v(_vm._s(_setup.sendBtnState.error))]) : _vm._e(), _vm._m(1)], 1)]) : _vm._e(); }; - var _sfc_staticRenderFns = []; + var _sfc_staticRenderFns = [function() { + var _vm = this, _c = _vm._self._c; + _vm._self._setupProxy; + return _c("footer", { staticClass: "k-field-footer" }, [_c("div", { staticClass: "k-help k-field-help k-text" }, [_c("p", [_vm._v(" Envoie seulement aux "), _c("a", { attrs: { "href": "/panel/users", "title": "voir la liste" } }, [_vm._v("éditeurs")]), _vm._v(". ")])])]); + }, function() { + var _vm = this, _c = _vm._self._c; + _vm._self._setupProxy; + return _c("footer", { staticClass: "k-field-footer" }, [_c("div", { staticClass: "k-help k-field-help k-text" }, [_c("strong", [_vm._v("⚠ Envoie à tous les abonnés.")])])]); + }]; _sfc_render._withStripped = true; var __component__ = /* @__PURE__ */ normalizeComponent( _sfc_main, diff --git a/site/plugins/send-button/index.php b/site/plugins/send-button/index.php index ee3acc1..b63feb1 100755 --- a/site/plugins/send-button/index.php +++ b/site/plugins/send-button/index.php @@ -7,6 +7,9 @@ Kirby::plugin('adrienpayet/send-button', [ 'pageUri' => function () { return $this->model()->uri(); }, + 'pageStatus' => function () { + return $this->model()->status(); + }, ] ] ] diff --git a/site/plugins/send-button/src/components/SendButtonField.vue b/site/plugins/send-button/src/components/SendButtonField.vue index 071a0ea..9474d7b 100755 --- a/site/plugins/send-button/src/components/SendButtonField.vue +++ b/site/plugins/send-button/src/components/SendButtonField.vue @@ -1,7 +1,51 @@