0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-17 23:44:39 -05:00

Added first version for offer redirects

refs https://github.com/TryGhost/Team/issues/1086

- fires stripe checkout for new Portal link for offers - `/#/portal/offers/OFFER_ID` as prototype
This commit is contained in:
Rishabh 2021-09-28 16:43:56 +05:30
parent 170e353b91
commit 63ca3a00f3
3 changed files with 33 additions and 8 deletions

View file

@ -10,7 +10,7 @@ import * as Fixtures from './utils/fixtures';
import ActionHandler from './actions'; import ActionHandler from './actions';
import './App.css'; import './App.css';
import NotificationParser from './utils/notifications'; import NotificationParser from './utils/notifications';
import {createPopupNotification, getCurrencySymbol, getFirstpromoterId, getProductFromId, getQueryPrice, getSiteDomain, isComplimentaryMember, isInviteOnlySite, isSentryEventAllowed, removePortalLinkFromUrl} from './utils/helpers'; import {createPopupNotification, getAvailablePrices, getCurrencySymbol, getFirstpromoterId, getProductFromId, getQueryPrice, getSiteDomain, isComplimentaryMember, isInviteOnlySite, isSentryEventAllowed, removePortalLinkFromUrl} from './utils/helpers';
const handleDataAttributes = require('./data-attributes'); const handleDataAttributes = require('./data-attributes');
const React = require('react'); const React = require('react');
@ -335,6 +335,7 @@ export default class App extends React.Component {
fetchLinkData() { fetchLinkData() {
const productMonthlyPriceQueryRegex = /^(?:(\w+?))?\/monthly$/; const productMonthlyPriceQueryRegex = /^(?:(\w+?))?\/monthly$/;
const productYearlyPriceQueryRegex = /^(?:(\w+?))?\/monthly$/; const productYearlyPriceQueryRegex = /^(?:(\w+?))?\/monthly$/;
const offersRegex = /^offers\/(\w+?)\/?$/;
const [path] = window.location.hash.substr(1).split('?'); const [path] = window.location.hash.substr(1).split('?');
const linkRegex = /^\/portal\/?(?:\/(\w+(?:\/\w+)*))?\/?$/; const linkRegex = /^\/portal\/?(?:\/(\w+(?:\/\w+)*))?\/?$/;
if (path && linkRegex.test(path)) { if (path && linkRegex.test(path)) {
@ -344,7 +345,8 @@ export default class App extends React.Component {
const showPopup = ( const showPopup = (
['monthly', 'yearly'].includes(pageQuery) || ['monthly', 'yearly'].includes(pageQuery) ||
productMonthlyPriceQueryRegex.test(pageQuery) || productMonthlyPriceQueryRegex.test(pageQuery) ||
productYearlyPriceQueryRegex.test(pageQuery) productYearlyPriceQueryRegex.test(pageQuery) ||
offersRegex.test(pageQuery)
) ? false : true; ) ? false : true;
return { return {
showPopup, showPopup,
@ -515,12 +517,28 @@ export default class App extends React.Component {
this.setState(updatedState); this.setState(updatedState);
} }
handleOfferQuery({site, offerId}) {
removePortalLinkFromUrl();
const prices = getAvailablePrices({site});
const priceId = prices?.[0]?.id;
if (this.state.member) {
this.dispatchAction('checkoutPlan', {plan: priceId, offerId});
} else {
this.dispatchAction('signup', {plan: priceId, offerId});
}
}
/** Handle direct signup link for a price */ /** Handle direct signup link for a price */
handleSignupQuery({site, pageQuery}) { handleSignupQuery({site, pageQuery}) {
const productMonthlyPriceQueryRegex = /^(?:(\w+?))?\/monthly$/; const productMonthlyPriceQueryRegex = /^(?:(\w+?))?\/monthly$/;
const productYearlyPriceQueryRegex = /^(?:(\w+?))?\/monthly$/; const productYearlyPriceQueryRegex = /^(?:(\w+?))?\/monthly$/;
const offerQueryRegex = /^offers\/(\w+?)\/?$/;
let priceId = pageQuery; let priceId = pageQuery;
if (productMonthlyPriceQueryRegex.test(pageQuery || '')) { if (offerQueryRegex.test(pageQuery || '')) {
const [, offerId] = pageQuery.match(offerQueryRegex);
this.handleOfferQuery({site, offerId});
return;
} else if (productMonthlyPriceQueryRegex.test(pageQuery || '')) {
const [, productId] = pageQuery.match(productMonthlyPriceQueryRegex); const [, productId] = pageQuery.match(productMonthlyPriceQueryRegex);
const product = getProductFromId({site, productId}); const product = getProductFromId({site, productId});
priceId = product?.monthlyPrice?.id; priceId = product?.monthlyPrice?.id;
@ -544,7 +562,12 @@ export default class App extends React.Component {
const customPricesSignupRegex = /^signup\/?(?:\/(\w+?))?\/?$/; const customPricesSignupRegex = /^signup\/?(?:\/(\w+?))?\/?$/;
const customMonthlyProductSignup = /^signup\/?(?:\/(\w+?))\/monthly\/?$/; const customMonthlyProductSignup = /^signup\/?(?:\/(\w+?))\/monthly\/?$/;
const customYearlyProductSignup = /^signup\/?(?:\/(\w+?))\/yearly\/?$/; const customYearlyProductSignup = /^signup\/?(?:\/(\w+?))\/yearly\/?$/;
if (path === 'signup') { const customOfferRegex = /^offers\/(\w+?)\/?$/;
if (customOfferRegex.test(path)) {
return {
pageQuery: path
};
} else if (path === 'signup') {
return { return {
page: 'signup' page: 'signup'
}; };

View file

@ -93,11 +93,11 @@ async function signin({data, api, state}) {
async function signup({data, state, api}) { async function signup({data, state, api}) {
try { try {
const {plan, email, name} = data; const {plan, email, name, offerId} = data;
if (plan.toLowerCase() === 'free') { if (plan.toLowerCase() === 'free') {
await api.member.sendMagicLink(data); await api.member.sendMagicLink(data);
} else { } else {
await api.member.checkoutPlan({plan, email, name}); await api.member.checkoutPlan({plan, email, name, offerId});
} }
return { return {
page: 'magiclink', page: 'magiclink',
@ -116,9 +116,10 @@ async function signup({data, state, api}) {
async function checkoutPlan({data, state, api}) { async function checkoutPlan({data, state, api}) {
try { try {
const {plan} = data; const {plan, offerId} = data;
await api.member.checkoutPlan({ await api.member.checkoutPlan({
plan, plan,
offerId,
metadata: { metadata: {
checkoutType: 'upgrade' checkoutType: 'upgrade'
} }

View file

@ -195,7 +195,7 @@ function setupGhostApi({siteUrl = window.location.origin}) {
}); });
}, },
async checkoutPlan({plan, cancelUrl, successUrl, email: customerEmail, name, metadata = {}} = {}) { async checkoutPlan({plan, cancelUrl, successUrl, email: customerEmail, name, offerId, metadata = {}} = {}) {
const siteUrlObj = new URL(siteUrl); const siteUrlObj = new URL(siteUrl);
const identity = await api.member.identity(); const identity = await api.member.identity();
const url = endpointFor({type: 'members', resource: 'create-stripe-checkout-session'}); const url = endpointFor({type: 'members', resource: 'create-stripe-checkout-session'});
@ -229,6 +229,7 @@ function setupGhostApi({siteUrl = window.location.origin}) {
}, },
body: JSON.stringify({ body: JSON.stringify({
priceId: plan, priceId: plan,
offerId,
identity: identity, identity: identity,
metadata: metadataObj, metadata: metadataObj,
successUrl, successUrl,