Add confirmation message for newsletter signup

Add success confirmation message to newsletter plugin
Update translation files with confirmation text
Improve form handling to show confirmation message
Add styling for confirmation message display
Ensure name field is properly included in form
This commit is contained in:
Ruben 2026-02-07 00:32:43 +01:00
parent 99ef5f93c2
commit b88baf1bef
3 changed files with 31 additions and 13 deletions

View file

@ -106,4 +106,5 @@ email_placeholder = "Your email address"
notice = "We send about 12 emails per year. You can unsubscribe whenever you want." notice = "We send about 12 emails per year. You can unsubscribe whenever you want."
submit_button = "Subscribe" submit_button = "Subscribe"
success_message = "Check your inbox!" success_message = "Check your inbox!"
success_confirm = "Thank you! We've sent you an email. Open the link in the email and confirm to complete your subscription."
error_message = "Something went wrong!" error_message = "Something went wrong!"

View file

@ -110,4 +110,5 @@ email_placeholder = "Din e-postadresse"
notice = "Vi sender omtrent 12 e-poster i året. Du kan melde deg av når som helst." notice = "Vi sender omtrent 12 e-poster i året. Du kan melde deg av når som helst."
submit_button = "Meld deg på" submit_button = "Meld deg på"
success_message = "Sjekk innboksen din!" success_message = "Sjekk innboksen din!"
success_confirm = "Takk! Vi har sendt en e-post til deg. Åpne lenken i e-posten og bekreft for å fullføre påmeldingen."
error_message = "Noe gikk galt!" error_message = "Noe gikk galt!"

View file

