web: add button to extend trial

This commit is contained in:
Abdullah Atta
2026-07-17 11:55:22 +05:00
parent d521eb3bd8
commit 88ecee9818
4 changed files with 65 additions and 19 deletions

View File

@@ -163,25 +163,56 @@ export const SubscriptionSettings: SettingsGroup[] = [
title: "Cancel",
variant: "error",
async action() {
const cancelTrial = await ConfirmDialog.show({
title: "Cancel trial?",
message:
"Cancel your trial to stop all future charges permanently. You will be immediately downgraded to the Free plan.",
negativeButtonText: "No",
positiveButtonText: "Yes"
});
if (cancelTrial) {
await TaskManager.startTask({
type: "modal",
title: "Cancelling your trial",
subtitle: "Please wait...",
action: () => db.subscriptions.cancel()
})
.catch((e) => showToast("error", e.message))
.then(() =>
showToast("success", "Your trial has been canceled.")
);
const canExtend =
!useUserStore.getState().user?.subscription?.extensionsAvailed
?.length;
if (canExtend) {
const isExtending = await ConfirmDialog.show({
title: "We're sorry to see you go!",
message:
"Before you cancel, did you just need more time to test? We'd love to give you an extra 14 days, completely free.",
negativeButtonText: "No, cancel my trial",
positiveButtonText: "Yes, extend my trial"
});
if (isExtending) {
const error = await TaskManager.startTask({
type: "modal",
title: "Extending your trial",
subtitle: "Please wait...",
action: async () => {
await db.subscriptions.extend();
await useUserStore.getState().refreshUser();
showToast(
"success",
"Your trial has been extended by 14 days. Enjoy!"
);
}
});
if (error instanceof Error) showToast("error", error.message);
return;
}
} else {
const cancelTrial = await ConfirmDialog.show({
title: "Cancel trial?",
message:
"Cancel your trial to stop all future charges permanently. You will be immediately downgraded to the Free plan.",
negativeButtonText: "No",
positiveButtonText: "Yes"
});
if (!cancelTrial) return;
}
await TaskManager.startTask({
type: "modal",
title: "Cancelling your trial",
subtitle: "Please wait...",
action: () => db.subscriptions.cancel()
})
.catch((e) => showToast("error", e.message))
.then(() =>
showToast("success", "Your trial has been canceled.")
);
}
}
]

View File

@@ -102,6 +102,14 @@ export default class Subscriptions {
await http.post(`${hosts.SUBSCRIPTIONS_HOST}/${endpoint}`, null, token);
}
async extend() {
const token = await this.db.tokenManager.getAccessToken();
const user = await this.db.user.getUser();
if (!token || !user || isLegacySubscription(user)) return;
const endpoint = `subscriptions/v2/extend`;
await http.post(`${hosts.SUBSCRIPTIONS_HOST}/${endpoint}`, null, token);
}
async pause() {
const token = await this.db.tokenManager.getAccessToken();
const user = await this.db.user.getUser();

View File

@@ -630,6 +630,12 @@ export enum SubscriptionProvider {
GIFT_CARD = 4
}
type SubscriptionExtension = {
expiry: number;
timestamp: number;
type: "trial_extension";
};
export type User = {
id: string;
email: string;
@@ -661,6 +667,7 @@ export type User = {
plan: SubscriptionPlan;
status: SubscriptionStatus;
trialsAvailed?: SubscriptionPlan[];
extensionsAvailed?: SubscriptionExtension[];
updateURL: string | null;
googlePurchaseToken: string | null;
};

View File

@@ -52,7 +52,7 @@ export const hosts = {
: "http://localhost:6264",
NOTESNOOK_HOST: isProduction()
? "https://notesnook.com"
: "http://localhost:8787"
: "http://localhost:3001"
};
export default hosts;