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:
Aman Harwara
2021-10-26 21:30:21 +05:30
committed by GitHub
parent 0c332d8b5e
commit 53ec0d4742
5 changed files with 60 additions and 36 deletions

View File

@@ -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;

View File

@@ -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} />
)} )}

View File

@@ -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>
</>
);
}
); );

View File

@@ -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? %>

View File

@@ -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>