feat(newsletter): Ajoute l'inscription et la désinscription à la newsletter
```
This commit is contained in:
Serreau Jovann
2026-01-11 13:26:10 +01:00
parent 6ba9d30b6a
commit e76650d5f1
16 changed files with 604 additions and 2 deletions

3
.env
View File

@@ -78,3 +78,6 @@ TURNSTILE_SECRET=1x0000000000000000000000000000000AA
###> stripe/stripe-php ### ###> stripe/stripe-php ###
STRIPE_SECRET_KEY=sk_test_*** STRIPE_SECRET_KEY=sk_test_***
###< stripe/stripe-php ### ###< stripe/stripe-php ###
NOTIFUSE_CLIENT_EMAIL=jovann@siteconseil.fr
NOTIFUSE_CLIENT_SECRET=d04zCk3Fa45oOjDWHpAvc1AZxnLdGffOnNWK+Jt2yXf37+FTfuMMHb8flcfPMqLluRR3rvhbr555r6j1DEigrA==
NOTIFUSE_WORKSPACE_ID=ecosplay

View File

@@ -6,6 +6,8 @@ use App\Entity\Account;
use App\Entity\AccountResetPasswordRequest; use App\Entity\AccountResetPasswordRequest;
use App\Form\RequestPasswordConfirmType; use App\Form\RequestPasswordConfirmType;
use App\Form\RequestPasswordRequestType; use App\Form\RequestPasswordRequestType;
use App\Service\Mailer\Mailer;
use App\Service\NotifuseClient;
use App\Service\ResetPassword\Event\ResetPasswordConfirmEvent; use App\Service\ResetPassword\Event\ResetPasswordConfirmEvent;
use App\Service\ResetPassword\Event\ResetPasswordEvent; use App\Service\ResetPassword\Event\ResetPasswordEvent;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
@@ -16,13 +18,72 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\HttpClient\HttpClientInterface;
use Twig\Environment; use Twig\Environment;
class HomeController extends AbstractController class HomeController extends AbstractController
{ {
#[Route(path: '/newsletter/{email}', name: 'app_newsletter_validate', options: ['sitemap' => false], methods: ['GET','POST'])]
public function newsletterValidate(string $email,NotifuseClient $notifuseClient): Response
{
$notifuseClient->login();
if($notifuseClient->contactExist($email)){
$notifuseClient->addList($email,'newsletter');
}
return $this->render('newsletter_confirmed.twig',[
'no_index' => true
]);
}
#[Route(path: '/newsletter/remove/{email}', name: 'app_newsletter_validate_remove', options: ['sitemap' => false], methods: ['GET', 'POST'])]
public function newsletterRemoveValidate(string $email, Request $request,NotifuseClient $notifuseClient): Response
{
$notifuseClient->login();
// 1. Gestion du "One-Click Unsubscribe" (Requête POST automatique des clients mail)
if ($request->isMethod('POST')) {
// Logique pour désinscrire l'utilisateur en base de données
// $userRepo->unsubscribeByEmail($email);
if($notifuseClient->contactExist($email)){
$notifuseClient->contactDelete($email);
}
return new Response('Unsubscribe successful', Response::HTTP_OK);
}
// 2. Gestion de l'affichage (Requête GET pour l'utilisateur qui clique)
// Ici, vous pouvez aussi traiter la désinscription si ce n'est pas déjà fait
if($notifuseClient->contactExist($email)){
$notifuseClient->contactDelete($email);
}
return $this->render('newsletter_remove.twig',[
'no_index' => true
]);
}
#[Route(path: '/newsletter', name: 'app_newsletter', options: ['sitemap' => false], methods: ['GET','POST'])]
public function newsletter(Request $request,NotifuseClient $notifuseClient,Mailer $mailer): Response
{
$request->request->set('email','jovannserreau@siteconseil.fr');
$datas= $request->request->all();
$notifuseClient->login();
$exit = $notifuseClient->contactExist($datas['email']);
if($exit == false){
$notifuseClient->contactAdd($datas['email']);
//send email vot validation
}
$mailer->send($datas['email'],$datas['email'],'[E-Cosplay] - Valider votre inscription à la newsletter',"mails/newsletter-valiate.twig",[
'confirmationUrl' => $this->generateUrl('app_newsletter_validate',['email'=>$datas['email']],UrlGeneratorInterface::ABSOLUTE_URL),
],[],true);
return $this->render('newsletter.twig', [
'no_index' => true
]);
}
#[Route(path: '/', name: 'app_home', options: ['sitemap' => false], methods: ['GET'])] #[Route(path: '/', name: 'app_home', options: ['sitemap' => false], methods: ['GET'])]
public function index(): Response public function index(): Response
{ {

View File

@@ -64,7 +64,8 @@ class Mailer
string $subject, string $subject,
string $template, string $template,
array $data, array $data,
array $files = [] array $files = [],
bool $isNewsletter = false,
): void { ): void {
$dest = new Address($address, $addressName); $dest = new Address($address, $addressName);
$src = new Address("contact@e-cosplay.fr", "E-Cosplay"); $src = new Address("contact@e-cosplay.fr", "E-Cosplay");
@@ -74,6 +75,19 @@ class Mailer
->to($dest) ->to($dest)
->from($src); ->from($src);
$header = $mail->getHeaders();
if($isNewsletter) {
$unsubscribeUrl = $this->urlGenerator->generate('app_newsletter_validate_remove',['email'=>$address],UrlGeneratorInterface::ABSOLUTE_URL);
$unsubscribeEmail = "mailto:contact@e-cosplay.fr?subject=unsubscribe";
// Ajout de l'en-tête standard
$header->addHeader('List-Unsubscribe', "<$unsubscribeEmail>, <$unsubscribeUrl>");
$header->addHeader('List-Unsubscribe-Post', 'List-Unsubscribe=One-Click');
$data['unsubscribeUrl'] = $unsubscribeUrl;
}
$mail->setHeaders($header);
$mjmlGenerator = $this->environment->render($template, [ $mjmlGenerator = $this->environment->render($template, [
'system' => [ 'system' => [
'subject' => $subject, 'subject' => $subject,
@@ -82,6 +96,7 @@ class Mailer
'datas' => $data, 'datas' => $data,
]); ]);
$htmlContent = $this->convertMjmlToHtml($mjmlGenerator); $htmlContent = $this->convertMjmlToHtml($mjmlGenerator);
$txtContent = $this->environment->render('txt-'.$template,[ $txtContent = $this->environment->render('txt-'.$template,[
'system' => [ 'system' => [

View File

@@ -0,0 +1,119 @@
<?php
namespace App\Service;
use DateTime;
use Detection\Cache\CacheItem;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Twig\Cache\FilesystemCache;
class NotifuseClient
{
public function __construct(private readonly HttpClientInterface $httpClient,private readonly KernelInterface $kernel)
{
$this->email = $_ENV['NOTIFUSE_CLIENT_EMAIL'];
$this->secret = $_ENV['NOTIFUSE_CLIENT_SECRET'];
$this->workspacce = $_ENV['NOTIFUSE_WORKSPACE_ID'];
$this->filesystem = new FilesystemAdapter(
'notifuse',
3600,
$this->kernel->getCacheDir()
);
}
public function login()
{
$this->accessToken = $this->filesystem->get('access_token',function (\Symfony\Component\Cache\CacheItem $cacheItem) {
$timestamp = time();
$message = $this->email . ":" . $timestamp;
$signature = hash_hmac('sha256', $message, $this->secret);
$response = $this->httpClient->request('POST', 'https://notifuse.esy-web.dev/api/user.rootSignin', [
'headers' => [
'Content-Type' => 'application/json',
],
'json' => [
'email' => $this->email,
'timestamp' => $timestamp,
'signature' => $signature,
]
]);
$content = json_decode($response->getContent());
$date = DateTime::createFromFormat('Y-m-d\TH:i:s.u', substr($content->expires_at, 0, 26));
$cacheItem->expiresAt($date);
return $content->token;
});
}
public function contactExist(string $email)
{
try {
$this->httpClient->request('GET', 'https://notifuse.esy-web.dev/api/contacts.getByEmail?workspace_id=' . $this->workspacce . '&email=' . $email, [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->accessToken,
]
]);
return true;
} catch (\Exception $e) {
return false;
} catch (TransportExceptionInterface $e) {
return false;
}
}
public function contactAdd(mixed $email)
{
$this->httpClient->request('POST', 'https://notifuse.esy-web.dev/api/contacts.upsert', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->accessToken,
],
'json' => [
'workspace_id' => $this->workspacce,
'contact' => [
'email' => $email,
]
]
]);
}
public function contactDelete(string $email)
{
$this->httpClient->request('POST', 'https://notifuse.esy-web.dev/api/contacts.delete', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->accessToken,
],
'json' => [
'workspace_id' => $this->workspacce,
'email' => $email,
]
]);
}
public function addList(string $email, string $string)
{
$this->httpClient->request('POST', 'https://notifuse.esy-web.dev/api/lists.subscribe', [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->accessToken,
],
'json' => [
'workspace_id' => $this->workspacce,
'contact' => [
'email' => $email,
],
'list_ids' => [
$string
]
]
]);
}
}

View File

@@ -178,6 +178,17 @@
{# SOCIAL & STRIPE #} {# SOCIAL & STRIPE #}
<div class="space-y-6"> <div class="space-y-6">
<h3 class="text-3xl font-black uppercase tracking-tighter italic border-b-4 border-gray-900 inline-block">{{ 'footer_follow_us_title'|trans }}</h3> <h3 class="text-3xl font-black uppercase tracking-tighter italic border-b-4 border-gray-900 inline-block">{{ 'footer_follow_us_title'|trans }}</h3>
<div class="bg-white border-4 border-gray-900 p-4 shadow-[6px_6px_0px_rgba(0,0,0,1)]">
<p class="text-xs font-black uppercase mb-2 tracking-widest">{{ 'newsletter.title'|trans }}</p>
<form action="{{ path('app_newsletter') }}" method="POST" class="flex flex-col gap-2">
<input required type="email" name="email" placeholder="email@e-cosplay.fr"
class="border-2 border-gray-900 p-2 text-xs font-bold uppercase focus:bg-pink-100 outline-none">
<button type="submit"
class="bg-indigo-600 text-white border-2 border-gray-900 py-2 px-4 text-xs font-black uppercase hover:bg-black hover:shadow-none shadow-[2px_2px_0px_rgba(0,0,0,1)] transition-all active:translate-x-1 active:translate-y-1">
{{ 'newsletter.subscribe'|trans }}
</button>
</form>
</div>
<div class="flex gap-4"> <div class="flex gap-4">
<a href="https://www.facebook.com/assocationecosplay" class="w-12 h-12 border-4 border-gray-900 flex items-center justify-center hover:bg-white transition-all"><i class="fab fa-facebook-f text-xl"></i></a> <a href="https://www.facebook.com/assocationecosplay" class="w-12 h-12 border-4 border-gray-900 flex items-center justify-center hover:bg-white transition-all"><i class="fab fa-facebook-f text-xl"></i></a>
<a href="https://www.instagram.com/asso_ecosplay/" class="w-12 h-12 border-4 border-gray-900 flex items-center justify-center hover:bg-white transition-all"><i class="fab fa-instagram text-xl"></i></a> <a href="https://www.instagram.com/asso_ecosplay/" class="w-12 h-12 border-4 border-gray-900 flex items-center justify-center hover:bg-white transition-all"><i class="fab fa-instagram text-xl"></i></a>

View File

@@ -22,7 +22,6 @@
{# Section d'en-tête #} {# Section d'en-tête #}
<mj-section background-color="#ffffff" padding-bottom="0px"> <mj-section background-color="#ffffff" padding-bottom="0px">
<mj-column> <mj-column>
{# Logo mis à jour pour SARL SITECONSEIL #}
<mj-image src="{{ system.path }}{{ asset('assets/images/logo.jpg') }}" alt="Logo E-COSPLAY" align="center" width="150px" padding-bottom="20px"></mj-image> <mj-image src="{{ system.path }}{{ asset('assets/images/logo.jpg') }}" alt="Logo E-COSPLAY" align="center" width="150px" padding-bottom="20px"></mj-image>
</mj-column> </mj-column>
</mj-section> </mj-section>

View File

@@ -0,0 +1,54 @@
{% extends 'mails/base.twig' %}
{% block subject %}
🚀 Valide ton inscription à la newsletter E-Cosplay !
{% endblock %}
{% block content %}
<mj-section background-color="#ffffff" padding-top="20px">
<mj-column width="100%">
{# Titre Impact #}
<mj-text font-size="28px" color="#1A1A1A" font-weight="900" align="center" font-style="italic" text-transform="uppercase">
Presque fini !
</mj-text>
<mj-divider border-color="#fabf04" border-width="4px" width="60px"></mj-divider>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" padding-top="0px">
<mj-column width="90%" border="3px solid #111827" background-color="#fbfbfb" padding="20px">
<mj-text font-size="16px" color="#111827" line-height="24px" align="center">
Merci de vouloir rejoindre la communauté <strong>E-Cosplay</strong> !
</mj-text>
<mj-text font-size="15px" color="#444444" line-height="22px" align="center">
Pour confirmer que c'est bien toi et commencer à recevoir nos actualités, évènements et projets, clique sur le bouton "BOMBE" ci-dessous :
</mj-text>
{# Bouton Action Brutaliste #}
<mj-button href="{{ datas.confirmationUrl }}" background-color="#4f46e5" color="#ffffff" font-size="18px" font-weight="900" border="3px solid #111827" inner-padding="15px 30px" border-radius="0px" text-transform="uppercase" padding-top="20px">
Confirmer mon inscription
</mj-button>
<mj-text font-size="12px" color="#ec4899" align="center" font-weight="bold" padding-top="15px">
Si tu n'es pas à l'origine de cette demande, ignore simplement cet email.
</mj-text>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" padding-top="20px">
<mj-column width="100%">
<mj-text font-size="13px" color="#888888" align="center" line-height="18px">
Si le bouton ne fonctionne pas, copie et colle ce lien dans ton navigateur :<br>
<a href="{{ datas.confirmationUrl }}" style="color: #4f46e5;">{{ datas.confirmationUrl }}</a>
</mj-text>
</mj-column>
</mj-section>
<mj-section padding-top="20px">
<mj-column width="100%">
<mj-text font-size="11px" color="#999999" align="center">
<a href="{{ datas.unsubscribeUrl }}" style="color: #999999;">Se désinscrire</a>
</mj-text>
</mj-column>
</mj-section>
{% endblock %}

47
templates/newsletter.twig Normal file
View File

@@ -0,0 +1,47 @@
{% extends 'base.twig' %}
{% block title %}{{'newsletter_confirme_register'|trans}}{% endblock %}
{% block meta_description %}{{'newsletter_confirme_register'|trans}}{% endblock %}
{% block canonical_url %}
<link rel="canonical" href="{{ url('app_newsletter') }}" />
{% endblock %}
{% block body %}
<div class="bg-white min-h-[70vh] flex items-center justify-center py-20">
<div class="container mx-auto px-6 max-w-2xl text-center">
{# --- CARTE DE CONFIRMATION STYLE NEUBRUTALISTE --- #}
<div class="bg-white border-8 border-gray-900 p-10 md:p-16 shadow-[20px_20px_0px_0px_rgba(79,70,229,1)] transform -rotate-1">
{# Icône Email #}
<div class="text-7xl mb-6 transform rotate-6 inline-block text-pink-500">
<i class="fas fa-envelope-open-text"></i>
</div>
<h1 class="text-4xl md:text-6xl font-black uppercase italic mb-6 tracking-tighter leading-none text-gray-900">
{{ 'newsletter.confirm_page.header'|trans }}
</h1>
<div class="w-24 h-4 bg-yellow-400 mx-auto mb-8 border-2 border-gray-900"></div>
<p class="text-xl md:text-2xl font-bold text-gray-800 mb-10 leading-relaxed uppercase">
{{ 'newsletter.confirm_page.message'|trans }}
</p>
{# Info supplémentaire #}
<div class="bg-gray-100 p-4 border-4 border-gray-900 border-dashed mb-10">
<p class="text-xs font-black uppercase tracking-widest text-gray-600">
{{ 'newsletter.confirm_page.spam_hint'|trans }}
</p>
</div>
{# Bouton retour #}
<a href="{{ path('app_home') }}" class="inline-block px-10 py-4 bg-indigo-600 text-white border-4 border-gray-900 font-black uppercase hover:bg-black transition-all shadow-[6px_6px_0px_0px_rgba(0,0,0,1)] active:shadow-none active:translate-x-1 active:translate-y-1">
{{ 'newsletter.confirm_page.back_home'|trans }}
</a>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,49 @@
{% extends 'base.twig' %}
{% block title %}{{ 'newsletter.success.title'|trans|default('Inscription validée !') }}{% endblock %}
{% block body %}
<div class="bg-white min-h-[70vh] flex items-center justify-center py-20 px-4">
<div class="container mx-auto max-w-2xl text-center">
{# --- CARTE DE SUCCÈS STYLE NEUBRUTALISTE --- #}
<div class="bg-white border-8 border-gray-900 p-10 md:p-16 shadow-[20px_20px_0px_0px_#fabf04] transform rotate-2">
{# Icône Succès #}
<div class="text-7xl mb-6 inline-block animate-bounce">
🎉
</div>
<h1 class="text-4xl md:text-6xl font-black uppercase italic mb-6 tracking-tighter leading-none text-gray-900">
{{ 'newsletter.success.header'|trans }}
</h1>
<div class="w-full h-2 bg-indigo-600 mb-8 border-2 border-gray-900"></div>
<p class="text-xl md:text-2xl font-bold text-gray-800 mb-10 leading-relaxed uppercase">
{{ 'newsletter.success.message'|trans }}
</p>
{# Bloc Info Fun #}
<div class="bg-pink-500 text-white p-4 border-4 border-gray-900 shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] mb-10">
<p class="text-sm font-black uppercase tracking-widest">
{{ 'newsletter.success.hint'|trans }}
</p>
</div>
{# Bouton Retour #}
<a href="{{ path('app_home') }}"
class="inline-block px-10 py-4 bg-gray-900 text-white border-4 border-gray-900 font-black uppercase hover:bg-indigo-600 transition-all shadow-[6px_6px_0px_0px_#fabf04] active:shadow-none active:translate-x-1 active:translate-y-1">
{{ 'newsletter.success.back_button'|trans }}
</a>
</div>
{# Déco de fond style comics #}
<div class="mt-12 flex justify-center gap-2 opacity-20">
<div class="w-4 h-4 bg-indigo-600 rounded-full"></div>
<div class="w-4 h-4 bg-pink-500 rounded-full"></div>
<div class="w-4 h-4 bg-yellow-400 rounded-full"></div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,44 @@
{% extends 'base.twig' %}
{% block title %}{{ 'newsletter.unsubscribe.title'|trans|default('Désinscription réussie') }}{% endblock %}
{% block body %}
<div class="bg-white min-h-[70vh] flex items-center justify-center py-20 px-4">
<div class="container mx-auto max-w-2xl">
{# --- CARTE DE DÉSINSCRIPTION STYLE BRUTALISTE --- #}
<div class="bg-white border-8 border-gray-900 p-10 md:p-16 shadow-[20px_20px_0px_0px_rgba(236,72,153,1)] transform rotate-1">
{# Icône Bye Bye #}
<div class="text-7xl mb-6 transform -rotate-12 inline-block">
👋
</div>
<h1 class="text-4xl md:text-5xl font-black uppercase italic mb-6 tracking-tighter leading-none text-gray-900">
{{ 'newsletter.unsubscribe.header'|trans }}
</h1>
{# Ligne de séparation jaune #}
<div class="w-32 h-4 bg-yellow-400 mb-8 border-2 border-gray-900"></div>
<p class="text-xl md:text-2xl font-bold text-gray-800 mb-10 leading-relaxed uppercase">
{{ 'newsletter.unsubscribe.message'|trans }}
</p>
{# Message de regret stylisé #}
<div class="bg-gray-100 p-6 border-4 border-gray-900 border-dashed mb-10">
<p class="text-sm font-black uppercase tracking-widest text-gray-600">
{{ 'newsletter.unsubscribe.footer'|trans }}
</p>
</div>
{# Bouton retour avec effet de mouvement #}
<a href="{{ path('app_home') }}"
class="inline-block px-10 py-4 bg-indigo-600 text-white border-4 border-gray-900 font-black uppercase hover:bg-black transition-all shadow-[6px_6px_0px_0px_rgba(0,0,0,1)] active:shadow-none active:translate-x-1 active:translate-y-1">
{{ 'newsletter.unsubscribe.back_button'|trans }}
</a>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,26 @@
{% extends 'txt-mails/base.twig' %}
{% block subject %}
🚀 Valide ton inscription à la newsletter E-Cosplay !
{% endblock %}
{% block content %}
PRESQUE FINI !
==============
Merci de vouloir rejoindre la communauté E-Cosplay !
Pour confirmer que c'est bien toi et commencer à recevoir nos actualités,
événements et projets, merci de valider ton inscription en copiant
le lien suivant dans ton navigateur :
LIEN DE CONFIRMATION :
{{ datas.confirmationUrl }}
----------------------------------------------------------
Si tu n'es pas à l'origine de cette demande,
ignore simplement cet email. Ton adresse ne sera pas conservée.
----------------------------------------------------------
Pour ne plus recevoir d'invitations :
{{ datas.unsubscribeUrl }}
{% endblock %}

View File

@@ -1132,3 +1132,38 @@ Sujet: "主题"
Téléphone (facultatif): "电话 (选填)" Téléphone (facultatif): "电话 (选填)"
Votre message: "你的留言" Votre message: "你的留言"
partner_w: '官方网站' partner_w: '官方网站'
newsletter_confirme_register: "邮件订阅确认 - E-Cosplay"
newsletter:
confirm_page:
header: "请查收你的邮件!"
message: "确认订阅的邮件已发送至你的邮箱,请点击邮件中的链接完成验证。"
spam_hint: "别忘了检查一下垃圾邮件箱Spam"
back_home: "返回首页"
title: "加入时事通讯"
subscribe: "立即订阅"
unsubscribe:
title: "取消订阅 - E-Cosplay"
header: "操作完成!"
message: "你的邮箱已成功从我们的订阅列表中移除。你将不再收到我们的后续邮件。"
back: "返回官网"
link_text: "取消订阅时事通讯" # 用于邮件页脚的链接文字
footer: "你的数据已从发送列表中删除。我们会想念你的!"
back_button: "返回官网"
# 闪存消息 (Flash Messages)
flash:
success_check_email: "🚀 第一步成功!请检查邮件并确认你的订阅。"
success_confirmed: "🎉 恭喜!你已正式加入 E-Cosplay 时事通讯。"
error_already_subscribed: "💡 你已经订阅过我们的时事通讯啦!"
error_invalid_email: "⚠️ 哎呀!这个邮箱地址看起来不太正确。"
error_technical: "🛠️ 出现了一些技术故障,请稍后再试。"
unsubscribed: "👋 已成功取消订阅。期待下次相见!"
# 最终成功页面 (Success Page)
success:
title: "订阅成功 - E-Cosplay"
header: "欢迎加入!"
message: "你的时事通讯订阅已成功验证。欢迎来到我们的社区!"
hint: "准备好在你的收件箱里接收最精彩的 Cosplay 资讯吧。"
back_button: "开启旅程!"

View File

@@ -1204,3 +1204,38 @@ Sujet: "Subject"
Téléphone (facultatif): "Phone (Optional)" Téléphone (facultatif): "Phone (Optional)"
Votre message: "Your Message" Votre message: "Your Message"
partner_w: 'Website' partner_w: 'Website'
newsletter_confirme_register: "Newsletter Confirmation - E-Cosplay"
newsletter:
confirm_page:
header: "CHECK YOUR EMAILS!"
message: "A subscription confirmation has been sent by email. Please click the link inside to validate your registration."
spam_hint: "Don't forget to check your junk/spam folder!"
back_home: "Back to Home"
title: "JOIN THE NEWSLETTER"
subscribe: "SUBSCRIBE"
unsubscribe:
title: "Newsletter Unsubscribe - E-Cosplay"
header: "IT'S DONE!"
message: "Your email address has been successfully removed from our mailing list. You will no longer receive updates from us."
back: "Back to site"
link_text: "Unsubscribe from newsletter" # Link text for email footers
footer: "Your data has been deleted from our mailing list. We'll miss you!"
back_button: "Back to the website"
# Flash Messages
flash:
success_check_email: "🚀 Step 1 successful! Check your emails to confirm your subscription."
success_confirmed: "🎉 Congratulations! You are now part of the E-Cosplay newsletter."
error_already_subscribed: "💡 You are already subscribed to our newsletter!"
error_invalid_email: "⚠️ Oops! That email address doesn't look valid."
error_technical: "🛠️ A technical issue occurred. Please try again later."
unsubscribed: "👋 You've been unsubscribed. See you soon!"
# Success Page
success:
title: "Subscription Confirmed - E-Cosplay"
header: "YOU'RE IN!"
message: "Your newsletter subscription has been successfully validated. Welcome to the community!"
hint: "Get ready to receive the best of Cosplay directly in your inbox."
back_button: "LET'S GO!"

View File

@@ -1140,3 +1140,38 @@ Sujet: "Asunto"
Téléphone (facultatif): "Teléfono (opcional)" Téléphone (facultatif): "Teléfono (opcional)"
Votre message: "Tu mensaje" Votre message: "Tu mensaje"
partner_w: 'Sitio web' partner_w: 'Sitio web'
newsletter_confirme_register: "Confirmación de la Newsletter - E-Cosplay"
newsletter:
confirm_page:
header: "¡REVISA TU CORREO!"
message: "Te hemos enviado un correo de confirmación. Por favor, haz clic en el enlace para validar tu suscripción."
spam_hint: "¡No olvides revisar tu carpeta de correo no deseado (Spam)!"
back_home: "Volver al inicio"
title: "ÚNETE A LA NEWSLETTER"
subscribe: "SUSCRIBIRSE"
unsubscribe:
title: "Darse de baja de la Newsletter - E-Cosplay"
header: "¡HECHO!"
message: "Tu dirección de correo ha sido eliminada de nuestra lista. Ya no recibirás más noticias por nuestra parte."
back: "Volver al sitio"
link_text: "Darse de baja de la newsletter" # Texto para el enlace al final de los correos
footer: "Tus datos han sido eliminados de nuestra lista de envío. ¡Te echaremos de menos!"
back_button: "Volver al sitio web"
# Mensajes Flash
flash:
success_check_email: "🚀 ¡Paso 1 completado! Revisa tu correo para confirmar tu suscripción."
success_confirmed: "🎉 ¡Felicidades! Ya formas parte de la newsletter de E-Cosplay."
error_already_subscribed: "💡 ¡Ya estás suscrito a nuestra newsletter!"
error_invalid_email: "⚠️ ¡Ups! Esta dirección de correo no parece válida."
error_technical: "🛠️ Ha ocurrido un problema técnico. Inténtalo de nuevo más tarde."
unsubscribed: "👋 Se ha tramitado tu baja. ¡Hasta pronto!"
# Página de éxito final
success:
title: "Suscripción Confirmada - E-Cosplay"
header: "¡YA ESTÁS DENTRO!"
message: "Tu suscripción a la newsletter ha sido validada con éxito. ¡Bienvenido a la comunidad!"
hint: "Prepárate para recibir lo mejor del Cosplay directamente en tu bandeja de entrada."
back_button: "¡VAMOS ALLÁ!"

View File

@@ -1191,3 +1191,37 @@ profils.password.1: "MOT DE PASSE"
profils.password_holder.1: "MOT DE PASSE" profils.password_holder.1: "MOT DE PASSE"
profils.password.2: "CONFIRMER LE MOT DE PASSE" profils.password.2: "CONFIRMER LE MOT DE PASSE"
profils.password_holder.2: "CONFIRMER LE MOT DE PASSE" profils.password_holder.2: "CONFIRMER LE MOT DE PASSE"
newsletter_confirme_register: "Confirmation de la Newsletter - E-Cosplay"
newsletter:
confirm_page:
header: "VÉRIFIE TES MAILS !"
message: "Une confirmation d'inscription à la newsletter a été envoyée par mail, merci de cliquer dessus pour valider."
spam_hint: "Pense à vérifier tes courriers indésirables (Spams) !"
back_home: "Retour à l'accueil"
title: "REJOINDRE LA NEWSLETTER"
subscribe: "S'ENREGISTRER"
unsubscribe:
title: "Désinscription Newsletter - E-Cosplay"
header: "C'EST FAIT !"
message: "Ton adresse email a bien été retirée de notre liste de diffusion. Tu ne recevras plus de nouvelles de notre part."
back: "Retour au site"
link_text: "Se désabonner de la newsletter" # Texte pour le lien en bas des mails
footer: "Tes données ont été supprimées de notre liste d'envoi. Tu vas nous manquer !"
back_button: "Retour sur le site"
# Messages Flash (s'affichent en haut du site)
flash:
success_check_email: "🚀 Étape 1 réussie ! Vérifie tes mails pour confirmer ton inscription."
success_confirmed: "🎉 Félicitations ! Tu fais maintenant partie de la newsletter E-Cosplay."
error_already_subscribed: "💡 Tu es déjà inscrit à notre newsletter !"
error_invalid_email: "⚠️ Oups ! Cette adresse email ne semble pas valide."
error_technical: "🛠️ Un problème technique est survenu. Réessaie plus tard."
unsubscribed: "👋 Ta désinscription a été prise en compte. À bientôt !"
# Textes de succès final
success:
title: "Inscription Confirmée - E-Cosplay"
header: "TU ES INSCRIT !"
message: "Ton inscription a été validée avec succès. Bienvenue dans la communauté !"
hint: "Prépare-toi à recevoir le meilleur du Cosplay directement dans ta boîte."
back_button: "C'EST PARTI !"

View File

@@ -1140,3 +1140,38 @@ Sujet: "Betreff"
Téléphone (facultatif): "Telefon (optional)" Téléphone (facultatif): "Telefon (optional)"
Votre message: "Deine Nachricht" Votre message: "Deine Nachricht"
partner_w: 'Webseite' partner_w: 'Webseite'
newsletter_confirme_register: "Newsletter-Bestätigung - E-Cosplay"
newsletter:
confirm_page:
header: "PRÜFE DEINE MAILS!"
message: "Eine Bestätigungsmail wurde an dich versendet. Bitte klicke auf den Link in der Mail, um deine Anmeldung abzuschließen."
spam_hint: "Schau auch unbedingt in deinen Spam-Ordner nach!"
back_home: "Zurück zur Startseite"
title: "NEWSLETTER ABONNIEREN"
subscribe: "ANMELDEN"
unsubscribe:
title: "Newsletter-Abmeldung - E-Cosplay"
header: "ERLEDIGT!"
message: "Deine E-Mail-Adresse wurde erfolgreich aus unserem Verteiler entfernt. Du wirst keine weiteren Nachrichten von uns erhalten."
back: "Zurück zur Seite"
link_text: "Newsletter abbestellen" # Text für den Link im Footer der Mails
footer: "Deine Daten wurden aus unserer Liste gelöscht. Wir werden dich vermissen!"
back_button: "Zurück zur Website"
# Flash-Nachrichten
flash:
success_check_email: "🚀 Schritt 1 abgeschlossen! Prüfe deine Mails, um das Abo zu bestätigen."
success_confirmed: "🎉 Glückwunsch! Du bist jetzt Teil des E-Cosplay Newsletters."
error_already_subscribed: "💡 Du bist bereits für unseren Newsletter angemeldet!"
error_invalid_email: "⚠️ Hoppla! Diese E-Mail-Adresse scheint nicht gültig zu sein."
error_technical: "🛠️ Ein technisches Problem ist aufgetreten. Bitte versuche es später noch einmal."
unsubscribed: "👋 Deine Abmeldung wurde erfolgreich durchgeführt. Bis bald!"
# Erfolgsseite (Final)
success:
title: "Anmeldung bestätigt - E-Cosplay"
header: "DU BIST DABEI!"
message: "Deine Anmeldung zum Newsletter wurde erfolgreich bestätigt. Willkommen in der Community!"
hint: "Mach dich bereit für das Beste aus der Welt des Cosplays, direkt in deinem Posteingang."
back_button: "LOS GEHT'S!"