Handled price selection for multiple products
refs https://github.com/TryGhost/Team/issues/767 - updated list of site prices to use all prices from products - handled price selection in product section
This commit is contained in:
parent
d7c645f71a
commit
c98ab9981a
@ -171,7 +171,7 @@ export const ProductsSectionStyles = `
|
||||
grid-gap: 20px;
|
||||
padding: 32px 0;
|
||||
}
|
||||
|
||||
|
||||
.gh-portal-products-priceswitch {
|
||||
padding-top: 18px;
|
||||
}
|
||||
@ -240,7 +240,8 @@ export const ProductsSectionStyles = `
|
||||
const ProductsContext = React.createContext({
|
||||
selectedInterval: 'month',
|
||||
selectedProduct: 'free',
|
||||
setSelectedProduct: null
|
||||
setSelectedProduct: null,
|
||||
onPlanSelect: null
|
||||
});
|
||||
|
||||
function productColumns() {
|
||||
@ -297,13 +298,14 @@ function ProductCardFooter({product}) {
|
||||
}
|
||||
|
||||
function ProductCard({product}) {
|
||||
const {selectedProduct, setSelectedProduct} = useContext(ProductsContext);
|
||||
const {selectedProduct, setSelectedProduct, selectedInterval, onPlanSelect} = useContext(ProductsContext);
|
||||
const cardClass = selectedProduct === product.id ? 'gh-portal-product-card checked' : 'gh-portal-product-card';
|
||||
|
||||
const selectedPrice = selectedInterval === 'month' ? product.monthlyPrice : product.yearlyPrice;
|
||||
return (
|
||||
<div className={cardClass} key={product.id} onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setSelectedProduct(product.id);
|
||||
onPlanSelect(e, selectedPrice?.id);
|
||||
}}>
|
||||
<div className="gh-portal-product-card-header">
|
||||
<Checkbox name={product.id} id={`${product.id}-checkbox`} isChecked={selectedProduct === product.id} onProductSelect={() => {
|
||||
@ -352,7 +354,7 @@ function FreeProductCard() {
|
||||
);
|
||||
}
|
||||
|
||||
function ProductsSection() {
|
||||
function ProductsSection({onPlanSelect}) {
|
||||
const {site} = useContext(AppContext);
|
||||
const products = getProducts({site});
|
||||
const [selectedInterval, setSelectedInterval] = useState('month');
|
||||
@ -362,7 +364,8 @@ function ProductsSection() {
|
||||
<ProductsContext.Provider value={{
|
||||
selectedInterval,
|
||||
selectedProduct,
|
||||
setSelectedProduct
|
||||
setSelectedProduct,
|
||||
onPlanSelect
|
||||
}}>
|
||||
<section className="gh-portal-products">
|
||||
<div className="gh-portal-products-priceswitch">
|
||||
|
@ -392,7 +392,11 @@ class SignupPage extends React.Component {
|
||||
renderProducts() {
|
||||
return (
|
||||
<>
|
||||
<ProductsSection />
|
||||
<ProductsSection
|
||||
onPlanSelect={(e, id) => {
|
||||
this.handleSelectPlan(e, id);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -413,6 +417,15 @@ class SignupPage extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderProductsOrPlans() {
|
||||
const {site} = this.context;
|
||||
if (hasMultipleProducts({site})) {
|
||||
return this.renderProducts();
|
||||
} else {
|
||||
return this.renderPlans();
|
||||
}
|
||||
}
|
||||
|
||||
renderForm() {
|
||||
const fields = this.getInputFields({state: this.state});
|
||||
const {site, pageQuery} = this.context;
|
||||
@ -427,33 +440,18 @@ class SignupPage extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (hasMultipleProducts({site})) {
|
||||
return (
|
||||
<section>
|
||||
<div className='gh-portal-section'>
|
||||
<InputForm
|
||||
fields={fields}
|
||||
onChange={(e, field) => this.handleInputChange(e, field)}
|
||||
onKeyDown={(e, field) => this.onKeyDown(e, field)}
|
||||
/>
|
||||
{this.renderProducts()}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<section>
|
||||
<div className='gh-portal-section'>
|
||||
<InputForm
|
||||
fields={fields}
|
||||
onChange={(e, field) => this.handleInputChange(e, field)}
|
||||
onKeyDown={(e, field) => this.onKeyDown(e, field)}
|
||||
/>
|
||||
{this.renderPlans()}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<section>
|
||||
<div className='gh-portal-section'>
|
||||
<InputForm
|
||||
fields={fields}
|
||||
onChange={(e, field) => this.handleInputChange(e, field)}
|
||||
onKeyDown={(e) => this.onKeyDown(e)}
|
||||
/>
|
||||
{this.renderProductsOrPlans()}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
renderSiteLogo() {
|
||||
|
@ -154,6 +154,16 @@ export function getProducts({site = {}}) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getProductPrices({site}) {
|
||||
const products = getProducts({site}) || [];
|
||||
const prices = products.reduce((accumPrices, product) => {
|
||||
accumPrices.push(product.monthlyPrice);
|
||||
accumPrices.push(product.yearlyPrice);
|
||||
return accumPrices;
|
||||
}, []);
|
||||
return prices;
|
||||
}
|
||||
|
||||
export function getAvailablePrices({site = {}, includeFree = true} = {}) {
|
||||
let {
|
||||
prices,
|
||||
@ -221,10 +231,14 @@ export function getSitePrices({site = {}, includeFree = true, pageQuery = ''} =
|
||||
if (!prices) {
|
||||
return [];
|
||||
}
|
||||
let availablePrices = prices;
|
||||
if (hasMultipleProducts({site})) {
|
||||
availablePrices = getProductPrices({site});
|
||||
}
|
||||
|
||||
const plansData = [];
|
||||
|
||||
const stripePrices = prices.filter((d) => {
|
||||
const stripePrices = availablePrices.filter((d) => {
|
||||
return !!(d && d.id);
|
||||
}).map((d) => {
|
||||
return {
|
||||
|
Loading…
Reference in New Issue
Block a user