diff --git a/assets/css/src/header.css b/assets/css/src/header.css index bf5a8d9..c39ab8f 100644 --- a/assets/css/src/header.css +++ b/assets/css/src/header.css @@ -123,8 +123,10 @@ button.toggle.right::before { [data-template="author"] .page-cover, [data-template="category"] .page-cover, - [data-template="year"] .page-cover { - height: initial; + [data-template="year"] .page-cover, + [data-template="email"] .page-cover, + [data-template="error"] .page-cover { + height: initial !important; } .page-cover .links { diff --git a/site/blueprints/pages/email.yml b/site/blueprints/pages/email.yml index 0f15dfe..78b650d 100644 --- a/site/blueprints/pages/email.yml +++ b/site/blueprints/pages/email.yml @@ -1,6 +1,7 @@ title: Email status: draft: Brouillon + unlisted: Testé listed: Envoyé image: back: black diff --git a/site/collections/categories.php b/site/collections/categories.php index b6e6c5e..81ec8f6 100644 --- a/site/collections/categories.php +++ b/site/collections/categories.php @@ -1,26 +1,28 @@ categories()->split() as $categoryName) { $category = new Page([ - 'slug' => Str::slug($categoryName), + 'slug' => Str::slug($categoryName), 'template' => 'category', - 'status' => 'listed', - 'content' => [ + 'status' => 'listed', + 'content' => [ 'title' => $categoryName, ], - 'children' => [] + 'children' => [], ]); $categories->add($category); - } + } return $categories; } -function createCategories() { +function createCategories() +{ $emptyCategories = createEmptyCategories(); foreach (page('textes')->grandChildren() as $text) { try { diff --git a/site/config/config.php b/site/config/config.php index 7d2c051..5fcfb1a 100644 --- a/site/config/config.php +++ b/site/config/config.php @@ -1,24 +1,23 @@ true, - "panel" => array( - "menu" => require __DIR__ . "/menu.php", - "css" => "assets/css/panel.css" - ), - "email" => [ - "transport" => [ - "type" => "smtp", - "host" => "mail.infomaniak.com", - "port" => 465, - "auth" => true, - "username" => "info@actuel-inactuel.fr", - "password" => "v!Vr$#JH7quJ35" - ] +return [ + 'debug' => true, + 'panel' => [ + 'menu' => require __DIR__ . '/menu.php', + 'css' => 'assets/css/panel.css', + ], + 'email' => [ + 'transport' => [ + 'type' => 'smtp', + 'host' => 'smtp.mailersend.net', + 'port' => 587, + 'auth' => true, + 'username' => 'MS_K9grTE@actuel-inactuel.fr', + 'password' => 'mssp.GJGywUh.z3m5jgrq71xldpyo.owybzs9', ], - "routes" => array( - require __DIR__ . "/routes/virtual-category.php", - require __DIR__ . "/routes/send-newsletter.php", - require __DIR__ . "/routes/subscribe.php", - ) -); + ], + 'routes' => [ + require __DIR__ . '/routes/virtual-category.php', + require __DIR__ . '/routes/subscribe.php', + ], +]; diff --git a/site/config/menu.php b/site/config/menu.php index 6831988..5b57f01 100644 --- a/site/config/menu.php +++ b/site/config/menu.php @@ -2,62 +2,62 @@ return [ 'site' => [ - 'label' => 'Accueil', + 'label' => 'Accueil', 'current' => function ($current) { $path = Kirby::instance()->request()->path()->toString(); return Str::contains($path, 'site'); - } + }, ], 'texts' => [ - 'icon' => 'pen', - 'label' => 'Textes', - 'link' => 'pages/textes', + 'icon' => 'pen', + 'label' => 'Textes', + 'link' => 'pages/textes', 'current' => function ($current) { $path = Kirby::instance()->request()->path()->toString(); return Str::contains($path, 'pages/textes'); - } + }, ], 'authors' => [ - 'icon' => 'users', - 'label' => 'Auteurs', - 'link' => 'pages/auteurs', + 'icon' => 'users', + 'label' => 'Auteurs', + 'link' => 'pages/auteurs', 'current' => function ($current) { - $path = Kirby::instance()->request()->path()->toString(); - return Str::contains($path, 'pages/auteurs'); - } + $path = Kirby::instance()->request()->path()->toString(); + return Str::contains($path, 'pages/auteurs'); + }, ], '-', '-', 'infos' => [ - 'icon' => 'question', - 'label' => 'À propos', - 'link' => 'pages/a-propos', + 'icon' => 'question', + 'label' => 'À propos', + 'link' => 'pages/a-propos', 'current' => function ($current) { $path = Kirby::instance()->request()->path()->toString(); return Str::contains($path, 'pages/a-propos'); - } + }, ], 'subscription' => [ - 'icon' => 'email', - 'label' => 'Liste de diffusion', - 'link' => 'pages/inscription', + 'icon' => 'email', + 'label' => 'Liste de diffusion', + 'link' => 'pages/lettre', 'current' => function ($current) { $path = Kirby::instance()->request()->path()->toString(); return Str::contains($path, 'pages/liste-de-diffusion'); - } + }, ], '-', '-', 'users', 'comments', 'admin' => [ - 'icon' => 'folder', - 'label' => 'Administration', - 'link' => 'pages/admin', + 'icon' => 'folder', + 'label' => 'Administration', + 'link' => 'pages/admin', 'current' => function ($current) { $path = Kirby::instance()->request()->path()->toString(); return Str::contains($path, 'pages/admin'); - } + }, ], '-', '-', diff --git a/site/config/routes/subscribe.php b/site/config/routes/subscribe.php index d54eab2..7d183d1 100644 --- a/site/config/routes/subscribe.php +++ b/site/config/routes/subscribe.php @@ -2,43 +2,42 @@ return [ 'pattern' => '/subscribe.json', - 'method' => 'POST', + 'method' => 'POST', 'action' => function () { - $jsonRequest = file_get_contents("php://input"); + $jsonRequest = file_get_contents('php://input'); $email = Str::lower(json_decode($jsonRequest)); if (V::email($email)) { kirby()->impersonate('kirby'); - - $page = page("inscription"); + + $page = page('lettre'); $subscribers = $page->subscribers()->yaml(); - $emailExists = in_array(["email" => $email], $subscribers); + $emailExists = in_array(['email' => $email], $subscribers); if ($emailExists) { return [ - "status" => "error", - "message" => "Cet email est déjà inscris." + 'status' => 'error', + 'message' => 'Cet email est déjà inscris.', ]; } - $newSubscriber = ["email" => $email]; + $newSubscriber = ['email' => $email]; $subscribers[] = $newSubscriber; - + $page->update([ - 'subscribers' => $subscribers + 'subscribers' => $subscribers, ]); return [ - "status" => "success", - "message" => "Inscription réussie." + 'status' => 'success', + 'message' => 'lettre réussie.', ]; } else { return [ - "status" => "error", - "message" => "Email invalide." + 'status' => 'error', + 'message' => 'Email invalide.', ]; } - } + }, ]; - diff --git a/site/plugins/helpers/index.php b/site/plugins/helpers/index.php index c52d137..69357d7 100644 --- a/site/plugins/helpers/index.php +++ b/site/plugins/helpers/index.php @@ -29,3 +29,4 @@ function getAuthorBySlug($slug) return $author; } + \ No newline at end of file diff --git a/site/plugins/send-button/index.css b/site/plugins/send-button/index.css index b5dbbb2..1331a1c 100644 --- a/site/plugins/send-button/index.css +++ b/site/plugins/send-button/index.css @@ -1 +1 @@ -.wrapper[data-v-76f92a36]{display:flex;gap:10vw}.k-field-footer[data-v-76f92a36]{width:15rem}@media screen and (max-width: 800px){.k-field-footer[data-v-76f92a36]{width:9rem}}@media screen and (min-width: 533px){button[data-v-76f92a36]{margin-top:2.15rem}} +.wrapper[data-v-0e6a95b9]{display:flex;gap:10vw}.k-field-footer[data-v-0e6a95b9]{width:15rem}@media screen and (max-width: 800px){.k-field-footer[data-v-0e6a95b9]{width:9rem}}@media screen and (min-width: 533px){button[data-v-0e6a95b9]{margin-top:2.15rem}} diff --git a/site/plugins/send-button/index.js b/site/plugins/send-button/index.js index d6cd167..293859c 100644 --- a/site/plugins/send-button/index.js +++ b/site/plugins/send-button/index.js @@ -1 +1 @@ -(function(){"use strict";function d(t,e,r,n,o,l,a,i){var s=typeof t=="function"?t.options:t;return s.render=e,s.staticRenderFns=r,s._compiled=!0,s._scopeId="data-v-"+l,{exports:t,options:s}}const _={__name:"SendButtonField",props:{pageUri:String,pageStatus:String},setup(t){const{pageUri:e}=t,r=Vue.ref({icon:"plane",text:"Tester",theme:null,error:null}),n=Vue.ref({icon:"plane",text:"Envoyer",theme:"orange",error:null});async function o(l,a=!1){l.preventDefault();const i=a?r:n;i.value={theme:"blue",text:"En cours…",icon:"loader",error:null};const s={method:"POST",body:JSON.stringify({pageUri:e,isTest:a})};try{const u=await(await fetch("/send-newsletter.json",s)).json();if(u.status==="success")i.value={theme:"green",icon:"check",text:a?"Test envoyé":"Envoi réussi",error:null},a?i.value={icon:"plane",text:"Re-tester",theme:null,error:null}:setTimeout(()=>{location.href=location.href},2e3);else throw new Error(u.message||"Erreur inconnue")}catch(c){i.value={theme:"red",icon:"alert",text:a?"Échec du test":"Erreur",error:c.message}}}return{__sfc:!0,testBtnState:r,sendBtnState:n,send:o}}};var f=function(){var e=this,r=e._self._c,n=e._self._setupProxy;return e.pageStatus==="draft"?r("div",{staticClass:"wrapper"},[r("div",{staticClass:"test-wrapper"},[r("k-button",{staticStyle:{width:"max-content"},attrs:{variant:"filled",help:"test",theme:n.testBtnState.theme,icon:n.testBtnState.icon},on:{click:function(o){return n.send(o,!0)}}},[e._v(e._s(n.testBtnState.text))]),e._m(0),n.testBtnState.error?r("k-box",{staticStyle:{"margin-top":"var(--spacing-1)"},attrs:{theme:"error"}},[e._v(e._s(n.testBtnState.error))]):e._e()],1),r("div",{staticClass:"send-wrapper"},[r("k-button",{attrs:{variant:"filled",theme:n.sendBtnState.theme,icon:n.sendBtnState.icon},on:{click:function(o){return n.send(o)}}},[e._v(e._s(n.sendBtnState.text))]),n.sendBtnState.error?r("k-box",{staticStyle:{"margin-top":"var(--spacing-1)"},attrs:{theme:"error"}},[e._v(e._s(n.sendBtnState.error))]):e._e(),e._m(1)],1)]):e._e()},p=[function(){var t=this,e=t._self._c;return t._self._setupProxy,e("footer",{staticClass:"k-field-footer"},[e("div",{staticClass:"k-help k-field-help k-text"},[e("p",[t._v(" Envoie seulement aux "),e("a",{attrs:{href:"/panel/users",title:"voir la liste"}},[t._v("éditeurs")]),t._v(". ")])])])},function(){var t=this,e=t._self._c;return t._self._setupProxy,e("footer",{staticClass:"k-field-footer"},[e("div",{staticClass:"k-help k-field-help k-text"},[e("strong",[t._v("⚠ Envoie à tous les abonnés.")])])])}],v=d(_,f,p,!1,null,"76f92a36");const m=v.exports;window.panel.plugin("adrienpayet/send-button",{fields:{"send-button":m}})})(); +(function(){"use strict";function d(t,e,r,n,o,l,a,i){var s=typeof t=="function"?t.options:t;return s.render=e,s.staticRenderFns=r,s._compiled=!0,s._scopeId="data-v-"+l,{exports:t,options:s}}const _={__name:"SendButtonField",props:{pageUri:String,pageStatus:String},setup(t){const{pageUri:e}=t,r=Vue.ref({icon:"plane",text:"Tester",theme:null,error:null}),n=Vue.ref({icon:"plane",text:"Envoyer",theme:"orange",error:null});async function o(l,a=!1){l.preventDefault();const i=a?r:n;i.value={theme:"blue",text:"En cours…",icon:"loader",error:null};const s={method:"POST",body:JSON.stringify({pageUri:e,isTest:a})};try{const u=await(await fetch("/send-newsletter.json",s)).json();if(u.status==="success")i.value={theme:"green",icon:"check",text:a?"Test envoyé":"Envoi réussi",error:null},setTimeout(()=>{location.href=location.href},2e3);else throw new Error(u.message||"Erreur inconnue")}catch(c){i.value={theme:"red",icon:"alert",text:a?"Échec du test":"Erreur",error:c.message}}}return{__sfc:!0,testBtnState:r,sendBtnState:n,send:o}}};var f=function(){var e=this,r=e._self._c,n=e._self._setupProxy;return e.pageStatus!=="listed"?r("div",{staticClass:"wrapper"},[r("div",{staticClass:"test-wrapper"},[r("k-button",{staticStyle:{width:"max-content"},attrs:{variant:"filled",help:"test",theme:n.testBtnState.theme,icon:n.testBtnState.icon},on:{click:function(o){return n.send(o,!0)}}},[e._v(e._s(n.testBtnState.text))]),e._m(0),n.testBtnState.error?r("k-box",{staticStyle:{"margin-top":"var(--spacing-1)"},attrs:{theme:"error"}},[e._v(e._s(n.testBtnState.error))]):e._e()],1),r("div",{staticClass:"send-wrapper"},[r("k-button",{attrs:{variant:"filled",theme:n.sendBtnState.theme,icon:n.sendBtnState.icon},on:{click:function(o){return n.send(o)}}},[e._v(e._s(n.sendBtnState.text))]),n.sendBtnState.error?r("k-box",{staticStyle:{"margin-top":"var(--spacing-1)"},attrs:{theme:"error"}},[e._v(e._s(n.sendBtnState.error))]):e._e(),e._m(1)],1)]):e._e()},p=[function(){var t=this,e=t._self._c;return t._self._setupProxy,e("footer",{staticClass:"k-field-footer"},[e("div",{staticClass:"k-help k-field-help k-text"},[e("p",[t._v(" Envoie seulement aux "),e("a",{attrs:{href:"/panel/users",title:"voir la liste"}},[t._v("éditeurs")]),t._v(". ")])])])},function(){var t=this,e=t._self._c;return t._self._setupProxy,e("footer",{staticClass:"k-field-footer"},[e("div",{staticClass:"k-help k-field-help k-text"},[e("strong",[t._v("⚠ Envoie à tous les abonnés.")])])])}],v=d(_,f,p,!1,null,"0e6a95b9");const m=v.exports;window.panel.plugin("adrienpayet/send-button",{fields:{"send-button":m}})})(); diff --git a/site/plugins/send-button/index.php b/site/plugins/send-button/index.php index b63feb1..5b596b4 100755 --- a/site/plugins/send-button/index.php +++ b/site/plugins/send-button/index.php @@ -5,12 +5,16 @@ Kirby::plugin('adrienpayet/send-button', [ 'send-button' => [ 'computed' => [ 'pageUri' => function () { - return $this->model()->uri(); + return $this->model()->uri(); }, 'pageStatus' => function () { - return $this->model()->status(); + return $this->model()->status(); }, - ] - ] - ] + ], + ], + ], + 'routes' => [ + require __DIR__ . '/routes/send-newsletter.php', + require __DIR__ . '/routes/unsubscribe-newsletter.php', + ], ]); diff --git a/site/config/routes/send-newsletter.php b/site/plugins/send-button/routes/send-newsletter.php similarity index 51% rename from site/config/routes/send-newsletter.php rename to site/plugins/send-button/routes/send-newsletter.php index 1329e30..17a2a76 100644 --- a/site/config/routes/send-newsletter.php +++ b/site/plugins/send-button/routes/send-newsletter.php @@ -2,74 +2,78 @@ return [ 'pattern' => '/send-newsletter.json', - 'method' => 'POST', - 'action' => function () { - $jsonRequest = file_get_contents("php://input"); + 'method' => 'POST', + 'action' => function () { + $jsonRequest = file_get_contents('php://input'); $data = json_decode($jsonRequest); if (!$data || !isset($data->pageUri) || !isset($data->isTest)) { return json_encode([ - 'status' => 'error', - 'message' => 'Invalid request data. Required fields: pageUri, isTest.' + 'status' => 'error', + 'message' => 'Invalid request data. Required fields: pageUri, isTest.', ]); } $kirby = kirby(); - $emailPage = page('inscription')->childrenAndDrafts()->find($data->pageUri); + $emailPage = page('lettre')->childrenAndDrafts()->find($data->pageUri); if (!$emailPage) { return json_encode([ - 'status' => 'error', - 'message' => 'The specified page does not exist.' + 'status' => 'error', + 'message' => 'The specified page does not exist.', ]); } $recipients = $data->isTest ? $kirby->users()->pluck('email', null, true) - : page('inscription')->subscribers()->toStructure()->pluck('email', true, true); + : page('lettre')->subscribers()->toStructure()->pluck('email', true, true); if (empty($recipients)) { return json_encode([ - 'status' => 'error', - 'message' => 'No recipients found.' + 'status' => 'error', + 'message' => 'No recipients found.', ]); } $subject = $data->isTest - ? "[TEST] - " . $emailPage->title()->value() + ? '[TEST] - ' . $emailPage->title()->value() : $emailPage->title()->value(); $from = new \Kirby\Cms\User([ 'email' => 'info@actuel-inactuel.fr', 'name' => 'actuel-inactuel', ]); - + try { foreach ($recipients as $recipient) { $kirby->email([ - 'from' => $from, - 'to' => $recipient, - 'subject' => $subject, + 'from' => $from, + 'to' => $recipient, + 'subject' => $subject, 'template' => 'newsletter', - 'data' => [ - 'body' => $emailPage->body() - ] + 'data' => [ + 'body' => $emailPage->body(), + 'url' => (string) $emailPage->url(), + 'recipient' => $recipient, + ], ]); } if (!$data->isTest) { $emailPage->changeStatus('listed'); + } else { + $emailPage->changeStatus('unlisted'); } return json_encode([ - 'status' => 'success', - 'message' => 'Email(s) sent successfully.' + 'status' => 'success', + 'message' => 'Email(s) sent successfully.', ]); } catch (Exception $error) { return json_encode([ - 'status' => 'error', - 'message' => $error->getMessage() . " file " . $error->getFile() . " line " . $error->getLine() + 'status' => 'error', + 'message' => $error->getMessage() . ' file ' . $error->getFile() . ' line ' . $error->getLine(), ]); } - } + }, ]; diff --git a/site/plugins/send-button/routes/unsubscribe-newsletter.php b/site/plugins/send-button/routes/unsubscribe-newsletter.php new file mode 100644 index 0000000..36cf263 --- /dev/null +++ b/site/plugins/send-button/routes/unsubscribe-newsletter.php @@ -0,0 +1,39 @@ + '/deslettre', + 'action' => function () { + $email = get('email'); + $page = page('lettre'); + + $emailExists = in_array(['email' => $email], $page->subscribers()->yaml()); + + if (!$emailExists) { + $title = 'Erreur'; + $body = '

' . $email . ' est introuvable dans la base de données. Vous pouvez demander une déslettre manuelle en écrivant à info@actuel-inactuel.fr.

'; + } else { + $subscribers = array_filter( + $page->subscribers()->yaml(), + fn($subscriber) => $subscriber !== ['email' => $email] + ); + + $page->update([ + 'subscribers' => $subscribers, + ]); + + $title = $email . ' désinscrit'; + $body = '

Si la déslettre automatique n\'a pas fonctionné et que vous continuez à recevoir des mails, vous pouvez demander la déslettre manuelle à info@actuel-inactuel.fr.

'; + + } + + return new Page([ + 'slug' => Str::slug('test'), + 'template' => 'error', + 'status' => 'unlisted', + 'content' => [ + 'title' => $title, + 'body' => $body, + ], + ]); + }, +]; diff --git a/site/plugins/send-button/src/components/SendButtonField.vue b/site/plugins/send-button/src/components/SendButtonField.vue index 40499d7..2aaf7d1 100755 --- a/site/plugins/send-button/src/components/SendButtonField.vue +++ b/site/plugins/send-button/src/components/SendButtonField.vue @@ -1,5 +1,5 @@