Skip to content

Commit

Permalink
Add Fx News one-click-subscribe page (Fixes #15142)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexgibson committed Oct 1, 2024
1 parent 2df9c9b commit 418fba4
Show file tree
Hide file tree
Showing 8 changed files with 464 additions and 0 deletions.
69 changes: 69 additions & 0 deletions bedrock/newsletter/templates/newsletter/firefox-confirm.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}

{% extends 'base-protocol.html' %}

{% block page_title %}Firefox Newsletter{% endblock page_title %}

{% block page_css %}
{{ css_bundle('newsletter-firefox-confirm') }}
{% endblock %}

{% if LANG == 'de' %}
{% set headline_text = 'Bleib mit Mozilla über unseren Firefox News-Newsletter auf dem Laufenden' %}
{% set tagline_text = 'Wenn du abonnierst, erhältst du aktuelle Produkt-Updates, Expert*innentipps und wichtige News von Mozilla.' %}
{% set cta_text = 'Abonnieren' %}
{% set thanks_text = 'Danke, dass Sie den Newsletter abonniert haben! Ihr Newsletter-Abonnement wurde bestätigt.' %}
{% elif LANG == 'fr' %}
{% set headline_text = 'Restez en lien avec Mozilla grâce à la newsletter Firefox News' %}
{% set tagline_text = 'En vous abonnant, vous recevrez les dernières mises à jour de nos produits, des conseils d’experts et des actualités importantes concernant Mozilla.' %}
{% set cta_text = 'Je m’abonne' %}
{% set thanks_text = 'Merci pour votre inscription ! Votre abonnement à la newsletter Firefox News est maintenant confirmé.' %}
{% else %}
{% set headline_text = 'Stay connected with Mozilla, courtesy of our Firefox News newsletter' %}
{% set tagline_text = 'By subscribing, you’ll receive the latest product updates, expert tips, and important news from Mozilla—ensuring you stay safe and informed online.' %}
{% set cta_text = 'Subscribe' %}
{% set thanks_text = 'Thanks for Subscribing! Your newsletter subscription has been confirmed.' %}
{% endif %}

{% block content %}
<main class="mzp-l-content mzp-t-content-lg mzp-u-centered">
<header>
<h1 class="page-title">{{ headline_text }}</h1>
</header>

<form id="confirmation-form" class="c-confirm-form" method="post" action="{{ action }}" data-recovery-url="{{ url('newsletter.recovery') }}">
<input type="hidden" name="newsletters" value="{{ newsletters }}">
<input type="hidden" name="source_url" value="{{ source_url|absolute_url }}">
<input type="hidden" name="lang" value="{{ newsletter_lang }}">
<p class="c-confirm-form-tagline">{{ tagline_text }}</p>
<div class="c-confirm-form-errors mzp-c-form-errors hidden" id="confirm-form-errors">
<p class="c-confirm-error-msg error-invalid-token hidden">
{{ ftl('newsletters-this-email-address-is-not', url=url('newsletter.firefox')) }}
</p>
<p class="c-confirm-error-msg error-try-again-later hidden">
{{ ftl('newsletters-we-are-sorry-but-there') }}
</p>
<p class="c-confirm-error-msg error-update-browser hidden">
{{ ftl('newsletters-update-your-browser') }}
</p>
</div>
<button type="submit" class="c-confirm-form-submit mzp-c-button">
{{ cta_text }}
</button>
<p class="c-confirm-small">
<small>{{ ftl('newsletter-form-we-will-only-send-firefox-v2') }}</small>
</p>
</form>
<div class="c-confirm-form-thanks hidden">
<p>{{ thanks_text }}</p>
</div>
</main>
{% endblock %}

{% block js %}
{{ js_bundle('newsletter-firefox-confirm') }}
{% endblock %}
2 changes: 2 additions & 0 deletions bedrock/newsletter/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
),
name="newsletter.firefox",
),
path("newsletter/firefox/confirm/<uuid:token>/", views.firefox_confirm, name="newsletter.firefox.confirm"),
path("newsletter/firefox/confirm/", views.firefox_confirm, name="newsletter.firefox.confirm.no-token"),
page("newsletter/developer/", "newsletter/developer.html", ftl_files=["mozorg/newsletters"]),
page("newsletter/fxa-error/", "newsletter/fxa-error.html", ftl_files=["mozorg/newsletters"]),
page("newsletter/family/", "newsletter/family.html", ftl_files=["mozorg/newsletters"], active_locales=["en-US"]),
Expand Down
16 changes: 16 additions & 0 deletions bedrock/newsletter/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,19 @@ def newsletter_subscribe(request):
return l10n_utils.render(request, "newsletter/index.html", ctx, ftl_files=FTL_FILES)

return l10n_utils.render(request, "newsletter/index.html", ftl_files=FTL_FILES)


def firefox_confirm(request, token=None):
locale = l10n_utils.get_locale(request)

