mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-25 07:59:48 +01:00
web: replace usage of subscription.type to subscription.plan
This commit is contained in:
@@ -426,7 +426,7 @@ export async function logout() {
|
||||
const result = await showLogoutConfirmation();
|
||||
if (!result) return;
|
||||
|
||||
if (result.backup) {
|
||||
if (result.checks?.backup) {
|
||||
try {
|
||||
await createBackup({ mode: "partial" });
|
||||
} catch (e) {
|
||||
|
||||
@@ -129,7 +129,7 @@ async function pickFile(
|
||||
options?: AddAttachmentOptions
|
||||
): Promise<Attachment | undefined> {
|
||||
try {
|
||||
if (!(await checkFeature("fileSize", file.size))) return;
|
||||
if (!(await checkFeature("fileSize", { value: file.size }))) return;
|
||||
|
||||
const hash = await addAttachment(file, options);
|
||||
return {
|
||||
@@ -154,7 +154,7 @@ async function pickImage(
|
||||
options?: AddAttachmentOptions
|
||||
): Promise<Attachment | undefined> {
|
||||
try {
|
||||
if (!(await checkFeature("fileSize", file.size))) return;
|
||||
if (!(await checkFeature("fileSize", { value: file.size }))) return;
|
||||
|
||||
const hash = await addAttachment(file, options);
|
||||
const dimensions = await getImageDimensions(file);
|
||||
|
||||
@@ -241,7 +241,7 @@ function NavigationMenu({ onExpand }: { onExpand?: () => void }) {
|
||||
}, [isNavPaneCollapsed]);
|
||||
|
||||
useEffect(() => {
|
||||
function onNavigate(_, location: string) {
|
||||
function onNavigate() {
|
||||
// collapse navigation menu on navigate e.g. when navigating to a notebook
|
||||
// or a tag
|
||||
if (!useAppStore.getState().isNavPaneCollapsed) return;
|
||||
|
||||
@@ -23,11 +23,10 @@ import { Loading, Coupon } from "../../components/icons";
|
||||
import { useStore as useUserStore } from "../../stores/user-store";
|
||||
import { useStore as useThemeStore } from "../../stores/theme-store";
|
||||
import Rocket from "../../assets/rocket.svg?url";
|
||||
import { hardNavigate } from "../../navigation";
|
||||
import { Features } from "./features";
|
||||
import { PaddleCheckout } from "./paddle";
|
||||
import { Plan, PricingInfo } from "./types";
|
||||
import { getPlans, PERIOD_METADATA, PLAN_METADATA, usePlans } from "./plans";
|
||||
import { getPlans, PERIOD_METADATA, PLAN_METADATA } from "./plans";
|
||||
import {
|
||||
ComparePlans,
|
||||
Footer,
|
||||
@@ -38,7 +37,6 @@ import {
|
||||
import { useCheckoutStore } from "./store";
|
||||
import { getCurrencySymbol, toPricingInfo } from "./helpers";
|
||||
import { isUserSubscribed } from "../../hooks/use-is-user-premium";
|
||||
import { SUBSCRIPTION_STATUS } from "../../common/constants";
|
||||
import BaseDialog from "../../components/dialog";
|
||||
import { ScopedThemeProvider } from "../../components/theme-provider";
|
||||
import { Period, SubscriptionPlan, User } from "@notesnook/core";
|
||||
@@ -186,14 +184,7 @@ export function CheckoutSideBar(props: SideBarProps) {
|
||||
);
|
||||
|
||||
if (user && isUserSubscribed(user)) {
|
||||
return (
|
||||
<AlreadyPremium
|
||||
isCanceled={
|
||||
user?.subscription?.type === SUBSCRIPTION_STATUS.PREMIUM_CANCELED
|
||||
}
|
||||
onShowPlans={onShowPlans}
|
||||
/>
|
||||
);
|
||||
return <AlreadyPremium />;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -232,39 +223,17 @@ export function CheckoutDetails({
|
||||
return <Features />;
|
||||
}
|
||||
|
||||
type AlreadyPremiumProps = {
|
||||
isCanceled?: boolean;
|
||||
onShowPlans: () => void;
|
||||
};
|
||||
function AlreadyPremium(props: AlreadyPremiumProps) {
|
||||
const { isCanceled, onShowPlans } = props;
|
||||
function AlreadyPremium() {
|
||||
return (
|
||||
<>
|
||||
<Image src={Rocket} style={{ flexShrink: 0, width: 200, height: 200 }} />
|
||||
<Text variant="heading" mt={4} sx={{ textAlign: "center" }}>
|
||||
Notesnook Pro
|
||||
Notesnook
|
||||
</Text>
|
||||
<Text variant="body" mt={1} sx={{ textAlign: "center" }}>
|
||||
You already have a Notesnook subscription. You can change your plan from
|
||||
Settings {">"} Subscription.
|
||||
</Text>
|
||||
{isCanceled ? (
|
||||
<>
|
||||
<Text variant="body" mt={1} sx={{ textAlign: "center" }}>
|
||||
Resubscribing to Notesnook Pro will replace your existing
|
||||
subscription.
|
||||
</Text>
|
||||
<Button
|
||||
variant="accent"
|
||||
mt={2}
|
||||
sx={{ borderRadius: 100, px: 6 }}
|
||||
onClick={onShowPlans}
|
||||
data-test-id="see-all-plans"
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<Text variant="body" mt={1} sx={{ textAlign: "center" }}>
|
||||
You are already subscribed to Notesnook Pro.
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,10 @@ export const PLAN_METADATA: PlanMetadata = {
|
||||
[SubscriptionPlan.EDUCATION]: {
|
||||
title: "Education",
|
||||
subtitle: ""
|
||||
},
|
||||
[SubscriptionPlan.LEGACY_PRO]: {
|
||||
title: "Pro (legacy)",
|
||||
subtitle: ""
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -357,7 +357,7 @@ async function getActiveNotebookCommands() {
|
||||
const commands: Command[] = [];
|
||||
|
||||
const parentId = await db.notebooks.parentId(notebook.id);
|
||||
const menuItems = notebookMenuItems(notebook, [notebook.id], {
|
||||
const menuItems = await notebookMenuItems(notebook, [notebook.id], {
|
||||
isRoot: !parentId
|
||||
});
|
||||
for (const menuItem of menuItems) {
|
||||
@@ -375,7 +375,7 @@ async function getActiveTagCommands() {
|
||||
const group = strings.actionsForTag(tag.title);
|
||||
const commands: Command[] = [];
|
||||
|
||||
const menuItems = tagMenuItems(tag, [tag.id]);
|
||||
const menuItems = await tagMenuItems(tag, [tag.id]);
|
||||
for (const menuItem of menuItems) {
|
||||
commands.push(...menuItemToCommands(menuItem, group, "active-tag"));
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ export type ConfirmDialogProps = BaseDialogProps<
|
||||
inputs?: Record<string, Input>;
|
||||
};
|
||||
|
||||
export const ConfirmDialog = DialogManager.register(function ConfirmDialog<>(
|
||||
export const ConfirmDialog = DialogManager.register(function ConfirmDialog(
|
||||
props: ConfirmDialogProps
|
||||
) {
|
||||
const {
|
||||
|
||||
@@ -40,7 +40,7 @@ import { BaseDialogProps, DialogManager } from "../common/dialog-manager";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { Virtuoso } from "react-virtuoso";
|
||||
import { CustomScrollbarsVirtualList } from "../components/list-container";
|
||||
import { BuyDialog } from "./buy-dialog";
|
||||
import { UpgradeDialog } from "./buy-dialog/upgrade-dialog";
|
||||
|
||||
export type NoteLinkingDialogProps = BaseDialogProps<LinkAttributes | false> & {
|
||||
attributes?: LinkAttributes;
|
||||
@@ -203,9 +203,11 @@ export const NoteLinkingDialog = DialogManager.register(
|
||||
{blockLinkingAvailability?.error}{" "}
|
||||
<Button
|
||||
onClick={() =>
|
||||
BuyDialog.show({
|
||||
plan: blockLinkingAvailability?.availableOn
|
||||
})
|
||||
blockLinkingAvailability
|
||||
? UpgradeDialog.show({
|
||||
feature: blockLinkingAvailability
|
||||
})
|
||||
: null
|
||||
}
|
||||
variant="anchor"
|
||||
>
|
||||
|
||||
@@ -86,10 +86,10 @@ export const BackupExportSettings: SettingsGroup[] = [
|
||||
{
|
||||
type: "dropdown",
|
||||
options: [
|
||||
{ value: "0", title: strings.never(), premium: true },
|
||||
{ value: "1", title: strings.daily(), premium: true },
|
||||
{ value: "2", title: strings.weekly(), premium: true },
|
||||
{ value: "3", title: strings.monthly(), premium: true }
|
||||
{ value: "0", title: strings.never() },
|
||||
{ value: "1", title: strings.daily() },
|
||||
{ value: "2", title: strings.weekly() },
|
||||
{ value: "3", title: strings.monthly() }
|
||||
],
|
||||
selectedOption: () =>
|
||||
useSettingStore.getState().backupReminderOffset.toString(),
|
||||
@@ -118,9 +118,9 @@ export const BackupExportSettings: SettingsGroup[] = [
|
||||
{
|
||||
type: "dropdown",
|
||||
options: [
|
||||
{ value: "0", title: strings.never(), premium: true },
|
||||
{ value: "1", title: strings.weekly(), premium: true },
|
||||
{ value: "2", title: strings.monthly(), premium: true }
|
||||
{ value: "0", title: strings.never() },
|
||||
{ value: "1", title: strings.weekly() },
|
||||
{ value: "2", title: strings.monthly() }
|
||||
],
|
||||
selectedOption: () =>
|
||||
useSettingStore.getState().fullBackupReminderOffset.toString(),
|
||||
@@ -212,13 +212,12 @@ export const BackupExportSettings: SettingsGroup[] = [
|
||||
options: [
|
||||
{ value: "-", title: strings.exportAs() },
|
||||
{ value: "txt", title: "Text" },
|
||||
{ value: "md", title: "Markdown", premium: true },
|
||||
{ value: "md", title: "Markdown" },
|
||||
{
|
||||
value: "md-frontmatter",
|
||||
title: "Markdown + Frontmatter",
|
||||
premium: true
|
||||
title: "Markdown + Frontmatter"
|
||||
},
|
||||
{ value: "html", title: "HTML", premium: true }
|
||||
{ value: "html", title: "HTML" }
|
||||
],
|
||||
selectedOption: () => "-",
|
||||
onSelectionChanged: async (value) => {
|
||||
|
||||
@@ -37,7 +37,7 @@ export function SubscriptionStatus() {
|
||||
const user = useUserStore((store) => store.user);
|
||||
const featuresUsage = usePromise(() => getFeaturesUsage(), [user]);
|
||||
|
||||
const { title, autoRenew, expiryDate, trialExpiryDate, trial, legacy } =
|
||||
const { title, autoRenew, expiryDate, trialExpiryDate, trial } =
|
||||
getSubscriptionInfo(user);
|
||||
const subtitle =
|
||||
title === "Free"
|
||||
@@ -76,10 +76,7 @@ export function SubscriptionStatus() {
|
||||
>
|
||||
{strings.currentPlan()}
|
||||
</Text>
|
||||
<Text variant="heading">
|
||||
{title}
|
||||
{legacy ? " (legacy)" : ""}
|
||||
</Text>
|
||||
<Text variant="heading">{title}</Text>
|
||||
{subtitle ? <Text variant="body">{subtitle}</Text> : null}
|
||||
{featuresUsage.status === "fulfilled" ? (
|
||||
<Grid
|
||||
|
||||
@@ -32,7 +32,6 @@ import {
|
||||
SubscriptionPlan,
|
||||
SubscriptionProvider,
|
||||
SubscriptionStatus,
|
||||
SubscriptionType,
|
||||
User
|
||||
} from "@notesnook/core";
|
||||
|
||||
@@ -41,30 +40,27 @@ export function getSubscriptionInfo(user?: User): {
|
||||
trial?: boolean;
|
||||
paused?: boolean;
|
||||
canceled?: boolean;
|
||||
legacy?: boolean;
|
||||
expiryDate?: string;
|
||||
startDate?: string;
|
||||
autoRenew?: boolean;
|
||||
trialExpiryDate?: string;
|
||||
} {
|
||||
user = user || useUserStore.getState().user;
|
||||
const { type, expiry, plan, status, provider } = user?.subscription || {};
|
||||
const { expiry, plan, status, provider } = user?.subscription || {};
|
||||
if (!expiry) return { title: "Free" };
|
||||
|
||||
const legacy = !!type;
|
||||
const trial =
|
||||
status === SubscriptionStatus.TRIAL || type === SubscriptionType.TRIAL;
|
||||
const trial = status === SubscriptionStatus.TRIAL;
|
||||
const title =
|
||||
plan === SubscriptionPlan.BELIEVER
|
||||
? "Believer"
|
||||
: plan === SubscriptionPlan.PRO ||
|
||||
type === SubscriptionType.PREMIUM ||
|
||||
type === SubscriptionType.PREMIUM_CANCELED
|
||||
: plan === SubscriptionPlan.PRO
|
||||
? "Pro"
|
||||
: plan === SubscriptionPlan.ESSENTIAL
|
||||
? "Essential"
|
||||
: plan === SubscriptionPlan.EDUCATION
|
||||
? "Education"
|
||||
: plan === SubscriptionPlan.LEGACY_PRO
|
||||
? "Pro (legacy)"
|
||||
: "Free";
|
||||
const autoRenew =
|
||||
(status === SubscriptionStatus.ACTIVE ||
|
||||
@@ -88,7 +84,6 @@ export function getSubscriptionInfo(user?: User): {
|
||||
|
||||
return {
|
||||
title,
|
||||
legacy,
|
||||
trial,
|
||||
expiryDate,
|
||||
startDate,
|
||||
@@ -107,7 +102,7 @@ export function UserProfile({ minimal }: Props) {
|
||||
const user = useUserStore((store) => store.user);
|
||||
const profile = useSettingStore((store) => store.profile);
|
||||
|
||||
const { title, legacy, trial } = getSubscriptionInfo(user);
|
||||
const { title, trial } = getSubscriptionInfo(user);
|
||||
|
||||
if (!user || !user.id)
|
||||
return (
|
||||
@@ -206,7 +201,7 @@ export function UserProfile({ minimal }: Props) {
|
||||
color: "accent"
|
||||
}}
|
||||
>
|
||||
{`${title}${trial ? " (trial)" : ""}${legacy ? " (legacy)" : ""}`}
|
||||
{`${title}${trial ? " (trial)" : ""}`}
|
||||
</Text>
|
||||
|
||||
<Text variant={minimal ? "body" : "subtitle"}>
|
||||
|
||||
@@ -90,7 +90,7 @@ export const SubscriptionSettings: SettingsGroup[] = [
|
||||
const user = useUserStore.getState().user;
|
||||
const status = user?.subscription.status;
|
||||
return (
|
||||
getSubscriptionInfo(user).legacy ||
|
||||
user?.subscription.plan === SubscriptionPlan.LEGACY_PRO ||
|
||||
user?.subscription.provider !== SubscriptionProvider.PADDLE ||
|
||||
!isUserSubscribed(user) ||
|
||||
status === SubscriptionStatusEnum.CANCELED ||
|
||||
@@ -162,7 +162,7 @@ export const SubscriptionSettings: SettingsGroup[] = [
|
||||
const user = useUserStore.getState().user;
|
||||
const status = user?.subscription.status;
|
||||
return (
|
||||
getSubscriptionInfo(user).legacy ||
|
||||
user?.subscription.plan === SubscriptionPlan.LEGACY_PRO ||
|
||||
user?.subscription.provider !== SubscriptionProvider.PADDLE ||
|
||||
!isUserSubscribed(user) ||
|
||||
status !== SubscriptionStatusEnum.TRIAL
|
||||
|
||||
@@ -21,9 +21,7 @@ import { SettingsGroup } from "./types";
|
||||
import { useStore as useAppStore } from "../../stores/app-store";
|
||||
import { useStore as useSettingStore } from "../../stores/setting-store";
|
||||
import { ConfirmDialog } from "../confirm";
|
||||
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { withFeatureCheck } from "../../common";
|
||||
|
||||
export const SyncSettings: SettingsGroup[] = [
|
||||
{
|
||||
@@ -115,7 +113,7 @@ export const SyncSettings: SettingsGroup[] = [
|
||||
positiveButtonText: strings.continue(),
|
||||
negativeButtonText: strings.cancel()
|
||||
}).then((result) => {
|
||||
if (!result || !result.accept) return;
|
||||
if (!result || !result.checks?.accept) return;
|
||||
return useAppStore
|
||||
.getState()
|
||||
.sync({ force: true, type: "send" });
|
||||
@@ -135,7 +133,7 @@ export const SyncSettings: SettingsGroup[] = [
|
||||
positiveButtonText: strings.continue(),
|
||||
negativeButtonText: strings.cancel()
|
||||
}).then((result) => {
|
||||
if (!result || !result.accept) return;
|
||||
if (!result || !result.checks?.accept) return;
|
||||
return useAppStore
|
||||
.getState()
|
||||
.sync({ force: true, type: "fetch" });
|
||||
|
||||
4
apps/web/src/global.d.ts
vendored
4
apps/web/src/global.d.ts
vendored
@@ -34,10 +34,6 @@ declare global {
|
||||
var IS_THEME_BUILDER: boolean;
|
||||
var hasNativeTitlebar: boolean;
|
||||
|
||||
interface Window {
|
||||
ApplePaySession?: PaymentRequest;
|
||||
}
|
||||
|
||||
interface AuthenticationExtensionsClientInputs {
|
||||
prf?: {
|
||||
eval: {
|
||||
|
||||
@@ -17,12 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
SubscriptionPlan,
|
||||
SubscriptionStatus,
|
||||
SubscriptionType,
|
||||
User
|
||||
} from "@notesnook/core";
|
||||
import { SubscriptionPlan, SubscriptionStatus, User } from "@notesnook/core";
|
||||
import { useStore as useUserStore } from "../stores/user-store";
|
||||
|
||||
export function isActiveSubscription(user?: User) {
|
||||
@@ -39,30 +34,10 @@ export function isUserSubscribed(user?: User) {
|
||||
user = user || useUserStore.getState().user;
|
||||
if (!user) return false;
|
||||
|
||||
const { type, expiry, plan, status } = user?.subscription || {};
|
||||
const { expiry, plan, status } = user?.subscription || {};
|
||||
if (!expiry) return false;
|
||||
const isLegacyPro =
|
||||
type !== undefined &&
|
||||
(type === SubscriptionType.BETA ||
|
||||
type === SubscriptionType.PREMIUM ||
|
||||
type === SubscriptionType.PREMIUM_CANCELED ||
|
||||
type === SubscriptionType.TRIAL);
|
||||
|
||||
if (isLegacyPro) {
|
||||
return (
|
||||
type === SubscriptionType.PREMIUM ||
|
||||
type === SubscriptionType.PREMIUM_CANCELED
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
plan !== SubscriptionPlan.FREE && status !== SubscriptionStatus.EXPIRED
|
||||
);
|
||||
|
||||
// const { type, plan } = user.subscription || {};
|
||||
// return (
|
||||
// (type === SubscriptionType.TRIAL || type === SubscriptionType.PREMIUM ||
|
||||
// type === SubscriptionType.PREMIUM_CANCELED) &&
|
||||
// plan !== SubscriptionPlan.FREE
|
||||
// );
|
||||
}
|
||||
|
||||
@@ -85,13 +85,6 @@ function Checkout() {
|
||||
const [currentStep, setCurrentStep] = useState(0);
|
||||
const [error, setError] = useState<string>();
|
||||
const [customer, setCustomer] = useState<{ id: string; email: string }>();
|
||||
const isCheckoutCompleted = useCheckoutStore((store) => store.isCompleted);
|
||||
|
||||
useEffect(() => {
|
||||
if (isCheckoutCompleted) {
|
||||
setCurrentStep(2);
|
||||
}
|
||||
}, [isCheckoutCompleted]);
|
||||
|
||||
useEffect(() => {
|
||||
useUserStore.getState().init();
|
||||
@@ -106,7 +99,11 @@ function Checkout() {
|
||||
return;
|
||||
}
|
||||
useCheckoutStore.getState().selectPlan(pricingInfo.data);
|
||||
useCheckoutStore.getState().updatePrice(toPricingInfo(pricingInfo.data));
|
||||
useCheckoutStore
|
||||
.getState()
|
||||
.updatePrice(
|
||||
toPricingInfo(pricingInfo.data, useUserStore.getState().user)
|
||||
);
|
||||
useCheckoutStore.getState().applyCoupon(pricingInfo.data.discount?.code);
|
||||
if (pricingInfo.data.customer) {
|
||||
setCustomer(pricingInfo.data.customer);
|
||||
@@ -263,7 +260,12 @@ function Checkout() {
|
||||
You are one step away from unlocking the full potential of
|
||||
Notesnook.
|
||||
</Text>
|
||||
<CheckoutDetails user={customer} />
|
||||
<CheckoutDetails
|
||||
user={customer}
|
||||
onComplete={() => {
|
||||
setCurrentStep(2);
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
) : currentStep === 2 ? (
|
||||
<Flex
|
||||
|
||||
Reference in New Issue
Block a user