update plan selector card with active plan
This commit is contained in:
parent
94a408d815
commit
ee03cce577
202
src/components/pages/gallery/PlanSelector/card.tsx
Normal file
202
src/components/pages/gallery/PlanSelector/card.tsx
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
import { PLAN_PERIOD } from './../../../../constants/gallery/index';
|
||||||
|
import { PeriodToggler } from './periodToggler';
|
||||||
|
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
||||||
|
import constants from 'utils/strings/constants';
|
||||||
|
import { Plan } from 'types/billing';
|
||||||
|
import {
|
||||||
|
isUserSubscribedPlan,
|
||||||
|
isSubscriptionCancelled,
|
||||||
|
updateSubscription,
|
||||||
|
hasStripeSubscription,
|
||||||
|
isOnFreePlan,
|
||||||
|
planForSubscription,
|
||||||
|
hasMobileSubscription,
|
||||||
|
hasPaypalSubscription,
|
||||||
|
getLocalUserSubscription,
|
||||||
|
hasPaidSubscription,
|
||||||
|
convertBytesToGBs,
|
||||||
|
getTotalFamilyUsage,
|
||||||
|
makeHumanReadableStorage,
|
||||||
|
} from 'utils/billing';
|
||||||
|
import { reverseString } from 'utils/common';
|
||||||
|
import { GalleryContext } from 'pages/gallery';
|
||||||
|
import billingService from 'services/billingService';
|
||||||
|
import { SetLoading } from 'types/gallery';
|
||||||
|
import { logError } from 'utils/sentry';
|
||||||
|
import { AppContext } from 'pages/_app';
|
||||||
|
import Plans from './plans';
|
||||||
|
import { Box, Stack, Typography } from '@mui/material';
|
||||||
|
import { useLocalState } from 'hooks/useLocalState';
|
||||||
|
import { LS_KEYS } from 'utils/storage/localStorage';
|
||||||
|
import { getLocalUserDetails } from 'utils/user';
|
||||||
|
import { ManageSubscription } from './manageSubscription';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
closeModal: any;
|
||||||
|
setLoading: SetLoading;
|
||||||
|
}
|
||||||
|
|
||||||
|
function PlanSelectorCard(props: Props) {
|
||||||
|
const subscription = useMemo(() => getLocalUserSubscription(), []);
|
||||||
|
const totalFamilyUsage = useMemo(
|
||||||
|
() => getTotalFamilyUsage(getLocalUserDetails().familyData),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
const [plans, setPlans] = useLocalState<Plan[]>(LS_KEYS.PLANS);
|
||||||
|
const [planPeriod, setPlanPeriod] = useState<PLAN_PERIOD>(PLAN_PERIOD.YEAR);
|
||||||
|
const galleryContext = useContext(GalleryContext);
|
||||||
|
const appContext = useContext(AppContext);
|
||||||
|
|
||||||
|
const togglePeriod = () => {
|
||||||
|
setPlanPeriod((prevPeriod) =>
|
||||||
|
prevPeriod === PLAN_PERIOD.MONTH
|
||||||
|
? PLAN_PERIOD.YEAR
|
||||||
|
: PLAN_PERIOD.MONTH
|
||||||
|
);
|
||||||
|
};
|
||||||
|
function onReopenClick() {
|
||||||
|
appContext.closeMessageDialog();
|
||||||
|
galleryContext.showPlanSelectorModal();
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
const main = async () => {
|
||||||
|
try {
|
||||||
|
props.setLoading(true);
|
||||||
|
let plans = await billingService.getPlans();
|
||||||
|
|
||||||
|
const planNotListed =
|
||||||
|
plans.filter((plan) =>
|
||||||
|
isUserSubscribedPlan(plan, subscription)
|
||||||
|
).length === 0;
|
||||||
|
if (
|
||||||
|
subscription &&
|
||||||
|
!isOnFreePlan(subscription) &&
|
||||||
|
planNotListed
|
||||||
|
) {
|
||||||
|
plans = [planForSubscription(subscription), ...plans];
|
||||||
|
}
|
||||||
|
setPlans(plans);
|
||||||
|
} catch (e) {
|
||||||
|
logError(e, 'plan selector modal open failed');
|
||||||
|
props.closeModal();
|
||||||
|
appContext.setDialogMessage({
|
||||||
|
title: constants.OPEN_PLAN_SELECTOR_MODAL_FAILED,
|
||||||
|
content: constants.UNKNOWN_ERROR,
|
||||||
|
close: { text: 'close', variant: 'danger' },
|
||||||
|
proceed: {
|
||||||
|
text: constants.REOPEN_PLAN_SELECTOR_MODAL,
|
||||||
|
variant: 'accent',
|
||||||
|
action: onReopenClick,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
props.setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
main();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function onPlanSelect(plan: Plan) {
|
||||||
|
if (
|
||||||
|
hasMobileSubscription(subscription) &&
|
||||||
|
!isSubscriptionCancelled(subscription)
|
||||||
|
) {
|
||||||
|
appContext.setDialogMessage({
|
||||||
|
title: constants.ERROR,
|
||||||
|
content: constants.CANCEL_SUBSCRIPTION_ON_MOBILE,
|
||||||
|
close: { variant: 'danger' },
|
||||||
|
});
|
||||||
|
} else if (
|
||||||
|
hasPaypalSubscription(subscription) &&
|
||||||
|
!isSubscriptionCancelled(subscription)
|
||||||
|
) {
|
||||||
|
appContext.setDialogMessage({
|
||||||
|
title: constants.MANAGE_PLAN,
|
||||||
|
content: constants.PAYPAL_MANAGE_NOT_SUPPORTED_MESSAGE(),
|
||||||
|
close: { variant: 'danger' },
|
||||||
|
});
|
||||||
|
} else if (hasStripeSubscription(subscription)) {
|
||||||
|
appContext.setDialogMessage({
|
||||||
|
title: `${constants.CONFIRM} ${reverseString(
|
||||||
|
constants.UPDATE_SUBSCRIPTION
|
||||||
|
)}`,
|
||||||
|
content: constants.UPDATE_SUBSCRIPTION_MESSAGE,
|
||||||
|
proceed: {
|
||||||
|
text: constants.UPDATE_SUBSCRIPTION,
|
||||||
|
action: updateSubscription.bind(
|
||||||
|
null,
|
||||||
|
plan,
|
||||||
|
appContext.setDialogMessage,
|
||||||
|
props.setLoading,
|
||||||
|
props.closeModal
|
||||||
|
),
|
||||||
|
variant: 'accent',
|
||||||
|
},
|
||||||
|
close: { text: constants.CANCEL },
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
props.setLoading(true);
|
||||||
|
await billingService.buySubscription(plan.stripeID);
|
||||||
|
} catch (e) {
|
||||||
|
props.setLoading(false);
|
||||||
|
appContext.setDialogMessage({
|
||||||
|
title: constants.ERROR,
|
||||||
|
content: constants.SUBSCRIPTION_PURCHASE_FAILED,
|
||||||
|
close: { variant: 'danger' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Stack spacing={3} p={1.5}>
|
||||||
|
{hasPaidSubscription(subscription) ? (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="h3" fontWeight={'bold'}>
|
||||||
|
{constants.SUBSCRIPTION}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color={'text.secondary'}>
|
||||||
|
{convertBytesToGBs(subscription.storage)}{' '}
|
||||||
|
{constants.GB}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
) : (
|
||||||
|
<Typography variant="h3" fontWeight={'bold'}>
|
||||||
|
{constants.CHOOSE_PLAN}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
{totalFamilyUsage > 0 && (
|
||||||
|
<Typography color={'text.secondary'} fontWeight={'bold'}>
|
||||||
|
{constants.CURRENT_USAGE(
|
||||||
|
makeHumanReadableStorage(totalFamilyUsage)
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
<Box>
|
||||||
|
<PeriodToggler
|
||||||
|
planPeriod={planPeriod}
|
||||||
|
togglePeriod={togglePeriod}
|
||||||
|
/>
|
||||||
|
<Typography mt={0.5} color="text.secondary">
|
||||||
|
{constants.TWO_MONTHS_FREE}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Plans
|
||||||
|
plans={plans}
|
||||||
|
planPeriod={planPeriod}
|
||||||
|
onPlanSelect={onPlanSelect}
|
||||||
|
subscription={subscription}
|
||||||
|
/>
|
||||||
|
<ManageSubscription
|
||||||
|
subscription={subscription}
|
||||||
|
closeModal={props.closeModal}
|
||||||
|
setLoading={props.setLoading}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PlanSelectorCard;
|
|
@ -1,150 +1,19 @@
|
||||||
import { PeriodToggler } from './periodToggler';
|
import React, { useContext } from 'react';
|
||||||
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
|
||||||
import constants from 'utils/strings/constants';
|
|
||||||
import { Plan } from 'types/billing';
|
|
||||||
import {
|
|
||||||
isUserSubscribedPlan,
|
|
||||||
isSubscriptionCancelled,
|
|
||||||
updateSubscription,
|
|
||||||
hasStripeSubscription,
|
|
||||||
isOnFreePlan,
|
|
||||||
planForSubscription,
|
|
||||||
hasMobileSubscription,
|
|
||||||
hasPaypalSubscription,
|
|
||||||
getLocalUserSubscription,
|
|
||||||
} from 'utils/billing';
|
|
||||||
import { reverseString } from 'utils/common';
|
|
||||||
import { GalleryContext } from 'pages/gallery';
|
|
||||||
import billingService from 'services/billingService';
|
|
||||||
import { SetLoading } from 'types/gallery';
|
import { SetLoading } from 'types/gallery';
|
||||||
import { logError } from 'utils/sentry';
|
|
||||||
import { AppContext } from 'pages/_app';
|
import { AppContext } from 'pages/_app';
|
||||||
import Plans from './plans';
|
import { Box, Dialog } from '@mui/material';
|
||||||
import { Box, Dialog, Stack, Typography } from '@mui/material';
|
import PlanSelectorCard from './card';
|
||||||
import { useLocalState } from 'hooks/useLocalState';
|
|
||||||
import { LS_KEYS } from 'utils/storage/localStorage';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modalView: boolean;
|
modalView: boolean;
|
||||||
closeModal: any;
|
closeModal: any;
|
||||||
|
|
||||||
setLoading: SetLoading;
|
setLoading: SetLoading;
|
||||||
}
|
}
|
||||||
export enum PLAN_PERIOD {
|
|
||||||
MONTH = 'month',
|
|
||||||
YEAR = 'year',
|
|
||||||
}
|
|
||||||
|
|
||||||
function PlanSelector(props: Props) {
|
function PlanSelector(props: Props) {
|
||||||
const subscription = useMemo(() => getLocalUserSubscription(), []);
|
|
||||||
const [plans, setPlans] = useLocalState<Plan[]>(LS_KEYS.PLANS);
|
|
||||||
const [planPeriod, setPlanPeriod] = useState<PLAN_PERIOD>(PLAN_PERIOD.YEAR);
|
|
||||||
const galleryContext = useContext(GalleryContext);
|
|
||||||
const appContext = useContext(AppContext);
|
const appContext = useContext(AppContext);
|
||||||
|
|
||||||
const togglePeriod = () => {
|
|
||||||
setPlanPeriod((prevPeriod) =>
|
|
||||||
prevPeriod === PLAN_PERIOD.MONTH
|
|
||||||
? PLAN_PERIOD.YEAR
|
|
||||||
: PLAN_PERIOD.MONTH
|
|
||||||
);
|
|
||||||
};
|
|
||||||
function onReopenClick() {
|
|
||||||
appContext.closeMessageDialog();
|
|
||||||
galleryContext.showPlanSelectorModal();
|
|
||||||
}
|
|
||||||
useEffect(() => {
|
|
||||||
if (!props.modalView) {
|
if (!props.modalView) {
|
||||||
return;
|
return <></>;
|
||||||
}
|
|
||||||
const main = async () => {
|
|
||||||
try {
|
|
||||||
props.setLoading(true);
|
|
||||||
let plans = await billingService.getPlans();
|
|
||||||
|
|
||||||
const planNotListed =
|
|
||||||
plans.filter((plan) =>
|
|
||||||
isUserSubscribedPlan(plan, subscription)
|
|
||||||
).length === 0;
|
|
||||||
if (
|
|
||||||
subscription &&
|
|
||||||
!isOnFreePlan(subscription) &&
|
|
||||||
planNotListed
|
|
||||||
) {
|
|
||||||
plans = [planForSubscription(subscription), ...plans];
|
|
||||||
}
|
|
||||||
setPlans(plans);
|
|
||||||
} catch (e) {
|
|
||||||
logError(e, 'plan selector modal open failed');
|
|
||||||
props.closeModal();
|
|
||||||
appContext.setDialogMessage({
|
|
||||||
title: constants.OPEN_PLAN_SELECTOR_MODAL_FAILED,
|
|
||||||
content: constants.UNKNOWN_ERROR,
|
|
||||||
close: { text: 'close', variant: 'danger' },
|
|
||||||
proceed: {
|
|
||||||
text: constants.REOPEN_PLAN_SELECTOR_MODAL,
|
|
||||||
variant: 'accent',
|
|
||||||
action: onReopenClick,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
props.setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
main();
|
|
||||||
}, [props.modalView]);
|
|
||||||
|
|
||||||
async function onPlanSelect(plan: Plan) {
|
|
||||||
if (
|
|
||||||
hasMobileSubscription(subscription) &&
|
|
||||||
!isSubscriptionCancelled(subscription)
|
|
||||||
) {
|
|
||||||
appContext.setDialogMessage({
|
|
||||||
title: constants.ERROR,
|
|
||||||
content: constants.CANCEL_SUBSCRIPTION_ON_MOBILE,
|
|
||||||
close: { variant: 'danger' },
|
|
||||||
});
|
|
||||||
} else if (
|
|
||||||
hasPaypalSubscription(subscription) &&
|
|
||||||
!isSubscriptionCancelled(subscription)
|
|
||||||
) {
|
|
||||||
appContext.setDialogMessage({
|
|
||||||
title: constants.MANAGE_PLAN,
|
|
||||||
content: constants.PAYPAL_MANAGE_NOT_SUPPORTED_MESSAGE(),
|
|
||||||
close: { variant: 'danger' },
|
|
||||||
});
|
|
||||||
} else if (hasStripeSubscription(subscription)) {
|
|
||||||
appContext.setDialogMessage({
|
|
||||||
title: `${constants.CONFIRM} ${reverseString(
|
|
||||||
constants.UPDATE_SUBSCRIPTION
|
|
||||||
)}`,
|
|
||||||
content: constants.UPDATE_SUBSCRIPTION_MESSAGE,
|
|
||||||
proceed: {
|
|
||||||
text: constants.UPDATE_SUBSCRIPTION,
|
|
||||||
action: updateSubscription.bind(
|
|
||||||
null,
|
|
||||||
plan,
|
|
||||||
appContext.setDialogMessage,
|
|
||||||
props.setLoading,
|
|
||||||
props.closeModal
|
|
||||||
),
|
|
||||||
variant: 'accent',
|
|
||||||
},
|
|
||||||
close: { text: constants.CANCEL },
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
props.setLoading(true);
|
|
||||||
await billingService.buySubscription(plan.stripeID);
|
|
||||||
} catch (e) {
|
|
||||||
props.setLoading(false);
|
|
||||||
appContext.setDialogMessage({
|
|
||||||
title: constants.ERROR,
|
|
||||||
content: constants.SUBSCRIPTION_PURCHASE_FAILED,
|
|
||||||
close: { variant: 'danger' },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -154,35 +23,10 @@ function PlanSelector(props: Props) {
|
||||||
onClose={props.closeModal}
|
onClose={props.closeModal}
|
||||||
PaperProps={{ sx: { width: '400px' } }}>
|
PaperProps={{ sx: { width: '400px' } }}>
|
||||||
<Box p={1}>
|
<Box p={1}>
|
||||||
<Stack spacing={3} p={1.5}>
|
<PlanSelectorCard
|
||||||
<Typography variant="h3" fontWeight={'bold'}>
|
|
||||||
{
|
|
||||||
/* hasPaidSubscription(subscription)
|
|
||||||
? constants.MANAGE_PLAN
|
|
||||||
: */ constants.CHOOSE_PLAN
|
|
||||||
}
|
|
||||||
</Typography>
|
|
||||||
<Box>
|
|
||||||
<PeriodToggler
|
|
||||||
planPeriod={planPeriod}
|
|
||||||
togglePeriod={togglePeriod}
|
|
||||||
/>
|
|
||||||
<Typography mt={0.5} color="text.secondary">
|
|
||||||
{constants.TWO_MONTHS_FREE}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<Plans
|
|
||||||
plans={plans}
|
|
||||||
planPeriod={planPeriod}
|
|
||||||
onPlanSelect={onPlanSelect}
|
|
||||||
subscription={subscription}
|
|
||||||
/>
|
|
||||||
{/* <ManageSubscription
|
|
||||||
subscription={subscription}
|
|
||||||
closeModal={props.closeModal}
|
closeModal={props.closeModal}
|
||||||
setLoading={props.setLoading}
|
setLoading={props.setLoading}
|
||||||
/> */}
|
/>
|
||||||
</Stack>
|
|
||||||
</Box>
|
</Box>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { styled, ToggleButton, ToggleButtonGroup } from '@mui/material';
|
import { styled, ToggleButton, ToggleButtonGroup } from '@mui/material';
|
||||||
|
import { PLAN_PERIOD } from 'constants/gallery';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import constants from 'utils/strings/constants';
|
import constants from 'utils/strings/constants';
|
||||||
import { PLAN_PERIOD } from '.';
|
|
||||||
export function PeriodToggler({ planPeriod, togglePeriod }) {
|
export function PeriodToggler({ planPeriod, togglePeriod }) {
|
||||||
const CustomToggleButton = styled(ToggleButton)(({ theme }) => ({
|
const CustomToggleButton = styled(ToggleButton)(({ theme }) => ({
|
||||||
textTransform: 'none',
|
textTransform: 'none',
|
||||||
|
|
|
@ -2,6 +2,7 @@ import ArrowForward from '@mui/icons-material/ArrowForward';
|
||||||
import { Box, Typography } from '@mui/material';
|
import { Box, Typography } from '@mui/material';
|
||||||
import { FlexWrapper, SpaceBetweenFlex } from 'components/Container';
|
import { FlexWrapper, SpaceBetweenFlex } from 'components/Container';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { isUserSubscribedPlan } from 'utils/billing';
|
||||||
import constants from 'utils/strings/constants';
|
import constants from 'utils/strings/constants';
|
||||||
import { PlanRow } from './planRow';
|
import { PlanRow } from './planRow';
|
||||||
|
|
||||||
|
@ -11,6 +12,7 @@ const Plans = ({ plans, planPeriod, subscription, onPlanSelect }) => (
|
||||||
?.filter((plan) => plan.period === planPeriod)
|
?.filter((plan) => plan.period === planPeriod)
|
||||||
?.map((plan) => (
|
?.map((plan) => (
|
||||||
<PlanRow
|
<PlanRow
|
||||||
|
disabled={isUserSubscribedPlan(plan, subscription)}
|
||||||
key={plan.stripeID}
|
key={plan.stripeID}
|
||||||
plan={plan}
|
plan={plan}
|
||||||
subscription={subscription}
|
subscription={subscription}
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
import { PlanIconButton } from './button';
|
|
||||||
import { Typography } from '@mui/material';
|
|
||||||
import React from 'react';
|
|
||||||
import { isUserSubscribedPlan, convertBytesToGBs } from 'utils/billing';
|
|
||||||
import constants from 'utils/strings/constants';
|
|
||||||
import { PLAN_PERIOD } from '..';
|
|
||||||
import PlanTile from './planTile';
|
|
||||||
|
|
||||||
export function PlanCard({ plan, subscription, onPlanSelect }) {
|
|
||||||
const handleClick = () => {
|
|
||||||
!isUserSubscribedPlan(plan, subscription) && onPlanSelect(plan);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PlanTile
|
|
||||||
key={plan.stripeID}
|
|
||||||
current={isUserSubscribedPlan(plan, subscription)}
|
|
||||||
onClick={handleClick}>
|
|
||||||
<Typography variant="title" fontWeight={'bold'}>
|
|
||||||
{convertBytesToGBs(plan.storage, 0)}
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<Typography
|
|
||||||
color="text.secondary"
|
|
||||||
variant="title"
|
|
||||||
fontWeight={'normal'}>
|
|
||||||
{`${plan.price} / ${
|
|
||||||
plan.period === PLAN_PERIOD.MONTH
|
|
||||||
? constants.MONTH_SHORT
|
|
||||||
: constants.YEAR_SHORT
|
|
||||||
}`}
|
|
||||||
</Typography>
|
|
||||||
|
|
||||||
<PlanIconButton
|
|
||||||
current={isUserSubscribedPlan(plan, subscription)}
|
|
||||||
onClick={handleClick}
|
|
||||||
/>
|
|
||||||
</PlanTile>
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,39 +1,62 @@
|
||||||
import { Box, Button, Typography } from '@mui/material';
|
import { Box, Button, ButtonProps, styled, Typography } from '@mui/material';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { isUserSubscribedPlan, convertBytesToGBs } from 'utils/billing';
|
import { isUserSubscribedPlan, convertBytesToGBs } from 'utils/billing';
|
||||||
import constants from 'utils/strings/constants';
|
import constants from 'utils/strings/constants';
|
||||||
import { PLAN_PERIOD } from '..';
|
|
||||||
import { FlexWrapper, FluidContainer } from 'components/Container';
|
import { FlexWrapper, FluidContainer } from 'components/Container';
|
||||||
import ArrowForward from '@mui/icons-material/ArrowForward';
|
import ArrowForward from '@mui/icons-material/ArrowForward';
|
||||||
|
import { PLAN_PERIOD } from 'constants/gallery';
|
||||||
|
import Done from '@mui/icons-material/Done';
|
||||||
|
import { Plan, Subscription } from 'types/billing';
|
||||||
|
|
||||||
export function PlanRow({ plan, subscription, onPlanSelect }) {
|
interface Iprops {
|
||||||
|
plan: Plan;
|
||||||
|
subscription: Subscription;
|
||||||
|
onPlanSelect: (plan: Plan) => void;
|
||||||
|
disabled: boolean;
|
||||||
|
}
|
||||||
|
const DisabledPlanButton = styled((props: ButtonProps) => (
|
||||||
|
<Button disabled endIcon={<Done />} {...props} />
|
||||||
|
))(({ theme }) => ({
|
||||||
|
'&&': {
|
||||||
|
cursor: 'default',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
color: theme.palette.text.primary,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const ActivePlanButton = (props: ButtonProps) => (
|
||||||
|
<Button color="accent" {...props} endIcon={<ArrowForward />} />
|
||||||
|
);
|
||||||
|
|
||||||
|
export function PlanRow({
|
||||||
|
plan,
|
||||||
|
subscription,
|
||||||
|
onPlanSelect,
|
||||||
|
disabled,
|
||||||
|
}: Iprops) {
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
!isUserSubscribedPlan(plan, subscription) && onPlanSelect(plan);
|
!isUserSubscribedPlan(plan, subscription) && onPlanSelect(plan);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PlanButton = disabled ? DisabledPlanButton : ActivePlanButton;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlexWrapper
|
<FlexWrapper
|
||||||
sx={{
|
sx={{
|
||||||
background:
|
background:
|
||||||
'linear-gradient(268.22deg, rgba(256, 256, 256, 0.08) -3.72%, rgba(256, 256, 256, 0) 85.73%)',
|
'linear-gradient(268.22deg, rgba(256, 256, 256, 0.08) -3.72%, rgba(256, 256, 256, 0) 85.73%)',
|
||||||
}}
|
}}
|
||||||
// current={isUserSubscribedPlan(plan, subscription)}
|
|
||||||
onClick={handleClick}>
|
onClick={handleClick}>
|
||||||
<FluidContainer sx={{ '&&': { alignItems: 'flex-start' } }}>
|
<FluidContainer sx={{ '&&': { alignItems: 'flex-start' } }}>
|
||||||
<Typography variant="h1" fontWeight={'bold'}>
|
<Typography variant="h1" fontWeight={'bold'}>
|
||||||
{convertBytesToGBs(plan.storage, 0)}
|
{convertBytesToGBs(plan.storage)}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="h3" color="text.secondary">
|
<Typography variant="h3" color="text.secondary">
|
||||||
{constants.GB}
|
{constants.GB}
|
||||||
</Typography>
|
</Typography>
|
||||||
</FluidContainer>
|
</FluidContainer>
|
||||||
{/* <PlanIconButton
|
<Box width="136px">
|
||||||
current={isUserSubscribedPlan(plan, subscription)} */}
|
<PlanButton size="large" onClick={handleClick}>
|
||||||
<Button
|
|
||||||
onClick={handleClick}
|
|
||||||
sx={{ width: '136px' }}
|
|
||||||
color="accent"
|
|
||||||
endIcon={<ArrowForward />}>
|
|
||||||
<Box>
|
<Box>
|
||||||
<Typography fontWeight={'bold'} variant="h4">
|
<Typography fontWeight={'bold'} variant="h4">
|
||||||
{plan.price}{' '}
|
{plan.price}{' '}
|
||||||
|
@ -45,7 +68,8 @@ export function PlanRow({ plan, subscription, onPlanSelect }) {
|
||||||
: constants.YEAR_SHORT}
|
: constants.YEAR_SHORT}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Button>
|
</PlanButton>
|
||||||
|
</Box>
|
||||||
</FlexWrapper>
|
</FlexWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,3 +6,8 @@ export const IMAGE_CONTAINER_MAX_WIDTH =
|
||||||
IMAGE_CONTAINER_MAX_HEIGHT - GAP_BTW_TILES;
|
IMAGE_CONTAINER_MAX_HEIGHT - GAP_BTW_TILES;
|
||||||
export const MIN_COLUMNS = 4;
|
export const MIN_COLUMNS = 4;
|
||||||
export const SPACE_BTW_DATES = 44;
|
export const SPACE_BTW_DATES = 44;
|
||||||
|
|
||||||
|
export enum PLAN_PERIOD {
|
||||||
|
MONTH = 'month',
|
||||||
|
YEAR = 'year',
|
||||||
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ export function convertBytesToHumanReadable(
|
||||||
|
|
||||||
export function makeHumanReadableStorage(
|
export function makeHumanReadableStorage(
|
||||||
bytes: number,
|
bytes: number,
|
||||||
|
|
||||||
round: 'round-up' | 'round-down' = 'round-down'
|
round: 'round-up' | 'round-down' = 'round-down'
|
||||||
): string {
|
): string {
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
||||||
|
@ -139,6 +138,13 @@ export function getFamilyPlanAdmin(familyData: FamilyData): FamilyMember {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getTotalFamilyUsage(familyData: FamilyData): number {
|
||||||
|
return familyData.members.reduce(
|
||||||
|
(sum, currentMember) => sum + currentMember.usage,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function getLocalUserSubscription(): Subscription {
|
export function getLocalUserSubscription(): Subscription {
|
||||||
return getData(LS_KEYS.SUBSCRIPTION);
|
return getData(LS_KEYS.SUBSCRIPTION);
|
||||||
}
|
}
|
||||||
|
|
|
@ -754,6 +754,7 @@ const englishConstants = {
|
||||||
GB: 'GB',
|
GB: 'GB',
|
||||||
FREE_PLAN_OPTION_LABEL: 'Continue with free trial',
|
FREE_PLAN_OPTION_LABEL: 'Continue with free trial',
|
||||||
FREE_PLAN_DESCRIPTION: '1 GB for 1 year',
|
FREE_PLAN_DESCRIPTION: '1 GB for 1 year',
|
||||||
|
CURRENT_USAGE: (usage) => `Current usage is ${usage}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default englishConstants;
|
export default englishConstants;
|
||||||
|
|
|
@ -24,5 +24,5 @@ export function getUserAnonymizedID() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLocalUserDetails(): UserDetails {
|
export function getLocalUserDetails(): UserDetails {
|
||||||
return getData(LS_KEYS.USER_DETAILS);
|
return getData(LS_KEYS.USER_DETAILS)?.value;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue