diff --git a/server/server.go b/server/server.go index 09256cf..1dbb0d0 100644 --- a/server/server.go +++ b/server/server.go @@ -41,8 +41,6 @@ import ( - payment methods - unmarshal to stripe.Subscription instead of gjson - delete subscription when account deleted - - add tier.visible - - fix tier selection boxes - delete messages + reserved topics on ResetTier Limits & rate limiting: diff --git a/web/public/static/langs/en.json b/web/public/static/langs/en.json index 47c3fc3..6b7825c 100644 --- a/web/public/static/langs/en.json +++ b/web/public/static/langs/en.json @@ -210,6 +210,7 @@ "account_upgrade_dialog_tier_features_attachment_file_size": "{{filesize}} per file", "account_upgrade_dialog_tier_features_attachment_total_size": "{{totalsize}} total storage", "account_upgrade_dialog_tier_selected_label": "Selected", + "account_upgrade_dialog_button_cancel": "Cancel", "account_upgrade_dialog_button_pay_now": "Pay now and subscribe", "account_upgrade_dialog_button_cancel_subscription": "Cancel subscription", "account_upgrade_dialog_button_update_subscription": "Update subscription", diff --git a/web/src/components/UpgradeDialog.js b/web/src/components/UpgradeDialog.js index 0c3b8db..724bba8 100644 --- a/web/src/components/UpgradeDialog.js +++ b/web/src/components/UpgradeDialog.js @@ -20,6 +20,7 @@ import List from "@mui/material/List"; import {Check} from "@mui/icons-material"; import ListItemIcon from "@mui/material/ListItemIcon"; import ListItemText from "@mui/material/ListItemText"; +import Box from "@mui/material/Box"; const UpgradeDialog = (props) => { const { t } = useTranslation(); @@ -27,6 +28,7 @@ const UpgradeDialog = (props) => { const fullScreen = useMediaQuery(theme.breakpoints.down('sm')); const [tiers, setTiers] = useState(null); const [newTier, setNewTier] = useState(account?.tier?.code); // May be undefined + const [loading, setLoading] = useState(false); const [errorText, setErrorText] = useState(""); useEffect(() => { @@ -59,8 +61,13 @@ const UpgradeDialog = (props) => { action = Action.UPDATE; } + if (loading) { + submitButtonEnabled = false; + } + const handleSubmit = async () => { try { + setLoading(true); if (action === Action.CREATE) { const response = await accountApi.createBillingSubscription(newTier); window.location.href = response.redirect_url; @@ -76,6 +83,8 @@ const UpgradeDialog = (props) => { session.resetAndRedirect(routes.login); } // FIXME show error + } finally { + setLoading(false); } } @@ -118,7 +127,7 @@ const UpgradeDialog = (props) => { } - + @@ -131,48 +140,52 @@ const TierCard = (props) => { const tier = props.tier; return ( - - - - {props.selected && -
{t("account_upgrade_dialog_tier_selected_label")}
- } - - {tier.name || t("account_usage_tier_free")} - - - {tier.limits.reservations > 0 && {t("account_upgrade_dialog_tier_features_reservations", { reservations: tier.limits.reservations })}} - {t("account_upgrade_dialog_tier_features_messages", { messages: formatNumber(tier.limits.messages) })} - {t("account_upgrade_dialog_tier_features_emails", { emails: formatNumber(tier.limits.emails) })} - {t("account_upgrade_dialog_tier_features_attachment_file_size", { filesize: formatBytes(tier.limits.attachment_file_size, 0) })} - {t("account_upgrade_dialog_tier_features_attachment_total_size", { totalsize: formatBytes(tier.limits.attachment_total_size, 0) })} - - {tier.price && - - {tier.price} / month + + + + {props.selected && +
{t("account_upgrade_dialog_tier_selected_label")}
+ } + + {tier.name || t("account_usage_tier_free")} - } -
-
-
+ + {tier.limits.reservations > 0 && {t("account_upgrade_dialog_tier_features_reservations", { reservations: tier.limits.reservations })}} + {t("account_upgrade_dialog_tier_features_messages", { messages: formatNumber(tier.limits.messages) })} + {t("account_upgrade_dialog_tier_features_emails", { emails: formatNumber(tier.limits.emails) })} + {t("account_upgrade_dialog_tier_features_attachment_file_size", { filesize: formatBytes(tier.limits.attachment_file_size, 0) })} + {t("account_upgrade_dialog_tier_features_attachment_total_size", { totalsize: formatBytes(tier.limits.attachment_total_size, 0) })} + + {tier.price && + + {tier.price} / month + + } +
+
+
+ + ); }