context = {
"action": f"{settings.BASKET_URL}/news/subscribe/",
"active_locales": ["en-US", "en-GB", "en-CA", "de", "fr"],
"ftl_files": ["mozorg/newsletters"],
"newsletter_lang": locale.split("-")[0],
"newsletters": "mozilla-and-you",
"recovery_url": reverse("newsletter.recovery"),
"source_url": reverse("newsletter.firefox.confirm.no-token"),
}

return l10n_utils.render(request, "newsletter/firefox-confirm.html", context)
41 changes: 41 additions & 0 deletions media/css/newsletter/newsletter-firefox-confirm.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

$font-path: '/media/protocol/fonts';
$image-path: '/media/protocol/img';

@import '~@mozilla-protocol/core/protocol/css/includes/lib';
@import '~@mozilla-protocol/core/protocol/css/components/forms/form';
@import '~@mozilla-protocol/core/protocol/css/components/forms/field';
@import '~@mozilla-protocol/core/protocol/css/components/forms/button-container';

main {
min-height: 500px;
}

.c-confirm-form {
margin-top: $layout-lg;
}

.c-confirm-form-tagline {
@include text-body-xl;
}

.c-confirm-small {
margin-top: $spacing-lg;
}

.c-confirm-form-thanks {
margin-top: $layout-lg;
@include text-body-xl;
}

.c-confirm-form-errors {
max-width: 400px;
margin: 0 auto $spacing-xl;
}

.c-confirm-error-msg {
margin-bottom: 0;
}
9 changes: 9 additions & 0 deletions media/js/newsletter/confirm-init.es6.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

import ConfirmForm from './confirm.es6';

ConfirmForm.init();
108 changes: 108 additions & 0 deletions media/js/newsletter/confirm.es6.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

import FormUtils from './form-utils.es6';

let _form;

const ConfirmationForm = {
meetsRequirements: () => {
return 'Promise' in window;
},

handleFormError: (msg) => {
FormUtils.enableFormFields(_form);
_form.querySelector('.mzp-c-form-errors').classList.remove('hidden');

if (msg && msg === FormUtils.errorList.TOKEN_INVALID) {
_form
.querySelector('.error-invalid-token')
.classList.remove('hidden');
} else if (msg && msg === FormUtils.errorList.UPDATE_BROWSER) {
_form
.querySelector('.error-update-browser')
.classList.remove('hidden');
} else {
_form
.querySelector('.error-try-again-later')
.classList.remove('hidden');
}
},

handleFormSuccess: () => {
_form.classList.add('hidden');
document
.querySelector('.c-confirm-form-thanks')
.classList.remove('hidden');
},

redirectToRecoveryPage: () => {
const recoveryUrl = _form.getAttribute('data-recovery-url');

if (FormUtils.isWellFormedURL(recoveryUrl)) {
window.location.href = recoveryUrl;
} else {
ConfirmationForm.handleFormError();
}
},

getFormActionURL: () => {
return _form.getAttribute('action');
},

serialize: () => {
const params = FormUtils.serialize(_form);
const token = FormUtils.getUserToken();

if (params && token) {
return `${params}&token=${token}`;
}

return '';
},

subscribe: (e) => {
const url = ConfirmationForm.getFormActionURL();

e.preventDefault();
e.stopPropagation();

// Disable form fields until POST has completed.
FormUtils.disableFormFields(_form);

// Clear any prior messages that might have been displayed.
FormUtils.clearFormErrors(_form);

const params = ConfirmationForm.serialize();

FormUtils.postToBasket(
null,
params,
url,
ConfirmationForm.handleFormSuccess,
ConfirmationForm.handleFormError
);
},

init: () => {
_form = document.getElementById('confirmation-form');

if (!ConfirmationForm.meetsRequirements()) {
ConfirmationForm.handleFormError('Update your browser');
return;
}

_form.addEventListener('submit', ConfirmationForm.subscribe, false);

// Look for a valid user token before rendering the page.
// If not found, redirect to /newsletter/recovery/.
return FormUtils.checkForUserToken().catch(
ConfirmationForm.redirectToRecoveryPage
);
}
};

export default ConfirmationForm;
12 changes: 12 additions & 0 deletions media/static-bundles.json
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,12 @@
],
"name": "newsletter-firefox"
},
{
"files": [
"css/newsletter/newsletter-firefox-confirm.scss"
],
"name": "newsletter-firefox-confirm"
},
{
"files": [
"css/mozorg/mpl-2-0.scss"
Expand Down Expand Up @@ -1362,6 +1368,12 @@
],
"name": "newsletter-firefox-experiment"
},
{
"files": [
"js/newsletter/confirm-init.es6.js"
],
"name": "newsletter-firefox-confirm"
},
{
"files": [
"js/firefox/features/features-article.es6.js"
Expand Down
Loading

0 comments on commit 418fba4

Please sign in to comment.