Show ADD_ON details + update subscription related msg (#1448)
This commit is contained in:
commit
6540d778b9
|
@ -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",
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
</>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue