feat: Add "Manage subscription" button to Subscription preferences (#705)
* feat: Add "Manage subscription" button to Subscription preferences * Update app/assets/javascripts/preferences/panes/account/subscription/SubscriptionInformation.tsx Co-authored-by: Mo <mo@standardnotes.org> * feat: Use convertTimestamp function instead of manual conversion in Subscription Info Co-authored-by: Mo <mo@standardnotes.org>
This commit is contained in:
@@ -6,6 +6,8 @@ declare global {
|
|||||||
_bugsnag_api_key?: string;
|
_bugsnag_api_key?: string;
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
_purchase_url?: string;
|
_purchase_url?: string;
|
||||||
|
// eslint-disable-next-line camelcase
|
||||||
|
_dashboard_url?: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +213,7 @@ if (IsWebPlatform) {
|
|||||||
(window as any)._default_sync_server as string,
|
(window as any)._default_sync_server as string,
|
||||||
new BrowserBridge(AppVersion),
|
new BrowserBridge(AppVersion),
|
||||||
(window as any)._enable_unfinished_features as boolean,
|
(window as any)._enable_unfinished_features as boolean,
|
||||||
(window as any)._websocket_url as string,
|
(window as any)._websocket_url as string
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
(window as any).startApplication = startApplication;
|
(window as any).startApplication = startApplication;
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export const Subscription: FunctionComponent<Props> = observer(({
|
|||||||
) : loading ? (
|
) : loading ? (
|
||||||
<Text>Loading subscription information...</Text>
|
<Text>Loading subscription information...</Text>
|
||||||
) : userSubscription && userSubscription.endsAt > now ? (
|
) : userSubscription && userSubscription.endsAt > now ? (
|
||||||
<SubscriptionInformation subscriptionState={subscriptionState} />
|
<SubscriptionInformation subscriptionState={subscriptionState} application={application}/>
|
||||||
) : (
|
) : (
|
||||||
<NoSubscription application={application} />
|
<NoSubscription application={application} />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -2,17 +2,22 @@ import { observer } from 'mobx-react-lite';
|
|||||||
import { SubscriptionState } from './subscription_state';
|
import { SubscriptionState } from './subscription_state';
|
||||||
import { Text } from '@/preferences/components';
|
import { Text } from '@/preferences/components';
|
||||||
import { Button } from '@/components/Button';
|
import { Button } from '@/components/Button';
|
||||||
|
import { WebApplication } from '@/ui_models/application';
|
||||||
|
import { convertTimestampToMilliseconds } from '@standardnotes/snjs';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
subscriptionState: SubscriptionState;
|
subscriptionState: SubscriptionState;
|
||||||
|
application?: WebApplication;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StatusText = observer(({ subscriptionState }: Props) => {
|
const StatusText = observer(({ subscriptionState }: Props) => {
|
||||||
const { userSubscription, userSubscriptionName } = subscriptionState;
|
const { userSubscription, userSubscriptionName } = subscriptionState;
|
||||||
const expirationDate = new Date(userSubscription!.endsAt / 1000).toLocaleString();
|
const expirationDate = new Date(
|
||||||
|
convertTimestampToMilliseconds(userSubscription!.endsAt)
|
||||||
|
).toLocaleString();
|
||||||
|
|
||||||
return userSubscription!.cancelled ? (
|
return userSubscription!.cancelled ? (
|
||||||
<Text>
|
<Text className="mt-1">
|
||||||
Your{' '}
|
Your{' '}
|
||||||
<span className="font-bold">
|
<span className="font-bold">
|
||||||
Standard Notes{userSubscriptionName ? ' ' : ''}
|
Standard Notes{userSubscriptionName ? ' ' : ''}
|
||||||
@@ -20,23 +25,19 @@ const StatusText = observer(({ subscriptionState }: Props) => {
|
|||||||
</span>{' '}
|
</span>{' '}
|
||||||
subscription has been{' '}
|
subscription has been{' '}
|
||||||
<span className="font-bold">
|
<span className="font-bold">
|
||||||
canceled but will remain valid until{' '}
|
canceled but will remain valid until {expirationDate}
|
||||||
{expirationDate}
|
|
||||||
</span>
|
</span>
|
||||||
. You may resubscribe below if you wish.
|
. You may resubscribe below if you wish.
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
<Text>
|
<Text className="mt-1">
|
||||||
Your{' '}
|
Your{' '}
|
||||||
<span className="font-bold">
|
<span className="font-bold">
|
||||||
Standard Notes{userSubscriptionName ? ' ' : ''}
|
Standard Notes{userSubscriptionName ? ' ' : ''}
|
||||||
{userSubscriptionName}
|
{userSubscriptionName}
|
||||||
</span>{' '}
|
</span>{' '}
|
||||||
subscription will be{' '}
|
subscription will be{' '}
|
||||||
<span className="font-bold">
|
<span className="font-bold">renewed on {expirationDate}</span>.
|
||||||
renewed on {expirationDate}
|
|
||||||
</span>
|
|
||||||
.
|
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -48,35 +49,53 @@ const PrimaryButton = observer(({ subscriptionState }: Props) => {
|
|||||||
<Button
|
<Button
|
||||||
className="min-w-20 mt-3"
|
className="min-w-20 mt-3"
|
||||||
type="primary"
|
type="primary"
|
||||||
label={userSubscription!.cancelled ? "Renew subscription" : "Cancel subscription"}
|
label={
|
||||||
|
userSubscription!.cancelled
|
||||||
|
? 'Renew subscription'
|
||||||
|
: 'Cancel subscription'
|
||||||
|
}
|
||||||
onClick={() => null}
|
onClick={() => null}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
export const SubscriptionInformation = observer(
|
export const SubscriptionInformation = observer(
|
||||||
({ subscriptionState }: Props) => (
|
({ subscriptionState, application }: Props) => {
|
||||||
<>
|
const openSubscriptionDashboard = async () => {
|
||||||
<StatusText
|
const token = await application?.getNewSubscriptionToken();
|
||||||
subscriptionState={subscriptionState}
|
if (!token) {
|
||||||
/>
|
return;
|
||||||
<div className="flex">
|
}
|
||||||
<Button
|
window.location.assign(
|
||||||
className="min-w-20 mt-3 mr-3"
|
`${window._dashboard_url}?subscription_token=${token}`
|
||||||
type="normal"
|
);
|
||||||
label="Refresh"
|
};
|
||||||
onClick={() => null}
|
|
||||||
/>
|
return (
|
||||||
<Button
|
<>
|
||||||
className="min-w-20 mt-3 mr-3"
|
<StatusText subscriptionState={subscriptionState} />
|
||||||
type="normal"
|
<div className="flex flex-wrap">
|
||||||
label="Change plan"
|
<Button
|
||||||
onClick={() => null}
|
className="min-w-20 mt-3 mr-3"
|
||||||
/>
|
type="normal"
|
||||||
<PrimaryButton
|
label="Manage subscription"
|
||||||
subscriptionState={subscriptionState}
|
onClick={openSubscriptionDashboard}
|
||||||
/>
|
/>
|
||||||
</div>
|
<Button
|
||||||
</>
|
className="min-w-20 mt-3 mr-3"
|
||||||
)
|
type="normal"
|
||||||
|
label="Refresh"
|
||||||
|
onClick={() => null}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className="min-w-20 mt-3 mr-3"
|
||||||
|
type="normal"
|
||||||
|
label="Change plan"
|
||||||
|
onClick={() => null}
|
||||||
|
/>
|
||||||
|
<PrimaryButton subscriptionState={subscriptionState} />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
window._enable_unfinished_features = "<%= ENV['ENABLE_UNFINISHED_FEATURES'] %>" === 'true';
|
window._enable_unfinished_features = "<%= ENV['ENABLE_UNFINISHED_FEATURES'] %>" === 'true';
|
||||||
window._websocket_url = "<%= ENV['WEBSOCKET_URL'] %>";
|
window._websocket_url = "<%= ENV['WEBSOCKET_URL'] %>";
|
||||||
window._purchase_url = "<%= ENV['PURCHASE_URL'] %>";
|
window._purchase_url = "<%= ENV['PURCHASE_URL'] %>";
|
||||||
|
window._dashboard_url = "<%= ENV['DASHBOARD_URL'] %>";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<% if Rails.env.development? %>
|
<% if Rails.env.development? %>
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
data-enable-unfinished-features="<%= env.ENABLE_UNFINISHED_FEATURES %>"
|
data-enable-unfinished-features="<%= env.ENABLE_UNFINISHED_FEATURES %>"
|
||||||
data-web-socket-url="<%= env.DEV_WEBSOCKET_URL %>"
|
data-web-socket-url="<%= env.DEV_WEBSOCKET_URL %>"
|
||||||
data-purchase-url="<%= env.PURCHASE_URL %>"
|
data-purchase-url="<%= env.PURCHASE_URL %>"
|
||||||
|
data-dashboard-url="<%= env.DASHBOARD_URL %>"
|
||||||
>
|
>
|
||||||
<script>
|
<script>
|
||||||
window._default_sync_server = document.body.dataset.defaultSyncServer || "https://api.standardnotes.com";
|
window._default_sync_server = document.body.dataset.defaultSyncServer || "https://api.standardnotes.com";
|
||||||
@@ -41,6 +42,7 @@
|
|||||||
window._enable_unfinished_features = document.body.dataset.enableUnfinishedFeatures === 'true';
|
window._enable_unfinished_features = document.body.dataset.enableUnfinishedFeatures === 'true';
|
||||||
window._websocket_url = document.body.dataset.webSocketUrl;
|
window._websocket_url = document.body.dataset.webSocketUrl;
|
||||||
window._purchase_url = document.body.dataset.purchaseUrl;
|
window._purchase_url = document.body.dataset.purchaseUrl;
|
||||||
|
window._dashboard_url = document.body.dataset.dashboardUrl;
|
||||||
</script>
|
</script>
|
||||||
<application-group-view />
|
<application-group-view />
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user