Upgrade dialog looks nice now

This commit is contained in:
binwiederhier 2023-01-17 19:40:03 -05:00
parent 695c1349e8
commit 4092f7fd51
9 changed files with 160 additions and 85 deletions

View file

@ -199,6 +199,13 @@ export const formatBytes = (bytes, decimals = 2) => {
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
export const formatNumber = (n) => {
if (n % 1000 === 0) {
return `${n/1000}k`;
}
return n;
}
export const openUrl = (url) => {
window.open(url, "_blank", "noopener,noreferrer");
};

View file

@ -2,7 +2,7 @@ import * as React from 'react';
import Dialog from '@mui/material/Dialog';
import DialogContent from '@mui/material/DialogContent';
import DialogTitle from '@mui/material/DialogTitle';
import {Alert, CardActionArea, CardContent, useMediaQuery} from "@mui/material";
import {Alert, CardActionArea, CardContent, ListItem, useMediaQuery} from "@mui/material";
import theme from "./theme";
import DialogFooter from "./DialogFooter";
import Button from "@mui/material/Button";
@ -13,16 +13,20 @@ import {useContext, useEffect, useState} from "react";
import Card from "@mui/material/Card";
import Typography from "@mui/material/Typography";
import {AccountContext} from "./App";
import {formatShortDate} from "../app/utils";
import {useTranslation} from "react-i18next";
import {formatBytes, formatNumber, formatShortDate} from "../app/utils";
import {Trans, useTranslation} from "react-i18next";
import subscriptionManager from "../app/SubscriptionManager";
import List from "@mui/material/List";
import {Check} from "@mui/icons-material";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
const UpgradeDialog = (props) => {
const { t } = useTranslation();
const { account } = useContext(AccountContext);
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
const [tiers, setTiers] = useState(null);
const [newTier, setNewTier] = useState(account?.tier?.code || null);
const [newTier, setNewTier] = useState(account?.tier?.code); // May be undefined
const [errorText, setErrorText] = useState("");
useEffect(() => {
@ -35,22 +39,22 @@ const UpgradeDialog = (props) => {
return <></>;
}
const currentTier = account.tier?.code || null;
const currentTier = account.tier?.code; // May be undefined
let action, submitButtonLabel, submitButtonEnabled;
if (currentTier === newTier) {
submitButtonLabel = "Update subscription";
submitButtonLabel = t("account_upgrade_dialog_button_update_subscription");
submitButtonEnabled = false;
action = null;
} else if (currentTier === null) {
submitButtonLabel = "Pay $5 now and subscribe";
} else if (!currentTier) {
submitButtonLabel = t("account_upgrade_dialog_button_pay_now");
submitButtonEnabled = true;
action = Action.CREATE;
} else if (newTier === null) {
submitButtonLabel = "Cancel subscription";
} else if (!newTier) {
submitButtonLabel = t("account_upgrade_dialog_button_cancel_subscription");
submitButtonEnabled = true;
action = Action.CANCEL;
} else {
submitButtonLabel = "Update subscription";
submitButtonLabel = t("account_upgrade_dialog_button_update_subscription");
submitButtonEnabled = true;
action = Action.UPDATE;
}
@ -76,7 +80,13 @@ const UpgradeDialog = (props) => {
}
return (
<Dialog open={props.open} onClose={props.onCancel} maxWidth="md" fullScreen={fullScreen}>
<Dialog
open={props.open}
onClose={props.onCancel}
maxWidth="md"
fullWidth
fullScreen={fullScreen}
>
<DialogTitle>{t("account_upgrade_dialog_title")}</DialogTitle>
<DialogContent>
<div style={{
@ -85,33 +95,25 @@ const UpgradeDialog = (props) => {
marginBottom: "8px",
width: "100%"
}}>
<TierCard
code={null}
name={t("account_usage_tier_free")}
price={null}
selected={newTier === null}
onClick={() => setNewTier(null)}
/>
{tiers.map(tier =>
<TierCard
key={`tierCard${tier.code}`}
code={tier.code}
name={tier.name}
price={tier.price}
features={tier.features}
selected={newTier === tier.code}
onClick={() => setNewTier(tier.code)}
key={`tierCard${tier.code || '_free'}`}
tier={tier}
selected={newTier === tier.code} // tier.code may be undefined!
onClick={() => setNewTier(tier.code)} // tier.code may be undefined!
/>
)}
</div>
{action === Action.CANCEL &&
<Alert severity="warning">
{t("account_upgrade_dialog_cancel_warning", { date: formatShortDate(account.billing.paid_until) })}
<Trans
i18nKey="account_upgrade_dialog_cancel_warning"
values={{ date: formatShortDate(account.billing.paid_until) }} />
</Alert>
}
{action === Action.UPDATE &&
{currentTier && (!action || action === Action.UPDATE) &&
<Alert severity="info">
{t("account_upgrade_dialog_proration_info")}
<Trans i18nKey="account_upgrade_dialog_proration_info" />
</Alert>
}
</DialogContent>
@ -124,12 +126,18 @@ const UpgradeDialog = (props) => {
};
const TierCard = (props) => {
const cardStyle = (props.selected) ? { background: "#eee", border: "2px solid #338574" } : {};
const { t } = useTranslation();
const cardStyle = (props.selected) ? { background: "#eee", border: "2px solid #338574" } : { border: "2px solid transparent" };
const tier = props.tier;
return (
<Card sx={{
m: 1,
minWidth: "190px",
maxWidth: "250px",
flexGrow: 1,
flexShrink: 1,
flexBasis: 0,
"&:first-child": { ml: 0 },
"&:last-child": { mr: 0 },
...cardStyle
@ -145,19 +153,21 @@ const TierCard = (props) => {
background: "#338574",
color: "white",
borderRadius: "3px",
}}>Selected</div>
}}>{t("account_upgrade_dialog_tier_selected_label")}</div>
}
<Typography gutterBottom variant="h5" component="div">
{props.name}
<Typography variant="h5" component="div">
{tier.name || t("account_usage_tier_free")}
</Typography>
{props.features &&
<Typography variant="body2" color="text.secondary" sx={{whiteSpace: "pre-wrap"}}>
{props.features}
</Typography>
}
{props.price &&
<Typography variant="subtitle1" sx={{mt: 1}}>
{props.price} / month
<List dense>
{tier.limits.reservations > 0 && <FeatureItem>{t("account_upgrade_dialog_tier_features_reservations", { reservations: tier.limits.reservations })}</FeatureItem>}
<FeatureItem>{t("account_upgrade_dialog_tier_features_messages", { messages: formatNumber(tier.limits.messages) })}</FeatureItem>
<FeatureItem>{t("account_upgrade_dialog_tier_features_emails", { emails: formatNumber(tier.limits.emails) })}</FeatureItem>
<FeatureItem>{t("account_upgrade_dialog_tier_features_attachment_file_size", { filesize: formatBytes(tier.limits.attachment_file_size, 0) })}</FeatureItem>
<FeatureItem>{t("account_upgrade_dialog_tier_features_attachment_total_size", { totalsize: formatBytes(tier.limits.attachment_total_size, 0) })}</FeatureItem>
</List>
{tier.price &&
<Typography variant="subtitle1" sx={{fontWeight: 500}}>
{tier.price} / month
</Typography>
}
</CardContent>
@ -166,6 +176,25 @@ const TierCard = (props) => {
);
}
const FeatureItem = (props) => {
return (
<ListItem disableGutters sx={{m: 0, p: 0}}>
<ListItemIcon sx={{minWidth: "24px"}}>
<Check fontSize="small" sx={{ color: "#338574" }}/>
</ListItemIcon>
<ListItemText
sx={{mt: "2px", mb: "2px"}}
primary={
<Typography variant="body2">
{props.children}
</Typography>
}
/>
</ListItem>
);
};
const Action = {
CREATE: 1,
UPDATE: 2,