mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
Added logic for introducing multiple products
refs https://github.com/TryGhost/Team/issues/767 - Adds new helper to switch UI for multiple products - Cleans up fixtures
This commit is contained in:
parent
f59711ab1b
commit
a73a04034b
3 changed files with 101 additions and 84 deletions
|
@ -4,7 +4,7 @@ import AppContext from '../../AppContext';
|
||||||
import PlansSection from '../common/PlansSection';
|
import PlansSection from '../common/PlansSection';
|
||||||
import InputForm from '../common/InputForm';
|
import InputForm from '../common/InputForm';
|
||||||
import {ValidateInputForm} from '../../utils/form';
|
import {ValidateInputForm} from '../../utils/form';
|
||||||
import {getSitePrices, hasOnlyFreePlan, isInviteOnlySite} from '../../utils/helpers';
|
import {getSitePrices, hasMultipleProducts, hasOnlyFreePlan, isInviteOnlySite} from '../../utils/helpers';
|
||||||
import {ReactComponent as InvitationIcon} from '../../images/icons/invitation.svg';
|
import {ReactComponent as InvitationIcon} from '../../images/icons/invitation.svg';
|
||||||
|
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
|
@ -448,7 +448,25 @@ class SignupPage extends React.Component {
|
||||||
return {sectionClass, footerClass};
|
return {sectionClass, footerClass};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
renderMultipleProducts() {
|
||||||
|
let {sectionClass, footerClass} = this.getClassNames();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={'gh-portal-content signup' + sectionClass}>
|
||||||
|
<CloseButton />
|
||||||
|
{this.renderFormHeader()}
|
||||||
|
{this.renderForm()}
|
||||||
|
</div>
|
||||||
|
<footer className={'gh-portal-signup-footer ' + footerClass}>
|
||||||
|
{this.renderSubmitButton()}
|
||||||
|
{this.renderLoginMessage()}
|
||||||
|
</footer>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderSingleProduct() {
|
||||||
let {sectionClass, footerClass} = this.getClassNames();
|
let {sectionClass, footerClass} = this.getClassNames();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -465,6 +483,14 @@ class SignupPage extends React.Component {
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {site} = this.context;
|
||||||
|
if (hasMultipleProducts({site})) {
|
||||||
|
return this.renderMultipleProducts();
|
||||||
|
}
|
||||||
|
return this.renderSingleProduct();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SignupPage;
|
export default SignupPage;
|
||||||
|
|
|
@ -11,35 +11,31 @@ const prices = [
|
||||||
interval: 'month'
|
interval: 'month'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '6086ead8070218227791fe4f',
|
id: '6086eff0823dd7240afc8083',
|
||||||
stripe_price_id: 'price_1IkXLAFToJelIqAseQdK4WSU',
|
stripe_price_id: 'price_1IkXgCFToJelIqAsTP3V1paQ',
|
||||||
stripe_product_id: 'prod_JNGGBrrogUXcoM',
|
stripe_product_id: 'prod_JNGGBrrogUXcoM',
|
||||||
active: 1,
|
active: 1,
|
||||||
nickname: 'Test Price 15',
|
nickname: 'Yearly',
|
||||||
currency: 'usd',
|
currency: 'usd',
|
||||||
amount: 1500,
|
amount: 5000,
|
||||||
type: 'recurring',
|
type: 'recurring',
|
||||||
interval: 'month'
|
interval: 'year'
|
||||||
},
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const products = [
|
||||||
{
|
{
|
||||||
id: '6086eb2a823dd7240afc8081',
|
name: 'Main Product',
|
||||||
stripe_price_id: 'price_1IkXMUFToJelIqAstq0R3Ero',
|
description: 'The default product',
|
||||||
stripe_product_id: 'prod_JNGGBrrogUXcoM',
|
prices: [
|
||||||
active: 1,
|
|
||||||
nickname: 'Test Price USD',
|
|
||||||
currency: 'usd',
|
|
||||||
amount: 1100,
|
|
||||||
type: 'recurring',
|
|
||||||
interval: 'month'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: '6086eb3e823dd7240afc8082',
|
id: '6086d2c776909b1a2382369a',
|
||||||
stripe_price_id: 'price_1IkXMoFToJelIqAsTHKl5ELV',
|
stripe_price_id: '7d6c89c0289ca1731226e86b95b5a162085b8561ca0d10d3a4f03afd3e3e6ba6',
|
||||||
stripe_product_id: 'prod_JNGGBrrogUXcoM',
|
stripe_product_id: '109c85c734fb9992e7bc30a26af66c22f5c94d8dc62e0a33cb797be902c06b2d',
|
||||||
active: 1,
|
active: 1,
|
||||||
nickname: 'Test Price Comp',
|
nickname: 'Monthly',
|
||||||
currency: 'usd',
|
currency: 'usd',
|
||||||
amount: 0,
|
amount: 500,
|
||||||
type: 'recurring',
|
type: 'recurring',
|
||||||
interval: 'month'
|
interval: 'month'
|
||||||
},
|
},
|
||||||
|
@ -50,42 +46,39 @@ const prices = [
|
||||||
active: 1,
|
active: 1,
|
||||||
nickname: 'Yearly',
|
nickname: 'Yearly',
|
||||||
currency: 'usd',
|
currency: 'usd',
|
||||||
amount: 12200,
|
amount: 5000,
|
||||||
type: 'recurring',
|
type: 'recurring',
|
||||||
interval: 'year'
|
interval: 'year'
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '6086f4c9823dd7240afc8084',
|
name: 'Advanced Product',
|
||||||
stripe_price_id: 'price_1IkY0CFToJelIqAs5h7qlgP5',
|
description: 'For extra content',
|
||||||
|
prices: [
|
||||||
|
{
|
||||||
|
id: '6086d2c776909b1a2382369a',
|
||||||
|
stripe_price_id: '7d6c89c0289ca1731226e86b95b5a162085b8561ca0d10d3a4f03afd3e3e6ba6',
|
||||||
|
stripe_product_id: '109c85c734fb9992e7bc30a26af66c22f5c94d8dc62e0a33cb797be902c06b2d',
|
||||||
|
active: 1,
|
||||||
|
nickname: 'Monthly',
|
||||||
|
currency: 'usd',
|
||||||
|
amount: 1200,
|
||||||
|
type: 'recurring',
|
||||||
|
interval: 'month'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '6086eff0823dd7240afc8083',
|
||||||
|
stripe_price_id: 'price_1IkXgCFToJelIqAsTP3V1paQ',
|
||||||
stripe_product_id: 'prod_JNGGBrrogUXcoM',
|
stripe_product_id: 'prod_JNGGBrrogUXcoM',
|
||||||
active: 1,
|
active: 1,
|
||||||
nickname: 'Test Price B',
|
nickname: 'Yearly',
|
||||||
currency: 'gbp',
|
currency: 'usd',
|
||||||
amount: 12000,
|
amount: 12000,
|
||||||
type: 'recurring',
|
type: 'recurring',
|
||||||
interval: 'year'
|
interval: 'year'
|
||||||
},
|
}
|
||||||
{
|
]
|
||||||
id: '6087c314d3e64b3266bf715e',
|
|
||||||
stripe_price_id: 'price_1IkljzFToJelIqAsPNGA2Lov',
|
|
||||||
stripe_product_id: 'prod_JNGGBrrogUXcoM',
|
|
||||||
active: 1,
|
|
||||||
nickname: 'Test Price A',
|
|
||||||
currency: 'cad',
|
|
||||||
amount: 12200,
|
|
||||||
type: 'recurring',
|
|
||||||
interval: 'month'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '6087c36ed3e64b3266bf715f',
|
|
||||||
stripe_price_id: 'price_1IkllSFToJelIqAsvElnxOwF',
|
|
||||||
stripe_product_id: 'prod_JNGGBrrogUXcoM',
|
|
||||||
active: 1,
|
|
||||||
nickname: 'Test Price X',
|
|
||||||
currency: 'gbp',
|
|
||||||
amount: 12300,
|
|
||||||
type: 'recurring',
|
|
||||||
interval: 'month'
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -101,10 +94,7 @@ export const site = {
|
||||||
yearly: 150000,
|
yearly: 150000,
|
||||||
currency: 'USD'
|
currency: 'USD'
|
||||||
},
|
},
|
||||||
product: {
|
products,
|
||||||
name: 'Main Product',
|
|
||||||
description: 'The default product'
|
|
||||||
},
|
|
||||||
prices: prices,
|
prices: prices,
|
||||||
allow_self_signup: true,
|
allow_self_signup: true,
|
||||||
members_signup_access: 'all',
|
members_signup_access: 'all',
|
||||||
|
|
|
@ -125,19 +125,6 @@ export function getQueryPrice({site = {}, priceId}) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProductDetails({site}) {
|
|
||||||
if (site && site.product) {
|
|
||||||
return {
|
|
||||||
name: site.product.name || '',
|
|
||||||
description: site.product.description || ''
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
name: '',
|
|
||||||
description: ''
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function capitalize(str) {
|
export function capitalize(str) {
|
||||||
if (typeof str !== 'string' || !str) {
|
if (typeof str !== 'string' || !str) {
|
||||||
return '';
|
return '';
|
||||||
|
@ -150,6 +137,20 @@ export function isInviteOnlySite({site = {}, pageQuery = ''}) {
|
||||||
return prices.length === 0 || (site && site.members_signup_access === 'invite');
|
return prices.length === 0 || (site && site.members_signup_access === 'invite');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function hasMultipleProducts({site = {}}) {
|
||||||
|
const {
|
||||||
|
products = []
|
||||||
|
} = site || {};
|
||||||
|
if (products?.length > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getProducts({site = {}}) {
|
||||||
|
return site?.products || [];
|
||||||
|
}
|
||||||
|
|
||||||
export function getAvailablePrices({site = {}, includeFree = true} = {}) {
|
export function getAvailablePrices({site = {}, includeFree = true} = {}) {
|
||||||
let {
|
let {
|
||||||
prices,
|
prices,
|
||||||
|
|
Loading…
Reference in a new issue