Skip to content
This repository was archived by the owner on Aug 11, 2021. It is now read-only.

Commit d66865f

Browse files
committed
Continue
1 parent 6a81815 commit d66865f

File tree

11 files changed

+756
-74
lines changed

11 files changed

+756
-74
lines changed

components/price/Price.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@ const CURRENCIES = {
88
CHF: 'CHF'
99
};
1010

11-
const Price = ({ children: amount = 0, currency = '', className = '', divisor = 100, suffix = '' }) => {
11+
const Price = ({ children: amount = 0, currency = '', className = '', divisor = 100, suffix = '', prefix = '' }) => {
1212
const fixedValue = Number(amount / divisor).toFixed(2);
1313
const value = fixedValue.replace('.00', '').replace('-', '');
1414
const c = <span className="currency">{CURRENCIES[currency] || currency}</span>;
1515
const p = amount < 0 ? <span className="prefix">-</span> : null;
1616
const v = <span className="amount">{value}</span>;
1717
const s = suffix ? <span className="suffix">{suffix}</span> : null;
18+
const pr = prefix ? <span className="prefix">{prefix}</span> : null;
1819

1920
if (currency === 'USD') {
2021
return (
2122
<span className={classnames(['price', className])} data-currency={currency}>
23+
{pr}
2224
{p}
2325
{c}
2426
{v}
@@ -29,6 +31,7 @@ const Price = ({ children: amount = 0, currency = '', className = '', divisor =
2931

3032
return (
3133
<span className={classnames(['price', className])} data-currency={currency}>
34+
{pr}
3235
{p}
3336
{v}
3437
{currency ? <> {c}</> : null}
@@ -42,7 +45,8 @@ Price.propTypes = {
4245
children: PropTypes.number,
4346
className: PropTypes.string,
4447
divisor: PropTypes.number,
45-
suffix: PropTypes.string
48+
suffix: PropTypes.string,
49+
prefix: PropTypes.string
4650
};
4751

4852
export default Price;

containers/payments/CurrencySelector.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ import PropTypes from 'prop-types';
33
import { Select, Group, ButtonGroup, classnames } from 'react-components';
44
import { CURRENCIES, DEFAULT_CURRENCY } from 'proton-shared/lib/constants';
55

6+
const addSymbol = (currency) => {
7+
if (currency === 'EUR') {
8+
return `€ ${currency}`;
9+
}
10+
11+
if (currency === 'USD') {
12+
return `$ ${currency}`;
13+
}
14+
15+
return currency;
16+
};
17+
618
const CurrencySelector = ({ currency = DEFAULT_CURRENCY, onSelect, mode = 'select', ...rest }) => {
719
const handleChange = ({ target }) => onSelect(target.value);
820
const options = CURRENCIES.map((c) => ({ text: c, value: c }));
@@ -26,7 +38,14 @@ const CurrencySelector = ({ currency = DEFAULT_CURRENCY, onSelect, mode = 'selec
2638
}
2739

2840
if (mode === 'select') {
29-
return <Select value={currency} options={options} onChange={handleChange} {...rest} />;
41+
return (
42+
<Select
43+
value={currency}
44+
options={options.map((option) => ({ ...option, text: addSymbol(option.text) }))}
45+
onChange={handleChange}
46+
{...rest}
47+
/>
48+
);
3049
}
3150

3251
return null;

containers/payments/PlansSection.js

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ import {
2121

2222
import { checkSubscription, deleteSubscription } from 'proton-shared/lib/api/payments';
2323
import { DEFAULT_CURRENCY, DEFAULT_CYCLE } from 'proton-shared/lib/constants';
24-
import { getPlans, isBundleEligible } from 'proton-shared/lib/helpers/subscription';
24+
import { getPlans, isBundleEligible, getPlan } from 'proton-shared/lib/helpers/subscription';
2525
import { isLoyal } from 'proton-shared/lib/helpers/organization';
2626

27-
import SubscriptionModal from './subscription/SubscriptionModal';
27+
import NewSubscriptionModal from './subscription/NewSubscriptionModal';
2828
import MailSubscriptionTable from './subscription/MailSubscriptionTable';
29-
import { mergePlansMap, getCheckParams } from './subscription/helpers';
3029

3130
const PlansSection = () => {
3231
const { call } = useEventManager();
@@ -38,6 +37,7 @@ const PlansSection = () => {
3837
const [organization = {}, loadingOrganization] = useOrganization();
3938
const [plans = [], loadingPlans] = usePlans();
4039
const api = useApi();
40+
const { Name } = getPlan(subscription) || {};
4141

4242
const [currency, setCurrency] = useState(DEFAULT_CURRENCY);
4343
const [cycle, setCycle] = useState(DEFAULT_CYCLE);
@@ -68,29 +68,25 @@ const PlansSection = () => {
6868
return handleUnsubscribe();
6969
};
7070

71-
const handleModal = (newPlansMap, step) => async () => {
72-
if (!newPlansMap) {
71+
const handleModal = async (planID) => {
72+
if (!planID) {
7373
handleOpenModal();
7474
return;
7575
}
7676

77-
const plansMap = mergePlansMap(newPlansMap, subscription);
7877
const couponCode = CouponCode ? CouponCode : undefined; // From current subscription; CouponCode can be null
7978
const { Coupon } = await api(
80-
checkSubscription(getCheckParams({ plans, plansMap, currency, cycle, coupon: couponCode }))
79+
checkSubscription({
80+
PlanIDs: [planID],
81+
Currency: currency,
82+
Cycle: cycle,
83+
CouponCode: couponCode
84+
})
8185
);
86+
8287
const coupon = Coupon ? Coupon.Code : undefined; // Coupon can equals null
8388

84-
createModal(
85-
<SubscriptionModal
86-
subscription={subscription}
87-
plansMap={plansMap}
88-
coupon={coupon}
89-
currency={currency}
90-
cycle={cycle}
91-
step={step}
92-
/>
93-
);
89+
createModal(<NewSubscriptionModal planIDs={[planID]} coupon={coupon} currency={currency} cycle={cycle} />);
9490
};
9591

9692
useEffect(() => {
@@ -138,13 +134,10 @@ const PlansSection = () => {
138134
</div>
139135
<MailSubscriptionTable
140136
plans={plans}
141-
subscription={subscription}
137+
planNameSelected={Name}
142138
cycle={cycle}
143139
currency={currency}
144-
onSelect={(planIndex) => {
145-
const { Name } = plans[planIndex];
146-
handleModal({ [Name]: 1 });
147-
}}
140+
onSelect={handleModal}
148141
/>
149142
</>
150143
);

containers/payments/subscription/MailSubscriptionTable.js

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { SubscriptionTable } from 'react-components';
33
import PropTypes from 'prop-types';
44
import { PLAN_NAMES, PLANS, CYCLE } from 'proton-shared/lib/constants';
5-
import { getPlan } from 'proton-shared/lib/helpers/subscription';
5+
import { toMap } from 'proton-shared/lib/helpers/object';
66
import { c } from 'ttag';
77
import freePlanSvg from 'design-system/assets/img/pm-images/free-plan.svg';
88
import plusPlanSvg from 'design-system/assets/img/pm-images/plus-plan.svg';
@@ -25,10 +25,11 @@ const FREE_PLAN = {
2525
}
2626
};
2727

28-
const MailSubscriptionTable = ({ subscription = {}, plans: apiPlans = [], cycle, currency, onSelect }) => {
29-
const plusPlan = apiPlans.find(({ Name }) => Name === PLANS.PLUS);
30-
const professionalPlan = apiPlans.find(({ Name }) => Name === PLANS.PROFESSIONAL);
31-
const visionaryPlan = apiPlans.find(({ Name }) => Name === PLANS.VISIONARY);
28+
const MailSubscriptionTable = ({ planNameSelected, plans: apiPlans = [], cycle, currency, onSelect }) => {
29+
const plansMap = toMap(apiPlans, 'Name');
30+
const plusPlan = plansMap[PLANS.PLUS];
31+
const professionalPlan = plansMap[PLANS.PROFESSIONAL];
32+
const visionaryPlan = plansMap[PLANS.VISIONARY];
3233
const plans = [
3334
{
3435
planName: 'Free',
@@ -63,6 +64,7 @@ const MailSubscriptionTable = ({ subscription = {}, plans: apiPlans = [], cycle,
6364
]
6465
},
6566
plusPlan && {
67+
planID: plusPlan.ID,
6668
planName: PLAN_NAMES[PLANS.PLUS],
6769
canCustomize: true,
6870
price: <SubscriptionPrices cycle={cycle} currency={currency} plan={plusPlan} />,
@@ -95,9 +97,17 @@ const MailSubscriptionTable = ({ subscription = {}, plans: apiPlans = [], cycle,
9597
]
9698
},
9799
professionalPlan && {
100+
planID: professionalPlan.ID,
98101
planName: PLAN_NAMES[PLANS.PROFESSIONAL],
99102
canCustomize: true,
100-
price: <SubscriptionPrices cycle={cycle} currency={currency} plan={professionalPlan} suffix={c('Suffix').t`/month/user`} />,
103+
price: (
104+
<SubscriptionPrices
105+
cycle={cycle}
106+
currency={currency}
107+
plan={professionalPlan}
108+
suffix={c('Suffix').t`/month/user`}
109+
/>
110+
),
101111
imageSrc: professionalPlanSvg,
102112
description: c('Description').t`For large organizations and businesses`,
103113
features: [
@@ -127,6 +137,7 @@ const MailSubscriptionTable = ({ subscription = {}, plans: apiPlans = [], cycle,
127137
]
128138
},
129139
visionaryPlan && {
140+
planID: visionaryPlan.ID,
130141
planName: PLAN_NAMES[PLANS.VISIONARY],
131142
canCustomize: false,
132143
price: <SubscriptionPrices cycle={cycle} currency={currency} plan={visionaryPlan} />,
@@ -159,24 +170,27 @@ const MailSubscriptionTable = ({ subscription = {}, plans: apiPlans = [], cycle,
159170
]
160171
}
161172
];
162-
const { Name } = getPlan(subscription);
163173

164174
return (
165175
<>
166176
<SubscriptionTable
167-
currentPlanIndex={INDEXES[Name] || 0}
177+
currentPlanIndex={INDEXES[planNameSelected] || 0}
168178
mostPopularIndex={1}
169179
plans={plans}
170-
onSelect={onSelect}
180+
onSelect={(index) => onSelect(plans[index].planID)}
171181
/>
172182
<p className="small mt1 mb0">* {c('Info concerning plan features').t`Customizable features`}</p>
173-
<p className="small mt0 mb0">** {c('Info concerning plan features').t`ProtonMail cannot be used for mass emailing or spamming. Legitimate emails are unlimited.`}</p>
183+
<p className="small mt0 mb0">
184+
**{' '}
185+
{c('Info concerning plan features')
186+
.t`ProtonMail cannot be used for mass emailing or spamming. Legitimate emails are unlimited.`}
187+
</p>
174188
</>
175189
);
176190
};
177191

178192
MailSubscriptionTable.propTypes = {
179-
subscription: PropTypes.object,
193+
planNameSelected: PropTypes.string,
180194
plans: PropTypes.arrayOf(PropTypes.object),
181195
onSelect: PropTypes.func.isRequired,
182196
cycle: PropTypes.oneOf([CYCLE.MONTHLY, CYCLE.YEARLY, CYCLE.TWO_YEARS]).isRequired,

0 commit comments

Comments
 (0)