@ -43,6 +43,7 @@ function newsletterT(string $key): string {
'notice' => 'Vi sender ca. 12 e-poster i året.', 'notice' => 'Vi sender ca. 12 e-poster i året.',
'submit_button' => 'Meld deg på', 'submit_button' => 'Meld deg på',
'success_message' => 'Sjekk innboksen din!', 'success_message' => 'Sjekk innboksen din!',
'success_confirm' => 'Takk! Vi har sendt en e-post til deg. Åpne lenken i e-posten og bekreft for å fullføre påmeldingen.',
'error_message' => 'Noe gikk galt!' 'error_message' => 'Noe gikk galt!'
]; ];
return $fallbacks[$key] ?? $key; return $fallbacks[$key] ?? $key;
@ -121,6 +122,7 @@ function newsletterGetTranslations(): array {
'notice' => htmlspecialchars(newsletterT('notice'), ENT_QUOTES, 'UTF-8'), 'notice' => htmlspecialchars(newsletterT('notice'), ENT_QUOTES, 'UTF-8'),
'submitButton' => htmlspecialchars(newsletterT('submit_button'), ENT_QUOTES, 'UTF-8'), 'submitButton' => htmlspecialchars(newsletterT('submit_button'), ENT_QUOTES, 'UTF-8'),
'successMessage' => htmlspecialchars(newsletterT('success_message'), ENT_QUOTES, 'UTF-8'), 'successMessage' => htmlspecialchars(newsletterT('success_message'), ENT_QUOTES, 'UTF-8'),
'successConfirm' => htmlspecialchars(newsletterT('success_confirm'), ENT_QUOTES, 'UTF-8'),
'errorMessage' => htmlspecialchars(newsletterT('error_message'), ENT_QUOTES, 'UTF-8'), 'errorMessage' => htmlspecialchars(newsletterT('error_message'), ENT_QUOTES, 'UTF-8'),
]; ];
} }
@ -160,14 +162,22 @@ function newsletterGetScript(): string {
.then(function(data) { .then(function(data) {
btn.classList.remove('is-loading'); btn.classList.remove('is-loading');
if (data.success) { if (data.success) {
btn.classList.add('is-success'); var confirmMsg = form.getAttribute('data-success-confirm');
var successTextEl = btn.querySelector('.btn-success-text'); if (confirmMsg) {
var successMsg = form.getAttribute('data-success-message'); var notice = document.createElement('p');
if (successTextEl && successMsg) successTextEl.textContent = successMsg; notice.className = 'newsletter-confirm';
setTimeout(function() { notice.textContent = confirmMsg;
btn.classList.remove('is-success'); form.replaceWith(notice);
btn.disabled = false; } else {
}, 5000); btn.classList.add('is-success');
var successTextEl = btn.querySelector('.btn-success-text');
var successMsg = form.getAttribute('data-success-message');
if (successTextEl && successMsg) successTextEl.textContent = successMsg;
setTimeout(function() {
btn.classList.remove('is-success');
btn.disabled = false;
}, 5000);
}
} else { } else {
btn.classList.add('is-error'); btn.classList.add('is-error');
var errorTextEl = btn.querySelector('.btn-error-text'); var errorTextEl = btn.querySelector('.btn-error-text');
@ -252,18 +262,18 @@ function newsletterRenderSmall(string $introText, string $formId): string {
$html = <<<HTML $html = <<<HTML
<aside class="newsletter-section newsletter-small" id="{$escapedFormId}"> <aside class="newsletter-section newsletter-small" id="{$escapedFormId}">
<p class="newsletter-intro">{$escapedIntro}</p> <p class="newsletter-intro">{$escapedIntro}</p>
<form class="newsletter-form" method="post" data-newsletter-form data-success-message="{$t['successMessage']}" data-error-message="{$t['errorMessage']}"> <form class="newsletter-form" method="post" data-newsletter-form data-success-message="{$t['successMessage']}" data-success-confirm="{$t['successConfirm']}" data-error-message="{$t['errorMessage']}">
<input type="hidden" name="newsletter_csrf" value="{$csrfToken}"> <input type="hidden" name="newsletter_csrf" value="{$csrfToken}">
<input type="hidden" name="newsletter_form_id" value="{$escapedFormId}"> <input type="hidden" name="newsletter_form_id" value="{$escapedFormId}">
<div class="newsletter-fields"> <div class="newsletter-fields">
<div class="newsletter-field">
<label for="newsletter_name_{$nonce}" class="visually-hidden">{$t['nameLabel']}</label>
<input type="text" id="newsletter_name_{$nonce}" name="newsletter_name" placeholder="{$t['namePlaceholder']}" required maxlength="100">
</div>
<div class="newsletter-field"> <div class="newsletter-field">
<label for="newsletter_email_{$nonce}" class="visually-hidden">{$t['emailLabel']}</label> <label for="newsletter_email_{$nonce}" class="visually-hidden">{$t['emailLabel']}</label>
<input type="email" id="newsletter_email_{$nonce}" name="newsletter_email" placeholder="{$t['emailPlaceholder']}" required maxlength="100"> <input type="email" id="newsletter_email_{$nonce}" name="newsletter_email" placeholder="{$t['emailPlaceholder']}" required maxlength="100">
</div> </div>
<div class="newsletter-field">
<label for="newsletter_name_{$nonce}" class="visually-hidden">{$t['nameLabel']}</label>
<input type="text" id="newsletter_name_{$nonce}" name="newsletter_name" placeholder="{$t['namePlaceholder']}" required maxlength="100">
</div>
<button type="submit" name="newsletter_submit" class="button"> <button type="submit" name="newsletter_submit" class="button">
<span class="btn-text">{$t['submitButton']}</span> <span class="btn-text">{$t['submitButton']}</span>
<span class="btn-spinner" aria-hidden="true"></span> <span class="btn-spinner" aria-hidden="true"></span>
@ -436,6 +446,12 @@ function newsletterGetStyles(): string {
font-size: 0.9rem; font-size: 0.9rem;
margin-top:0; margin-top:0;
} }
.newsletter-small .newsletter-confirm {
margin: 0.3rem 0 0;
font-size: 0.95rem;
color: var(--color-green);
font-weight: 600;
}
.newsletter-small .button.is-success { background-color: var(--color-green); color: white; } .newsletter-small .button.is-success { background-color: var(--color-green); color: white; }
.newsletter-small .button.is-error { background-color: oklch(0.55 0.2 25); color: white; outline: none; } .newsletter-small .button.is-error { background-color: oklch(0.55 0.2 25); color: white; outline: none; }
</style> </style>