diff --git a/app/assets/javascripts/preferences/panes/AccountPreferences.tsx b/app/assets/javascripts/preferences/panes/AccountPreferences.tsx
index 6b034d7c6..8dd126cba 100644
--- a/app/assets/javascripts/preferences/panes/AccountPreferences.tsx
+++ b/app/assets/javascripts/preferences/panes/AccountPreferences.tsx
@@ -1,4 +1,4 @@
-import { Sync } from '@/preferences/panes/account';
+import { Sync, Subscription } from '@/preferences/panes/account';
import { PreferencesPane } from '@/preferences/components';
import { observer } from 'mobx-react-lite';
import { WebApplication } from '@/ui_models/application';
@@ -7,6 +7,7 @@ export const AccountPreferences = observer(({application}: {application: WebAppl
return (
+
);
});
diff --git a/app/assets/javascripts/preferences/panes/account/Subscription.tsx b/app/assets/javascripts/preferences/panes/account/Subscription.tsx
new file mode 100644
index 000000000..0a3c79bd4
--- /dev/null
+++ b/app/assets/javascripts/preferences/panes/account/Subscription.tsx
@@ -0,0 +1,187 @@
+import {
+ PreferencesGroup,
+ PreferencesSegment,
+ Text,
+ Title,
+} from '@/preferences/components';
+import { Button } from '@/components/Button';
+import { observer } from '@node_modules/mobx-react-lite';
+import { WebApplication } from '@/ui_models/application';
+import { useEffect, useState } from 'preact/hooks';
+import { GetSubscriptionResponse } from '@standardnotes/snjs/dist/@types/services/api/responses';
+
+type Props = {
+ application: WebApplication;
+};
+
+enum PlanName {
+ CorePlan = 'CORE_PLAN',
+ PlusPlan = 'PLUS_PLAN',
+ ProPlan = 'PRO_PLAN',
+}
+
+type Subscription = {
+ cancelled: boolean;
+ planName: PlanName;
+ endsAt: number;
+};
+
+type SubscriptionInformationProps = {
+ subscription?: Subscription;
+};
+
+type ValidSubscriptionProps = {
+ subscription: Subscription;
+};
+
+const mapPlanNameToString = (planName: PlanName) => {
+ switch (planName) {
+ case 'CORE_PLAN':
+ return 'Core';
+ case 'PLUS_PLAN':
+ return 'Plus';
+ case 'PRO_PLAN':
+ return 'Pro';
+ default:
+ return '';
+ }
+};
+
+const NoSubscription = () => (
+ <>
+ You don't have a Standard Notes subscription yet.
+
+
+ >
+);
+
+const ActiveSubscription = ({ subscription }: ValidSubscriptionProps) => (
+ <>
+
+ Your{' '}
+
+ Standard Notes {mapPlanNameToString(subscription.planName)}
+ {' '}
+ subscription will be{' '}
+
+ renewed on {new Date(subscription.endsAt).toLocaleString()}
+
+ .
+
+
+ null}
+ />
+ null}
+ />
+ null}
+ />
+
+ >
+);
+
+const CancelledSubscription = ({ subscription }: ValidSubscriptionProps) => (
+ <>
+
+ Your{' '}
+
+ Standard Notes {mapPlanNameToString(subscription.planName)}
+ {' '}
+ subscription has been{' '}
+
+ canceled but will remain valid until{' '}
+ {new Date(subscription.endsAt).toLocaleString()}
+
+ . You may resubscribe below if you wish.
+
+
+ null}
+ />
+ null}
+ />
+ null}
+ />
+
+ >
+);
+
+const SubscriptionInformation = ({
+ subscription,
+}: SubscriptionInformationProps) => {
+ const now = new Date().getTime();
+ if (subscription && subscription.endsAt > now) {
+ return subscription.cancelled ? (
+
+ ) : (
+
+ );
+ }
+ return ;
+};
+
+const Subscription = observer(({ application }: Props) => {
+ const [subscription, setSubscription] =
+ useState(undefined);
+
+ useEffect(() => {
+ const getSubscription = async () => {
+ const result = await application.getUserSubscription();
+ if (!result.error && result.data) {
+ const data = (result as GetSubscriptionResponse).data;
+ const subscription = data!.subscription;
+ setSubscription(subscription);
+ }
+ };
+ getSubscription();
+ }, [application]);
+
+ return (
+
+
+
+
+
+ );
+});
+
+export default Subscription;
diff --git a/app/assets/javascripts/preferences/panes/account/index.ts b/app/assets/javascripts/preferences/panes/account/index.ts
index 2225b5881..d30c31420 100644
--- a/app/assets/javascripts/preferences/panes/account/index.ts
+++ b/app/assets/javascripts/preferences/panes/account/index.ts
@@ -1 +1,2 @@
export { default as Sync } from './Sync';
+export { default as Subscription } from './Subscription';
diff --git a/app/assets/stylesheets/_sn.scss b/app/assets/stylesheets/_sn.scss
index 32baa1cb4..a8a4bed8b 100644
--- a/app/assets/stylesheets/_sn.scss
+++ b/app/assets/stylesheets/_sn.scss
@@ -149,3 +149,7 @@
.sn-title {
@extend .font-bold;
}
+
+.mr-3 {
+ margin-right: 0.75rem;
+}