A little polishing, make upgrade banner work when not logged in

This commit is contained in:
binwiederhier 2023-01-18 13:46:40 -05:00
parent 7cff44b647
commit f945fb4cdd
15 changed files with 98 additions and 121 deletions

View file

@ -211,6 +211,7 @@
"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_redirect_signup": "Sign up now",
"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",

View file

@ -8,7 +8,7 @@ import {
accountTokenUrl,
accountUrl, maybeWithAuth, topicUrl,
withBasicAuth,
withBearerAuth, accountBillingSubscriptionUrl, accountBillingPortalUrl, accountBillingTiersUrl
withBearerAuth, accountBillingSubscriptionUrl, accountBillingPortalUrl, tiersUrl
} from "./utils";
import session from "./Session";
import subscriptionManager from "./SubscriptionManager";
@ -170,7 +170,6 @@ class AccountApi {
} else if (response.status !== 200) {
throw new Error(`Unexpected server response ${response.status}`);
}
this.triggerChange(); // Dangle!
}
async addSubscription(payload) {
@ -189,7 +188,6 @@ class AccountApi {
}
const subscription = await response.json();
console.log(`[AccountApi] Subscription`, subscription);
this.triggerChange(); // Dangle!
return subscription;
}
@ -209,7 +207,6 @@ class AccountApi {
}
const subscription = await response.json();
console.log(`[AccountApi] Subscription`, subscription);
this.triggerChange(); // Dangle!
return subscription;
}
@ -225,7 +222,6 @@ class AccountApi {
} else if (response.status !== 200) {
throw new Error(`Unexpected server response ${response.status}`);
}
this.triggerChange(); // Dangle!
}
async upsertReservation(topic, everyone) {
@ -246,7 +242,6 @@ class AccountApi {
} else if (response.status !== 200) {
throw new Error(`Unexpected server response ${response.status}`);
}
this.triggerChange(); // Dangle!
}
async deleteReservation(topic) {
@ -261,18 +256,13 @@ class AccountApi {
} else if (response.status !== 200) {
throw new Error(`Unexpected server response ${response.status}`);
}
this.triggerChange(); // Dangle!
}
async billingTiers() {
const url = accountBillingTiersUrl(config.base_url);
const url = tiersUrl(config.base_url);
console.log(`[AccountApi] Fetching billing tiers`);
const response = await fetch(url, {
headers: withBearerAuth({}, session.token())
});
if (response.status === 401 || response.status === 403) {
throw new UnauthorizedError();
} else if (response.status !== 200) {
const response = await fetch(url); // No auth needed!
if (response.status !== 200) {
throw new Error(`Unexpected server response ${response.status}`);
}
return await response.json();
@ -367,35 +357,6 @@ class AccountApi {
}
}
async triggerChange() {
return null;
const account = await this.get();
if (!account.sync_topic) {
return;
}
const url = topicUrl(config.base_url, account.sync_topic);
console.log(`[AccountApi] Triggering account change to ${url}`);
const user = await userManager.get(config.base_url);
const headers = {
Cache: "no" // We really don't need to store this!
};
try {
const response = await fetch(url, {
method: 'PUT',
body: JSON.stringify({
event: "sync",
source: this.identity
}),
headers: maybeWithAuth(headers, user)
});
if (response.status < 200 || response.status > 299) {
throw new Error(`Unexpected response: ${response.status}`);
}
} catch (e) {
console.log(`[AccountApi] Publishing to sync topic failed`, e);
}
}
startWorker() {
if (this.timer !== null) {
return;

View file

@ -28,7 +28,7 @@ export const accountReservationUrl = (baseUrl) => `${baseUrl}/v1/account/reserva
export const accountReservationSingleUrl = (baseUrl, topic) => `${baseUrl}/v1/account/reservation/${topic}`;
export const accountBillingSubscriptionUrl = (baseUrl) => `${baseUrl}/v1/account/billing/subscription`;
export const accountBillingPortalUrl = (baseUrl) => `${baseUrl}/v1/account/billing/portal`;
export const accountBillingTiersUrl = (baseUrl) => `${baseUrl}/v1/account/billing/tiers`;
export const tiersUrl = (baseUrl) => `${baseUrl}/v1/tiers`;
export const shortUrl = (url) => url.replaceAll(/https?:\/\//g, "");
export const expandUrl = (url) => [`https://${url}`, `http://${url}`];
export const expandSecureUrl = (url) => `https://${url}`;

View file

@ -24,7 +24,7 @@ import Box from "@mui/material/Box";
const UpgradeDialog = (props) => {
const { t } = useTranslation();
const { account } = useContext(AccountContext);
const { account } = useContext(AccountContext); // May be undefined!
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
const [tiers, setTiers] = useState(null);
const [newTier, setNewTier] = useState(account?.tier?.code); // May be undefined
@ -37,28 +37,32 @@ const UpgradeDialog = (props) => {
})();
}, []);
if (!account || !tiers) {
if (!tiers) {
return <></>;
}
const currentTier = account.tier?.code; // May be undefined
const currentTier = account?.tier?.code; // May be undefined
let action, submitButtonLabel, submitButtonEnabled;
if (currentTier === newTier) {
if (!account) {
submitButtonLabel = t("account_upgrade_dialog_button_redirect_signup");
submitButtonEnabled = true;
action = Action.REDIRECT_SIGNUP;
} else if (currentTier === newTier) {
submitButtonLabel = t("account_upgrade_dialog_button_update_subscription");
submitButtonEnabled = false;
action = null;
} else if (!currentTier) {
submitButtonLabel = t("account_upgrade_dialog_button_pay_now");
submitButtonEnabled = true;
action = Action.CREATE;
action = Action.CREATE_SUBSCRIPTION;
} else if (!newTier) {
submitButtonLabel = t("account_upgrade_dialog_button_cancel_subscription");
submitButtonEnabled = true;
action = Action.CANCEL;
action = Action.CANCEL_SUBSCRIPTION;
} else {
submitButtonLabel = t("account_upgrade_dialog_button_update_subscription");
submitButtonEnabled = true;
action = Action.UPDATE;
action = Action.UPDATE_SUBSCRIPTION;
}
if (loading) {
@ -66,14 +70,18 @@ const UpgradeDialog = (props) => {
}
const handleSubmit = async () => {
if (action === Action.REDIRECT_SIGNUP) {
window.location.href = routes.signup;
return;
}
try {
setLoading(true);
if (action === Action.CREATE) {
if (action === Action.CREATE_SUBSCRIPTION) {
const response = await accountApi.createBillingSubscription(newTier);
window.location.href = response.redirect_url;
} else if (action === Action.UPDATE) {
} else if (action === Action.UPDATE_SUBSCRIPTION) {
await accountApi.updateBillingSubscription(newTier);
} else if (action === Action.CANCEL) {
} else if (action === Action.CANCEL_SUBSCRIPTION) {
await accountApi.deleteBillingSubscription();
}
props.onCancel();
@ -113,14 +121,14 @@ const UpgradeDialog = (props) => {
/>
)}
</div>
{action === Action.CANCEL &&
{action === Action.CANCEL_SUBSCRIPTION &&
<Alert severity="warning">
<Trans
i18nKey="account_upgrade_dialog_cancel_warning"
values={{ date: formatShortDate(account.billing.paid_until) }} />
values={{ date: formatShortDate(account?.billing?.paid_until || 0) }} />
</Alert>
}
{currentTier && (!action || action === Action.UPDATE) &&
{currentTier && (!action || action === Action.UPDATE_SUBSCRIPTION) &&
<Alert severity="info">
<Trans i18nKey="account_upgrade_dialog_proration_info" />
</Alert>
@ -148,8 +156,8 @@ const TierCard = (props) => {
flexShrink: 1,
flexBasis: 0,
borderRadius: "3px",
"&:first-child": { ml: 0 },
"&:last-child": { mr: 0 },
"&:first-of-type": { ml: 0 },
"&:last-of-type": { mr: 0 },
...cardStyle
}}>
<Card sx={{ height: "100%" }}>
@ -209,9 +217,10 @@ const FeatureItem = (props) => {
};
const Action = {
CREATE: 1,
UPDATE: 2,
CANCEL: 3
REDIRECT_SIGNUP: 0,
CREATE_SUBSCRIPTION: 1,
UPDATE_SUBSCRIPTION: 2,
CANCEL_SUBSCRIPTION: 3
};
export default UpgradeDialog;