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:
Rishabh 2021-06-14 13:55:11 +05:30
parent d7c645f71a
commit c98ab9981a
3 changed files with 50 additions and 35 deletions

View File

@ -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">

View File

@ -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() {

View File

@ -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 {