Skip to content

Commit 81081bd

Browse files
authored
fix: display those with no subscription as Free Tier users (#2221)
Closes #2218 Users without a subscription will no longer be treated as early adopters, but as Free tier users.
1 parent 3befe79 commit 81081bd

File tree

6 files changed

+38
-108
lines changed

6 files changed

+38
-108
lines changed

packages/website/components/account/storageManager/storageManager.js

+10-23
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,18 @@ const StorageManager = ({ className = '', content }) => {
3333
const uploaded = useMemo(() => data?.usedStorage?.uploaded || 0, [data]);
3434
const psaPinned = useMemo(() => data?.usedStorage?.psaPinned || 0, [data]);
3535
const limit = useMemo(() => {
36-
if (currentPlan?.id === 'earlyAdopter') {
37-
return data?.storageLimitBytes || defaultStorageLimit;
38-
} else {
39-
const byteConversion = currentPlan?.tiers?.[0].upTo ? gibibyte * currentPlan.tiers[0].upTo : defaultStorageLimit;
40-
return byteConversion;
41-
}
42-
}, [data, currentPlan]);
36+
const byteConversion = currentPlan?.tiers?.[0].upTo ? gibibyte * currentPlan.tiers[0].upTo : defaultStorageLimit;
37+
return byteConversion;
38+
}, [currentPlan]);
4339
const [componentInViewport, setComponentInViewport] = useState(false);
4440
const storageManagerRef = useRef(/** @type {HTMLDivElement | null} */ (null));
4541

