This commit is contained in:
Manav Rathi
2024-11-09 15:35:13 +05:30
parent cebb213eaa
commit 0fe9f4db4b

View File

@@ -59,7 +59,6 @@ import Typography from "@mui/material/Typography";
import { t } from "i18next";
import React, { useCallback, useContext, useEffect, useState } from "react";
import { Trans } from "react-i18next";
import { SetLoading } from "types/gallery";
type PlanSelectorProps = ModalVisibilityProps & {
setLoading: (loading: boolean) => void;
@@ -209,22 +208,22 @@ const PlanSelectorCard: React.FC<PlanSelectorCardProps> = ({
};
const commonCardData = {
onClose,
setLoading,
subscription,
addOnBonuses,
closeModal: onClose,
planPeriod,
togglePeriod,
setLoading,
};
const plansList = (
<Plans
onClose={onClose}
plansData={plansData}
planPeriod={planPeriod}
onPlanSelect={handlePlanSelect}
subscription={subscription}
hasAddOnBonus={addOnBonuses.length > 0}
closeModal={onClose}
/>
);
@@ -283,136 +282,156 @@ const planSelectionOutcome = (subscription: Subscription | undefined) => {
return "contactSupport";
};
function FreeSubscriptionPlanSelectorCard({
children,
type FreeSubscriptionPlanSelectorCardProps = Pick<
PlanSelectorProps,
"onClose" | "setLoading"
> & {
subscription: Subscription;
addOnBonuses: Bonus[];
planPeriod: PlanPeriod;
togglePeriod: () => void;
};
const FreeSubscriptionPlanSelectorCard: React.FC<
React.PropsWithChildren<FreeSubscriptionPlanSelectorCardProps>
> = ({
onClose,
setLoading,
subscription,
addOnBonuses,
closeModal,
setLoading,
planPeriod,
togglePeriod,
}) {
return (
<>
<Typography variant="h3" fontWeight={"bold"}>
{t("choose_plan")}
</Typography>
<Box>
<Stack spacing={3}>
<Box>
<PeriodToggler
planPeriod={planPeriod}
togglePeriod={togglePeriod}
/>
<Typography variant="small" mt={0.5} color="text.muted">
{t("two_months_free")}
</Typography>
</Box>
{children}
{subscription && addOnBonuses.length > 0 && (
<>
<AddOnBonusRows addOnBonuses={addOnBonuses} />
<ManageSubscription
subscription={subscription}
hasAddOnBonus={true}
closeModal={closeModal}
setLoading={setLoading}
/>
</>
)}
</Stack>
</Box>
</>
);
}
function PaidSubscriptionPlanSelectorCard({
children,
subscription,
addOnBonuses,
closeModal,
usage,
planPeriod,
togglePeriod,
setLoading,
}) {
return (
<>
<Box pl={1.5} py={0.5}>
<SpaceBetweenFlex>
<Box>
<Typography variant="h3" fontWeight={"bold"}>
{t("subscription")}
</Typography>
<Typography variant="small" color={"text.muted"}>
{bytesInGB(subscription.storage, 2)}{" "}
{t("storage_unit.gb")}
</Typography>
</Box>
<IconButton onClick={closeModal} color="secondary">
<Close />
</IconButton>
</SpaceBetweenFlex>
</Box>
<Box px={1.5}>
<Typography color={"text.muted"} fontWeight={"bold"}>
<Trans
i18nKey="current_usage"
values={{
usage: `${bytesInGB(usage, 2)} ${t("storage_unit.gb")}`,
}}
}) => (
<>
<Typography variant="h3" fontWeight={"bold"}>
{t("choose_plan")}
</Typography>
<Box>
<Stack spacing={3}>
<Box>
<PeriodToggler
planPeriod={planPeriod}
togglePeriod={togglePeriod}
/>
</Typography>
</Box>
<Box>
<Stack
spacing={3}
border={(theme) => `1px solid ${theme.palette.divider}`}
p={1.5}
borderRadius={(theme) => `${theme.shape.borderRadius}px`}
>
<Box>
<PeriodToggler
planPeriod={planPeriod}
togglePeriod={togglePeriod}
/>
<Typography variant="small" mt={0.5} color="text.muted">
{t("two_months_free")}
</Typography>
</Box>
{children}
</Stack>
<Box py={1} px={1.5}>
<Typography color={"text.muted"}>
{!isSubscriptionCancelled(subscription)
? t("subscription_status_renewal_active", {
date: subscription.expiryTime,
})
: t("subscription_status_renewal_cancelled", {
date: subscription.expiryTime,
})}
<Typography variant="small" mt={0.5} color="text.muted">
{t("two_months_free")}
</Typography>
{addOnBonuses.length > 0 && (
<AddOnBonusRows addOnBonuses={addOnBonuses} />
)}
</Box>
</Box>
{children}
{subscription && addOnBonuses.length > 0 && (
<>
<AddOnBonusRows addOnBonuses={addOnBonuses} />
<ManageSubscription
{...{ onClose, setLoading, subscription }}
hasAddOnBonus={true}
/>
</>
)}
</Stack>
</Box>
</>
);
<ManageSubscription
subscription={subscription}
hasAddOnBonus={addOnBonuses.length > 0}
closeModal={closeModal}
setLoading={setLoading}
/>
</>
);
type PaidSubscriptionPlanSelectorCardProps =
FreeSubscriptionPlanSelectorCardProps & {
usage: number;
};
const PaidSubscriptionPlanSelectorCard: React.FC<
React.PropsWithChildren<PaidSubscriptionPlanSelectorCardProps>
> = ({
onClose,
setLoading,
subscription,
addOnBonuses,
planPeriod,
togglePeriod,
usage,
children,
}) => (
<>
<Box pl={1.5} py={0.5}>
<SpaceBetweenFlex>
<Box>
<Typography variant="h3" fontWeight={"bold"}>
{t("subscription")}
</Typography>
<Typography variant="small" color={"text.muted"}>
{bytesInGB(subscription.storage, 2)}{" "}
{t("storage_unit.gb")}
</Typography>
</Box>
<IconButton onClick={onClose} color="secondary">
<Close />
</IconButton>
</SpaceBetweenFlex>
</Box>
<Box px={1.5}>
<Typography color={"text.muted"} fontWeight={"bold"}>
<Trans
i18nKey="current_usage"
values={{
usage: `${bytesInGB(usage, 2)} ${t("storage_unit.gb")}`,
}}
/>
</Typography>
</Box>
<Box>
<Stack
spacing={3}
border={(theme) => `1px solid ${theme.palette.divider}`}
p={1.5}
borderRadius={(theme) => `${theme.shape.borderRadius}px`}
>
<Box>
<PeriodToggler
planPeriod={planPeriod}
togglePeriod={togglePeriod}
/>
<Typography variant="small" mt={0.5} color="text.muted">
{t("two_months_free")}
</Typography>
</Box>
{children}
</Stack>
<Box py={1} px={1.5}>
<Typography color={"text.muted"}>
{!isSubscriptionCancelled(subscription)
? t("subscription_status_renewal_active", {
date: subscription.expiryTime,
})
: t("subscription_status_renewal_cancelled", {
date: subscription.expiryTime,
})}
</Typography>
{addOnBonuses.length > 0 && (
<AddOnBonusRows addOnBonuses={addOnBonuses} />
)}
</Box>
</Box>
<ManageSubscription
onClose={onClose}
setLoading={setLoading}
subscription={subscription}
hasAddOnBonus={addOnBonuses.length > 0}
/>
</>
);
interface PeriodTogglerProps {
planPeriod: PlanPeriod;
togglePeriod: () => void;
}
function PeriodToggler({ planPeriod, togglePeriod }) {
const PeriodToggler: React.FC<PeriodTogglerProps> = ({
planPeriod,
togglePeriod,
}) => {
const handleChange = (_, newPlanPeriod: PlanPeriod) => {
if (newPlanPeriod !== planPeriod) togglePeriod();
};
@@ -432,7 +451,7 @@ function PeriodToggler({ planPeriod, togglePeriod }) {
</CustomToggleButton>
</ToggleButtonGroup>
);
}
};
const CustomToggleButton = styled(ToggleButton)(({ theme }) => ({
textTransform: "none",
@@ -453,22 +472,22 @@ const CustomToggleButton = styled(ToggleButton)(({ theme }) => ({
}));
interface PlansProps {
onClose: () => void;
plansData: PlansData | undefined;
planPeriod: PlanPeriod;
subscription: Subscription;
hasAddOnBonus: boolean;
onPlanSelect: (plan: Plan) => void;
closeModal: () => void;
}
const Plans = ({
const Plans: React.FC<PlansProps> = ({
onClose,
plansData,
planPeriod,
subscription,
hasAddOnBonus,
onPlanSelect,
closeModal,
}: PlansProps) => {
}) => {
const { freePlan, plans } = plansData ?? {};
return (
<Stack spacing={2}>
@@ -490,10 +509,7 @@ const Plans = ({
{!(subscription && isSubscriptionActivePaid(subscription)) &&
!hasAddOnBonus &&
freePlan && (
<FreePlanRow
storage={freePlan.storage}
closeModal={closeModal}
/>
<FreePlanRow onClose={onClose} storage={freePlan.storage} />
)}
</Stack>
);
@@ -510,13 +526,13 @@ interface PlanRowProps {
popular: boolean;
}
function PlanRow({
const PlanRow: React.FC<PlanRowProps> = ({
plan,
subscription,
onPlanSelect,
disabled,
popular,
}: PlanRowProps) {
}) => {
const handleClick = () => !disabled && onPlanSelect(plan);
const PlanButton = disabled ? DisabledPlanButton : ActivePlanButton;
@@ -564,7 +580,7 @@ function PlanRow({
</Box>
</PlanRowContainer>
);
}
};
const PlanRowContainer = styled(FlexWrapper)(() => ({
background:
@@ -606,27 +622,25 @@ const Badge = styled(Box)(({ theme }) => ({
}));
interface FreePlanRowProps {
onClose: () => void;
storage: number;
closeModal: () => void;
}
const FreePlanRow: React.FC<FreePlanRowProps> = ({ closeModal, storage }) => {
return (
<FreePlanRow_ onClick={closeModal}>
<Box>
<Typography>{t("free_plan_option")}</Typography>
<Typography variant="small" color="text.muted">
{t("free_plan_description", {
storage: formattedStorageByteSize(storage),
})}
</Typography>
</Box>
<IconButton className={"endIcon"}>
<ArrowForward />
</IconButton>
</FreePlanRow_>
);
};
const FreePlanRow: React.FC<FreePlanRowProps> = ({ onClose, storage }) => (
<FreePlanRow_ onClick={onClose}>
<Box>
<Typography>{t("free_plan_option")}</Typography>
<Typography variant="small" color="text.muted">
{t("free_plan_description", {
storage: formattedStorageByteSize(storage),
})}
</Typography>
</Box>
<IconButton className={"endIcon"}>
<ArrowForward />
</IconButton>
</FreePlanRow_>
);
const FreePlanRow_ = styled(SpaceBetweenFlex)(({ theme }) => ({
gap: theme.spacing(1.5),
@@ -657,18 +671,19 @@ const AddOnBonusRows: React.FC<AddOnBonusRowsProps> = ({ addOnBonuses }) => (
</>
);
interface ManageSubscriptionProps {
type ManageSubscriptionProps = Pick<
PlanSelectorProps,
"onClose" | "setLoading"
> & {
subscription: Subscription;
hasAddOnBonus: boolean;
closeModal: () => void;
setLoading: SetLoading;
}
};
function ManageSubscription({
onClose,
setLoading,
subscription,
hasAddOnBonus,
closeModal,
setLoading,
}: ManageSubscriptionProps) {
const { onGenericError } = useAppContext();
@@ -686,9 +701,7 @@ function ManageSubscription({
<Stack spacing={1}>
{isSubscriptionStripe(subscription) && (
<StripeSubscriptionOptions
onClose={closeModal}
subscription={subscription}
hasAddOnBonus={hasAddOnBonus}
{...{ onClose, subscription, hasAddOnBonus }}
/>
)}
<ManageSubscriptionButton
@@ -701,11 +714,10 @@ function ManageSubscription({
);
}
interface StripeSubscriptionOptionsProps {
onClose: () => void;
type StripeSubscriptionOptionsProps = Pick<PlanSelectorProps, "onClose"> & {
subscription: Subscription;
hasAddOnBonus: boolean;
}
};
const StripeSubscriptionOptions: React.FC<StripeSubscriptionOptionsProps> = ({
onClose,
@@ -797,7 +809,10 @@ const StripeSubscriptionOptions: React.FC<StripeSubscriptionOptionsProps> = ({
);
};
const ManageSubscriptionButton = ({ children, ...props }: ButtonProps) => (
const ManageSubscriptionButton: React.FC<ButtonProps> = ({
children,
...props
}) => (
<Button size="large" endIcon={<ChevronRight />} {...props}>
<FluidContainer>{children}</FluidContainer>
</Button>