Skip to content

Commit 4e6c4d2

Browse files
tyxladelawski
authored andcommitted
Plans: Add price matrix for Jetpack backups, add support in ProductSelector (#37023)
* Blocks: Add price matrix support to ProductSelector * Plans: Define a Jetpack backup product price matrix
1 parent 7a91c72 commit 4e6c4d2

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

client/blocks/product-selector/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,7 @@ The following props can be passed to the Product Selector block:
6161
}
6262
```
6363
* `optionsLabel`: ( string ) Title of the product options section.
64+
* `productPriceMatrix`: ( object ) Matrix of product price relationships. Each key is a product slug, and each value is an object with the following structure:
65+
* `relatedProduct`: ( string ) Slug of the related product.
66+
* `ratio`: ( number ) Ratio between original plan and related plan. Example: for a `yearly` to `monthly` plan, this should be `12`.
6467
* `siteId`: ( number ) ID of the site we're retrieving purchases for. Used to fetch information about the associated purchases of the selected products.

client/blocks/product-selector/index.jsx

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ export class ProductSelector extends Component {
106106
return {
107107
billingTimeFrame: this.getBillingTimeFrameLabel(),
108108
currencyCode: productObject.currency_code,
109-
fullPrice: productObject.cost,
109+
fullPrice: this.getProductOptionFullPrice( productSlug ),
110+
discountedPrice: this.getProductOptionDiscountedPrice( productSlug ),
110111
slug: productSlug,
111112
title: this.getProductName( product, productSlug ),
112113
};
@@ -144,6 +145,40 @@ export class ProductSelector extends Component {
144145
);
145146
}
146147

148+
getProductOptionFullPrice( productSlug ) {
149+
const { productPriceMatrix, storeProducts } = this.props;
150+
151+
if ( isEmpty( storeProducts ) ) {
152+
return null;
153+
}
154+
155+
const productObject = storeProducts[ productSlug ];
156+
const relatedProductObject = productPriceMatrix[ productSlug ];
157+
158+
if ( relatedProductObject ) {
159+
return storeProducts[ relatedProductObject.relatedProduct ].cost * relatedProductObject.ratio;
160+
}
161+
162+
return productObject.cost;
163+
}
164+
165+
getProductOptionDiscountedPrice( productSlug ) {
166+
const { productPriceMatrix, storeProducts } = this.props;
167+
168+
if ( isEmpty( storeProducts ) ) {
169+
return null;
170+
}
171+
172+
const productObject = storeProducts[ productSlug ];
173+
const relatedProductObject = productPriceMatrix[ productSlug ];
174+
175+
if ( relatedProductObject ) {
176+
return productObject.cost;
177+
}
178+
179+
return null;
180+
}
181+
147182
renderProducts() {
148183
const { currencyCode, intervalType, products, storeProducts } = this.props;
149184

@@ -171,7 +206,8 @@ export class ProductSelector extends Component {
171206
key={ product.id }
172207
title={ product.title }
173208
billingTimeFrame={ this.getBillingTimeFrameLabel() }
174-
fullPrice={ productObject.cost }
209+
fullPrice={ this.getProductOptionFullPrice( selectedProductSlug ) }
210+
discountedPrice={ this.getProductOptionDiscountedPrice( selectedProductSlug ) }
175211
description={ product.description }
176212
currencyCode={ currencyCode }
177213
purchase={ purchase }
@@ -215,9 +251,16 @@ ProductSelector.propTypes = {
215251
products: PropTypes.arrayOf(
216252
PropTypes.shape( {
217253
title: PropTypes.string,
254+
id: PropTypes.string,
255+
description: PropTypes.oneOfType( [ PropTypes.string, PropTypes.element ] ),
218256
options: PropTypes.objectOf( PropTypes.arrayOf( PropTypes.string ) ).isRequired,
257+
optionsLabel: PropTypes.string,
219258
} )
220259
).isRequired,
260+
productPriceMatrix: PropTypes.shape( {
261+
relatedProduct: PropTypes.string,
262+
ratio: PropTypes.number,
263+
} ),
221264
siteId: PropTypes.number,
222265

223266
// Connected props

client/my-sites/plans-features-main/index.jsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ import {
3232
JETPACK_BACKUP_PRODUCTS_MONTHLY,
3333
JETPACK_BACKUP_PRODUCTS_YEARLY,
3434
PRODUCT_JETPACK_BACKUP,
35+
PRODUCT_JETPACK_BACKUP_DAILY,
36+
PRODUCT_JETPACK_BACKUP_DAILY_MONTHLY,
37+
PRODUCT_JETPACK_BACKUP_REALTIME,
38+
PRODUCT_JETPACK_BACKUP_REALTIME_MONTHLY,
3539
} from 'lib/products-values/constants';
3640
import { addQueryArgs } from 'lib/url';
3741
import JetpackFAQ from './jetpack-faq';
@@ -96,6 +100,17 @@ const jetpackProducts = [
96100
},
97101
];
98102

103+
const jetpackProductPriceMatrix = {
104+
[ PRODUCT_JETPACK_BACKUP_DAILY ]: {
105+
relatedProduct: PRODUCT_JETPACK_BACKUP_DAILY_MONTHLY,
106+
ratio: 12,
107+
},
108+
[ PRODUCT_JETPACK_BACKUP_REALTIME ]: {
109+
relatedProduct: PRODUCT_JETPACK_BACKUP_REALTIME_MONTHLY,
110+
ratio: 12,
111+
},
112+
};
113+
99114
export class PlansFeaturesMain extends Component {
100115
componentDidUpdate( prevProps ) {
101116
/**
@@ -428,7 +443,11 @@ export class PlansFeaturesMain extends Component {
428443
subHeaderText="Just looking for backups? We’ve got you covered."
429444
compactOnMobile
430445
/>
431-
<ProductSelector products={ jetpackProducts } intervalType={ intervalType } />
446+
<ProductSelector
447+
products={ jetpackProducts }
448+
intervalType={ intervalType }
449+
productPriceMatrix={ jetpackProductPriceMatrix }
450+
/>
432451
</div>
433452
);
434453
}

0 commit comments

Comments
 (0)