@woosmap/ui 4.227.4 → 4.228.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/PricingSlider/PricingData.js +653 -586
- package/src/components/PricingSlider/PricingSimulator.js +16 -4
- package/src/components/PricingSlider/PricingSlider.js +91 -7
- package/src/locales/en/translation.json +1 -1
- package/src/locales/fr/translation.json +1 -1
|
@@ -23,7 +23,7 @@ export default class PricingSimulator extends Component {
|
|
|
23
23
|
};
|
|
24
24
|
});
|
|
25
25
|
});
|
|
26
|
-
this.state = { sliders };
|
|
26
|
+
this.state = { sliders, displayCompetitorsProduct: null };
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
onChange = (category, pricingKey) => (data) => {
|
|
@@ -161,8 +161,14 @@ export default class PricingSimulator extends Component {
|
|
|
161
161
|
);
|
|
162
162
|
};
|
|
163
163
|
|
|
164
|
+
displayCompetitorsCallback = (competitorProductKey) => (force) => {
|
|
165
|
+
this.setState({
|
|
166
|
+
displayCompetitorsProduct: force ? competitorProductKey : null,
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
|
|
164
170
|
render() {
|
|
165
|
-
const { sliders } = this.state;
|
|
171
|
+
const { sliders, displayCompetitorsProduct } = this.state;
|
|
166
172
|
const { currency, hlPricings, planId } = this.props;
|
|
167
173
|
const { total, contactSale, totalBeforeDiscount } = this.computeTotal();
|
|
168
174
|
const totalDisplayed = this.displayAmount(parseInt(total, 10), currency);
|
|
@@ -184,7 +190,7 @@ export default class PricingSimulator extends Component {
|
|
|
184
190
|
<span className="pricing-total__label__title">{tr('Monthly cost estimation')}</span>
|
|
185
191
|
{contactSale && (
|
|
186
192
|
<span className="pricing-total__label__info">
|
|
187
|
-
{tr('* Some products require
|
|
193
|
+
{tr('* Some products require contacting sales for pricing')}
|
|
188
194
|
</span>
|
|
189
195
|
)}
|
|
190
196
|
</div>
|
|
@@ -226,6 +232,12 @@ export default class PricingSimulator extends Component {
|
|
|
226
232
|
onChange={this.onChange(category, pricingKey)}
|
|
227
233
|
hlPricings={hlPricings}
|
|
228
234
|
planId={planId}
|
|
235
|
+
displayCompetitorsCallback={this.displayCompetitorsCallback(
|
|
236
|
+
`${category}-${pricingKey}`,
|
|
237
|
+
)}
|
|
238
|
+
displayCompetitors={
|
|
239
|
+
displayCompetitorsProduct === `${category}-${pricingKey}`
|
|
240
|
+
}
|
|
229
241
|
/>
|
|
230
242
|
);
|
|
231
243
|
})}
|
|
@@ -250,7 +262,7 @@ export default class PricingSimulator extends Component {
|
|
|
250
262
|
</div>
|
|
251
263
|
{contactSale && (
|
|
252
264
|
<div className="pricing-total__amount__info">
|
|
253
|
-
{tr('* Some products require
|
|
265
|
+
{tr('* Some products require contacting sales for pricing')}
|
|
254
266
|
</div>
|
|
255
267
|
)}
|
|
256
268
|
{this.getAmountByProducts()}
|
|
@@ -24,7 +24,10 @@ export default class PricingSlider extends Component {
|
|
|
24
24
|
return currency === '€' ? `${amount}${currency}` : `${currency}${amount}`;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
computeAmount = (pricing, queries) => {
|
|
27
|
+
computeAmount = (pricing, queries, competitor = false) => {
|
|
28
|
+
const { currency } = this.props;
|
|
29
|
+
|
|
30
|
+
const coef = competitor && currency === '$' ? 0.9 : 1;
|
|
28
31
|
let q = queries;
|
|
29
32
|
let previousPricingTier;
|
|
30
33
|
if (queries === '∞') {
|
|
@@ -37,12 +40,12 @@ export default class PricingSlider extends Component {
|
|
|
37
40
|
const valueToRemove = Math.min(tier[0] - previousPricingTier[0], q);
|
|
38
41
|
if (valueToRemove > 0) {
|
|
39
42
|
q -= valueToRemove;
|
|
40
|
-
return amount + (valueToRemove / 1000) * tier[1];
|
|
43
|
+
return amount + ((valueToRemove / 1000) * tier[1]) / coef;
|
|
41
44
|
}
|
|
42
45
|
} else {
|
|
43
46
|
const valueToRemove = Math.min(tier[0], q);
|
|
44
47
|
q -= valueToRemove;
|
|
45
|
-
return amount + (valueToRemove / 1000) * tier[1];
|
|
48
|
+
return amount + ((valueToRemove / 1000) * tier[1]) / coef;
|
|
46
49
|
}
|
|
47
50
|
return Math.floor(amount);
|
|
48
51
|
}, 0);
|
|
@@ -142,6 +145,14 @@ export default class PricingSlider extends Component {
|
|
|
142
145
|
const computedQueries = this.computeQueries(queries);
|
|
143
146
|
const formatedQueries = computedQueries === '∞' ? computedQueries : numeral(computedQueries).format('0.[0]a');
|
|
144
147
|
const amount = this.computeAmount(displayedPricing, computedQueries);
|
|
148
|
+
const amountGmp =
|
|
149
|
+
productPricing.pricing_gmp?.length > 0
|
|
150
|
+
? this.computeAmount(productPricing.pricing_gmp, computedQueries, true)
|
|
151
|
+
: null;
|
|
152
|
+
const amountMbx = productPricing.pricing_mbx?.length
|
|
153
|
+
? this.computeAmount(productPricing.pricing_mbx, computedQueries, true)
|
|
154
|
+
: null;
|
|
155
|
+
|
|
145
156
|
const aboveLastTier =
|
|
146
157
|
formatedQueries === '∞'
|
|
147
158
|
? `>${numeral(displayedPricing[displayedPricing.length - 2][0]).format('0.[0]a')}`
|
|
@@ -157,6 +168,8 @@ export default class PricingSlider extends Component {
|
|
|
157
168
|
discountEligible: productPricing.discountEligible,
|
|
158
169
|
displayedPricing,
|
|
159
170
|
aboveLastTier,
|
|
171
|
+
amountMbx,
|
|
172
|
+
amountGmp,
|
|
160
173
|
};
|
|
161
174
|
};
|
|
162
175
|
|
|
@@ -207,12 +220,55 @@ export default class PricingSlider extends Component {
|
|
|
207
220
|
</div>
|
|
208
221
|
);
|
|
209
222
|
|
|
223
|
+
displayCompetitorAmount = (amount) => {
|
|
224
|
+
if (amount === '∞') {
|
|
225
|
+
return 'N/A';
|
|
226
|
+
}
|
|
227
|
+
if (amount === null) {
|
|
228
|
+
return 'No equivalent product';
|
|
229
|
+
}
|
|
230
|
+
return this.displayAmount(amount);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
displayCompetitorDetails = (amountGmp, amountMbx) => (
|
|
234
|
+
<div className="pricing-slider__detailed-price">
|
|
235
|
+
<table>
|
|
236
|
+
<tr>
|
|
237
|
+
<td>
|
|
238
|
+
<strong>Competitors</strong>
|
|
239
|
+
</td>
|
|
240
|
+
<td>
|
|
241
|
+
<strong>{tr('Estimated cost')}</strong>
|
|
242
|
+
</td>
|
|
243
|
+
</tr>
|
|
244
|
+
|
|
245
|
+
<tr>
|
|
246
|
+
<td>Google Maps Platform</td>
|
|
247
|
+
<td>{this.displayCompetitorAmount(amountGmp)}</td>
|
|
248
|
+
</tr>
|
|
249
|
+
|
|
250
|
+
<tr>
|
|
251
|
+
<td>Mapbox</td>
|
|
252
|
+
<td>{this.displayCompetitorAmount(amountMbx)}</td>
|
|
253
|
+
</tr>
|
|
254
|
+
</table>
|
|
255
|
+
</div>
|
|
256
|
+
);
|
|
257
|
+
|
|
210
258
|
render() {
|
|
211
|
-
const { name, productPricing, values, id } = this.props;
|
|
259
|
+
const { name, productPricing, values, id, displayCompetitors, displayCompetitorsCallback } = this.props;
|
|
212
260
|
const { displayDetailed } = this.state;
|
|
213
261
|
const { queries } = values;
|
|
214
|
-
const {
|
|
215
|
-
|
|
262
|
+
const {
|
|
263
|
+
displayedPricing,
|
|
264
|
+
amount,
|
|
265
|
+
formatedQueries,
|
|
266
|
+
marks,
|
|
267
|
+
computedQueries,
|
|
268
|
+
aboveLastTier,
|
|
269
|
+
amountGmp,
|
|
270
|
+
amountMbx,
|
|
271
|
+
} = this.getDisplayedData(queries);
|
|
216
272
|
|
|
217
273
|
let displayedAmount = <span className="amount">{this.displayAmount(0)}</span>;
|
|
218
274
|
if (amount === '∞') {
|
|
@@ -277,11 +333,38 @@ export default class PricingSlider extends Component {
|
|
|
277
333
|
type="toggle"
|
|
278
334
|
label={tr('Detailed Pricing')}
|
|
279
335
|
icon={displayDetailed ? 'caret-top' : 'caret-bottom'}
|
|
280
|
-
onClick={() =>
|
|
336
|
+
onClick={() =>
|
|
337
|
+
this.setState(
|
|
338
|
+
{
|
|
339
|
+
displayDetailed: !displayDetailed,
|
|
340
|
+
},
|
|
341
|
+
displayCompetitorsCallback(false),
|
|
342
|
+
)
|
|
343
|
+
}
|
|
344
|
+
/>
|
|
345
|
+
|
|
346
|
+
<Button
|
|
347
|
+
className="pricing-slider__detailed-price-btn"
|
|
348
|
+
iconRight
|
|
349
|
+
type="toggle"
|
|
350
|
+
disabled={queries === 0}
|
|
351
|
+
label={tr('Compare with competitors')}
|
|
352
|
+
icon={displayCompetitors ? 'caret-top' : 'caret-bottom'}
|
|
353
|
+
onClick={() =>
|
|
354
|
+
this.setState(
|
|
355
|
+
{
|
|
356
|
+
displayDetailed: false,
|
|
357
|
+
},
|
|
358
|
+
displayCompetitorsCallback(!displayCompetitors),
|
|
359
|
+
)
|
|
360
|
+
}
|
|
281
361
|
/>
|
|
362
|
+
|
|
363
|
+
{displayCompetitors && this.displayCompetitorDetails(amountGmp, amountMbx)}
|
|
282
364
|
{displayDetailed && this.displayDetails(displayedPricing, productPricing.unit)}
|
|
283
365
|
</div>
|
|
284
366
|
)}
|
|
367
|
+
|
|
285
368
|
<div className="pricing-slider__documentation">
|
|
286
369
|
<span>
|
|
287
370
|
{tr('Read more about')} <strong>{name}</strong>
|
|
@@ -314,3 +397,4 @@ PricingSlider.propTypes = {
|
|
|
314
397
|
planId: PropTypes.string.isRequired,
|
|
315
398
|
hlPricings: PropTypes.object.isRequired,
|
|
316
399
|
};
|
|
400
|
+
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"": "",
|
|
3
3
|
" Response": " Response",
|
|
4
4
|
"(Estimated)": "(Estimated)",
|
|
5
|
-
"* Some products require
|
|
5
|
+
"* Some products require contacting sales for pricing": "* Some products require contacting sales for pricing",
|
|
6
6
|
"/ mo": "/ mo",
|
|
7
7
|
"/ month": "/ month",
|
|
8
8
|
"Accuracy": "Accuracy",
|