From 514e02252021032fc694ee822dac023c903ebefc Mon Sep 17 00:00:00 2001 From: Rish Date: Wed, 27 May 2020 16:55:24 +0530 Subject: [PATCH] Copied existing public members.js script from core refs https://github.com/TryGhost/members.js/issues/32 - Copies over existing members.js script from core - Handles members functionality in a theme using data-attributes assinged - Only modification is tto use `siteUrl` value passed to the function for API calls --- ghost/portal/src/data-attributes.js | 314 ++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 ghost/portal/src/data-attributes.js diff --git a/ghost/portal/src/data-attributes.js b/ghost/portal/src/data-attributes.js new file mode 100644 index 0000000000..18775d977f --- /dev/null +++ b/ghost/portal/src/data-attributes.js @@ -0,0 +1,314 @@ +function handleDataAttributes({siteUrl}) { + Array.prototype.forEach.call(document.querySelectorAll('form[data-members-form]'), function (form) { + let errorEl = form.querySelector('[data-members-error]'); + function submitHandler(event) { + form.removeEventListener('submit', submitHandler); + event.preventDefault(); + if (errorEl) { + errorEl.innerText = ''; + } + form.classList.remove('success', 'invalid', 'error'); + let input = event.target.querySelector('input[data-members-email]'); + let email = input.value; + let emailType = undefined; + let labels = []; + + let labelInputs = event.target.querySelectorAll('input[data-members-label]') || []; + for (let i = 0; i < labelInputs.length; ++i) { + labels.push(labelInputs[i].value); + } + + if (form.dataset.membersForm) { + emailType = form.dataset.membersForm; + } + + form.classList.add('loading'); + fetch(`${siteUrl}/members/api/send-magic-link/`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + email: email, + emailType: emailType, + labels: labels + }) + }).then(function (res) { + form.addEventListener('submit', submitHandler); + form.classList.remove('loading'); + if (res.ok) { + form.classList.add('success'); + } else { + if (errorEl) { + errorEl.innerText = 'There was an error sending the email, please try again'; + } + form.classList.add('error'); + } + }); + } + form.addEventListener('submit', submitHandler); + }); + + Array.prototype.forEach.call(document.querySelectorAll('[data-members-plan]'), function (el) { + let errorEl = el.querySelector('[data-members-error]'); + function clickHandler(event) { + el.removeEventListener('click', clickHandler); + event.preventDefault(); + + let plan = el.dataset.membersPlan; + let successUrl = el.dataset.membersSuccess; + let cancelUrl = el.dataset.membersCancel; + let checkoutSuccessUrl; + let checkoutCancelUrl; + + if (successUrl) { + checkoutSuccessUrl = (new URL(successUrl, window.location.href)).href; + } + + if (cancelUrl) { + checkoutCancelUrl = (new URL(cancelUrl, window.location.href)).href; + } + + if (errorEl) { + errorEl.innerText = ''; + } + el.classList.add('loading'); + fetch(`${siteUrl}/members/api/session`, { + credentials: 'same-origin' + }).then(function (res) { + if (!res.ok) { + return null; + } + return res.text(); + }).then(function (identity) { + return fetch(`${siteUrl}/members/api/create-stripe-checkout-session/`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + plan: plan, + identity: identity, + successUrl: checkoutSuccessUrl, + cancelUrl: checkoutCancelUrl + }) + }).then(function (res) { + if (!res.ok) { + throw new Error('Could not create stripe checkout session'); + } + return res.json(); + }); + }).then(function (result) { + let stripe = window.Stripe(result.publicKey); + return stripe.redirectToCheckout({ + sessionId: result.sessionId + }); + }).then(function (result) { + if (result.error) { + throw new Error(result.error.message); + } + }).catch(function (err) { + console.error(err); + el.addEventListener('click', clickHandler); + el.classList.remove('loading'); + if (errorEl) { + errorEl.innerText = err.message; + } + el.classList.add('error'); + }); + } + el.addEventListener('click', clickHandler); + }); + + Array.prototype.forEach.call(document.querySelectorAll('[data-members-edit-billing]'), function (el) { + let errorEl = el.querySelector('[data-members-error]'); + let membersSuccess = el.dataset.membersSuccess; + let membersCancel = el.dataset.membersCancel; + let successUrl; + let cancelUrl; + + if (membersSuccess) { + successUrl = (new URL(membersSuccess, window.location.href)).href; + } + + if (membersCancel) { + cancelUrl = (new URL(membersCancel, window.location.href)).href; + } + + function clickHandler(event) { + el.removeEventListener('click', clickHandler); + event.preventDefault(); + + if (errorEl) { + errorEl.innerText = ''; + } + el.classList.add('loading'); + fetch(`${siteUrl}/members/api/session`, { + credentials: 'same-origin' + }).then(function (res) { + if (!res.ok) { + return null; + } + return res.text(); + }).then(function (identity) { + return fetch(`${siteUrl}/members/api/create-stripe-update-session/`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + identity: identity, + successUrl: successUrl, + cancelUrl: cancelUrl + }) + }).then(function (res) { + if (!res.ok) { + throw new Error('Could not create stripe checkout session'); + } + return res.json(); + }); + }).then(function (result) { + let stripe = window.Stripe(result.publicKey); + return stripe.redirectToCheckout({ + sessionId: result.sessionId + }); + }).then(function (result) { + if (result.error) { + throw new Error(result.error.message); + } + }).catch(function (err) { + console.error(err); + el.addEventListener('click', clickHandler); + el.classList.remove('loading'); + if (errorEl) { + errorEl.innerText = err.message; + } + el.classList.add('error'); + }); + } + el.addEventListener('click', clickHandler); + }); + + Array.prototype.forEach.call(document.querySelectorAll('[data-members-signout]'), function (el) { + function clickHandler(event) { + el.removeEventListener('click', clickHandler); + event.preventDefault(); + el.classList.remove('error'); + el.classList.add('loading'); + fetch(`${siteUrl}/members/api/session`, { + method: 'DELETE' + }).then(function (res) { + if (res.ok) { + window.location.reload(); + } else { + el.addEventListener('click', clickHandler); + el.classList.remove('loading'); + el.classList.add('error'); + } + }); + } + el.addEventListener('click', clickHandler); + }); + + Array.prototype.forEach.call(document.querySelectorAll('[data-members-cancel-subscription]'), function (el) { + let errorEl = el.parentElement.querySelector('[data-members-error]'); + function clickHandler(event) { + el.removeEventListener('click', clickHandler); + event.preventDefault(); + el.classList.remove('error'); + el.classList.add('loading'); + + let subscriptionId = el.dataset.membersCancelSubscription; + + if (errorEl) { + errorEl.innerText = ''; + } + + return fetch(`${siteUrl}/members/api/session`, { + credentials: 'same-origin' + }).then(function (res) { + if (!res.ok) { + return null; + } + + return res.text(); + }).then(function (identity) { + return fetch(`${siteUrl}/members/api/subscriptions/${subscriptionId}/`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + identity: identity, + cancel_at_period_end: true + }) + }); + }).then(function (res) { + if (res.ok) { + window.location.reload(); + } else { + el.addEventListener('click', clickHandler); + el.classList.remove('loading'); + el.classList.add('error'); + + if (errorEl) { + errorEl.innerText = 'There was an error cancelling your subscription, please try again.'; + } + } + }); + } + el.addEventListener('click', clickHandler); + }); + + Array.prototype.forEach.call(document.querySelectorAll('[data-members-continue-subscription]'), function (el) { + let errorEl = el.parentElement.querySelector('[data-members-error]'); + function clickHandler(event) { + el.removeEventListener('click', clickHandler); + event.preventDefault(); + el.classList.remove('error'); + el.classList.add('loading'); + + let subscriptionId = el.dataset.membersContinueSubscription; + + if (errorEl) { + errorEl.innerText = ''; + } + + return fetch(`${siteUrl}/members/api/session`, { + credentials: 'same-origin' + }).then(function (res) { + if (!res.ok) { + return null; + } + + return res.text(); + }).then(function (identity) { + return fetch(`${siteUrl}/members/api/subscriptions/${subscriptionId}/`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + identity: identity, + cancel_at_period_end: false + }) + }); + }).then(function (res) { + if (res.ok) { + window.location.reload(); + } else { + el.addEventListener('click', clickHandler); + el.classList.remove('loading'); + el.classList.add('error'); + + if (errorEl) { + errorEl.innerText = 'There was an error continuing your subscription, please try again.'; + } + } + }); + } + el.addEventListener('click', clickHandler); + }); +} + +module.exports = handleDataAttributes; \ No newline at end of file