Show ADD_ON details + update subscription related msg (#1448)

This commit is contained in:
Abhinav Kumar 2023-11-20 11:07:26 +05:30 committed by GitHub
commit 6540d778b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 139 additions and 39 deletions

View file

@ -157,6 +157,7 @@
"RENEWAL_ACTIVE_SUBSCRIPTION_STATUS": "Renews on {{date, dateTime}}",
"RENEWAL_CANCELLED_SUBSCRIPTION_STATUS": "Ends on {{date, dateTime}}",
"RENEWAL_CANCELLED_SUBSCRIPTION_INFO": "Your subscription will be cancelled on {{date, dateTime}}",
"ADD_ON_AVAILABLE_TILL": "Your {{storage, string}} add-on is valid till {{date, dateTime}}",
"STORAGE_QUOTA_EXCEEDED_SUBSCRIPTION_INFO": "You have exceeded your storage quota, please <a>upgrade</a>",
"SUBSCRIPTION_PURCHASE_SUCCESS": "<p>We've received your payment</p><p>Your subscription is valid till <strong>{{date, dateTime}}</strong></p>",
"SUBSCRIPTION_PURCHASE_CANCELLED": "Your purchase was canceled, please try again if you want to subscribe",
@ -171,6 +172,7 @@
"UPDATE_SUBSCRIPTION": "Change plan",
"CANCEL_SUBSCRIPTION": "Cancel subscription",
"CANCEL_SUBSCRIPTION_MESSAGE": "<p>All of your data will be deleted from our servers at the end of this billing period.</p><p>Are you sure that you want to cancel your subscription?</p>",
"CANCEL_SUBSCRIPTION_WITH_ADDON_MESSAGE": "<p>Are you sure you want to cancel your subscription?</p> <p>Your data will be scheduled for deletion at the end of your add-on pack's validity.</p>",
"SUBSCRIPTION_CANCEL_FAILED": "Failed to cancel subscription",
"SUBSCRIPTION_CANCEL_SUCCESS": "Subscription canceled successfully",
"REACTIVATE_SUBSCRIPTION": "Reactivate subscription",

View file

@ -69,6 +69,48 @@ export default function SubscriptionStatus({
return <></>;
}
const messages = [];
if (!hasAddOnBonus(userDetails.bonusData)) {
if (isSubscriptionActive(userDetails.subscription)) {
if (isOnFreePlan(userDetails.subscription)) {
messages.push(
<Trans
i18nKey={'FREE_SUBSCRIPTION_INFO'}
values={{
date: userDetails.subscription?.expiryTime,
}}
/>
);
} else if (isSubscriptionCancelled(userDetails.subscription)) {
messages.push(
t('RENEWAL_CANCELLED_SUBSCRIPTION_INFO', {
date: userDetails.subscription?.expiryTime,
})
);
}
} else {
messages.push(
<Trans
i18nKey={'SUBSCRIPTION_EXPIRED_MESSAGE'}
components={{
a: <LinkButton onClick={handleClick} />,
}}
/>
);
}
}
if (hasExceededStorageQuota(userDetails) && messages.length === 0) {
messages.push(
<Trans
i18nKey={'STORAGE_QUOTA_EXCEEDED_SUBSCRIPTION_INFO'}
components={{
a: <LinkButton onClick={handleClick} />,
}}
/>
);
}
return (
<Box px={1} pt={0.5}>
<Typography
@ -76,42 +118,7 @@ export default function SubscriptionStatus({
color={'text.muted'}
onClick={handleClick && handleClick}
sx={{ cursor: handleClick && 'pointer' }}>
{isSubscriptionActive(userDetails.subscription) ? (
isOnFreePlan(userDetails.subscription) ? (
hasAddOnBonus(userDetails.bonusData) ? (
''
) : (
<Trans
i18nKey={'FREE_SUBSCRIPTION_INFO'}
values={{
date: userDetails.subscription?.expiryTime,
}}
/>
)
) : isSubscriptionCancelled(userDetails.subscription) ? (
t('RENEWAL_CANCELLED_SUBSCRIPTION_INFO', {
date: userDetails.subscription?.expiryTime,
})
) : (
hasExceededStorageQuota(userDetails) && (
<Trans
i18nKey={
'STORAGE_QUOTA_EXCEEDED_SUBSCRIPTION_INFO'
}
components={{
a: <LinkButton onClick={handleClick} />,
}}
/>
)
)
) : (
<Trans
i18nKey={'SUBSCRIPTION_EXPIRED_MESSAGE'}
components={{
a: <LinkButton onClick={handleClick} />,
}}
/>
)}
{messages}
</Typography>
</Box>
);

View file

@ -5,10 +5,13 @@ import React from 'react';
import { t } from 'i18next';
import { PeriodToggler } from '../periodToggler';
import Plans from '../plans';
import { hasAddOnBonus } from 'utils/billing';
import { BFAddOnRow } from '../plans/BfAddOnRow';
export default function FreeSubscriptionPlanSelectorCard({
plans,
subscription,
bonusData,
closeModal,
planPeriod,
togglePeriod,
@ -36,8 +39,15 @@ export default function FreeSubscriptionPlanSelectorCard({
planPeriod={planPeriod}
onPlanSelect={onPlanSelect}
subscription={subscription}
bonusData={bonusData}
closeModal={closeModal}
/>
{hasAddOnBonus(bonusData) && (
<BFAddOnRow
bonusData={bonusData}
closeModal={closeModal}
/>
)}
</Stack>
</Box>
</>

View file

@ -44,6 +44,13 @@ function PlanSelectorCard(props: Props) {
);
const galleryContext = useContext(GalleryContext);
const appContext = useContext(AppContext);
const bonusData = useMemo(() => {
const userDetails = getLocalUserDetails();
if (!userDetails) {
return null;
}
return userDetails.bonusData;
}, []);
const usage = useMemo(() => {
const userDetails = getLocalUserDetails();
@ -170,6 +177,7 @@ function PlanSelectorCard(props: Props) {
<PaidSubscriptionPlanSelectorCard
plans={plans}
subscription={subscription}
bonusData={bonusData}
closeModal={props.closeModal}
planPeriod={planPeriod}
togglePeriod={togglePeriod}
@ -181,6 +189,7 @@ function PlanSelectorCard(props: Props) {
<FreeSubscriptionPlanSelectorCard
plans={plans}
subscription={subscription}
bonusData={bonusData}
closeModal={props.closeModal}
planPeriod={planPeriod}
togglePeriod={togglePeriod}

View file

@ -5,15 +5,21 @@ import Typography from '@mui/material/Typography';
import { SpaceBetweenFlex } from '@ente/shared/components/Container';
import React from 'react';
import { t } from 'i18next';
import { convertBytesToGBs, isSubscriptionCancelled } from 'utils/billing';
import {
convertBytesToGBs,
hasAddOnBonus,
isSubscriptionCancelled,
} from 'utils/billing';
import { ManageSubscription } from '../manageSubscription';
import { PeriodToggler } from '../periodToggler';
import Plans from '../plans';
import { Trans } from 'react-i18next';
import { BFAddOnRow } from '../plans/BfAddOnRow';
export default function PaidSubscriptionPlanSelectorCard({
plans,
subscription,
bonusData,
closeModal,
usage,
planPeriod,
@ -71,6 +77,7 @@ export default function PaidSubscriptionPlanSelectorCard({
planPeriod={planPeriod}
onPlanSelect={onPlanSelect}
subscription={subscription}
bonusData={bonusData}
closeModal={closeModal}
/>
</Stack>
@ -85,11 +92,18 @@ export default function PaidSubscriptionPlanSelectorCard({
date: subscription.expiryTime,
})}
</Typography>
{hasAddOnBonus(bonusData) && (
<BFAddOnRow
bonusData={bonusData}
closeModal={closeModal}
/>
)}
</Box>
</Box>
<ManageSubscription
subscription={subscription}
bonusData={bonusData}
closeModal={closeModal}
setLoading={setLoading}
/>

View file

@ -12,16 +12,21 @@ import {
manageFamilyMethod,
hasStripeSubscription,
isSubscriptionCancelled,
hasAddOnBonus,
} from 'utils/billing';
import ManageSubscriptionButton from './button';
import { BonusData } from 'types/user';
interface Iprops {
subscription: Subscription;
bonusData?: BonusData;
closeModal: () => void;
setLoading: SetLoading;
}
export function ManageSubscription({
subscription,
bonusData,
closeModal,
setLoading,
}: Iprops) {
@ -34,6 +39,7 @@ export function ManageSubscription({
{hasStripeSubscription(subscription) && (
<StripeSubscriptionOptions
subscription={subscription}
bonusData={bonusData}
closeModal={closeModal}
setLoading={setLoading}
/>
@ -49,6 +55,7 @@ export function ManageSubscription({
function StripeSubscriptionOptions({
subscription,
bonusData,
setLoading,
closeModal,
}: Iprops) {
@ -77,7 +84,11 @@ function StripeSubscriptionOptions({
const confirmCancel = () =>
appContext.setDialogMessage({
title: t('CANCEL_SUBSCRIPTION'),
content: <Trans i18nKey={'CANCEL_SUBSCRIPTION_MESSAGE'} />,
content: hasAddOnBonus(bonusData) ? (
<Trans i18nKey={'CANCEL_SUBSCRIPTION_WITH_ADDON_MESSAGE'} />
) : (
<Trans i18nKey={'CANCEL_SUBSCRIPTION_MESSAGE'} />
),
proceed: {
text: t('CANCEL_SUBSCRIPTION'),
action: cancelSubscription.bind(

View file

@ -0,0 +1,43 @@
import { Box, styled, Typography } from '@mui/material';
import { SpaceBetweenFlex } from '@ente/shared/components/Container';
import React from 'react';
import { Trans } from 'react-i18next';
import { makeHumanReadableStorage } from 'utils/billing';
const RowContainer = styled(SpaceBetweenFlex)(({ theme }) => ({
// gap: theme.spacing(1.5),
padding: theme.spacing(1, 0),
cursor: 'pointer',
'&:hover .endIcon': {
backgroundColor: 'rgba(255,255,255,0.08)',
},
}));
export function BFAddOnRow({ bonusData, closeModal }) {
return (
<>
{bonusData.storageBonuses.map((bonus) => {
if (bonus.type.startsWith('ADD_ON')) {
return (
<RowContainer key={bonus.id} onClick={closeModal}>
<Box>
<Typography color="text.muted">
<Trans
i18nKey={'ADD_ON_AVAILABLE_TILL'}
values={{
storage: makeHumanReadableStorage(
bonus.storage
),
date: bonus.validTill,
}}
/>
</Typography>
</Box>
</RowContainer>
);
}
return null;
})}
</>
);
}

View file

@ -2,6 +2,7 @@ import { FreePlanRow } from './FreePlanRow';
import { Stack } from '@mui/material';
import React from 'react';
import {
hasAddOnBonus,
hasPaidSubscription,
isPopularPlan,
isUserSubscribedPlan,
@ -9,11 +10,13 @@ import {
import { PlanRow } from './planRow';
import { Plan, Subscription } from 'types/billing';
import { PLAN_PERIOD } from 'constants/gallery';
import { BonusData } from 'types/user';
interface Iprops {
plans: Plan[];
planPeriod: PLAN_PERIOD;
subscription: Subscription;
bonusData?: BonusData;
onPlanSelect: (plan: Plan) => void;
closeModal: () => void;
}
@ -22,6 +25,7 @@ const Plans = ({
plans,
planPeriod,
subscription,
bonusData,
onPlanSelect,
closeModal,
}: Iprops) => (
@ -38,7 +42,7 @@ const Plans = ({
onPlanSelect={onPlanSelect}
/>
))}
{!hasPaidSubscription(subscription) && (
{!hasPaidSubscription(subscription) && !hasAddOnBonus(bonusData) && (
<FreePlanRow closeModal={closeModal} />
)}
</Stack>