46-
const { maxSpaceLabel, percentUploaded, percentPinned } = useMemo(
42+
const { percentUploaded, percentPinned } = useMemo(
4743
() => ({
48-
maxSpaceLabel: `${Math.floor(limit / tebibyte)} ${content.max_space_tib_label}`,
4944
percentUploaded: Math.min((uploaded / limit) * 100, 100),
5045
percentPinned: Math.min((psaPinned / limit) * 100, 100),
5146
}),
52-
[uploaded, psaPinned, limit, content]
47+
[uploaded, psaPinned, limit]
5348
);
5449

5550
useEffect(() => {
@@ -116,19 +111,11 @@ const StorageManager = ({ className = '', content }) => {
116111
standard: 'iec',
117112
})}
118113
</span>
119-
{currentPlan?.id === 'earlyAdopter' ? (
120-
<>
121-
&nbsp;of <span className="storage-number">{maxSpaceLabel}</span> used
122-
</>
123-
) : (
124-
<>
125-
&nbsp;of{' '}
126-
<span className="storage-number">
127-
{currentPlan?.tiers?.[0].upTo ? formatAsStorageAmount(currentPlan?.tiers?.[0].upTo) : ''}
128-
</span>{' '}
129-
used
130-
</>
131-
)}
114+
&nbsp;of{' '}
115+
<span className="storage-number">
116+
{currentPlan?.tiers?.[0].upTo ? formatAsStorageAmount(currentPlan?.tiers?.[0].upTo) : ''}
117+
</span>{' '}
118+
used
132119
<Tooltip content={content.tooltip_total}>
133120
<InfoIcon />
134121
</Tooltip>

packages/website/components/accountPlansModal/accountPlansModal.js

-3
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,6 @@ const AccountPlansModal = ({
121121
if (typeof currentPlan === 'undefined') {
122122
throw new Error('Change plan modal form submitted without selected plan');
123123
}
124-
if (currentPlan.id === 'earlyAdopter') {
125-
throw new Error('Change plan modal form submitted with early adopter plan, but it must be a paid plan');
126-
}
127124
if (currentPlan.id !== 'free' && currentPlan.id !== 'pro' && currentPlan.id !== 'lite') {
128125
throw new Error('Unrecognized plan');
129126
}

packages/website/components/contexts/plansContext.js

+17-40
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,6 @@
77
* @property {StoragePrice|Plan} price
88
*/
99

10-
/**
11-
* @typedef {null} EarlyAdopterStorageSubscription
12-
* When api's /user/payment .subscription.storage is null, there is no storage subscription.
13-
* And that is what we sometimes render as 'Early Adopter'
14-
*/
15-
16-
/**
17-
* @typedef {'earlyAdopter'} EarlyAdopterPlanId
18-
*/
19-
2010
/**
2111
* @typedef {object} StripeTier
2212
* @property {number|null} flatAmount
@@ -34,7 +24,23 @@
3424
* @property {StripeTier[]} [tiers]
3525
*/
3626

37-
export const sharedPlans = [
27+
export const freePlan = {
28+
id: /** @type {const} */ ('free'),
29+
description: 'You are currently on the free tier. You can use our service up to 5GiB without being charged.',
30+
label: 'Free',
31+
bandwidth: '10',
32+
isPreferred: false,
33+
tiers: [
34+
{
35+
flatAmount: 0,
36+
unitAmount: 0,
37+
upTo: 5,
38+
},
39+
],
40+
};
41+
42+
export const plans = [
43+
freePlan,
3844
{
3945
id: /** @type {const} */ ('lite'),
4046
description: 'For those that want to take advantage of more storage',
@@ -74,32 +80,3 @@ export const sharedPlans = [
7480
],
7581
},
7682
];
77-
78-
export const freePlan = {
79-
id: /** @type {const} */ ('free'),
80-
description: 'You are currently on the free tier. You can use our service up to 5GiB without being charged.',
81-
label: 'Free',
82-
bandwidth: '10',
83-
isPreferred: false,
84-
tiers: [
85-
{
86-
flatAmount: 0,
87-
unitAmount: 0,
88-
upTo: 5,
89-
},
90-
],
91-
};
92-
93-
export const earlyAdopterPlan = {
94-
id: /** @type {const} */ ('earlyAdopter'),
95-
isPreferred: true,
96-
bandwidth: null,
97-
description:
98-
'As an early adopter we appreciate your support and can continue to use the storage you are already accustomed to.',
99-
label: 'Early Adopter',
100-
tiers: [],
101-
};
102-
103-
export const plans = [freePlan, ...sharedPlans];
104-
export const plansEarly = [earlyAdopterPlan, ...sharedPlans];
105-
export const plansAll = [freePlan, earlyAdopterPlan, ...sharedPlans];

packages/website/hooks/use-payment.js

+4-18
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useState, useEffect, useMemo } from 'react';
22

33
import { userBillingSettings } from '../lib/api';
44
import constants from '../lib/constants';
5-
import { earlyAdopterPlan, plans, plansEarly } from '../components/contexts/plansContext';
5+
import { freePlan, plans } from '../components/contexts/plansContext';
66

77
/**
88
* @typedef {import('../components/contexts/plansContext').Plan} Plan
@@ -42,19 +42,6 @@ export const usePayment = () => {
4242
loadPaymentSettings();
4343
}, [needsFetchPaymentSettings]);
4444

45-
// When storageSubscription is null, user sees a version of planList that contains 'Early Adopter' instead of 'free'
46-
/** @type {Array<Plan>} */
47-
const planList = useMemo(() => {
48-
if (typeof paymentSettings === 'undefined') {
49-
return plans;
50-
}
51-
const storageSubscription = paymentSettings.subscription.storage;
52-
if (storageSubscription === null) {
53-
return plansEarly;
54-
}
55-
return plans;
56-
}, [paymentSettings]);
57-
5845
// whenever the optimisticCurrentPlan is set, enqueue a fetch of actual payment settings
5946
useEffect(() => {
6047
if (optimisticCurrentPlan) {
@@ -72,10 +59,9 @@ export const usePayment = () => {
7259
}
7360
const storageSubscription = paymentSettings.subscription.storage;
7461
if (!storageSubscription) {
75-
// user has no storage subscription, show early adopter plan
76-
return earlyAdopterPlan;
62+
return freePlan;
7763
}
78-
const matchingStandardPlan = planList.find(plan => {
64+
const matchingStandardPlan = plans.find(plan => {
7965
return plan.id === storageSubscription.price;
8066
});
8167

@@ -84,7 +70,7 @@ export const usePayment = () => {
8470
}
8571

8672
return matchingStandardPlan;
87-
}, [planList, paymentSettings, optimisticCurrentPlan]);
73+
}, [paymentSettings, optimisticCurrentPlan]);
8874

8975
const savedPaymentMethod = useMemo(() => {
9076
return paymentSettings?.paymentMethod;

packages/website/lib/api.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,6 @@ export class UnexpectedAPIResponseError extends APIError {
333333

334334
/**
335335
* @typedef {import('../components/contexts/plansContext').StorageSubscription} StorageSubscription
336-
* @typedef {import('../components/contexts/plansContext').EarlyAdopterStorageSubscription
337-
* } EarlyAdopterStorageSubscription
338336
*/
339337

340338
/**
@@ -364,7 +362,7 @@ export function isW3STermsOfServiceAgreement(value) {
364362
* Gets/Puts saved user plan and billing settings.
365363
* @param {W3STermsOfServiceAgreement|undefined} agreement
366364
* @param {string} [pmId] - payment method id
367-
* @param {StorageSubscription|EarlyAdopterStorageSubscription} [storageSubscription]
365+
* @param {StorageSubscription} [storageSubscription]
368366
*/
369367
export async function userBillingSettings(agreement, pmId, storageSubscription) {
370368
const putBody =

packages/website/pages/account/payment.js

+6-21
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import PaymentTable from '../../components/account/paymentTable.js/paymentTable.
1414
import PaymentMethodCard from '../../components/account/paymentMethodCard/paymentMethodCard.js';
1515
import AccountPlansModal from '../../components/accountPlansModal/accountPlansModal.js';
1616
import AddPaymentMethodForm from '../../components/account/addPaymentMethodForm/addPaymentMethodForm.js';
17-
import { earlyAdopterPlan, plans, plansEarly } from '../../components/contexts/plansContext';
17+
import { plans, freePlan } from '../../components/contexts/plansContext';
1818
import { userBillingSettings } from '../../lib/api';
1919
import GeneralPageData from '../../content/pages/general.json';
2020
import constants from '../../lib/constants.js';
@@ -23,7 +23,6 @@ import constants from '../../lib/constants.js';
2323
* @typedef {import('../../components/contexts/plansContext').Plan} Plan
2424
* @typedef {import('../../components/contexts/plansContext').StorageSubscription} StorageSubscription
2525
* @typedef {import('../../components/contexts/plansContext').StoragePrice} StoragePrice
26-
* @typedef {import('../../components/contexts/plansContext').EarlyAdopterPlanId} EarlyAdopterPlanId
2726
*/
2827

2928
/**
@@ -96,19 +95,6 @@ const PaymentSettingsPage = props => {
9695
loadPaymentSettings();
9796
}, [needsFetchPaymentSettings]);
9897

99-
// When storageSubscription is null, user sees a version of planList that contains 'Early Adopter' instead of 'free'
100-
/** @type {Array<Plan>} */
101-
const planList = useMemo(() => {
102-
if (typeof paymentSettings === 'undefined') {
103-
return plans;
104-
}
105-
const storageSubscription = paymentSettings.subscription.storage;
106-
if (storageSubscription === null) {
107-
return plansEarly;
108-
}
109-
return plans;
110-
}, [paymentSettings]);
111-
11298
// whenever the optimisticCurrentPlan is set, enqueue a fetch of actual payment settings
11399
useEffect(() => {
114100
if (optimisticCurrentPlan) {
@@ -126,15 +112,14 @@ const PaymentSettingsPage = props => {
126112
}
127113
const storageSubscription = paymentSettings.subscription.storage;
128114
if (!storageSubscription) {
129-
// user has no storage subscription, show early adopter plan
130-
return earlyAdopterPlan;
115+
return freePlan;
131116
}
132117
return typeof storageSubscription.price === 'string'
133-
? planList.find(plan => {
118+
? plans.find(plan => {
134119
return plan.id === storageSubscription.price;
135120
})
136121
: storageSubscription.price;
137-
}, [planList, paymentSettings, optimisticCurrentPlan]);
122+
}, [paymentSettings, optimisticCurrentPlan]);
138123
const savedPaymentMethod = useMemo(() => {
139124
return paymentSettings?.paymentMethod;
140125
}, [paymentSettings]);
@@ -160,7 +145,7 @@ const PaymentSettingsPage = props => {
160145
<Loading message="Fetching user info..." />
161146
) : (
162147
<PaymentTable
163-
plans={planList}
148+
plans={plans}
164149
currentPlan={currentPlan}
165150
setPlanSelection={setPlanSelection}
166151
setIsPaymentPlanModalOpen={setIsPaymentPlanModalOpen}
@@ -214,7 +199,7 @@ const PaymentSettingsPage = props => {
214199
removePlanQueryParam();
215200
}
216201
}}
217-
planList={planList}
202+
planList={plans}
218203
planSelection={planSelection}
219204
setCurrentPlan={setOptimisticCurrentPlan}
220205
savedPaymentMethod={savedPaymentMethod}

0 commit comments

Comments
 (0)