From 524d55f46e3834a84db17945eaa1c65891f06547 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Thu, 8 Aug 2019 19:50:17 +0200 Subject: Add option to subscribe to trial via account dashboard --- src/components/auth/Pricing.js | 2 +- .../settings/account/AccountDashboard.js | 114 ++++--- src/components/subscription/SubscriptionForm.js | 238 ++++----------- src/config.js | 24 ++ .../subscription/SubscriptionFormScreen.js | 18 +- src/helpers/plan-helpers.js | 43 +++ src/i18n/locales/defaultMessages.json | 328 ++++++++++++++++++--- src/i18n/locales/en-US.json | 57 ++-- .../settings/account/AccountDashboard.json | 116 ++++++-- .../components/subscription/SubscriptionForm.json | 145 +-------- src/i18n/messages/src/helpers/plan-helpers.json | 80 +++++ src/i18n/messages/src/helpers/pricing-helpers.json | 80 +++++ src/stores/AppStore.js | 2 + src/styles/settings.scss | 1 + 14 files changed, 780 insertions(+), 468 deletions(-) create mode 100644 src/helpers/plan-helpers.js create mode 100644 src/i18n/messages/src/helpers/plan-helpers.json create mode 100644 src/i18n/messages/src/helpers/pricing-helpers.json (limited to 'src') diff --git a/src/components/auth/Pricing.js b/src/components/auth/Pricing.js index d20779025..cbeaaa5d9 100644 --- a/src/components/auth/Pricing.js +++ b/src/components/auth/Pricing.js @@ -8,7 +8,7 @@ import classnames from 'classnames'; import { Button } from '@meetfranz/forms'; import { FeatureItem } from '../ui/FeatureItem'; -import FeatureList from '../ui/FeatureList'; +import { FeatureList } from '../ui/FeatureList'; const messages = defineMessages({ diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js index 0366dc1ee..079d50380 100644 --- a/src/components/settings/account/AccountDashboard.js +++ b/src/components/settings/account/AccountDashboard.js @@ -1,14 +1,18 @@ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; import { defineMessages, intlShape } from 'react-intl'; import ReactTooltip from 'react-tooltip'; -import { ProBadge } from '@meetfranz/ui'; +import { + ProBadge, H2, H1, H3, +} from '@meetfranz/ui'; +import moment from 'moment'; import Loader from '../../ui/Loader'; import Button from '../../ui/Button'; import Infobox from '../../ui/Infobox'; import SubscriptionForm from '../../../containers/subscription/SubscriptionFormScreen'; +import { i18nPlanName } from '../../../helpers/plan-helpers'; const messages = defineMessages({ headline: { @@ -20,8 +24,8 @@ const messages = defineMessages({ defaultMessage: '!!!Your Subscription', }, headlineUpgrade: { - id: 'settings.account.headlineUpgrade', - defaultMessage: '!!!Upgrade your Account', + id: 'settings.account.headlineTrialUpgrade', + defaultMessage: '!!!Get the free 14 day Franz Professional Trial', }, headlineDangerZone: { id: 'settings.account.headlineDangerZone', @@ -71,6 +75,22 @@ const messages = defineMessages({ id: 'settings.account.deleteEmailSent', defaultMessage: '!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!', }, + trial: { + id: 'settings.account.trial', + defaultMessage: '!!!Free Trial', + }, + yourLicense: { + id: 'settings.account.yourLicense', + defaultMessage: '!!!Your license:', + }, + trialEndsIn: { + id: 'settings.account.trialEndsIn', + defaultMessage: '!!!Your free trial ends in {duration}.', + }, + trialUpdateBillingInformation: { + id: 'settings.account.trialUpdateBillingInfo', + defaultMessage: '!!!Please update your billing info to continue using {license} after your trial period.', + }, }); export default @observer class AccountDashboard extends Component { @@ -110,6 +130,13 @@ export default @observer class AccountDashboard extends Component { } = this.props; const { intl } = this.context; + let planName = ''; + + if (user.team && user.team.plan) { + planName = i18nPlanName(user.team.plan, intl); + console.log(planName); + } + return (
@@ -147,7 +174,7 @@ export default @observer class AccountDashboard extends Component { />
-

+

{`${user.firstname} ${user.lastname}`} {user.isPremium && ( <> @@ -156,7 +183,7 @@ export default @observer class AccountDashboard extends Component { {/* {intl.formatMessage(messages.accountTypePremium)} */} )} -

+

{user.organization && `${user.organization}, `} {user.email} @@ -197,54 +224,61 @@ export default @observer class AccountDashboard extends Component { {user.isSubscriptionOwner && (

-

- Your license: {user.team.plan} -

+

+ {intl.formatMessage(messages.yourLicense)} +

+

+ {planName} + {user.team.isTrial && ( + <> + {' – '} + {intl.formatMessage(messages.trial)} + + )} +

{user.team.isTrial && ( <>

- Trial ends in 14 days + {intl.formatMessage(messages.trialEndsIn, { + duration: moment.duration(moment().diff(user.team.trialEnd)).humanize(), + })} +

+

+ {intl.formatMessage(messages.trialUpdateBillingInformation, { + license: planName, + })}

)} - {user.isPremium && ( -
-
- )} +
+
)} - - )} - - {!user.isPremium && ( - isLoadingPlans ? ( - - ) : ( -
-
-

{intl.formatMessage(messages.headlineUpgrade)}

- + {!user.isPremium && ( +
+
+

{intl.formatMessage(messages.headlineUpgrade)}

+ +
-
- ) + )} + )}
-

{intl.formatMessage(messages.headlineDangerZone)}

+

{intl.formatMessage(messages.headlineDangerZone)}

{!isDeleteAccountSuccessful && (

{intl.formatMessage(messages.deleteInfo)}

diff --git a/src/components/subscription/SubscriptionForm.js b/src/components/subscription/SubscriptionForm.js index 50f1e0522..0c630f047 100644 --- a/src/components/subscription/SubscriptionForm.js +++ b/src/components/subscription/SubscriptionForm.js @@ -1,214 +1,94 @@ -import React, { Component, Fragment } from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; +import { observer } from 'mobx-react'; import { defineMessages, intlShape } from 'react-intl'; +import injectSheet from 'react-jss'; -import Form from '../../lib/Form'; -import Radio from '../ui/Radio'; -import Button from '../ui/Button'; -import Loader from '../ui/Loader'; +import { H3 } from '@meetfranz/ui'; -import { required } from '../../helpers/validation-helpers'; +import { Button } from '@meetfranz/forms'; +import { FeatureList } from '../ui/FeatureList'; +import { FeatureItem } from '../ui/FeatureItem'; const messages = defineMessages({ submitButtonLabel: { - id: 'subscription.submit.label', - defaultMessage: '!!!Support the development of Franz', - }, - paymentSessionError: { - id: 'subscription.paymentSessionError', - defaultMessage: '!!!Could not initialize payment form', - }, - typeFree: { - id: 'subscription.type.free', - defaultMessage: '!!!free', - }, - typeMonthly: { - id: 'subscription.type.month', - defaultMessage: '!!!month', - }, - typeYearly: { - id: 'subscription.type.year', - defaultMessage: '!!!year', + id: 'subscription.cta.activateTrial', + defaultMessage: '!!!Yes, upgrade my account to Franz Professional', }, includedFeatures: { - id: 'subscription.includedFeatures', - defaultMessage: '!!!The Franz Premium Supporter Account includes', - }, - onpremise: { - id: 'subscription.features.onpremise.mattermost', - defaultMessage: '!!!Add on-premise/hosted services like Mattermost', - }, - noInterruptions: { - id: 'subscription.features.noInterruptions', - defaultMessage: '!!!No app delays & nagging to upgrade license', + id: 'subscription.includedProFeatures', + defaultMessage: '!!!The Franz Professional Plan includes:', }, - proxy: { - id: 'subscription.features.proxy', - defaultMessage: '!!!Proxy support for services', + noStringsAttachedHeadline: { + id: 'pricing.trial.terms.headline', + defaultMessage: '!!!No strings attached', }, - spellchecker: { - id: 'subscription.features.spellchecker', - defaultMessage: '!!!Support for Spellchecker', + noCreditCard: { + id: 'pricing.trial.terms.noCreditCard', + defaultMessage: '!!!No credit card required', }, - workspaces: { - id: 'subscription.features.workspaces', - defaultMessage: '!!!Organize your services in workspaces', + automaticTrialEnd: { + id: 'pricing.trial.terms.automaticTrialEnd', + defaultMessage: '!!!Your free trial ends automatically after 14 days', }, - ads: { - id: 'subscription.features.ads', - defaultMessage: '!!!No ads, ever!', - }, - comingSoon: { - id: 'subscription.features.comingSoon', - defaultMessage: '!!!coming soon', +}); + +const styles = () => ({ + activateTrialButton: { + margin: [40, 0, 50], }, - euTaxInfo: { - id: 'subscription.euTaxInfo', - defaultMessage: '!!!EU residents: local sales tax may apply', + keyTerms: { + marginTop: 20, }, }); -export default @observer class SubscriptionForm extends Component { +export default @observer @injectSheet(styles) class SubscriptionForm extends Component { static propTypes = { - plan: MobxPropTypes.objectOrObservableObject.isRequired, - isLoading: PropTypes.bool.isRequired, - handlePayment: PropTypes.func.isRequired, - retryPlanRequest: PropTypes.func.isRequired, - isCreatingHostedPage: PropTypes.bool.isRequired, - error: PropTypes.bool.isRequired, - showSkipOption: PropTypes.bool, - skipAction: PropTypes.func, - skipButtonLabel: PropTypes.string, - hideInfo: PropTypes.bool.isRequired, - }; - - static defaultProps = { - showSkipOption: false, - skipAction: () => null, - skipButtonLabel: '', + activateTrial: PropTypes.func.isRequired, + isActivatingTrial: PropTypes.bool.isRequired, + classes: PropTypes.object.isRequired, }; static contextTypes = { intl: intlShape, }; - componentWillMount() { - this.form = this.prepareForm(); - } - - prepareForm() { - const { intl } = this.context; - - const form = { - fields: { - paymentTier: { - value: 'year', - validators: [required], - options: [{ - value: 'month', - label: `€ ${Object.hasOwnProperty.call(this.props.plan, 'month') - ? `${this.props.plan.month.price} / ${intl.formatMessage(messages.typeMonthly)}` - : 'monthly'}`, - }, { - value: 'year', - label: `€ ${Object.hasOwnProperty.call(this.props.plan, 'year') - ? `${this.props.plan.year.price} / ${intl.formatMessage(messages.typeYearly)}` - : 'yearly'}`, - }], - }, - }, - }; - - if (this.props.showSkipOption) { - form.fields.paymentTier.options.unshift({ - value: 'skip', - label: `€ 0 / ${intl.formatMessage(messages.typeFree)}`, - }); - } - - return new Form(form, this.context.intl); - } - render() { const { - isLoading, - isCreatingHostedPage, - handlePayment, - retryPlanRequest, - error, - showSkipOption, - skipAction, - skipButtonLabel, - hideInfo, + isActivatingTrial, + activateTrial, + classes, } = this.props; const { intl } = this.context; - if (error) { - return ( -
+ ); } } diff --git a/src/config.js b/src/config.js index 3c8b0f0d0..edcae9df1 100644 --- a/src/config.js +++ b/src/config.js @@ -84,3 +84,27 @@ export const ALLOWED_PROTOCOLS = [ 'http:', 'ftp:', ]; + +export const PLANS = { + PERSONAL_MONTHLY: 'PERSONAL_MONTHLY', + PERSONAL_YEARLY: 'PERSONAL_YEARLY', + PRO_MONTHLY: 'PRO_MONTHLY', + PRO_YEARLY: 'PRO_YEARLY', + LEGACY: 'LEGACY', + FREE: 'FREE', +}; + +export const PLANS_MAPPING = { + 'franz-personal-monthly': PLANS.PERSONAL_MONTHLY, + 'franz-personal-yearly': PLANS.PERSONAL_YEARLY, + 'franz-pro-monthly': PLANS.PRO_MONTHLY, + 'franz-pro-yearly': PLANS.PRO_YEARLY, + 'franz-supporter-license': PLANS.LEGACY, + 'franz-supporter-license-x1': PLANS.LEGACY, + 'franz-supporter-license-x2': PLANS.LEGACY, + 'franz-supporter-license-year': PLANS.LEGACY, + 'franz-supporter-license-year-x1': PLANS.LEGACY, + 'franz-supporter-license-year-x2': PLANS.LEGACY, + 'franz-supporter-license-year-2019': PLANS.LEGACY, + free: PLANS.FREE, +}; diff --git a/src/containers/subscription/SubscriptionFormScreen.js b/src/containers/subscription/SubscriptionFormScreen.js index aa1166f5e..7486cc498 100644 --- a/src/containers/subscription/SubscriptionFormScreen.js +++ b/src/containers/subscription/SubscriptionFormScreen.js @@ -74,28 +74,14 @@ export default @inject('stores', 'actions') @observer class SubscriptionFormScre render() { const { - content, actions, stores, - showSkipOption, - skipAction, - skipButtonLabel, - hideInfo, } = this.props; return ( stores.payment.plansRequest.reload()} - isCreatingHostedPage={stores.payment.createHostedPageRequest.isExecuting} - handlePayment={price => this.handlePayment(price)} - content={content} - error={stores.payment.plansRequest.isError} - showSkipOption={showSkipOption} - skipAction={skipAction} - skipButtonLabel={skipButtonLabel} - hideInfo={hideInfo} - openExternalUrl={actions.app.openExternalUrl} + activateTrial={() => actions.user.activateTrial({ planId: stores.features.features.defaultTrialPlan })} + isActivatingTrial={stores.user.activateTrialRequest.isExecuting || stores.user.getUserInfoRequest.isExecuting} /> ); } diff --git a/src/helpers/plan-helpers.js b/src/helpers/plan-helpers.js new file mode 100644 index 000000000..37a4457af --- /dev/null +++ b/src/helpers/plan-helpers.js @@ -0,0 +1,43 @@ +import { defineMessages } from 'react-intl'; +import { PLANS_MAPPING, PLANS } from '../config'; + +const messages = defineMessages({ + [PLANS.PRO_YEARLY]: { + id: 'pricing.plan.pro-yearly', + defaultMessage: '!!!Franz Professional Yearly', + }, + [PLANS.PRO_MONTHLY]: { + id: 'pricing.plan.pro-monthly', + defaultMessage: '!!!Franz Professional Monthly', + }, + [PLANS.PERSONAL_YEARLY]: { + id: 'pricing.plan.personal-yearly', + defaultMessage: '!!!Franz Personal Yearly', + }, + [PLANS.PERSONAL_MONTHLY]: { + id: 'pricing.plan.personal-monthly', + defaultMessage: '!!!Franz Personal Monthly', + }, + [PLANS.FREE]: { + id: 'pricing.plan.free', + defaultMessage: '!!!Franz Free', + }, + [PLANS.LEGACY]: { + id: 'pricing.plan.legacy', + defaultMessage: '!!!Franz Premium', + }, +}); + +export function i18nPlanName(planId, intl) { + if (!planId) { + throw new Error('planId is required'); + } + + if (!intl) { + throw new Error('intl context is required'); + } + + const plan = PLANS_MAPPING[planId]; + + return intl.formatMessage(messages[plan]); +} diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index 930f6752e..836fe3b24 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -734,39 +734,39 @@ "defaultMessage": "!!!Your services have been updated.", "end": { "column": 3, - "line": 29 + "line": 30 }, "file": "src/components/layout/AppLayout.js", "id": "infobar.servicesUpdated", "start": { "column": 19, - "line": 26 + "line": 27 } }, { "defaultMessage": "!!!Reload services", "end": { "column": 3, - "line": 33 + "line": 34 }, "file": "src/components/layout/AppLayout.js", "id": "infobar.buttonReloadServices", "start": { "column": 24, - "line": 30 + "line": 31 } }, { "defaultMessage": "!!!Could not load services and user information", "end": { "column": 3, - "line": 37 + "line": 38 }, "file": "src/components/layout/AppLayout.js", "id": "infobar.requiredRequestsFailed", "start": { "column": 26, - "line": 34 + "line": 35 } } ], @@ -1242,195 +1242,247 @@ "defaultMessage": "!!!Account", "end": { "column": 3, - "line": 17 + "line": 19 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.headline", "start": { "column": 12, - "line": 14 + "line": 16 } }, { "defaultMessage": "!!!Your Subscription", "end": { "column": 3, - "line": 21 + "line": 23 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.headlineSubscription", "start": { "column": 24, - "line": 18 + "line": 20 } }, { "defaultMessage": "!!!Upgrade your Account", "end": { "column": 3, - "line": 25 + "line": 27 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.headlineUpgrade", "start": { "column": 19, - "line": 22 + "line": 24 } }, { "defaultMessage": "!!Danger Zone", "end": { "column": 3, - "line": 29 + "line": 31 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.headlineDangerZone", "start": { "column": 22, - "line": 26 + "line": 28 } }, { "defaultMessage": "!!!Manage your subscription", "end": { "column": 3, - "line": 33 + "line": 35 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.manageSubscription.label", "start": { "column": 33, - "line": 30 + "line": 32 } }, { "defaultMessage": "!!!Basic Account", "end": { "column": 3, - "line": 37 + "line": 39 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.accountType.basic", "start": { "column": 20, - "line": 34 + "line": 36 } }, { "defaultMessage": "!!!Premium Supporter Account", "end": { "column": 3, - "line": 41 + "line": 43 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.accountType.premium", "start": { "column": 22, - "line": 38 + "line": 40 } }, { "defaultMessage": "!!!Edit Account", "end": { "column": 3, - "line": 45 + "line": 47 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.account.editButton", "start": { "column": 21, - "line": 42 + "line": 44 } }, { "defaultMessage": "!!Invoices", "end": { "column": 3, - "line": 49 + "line": 51 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.headlineInvoices", "start": { "column": 18, - "line": 46 + "line": 48 } }, { "defaultMessage": "!!!Download", "end": { "column": 3, - "line": 53 + "line": 55 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.invoiceDownload", "start": { "column": 19, - "line": 50 + "line": 52 } }, { "defaultMessage": "!!!Could not load user information", "end": { "column": 3, - "line": 57 + "line": 59 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.userInfoRequestFailed", "start": { "column": 25, - "line": 54 + "line": 56 } }, { "defaultMessage": "!!!Try again", "end": { "column": 3, - "line": 61 + "line": 63 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.tryReloadUserInfoRequest", "start": { "column": 28, - "line": 58 + "line": 60 } }, { "defaultMessage": "!!!Delete account", "end": { "column": 3, - "line": 65 + "line": 67 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.deleteAccount", "start": { "column": 17, - "line": 62 + "line": 64 } }, { "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", "end": { "column": 3, - "line": 69 + "line": 71 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.deleteInfo", "start": { "column": 14, - "line": 66 + "line": 68 } }, { "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", "end": { "column": 3, - "line": 73 + "line": 75 }, "file": "src/components/settings/account/AccountDashboard.js", "id": "settings.account.deleteEmailSent", "start": { "column": 19, - "line": 70 + "line": 72 + } + }, + { + "defaultMessage": "!!!Free Trial", + "end": { + "column": 3, + "line": 79 + }, + "file": "src/components/settings/account/AccountDashboard.js", + "id": "settings.account.trial", + "start": { + "column": 9, + "line": 76 + } + }, + { + "defaultMessage": "!!!Your license:", + "end": { + "column": 3, + "line": 83 + }, + "file": "src/components/settings/account/AccountDashboard.js", + "id": "settings.account.yourLicense", + "start": { + "column": 15, + "line": 80 + } + }, + { + "defaultMessage": "!!!Your free trial ends in {duration}.", + "end": { + "column": 3, + "line": 87 + }, + "file": "src/components/settings/account/AccountDashboard.js", + "id": "settings.account.trialEndsIn", + "start": { + "column": 15, + "line": 84 + } + }, + { + "defaultMessage": "!!!Please update your billing info to continue using {license} after your trial period.", + "end": { + "column": 3, + "line": 91 + }, + "file": "src/components/settings/account/AccountDashboard.js", + "id": "settings.account.trialUpdateBillingInfo", + "start": { + "column": 33, + "line": 88 } } ], @@ -2869,6 +2921,24 @@ ], "path": "src/components/subscription/SubscriptionPopup.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!Your trial was successfully activated. Happy messaging!", + "end": { + "column": 3, + "line": 14 + }, + "file": "src/components/TrialActivationInfoBar.js", + "id": "infobar.trialActivated", + "start": { + "column": 11, + "line": 11 + } + } + ], + "path": "src/components/TrialActivationInfoBar.json" + }, { "descriptors": [ { @@ -3578,65 +3648,65 @@ "defaultMessage": "!!!Please purchase license to skip waiting", "end": { "column": 3, - "line": 19 + "line": 20 }, "file": "src/features/delayApp/Component.js", "id": "feature.delayApp.headline", "start": { "column": 12, - "line": 16 + "line": 17 } }, { "defaultMessage": "!!!Get the free Franz Professional 14 day trial and skip the line", "end": { "column": 3, - "line": 23 + "line": 24 }, "file": "src/features/delayApp/Component.js", "id": "feature.delayApp.trial.headline", "start": { "column": 17, - "line": 20 + "line": 21 } }, { "defaultMessage": "!!!Get a Franz Supporter License", "end": { "column": 3, - "line": 27 + "line": 28 }, "file": "src/features/delayApp/Component.js", "id": "feature.delayApp.upgrade.action", "start": { "column": 10, - "line": 24 + "line": 25 } }, { "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", "end": { "column": 3, - "line": 31 + "line": 32 }, "file": "src/features/delayApp/Component.js", "id": "feature.delayApp.trial.action", "start": { "column": 15, - "line": 28 + "line": 29 } }, { "defaultMessage": "!!!Franz will continue in {seconds} seconds.", "end": { "column": 3, - "line": 35 + "line": 36 }, "file": "src/features/delayApp/Component.js", "id": "feature.delayApp.text", "start": { "column": 8, - "line": 32 + "line": 33 } } ], @@ -4181,6 +4251,172 @@ ], "path": "src/features/workspaces/components/WorkspaceSwitchingIndicator.json" }, + { + "descriptors": [ + { + "defaultMessage": "!!!Franz Professional Yearly", + "end": { + "column": 3, + "line": 8 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.pro-yearly", + "start": { + "column": 22, + "line": 5 + } + }, + { + "defaultMessage": "!!!Franz Professional Monthly", + "end": { + "column": 3, + "line": 12 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.pro-monthly", + "start": { + "column": 23, + "line": 9 + } + }, + { + "defaultMessage": "!!!Franz Personal Yearly", + "end": { + "column": 3, + "line": 16 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.personal-yearly", + "start": { + "column": 27, + "line": 13 + } + }, + { + "defaultMessage": "!!!Franz Personal Monthly", + "end": { + "column": 3, + "line": 20 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.personal-monthly", + "start": { + "column": 28, + "line": 17 + } + }, + { + "defaultMessage": "!!!Franz Free", + "end": { + "column": 3, + "line": 24 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.free", + "start": { + "column": 16, + "line": 21 + } + }, + { + "defaultMessage": "!!!Franz Premium", + "end": { + "column": 3, + "line": 28 + }, + "file": "src/helpers/plan-helpers.js", + "id": "pricing.plan.legacy", + "start": { + "column": 18, + "line": 25 + } + } + ], + "path": "src/helpers/plan-helpers.json" + }, + { + "descriptors": [ + { + "defaultMessage": "!!!Franz Professional Yearly", + "end": { + "column": 3, + "line": 8 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.pro-yearly", + "start": { + "column": 22, + "line": 5 + } + }, + { + "defaultMessage": "!!!Franz Professional Monthly", + "end": { + "column": 3, + "line": 12 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.pro-monthly", + "start": { + "column": 23, + "line": 9 + } + }, + { + "defaultMessage": "!!!Franz Personal Yearly", + "end": { + "column": 3, + "line": 16 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.personal-yearly", + "start": { + "column": 27, + "line": 13 + } + }, + { + "defaultMessage": "!!!Franz Personal Monthly", + "end": { + "column": 3, + "line": 20 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.personal-monthly", + "start": { + "column": 28, + "line": 17 + } + }, + { + "defaultMessage": "!!!Franz Free", + "end": { + "column": 3, + "line": 24 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.free", + "start": { + "column": 16, + "line": 21 + } + }, + { + "defaultMessage": "!!!Franz Premium", + "end": { + "column": 3, + "line": 28 + }, + "file": "src/helpers/pricing-helpers.js", + "id": "pricing.plan.legacy", + "start": { + "column": 18, + "line": 25 + } + } + ], + "path": "src/helpers/pricing-helpers.json" + }, { "descriptors": [ { diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 4049e9400..eb0027424 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -4,9 +4,9 @@ "feature.announcements.changelog.headline": "Changes in Franz {version}", "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", "feature.delayApp.text": "Franz will continue in {seconds} seconds.", - "feature.delayApp.trial.action": "!!!Yes, I want the free 14 day trial of Franz Professional", - "feature.delayApp.trial.headline": "!!!Get the free Franz Professional 14 day trial and skip the line", - "feature.delayApp.upgrade.action": "!!!Get a Franz Supporter License", + "feature.delayApp.trial.action": "Yes, I want the free 14 day trial of Franz Professional", + "feature.delayApp.trial.headline": "Get the free Franz Professional 14 day trial and skip the line", + "feature.delayApp.upgrade.action": "Get a Franz Supporter License", "feature.serviceLimit.limitReached": "You have added {amount} out of {limit} services that are included in your plan. Please upgrade your account to add more services.", "feature.shareFranz.action.email": "Send as email", "feature.shareFranz.action.facebook": "Share on Facebook", @@ -30,6 +30,7 @@ "infobar.buttonReloadServices": "Reload services", "infobar.requiredRequestsFailed": "Could not load services and user information", "infobar.servicesUpdated": "Your services have been updated.", + "infobar.trialActivated": "Your trial was successfully activated. Happy messaging!", "infobar.updateAvailable": "A new update for Franz is available.", "invite.email.label": "Email address", "invite.headline.friends": "Invite 3 of your friends or colleagues", @@ -106,25 +107,31 @@ "password.submit.label": "Submit", "password.successInfo": "Please check your email", "premiumFeature.button.upgradeAccount": "Upgrade account", - "pricing.features.adFree": "!!!Forever ad-free", - "pricing.features.appDelays": "!!!No Waiting Screens", - "pricing.features.customWebsites": "!!!Add Custom Websites", - "pricing.features.onPremise": "!!!On-premise & other Hosted Services", - "pricing.features.serviceProxies": "!!!Service Proxies", - "pricing.features.spellchecker": "!!!Spellchecker support", - "pricing.features.teamManagement": "!!!Team Management", - "pricing.features.thirdPartyServices": "!!!Install 3rd party services", - "pricing.features.unlimitedServices": "!!!Add unlimited services", - "pricing.features.workspaces": "!!!Workspaces", - "pricing.trial.cta.accept": "!!!Yes, upgrade my account to Franz Professional", - "pricing.trial.cta.skip": "!!!Continue to Franz", - "pricing.trial.error": "!!!Sorry, we could not activate your trial!", - "pricing.trial.features.headline": "!!!Franz Professional includes:", - "pricing.trial.headline": "!!!Franz Professional", - "pricing.trial.subheadline": "!!!Your personal welcome offer:", - "pricing.trial.terms.automaticTrialEnd": "!!!Your free trial ends automatically after 14 days", - "pricing.trial.terms.headline": "!!!No strings attached", - "pricing.trial.terms.noCreditCard": "!!!No credit card required", + "pricing.features.adFree": "Forever ad-free", + "pricing.features.appDelays": "No Waiting Screens", + "pricing.features.customWebsites": "Add Custom Websites", + "pricing.features.onPremise": "On-premise & other Hosted Services", + "pricing.features.serviceProxies": "Service Proxies", + "pricing.features.spellchecker": "Spellchecker support", + "pricing.features.teamManagement": "Team Management", + "pricing.features.thirdPartyServices": "Install 3rd party services", + "pricing.features.unlimitedServices": "Add unlimited services", + "pricing.features.workspaces": "Workspaces", + "pricing.plan.free": "Franz Free", + "pricing.plan.legacy": "Franz Premium", + "pricing.plan.personal-monthly": "Franz Personal Monthly", + "pricing.plan.personal-yearly": "Franz Personal Yearly", + "pricing.plan.pro-monthly": "Franz Professional Monthly", + "pricing.plan.pro-yearly": "Franz Professional Yearly", + "pricing.trial.cta.accept": "Yes, upgrade my account to Franz Professional", + "pricing.trial.cta.skip": "Continue to Franz", + "pricing.trial.error": "Sorry, we could not activate your trial!", + "pricing.trial.features.headline": "Franz Professional includes:", + "pricing.trial.headline": "Franz Professional", + "pricing.trial.subheadline": "Your personal welcome offer:", + "pricing.trial.terms.automaticTrialEnd": "Your free trial ends automatically after 14 days", + "pricing.trial.terms.headline": "No strings attached", + "pricing.trial.terms.noCreditCard": "No credit card required", "service.crashHandler.action": "Reload {name}", "service.crashHandler.autoReload": "Trying to automatically restore {name} in {seconds} seconds", "service.crashHandler.headline": "Oh no!", @@ -162,9 +169,13 @@ "settings.account.invoiceDownload": "Download", "settings.account.manageSubscription.label": "Manage your subscription", "settings.account.successInfo": "Your changes have been saved", + "settings.account.trial": "Free Trial", + "settings.account.trialEndsIn": "Your free trial ends in {duration}.", + "settings.account.trialUpdateBillingInfo": "Please update your billing info to continue using {license} after your trial period.", "settings.account.tryReloadServices": "Try again", "settings.account.tryReloadUserInfoRequest": "Try again", "settings.account.userInfoRequestFailed": "Could not load user information", + "settings.account.yourLicense": "Your license:", "settings.app.buttonClearAllCache": "Clear cache", "settings.app.buttonInstallUpdate": "Restart & install update", "settings.app.buttonSearchForUpdate": "Check for updates", @@ -358,4 +369,4 @@ "workspaceDrawer.workspaceFeatureInfo": "

Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaceDrawer.workspacesSettingsTooltip": "Edit workspaces settings", "workspaces.switchingIndicator.switchingTo": "Switching to" -} \ No newline at end of file +} diff --git a/src/i18n/messages/src/components/settings/account/AccountDashboard.json b/src/i18n/messages/src/components/settings/account/AccountDashboard.json index 4969db910..1e21bad69 100644 --- a/src/i18n/messages/src/components/settings/account/AccountDashboard.json +++ b/src/i18n/messages/src/components/settings/account/AccountDashboard.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Account", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 14, + "line": 18, "column": 12 }, "end": { - "line": 17, + "line": 21, "column": 3 } }, @@ -17,24 +17,24 @@ "defaultMessage": "!!!Your Subscription", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 18, + "line": 22, "column": 24 }, "end": { - "line": 21, + "line": 25, "column": 3 } }, { - "id": "settings.account.headlineUpgrade", - "defaultMessage": "!!!Upgrade your Account", + "id": "settings.account.headlineTrialUpgrade", + "defaultMessage": "!!!Get the free 14 day Franz Professional Trial", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 22, + "line": 26, "column": 19 }, "end": { - "line": 25, + "line": 29, "column": 3 } }, @@ -43,11 +43,11 @@ "defaultMessage": "!!Danger Zone", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 26, + "line": 30, "column": 22 }, "end": { - "line": 29, + "line": 33, "column": 3 } }, @@ -56,11 +56,11 @@ "defaultMessage": "!!!Manage your subscription", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 30, + "line": 34, "column": 33 }, "end": { - "line": 33, + "line": 37, "column": 3 } }, @@ -69,11 +69,11 @@ "defaultMessage": "!!!Basic Account", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 34, + "line": 38, "column": 20 }, "end": { - "line": 37, + "line": 41, "column": 3 } }, @@ -82,11 +82,11 @@ "defaultMessage": "!!!Premium Supporter Account", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 38, + "line": 42, "column": 22 }, "end": { - "line": 41, + "line": 45, "column": 3 } }, @@ -95,11 +95,11 @@ "defaultMessage": "!!!Edit Account", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 42, + "line": 46, "column": 21 }, "end": { - "line": 45, + "line": 49, "column": 3 } }, @@ -108,11 +108,11 @@ "defaultMessage": "!!Invoices", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 46, + "line": 50, "column": 18 }, "end": { - "line": 49, + "line": 53, "column": 3 } }, @@ -121,11 +121,11 @@ "defaultMessage": "!!!Download", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 50, + "line": 54, "column": 19 }, "end": { - "line": 53, + "line": 57, "column": 3 } }, @@ -134,11 +134,11 @@ "defaultMessage": "!!!Could not load user information", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 54, + "line": 58, "column": 25 }, "end": { - "line": 57, + "line": 61, "column": 3 } }, @@ -147,11 +147,11 @@ "defaultMessage": "!!!Try again", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 58, + "line": 62, "column": 28 }, "end": { - "line": 61, + "line": 65, "column": 3 } }, @@ -160,11 +160,11 @@ "defaultMessage": "!!!Delete account", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 62, + "line": 66, "column": 17 }, "end": { - "line": 65, + "line": 69, "column": 3 } }, @@ -173,11 +173,11 @@ "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 66, + "line": 70, "column": 14 }, "end": { - "line": 69, + "line": 73, "column": 3 } }, @@ -186,11 +186,63 @@ "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", "file": "src/components/settings/account/AccountDashboard.js", "start": { - "line": 70, + "line": 74, "column": 19 }, "end": { - "line": 73, + "line": 77, + "column": 3 + } + }, + { + "id": "settings.account.trial", + "defaultMessage": "!!!Free Trial", + "file": "src/components/settings/account/AccountDashboard.js", + "start": { + "line": 78, + "column": 9 + }, + "end": { + "line": 81, + "column": 3 + } + }, + { + "id": "settings.account.yourLicense", + "defaultMessage": "!!!Your license:", + "file": "src/components/settings/account/AccountDashboard.js", + "start": { + "line": 82, + "column": 15 + }, + "end": { + "line": 85, + "column": 3 + } + }, + { + "id": "settings.account.trialEndsIn", + "defaultMessage": "!!!Your free trial ends in {duration}.", + "file": "src/components/settings/account/AccountDashboard.js", + "start": { + "line": 86, + "column": 15 + }, + "end": { + "line": 89, + "column": 3 + } + }, + { + "id": "settings.account.trialUpdateBillingInfo", + "defaultMessage": "!!!Please update your billing info to continue using {license} after your trial period.", + "file": "src/components/settings/account/AccountDashboard.js", + "start": { + "line": 90, + "column": 33 + }, + "end": { + "line": 93, "column": 3 } } diff --git a/src/i18n/messages/src/components/subscription/SubscriptionForm.json b/src/i18n/messages/src/components/subscription/SubscriptionForm.json index f98eb986f..224a78c4c 100644 --- a/src/i18n/messages/src/components/subscription/SubscriptionForm.json +++ b/src/i18n/messages/src/components/subscription/SubscriptionForm.json @@ -1,7 +1,7 @@ [ { - "id": "subscription.submit.label", - "defaultMessage": "!!!Support the development of Franz", + "id": "subscription.cta.activateTrial", + "defaultMessage": "!!!Yes, upgrade my account to Franz Professional", "file": "src/components/subscription/SubscriptionForm.js", "start": { "line": 14, @@ -13,12 +13,12 @@ } }, { - "id": "subscription.paymentSessionError", - "defaultMessage": "!!!Could not initialize payment form", + "id": "subscription.includedProFeatures", + "defaultMessage": "!!!The Franz Professional Plan includes:", "file": "src/components/subscription/SubscriptionForm.js", "start": { "line": 18, - "column": 23 + "column": 20 }, "end": { "line": 21, @@ -26,12 +26,12 @@ } }, { - "id": "subscription.type.free", - "defaultMessage": "!!!free", + "id": "pricing.trial.terms.headline", + "defaultMessage": "!!!No strings attached", "file": "src/components/subscription/SubscriptionForm.js", "start": { "line": 22, - "column": 12 + "column": 29 }, "end": { "line": 25, @@ -39,12 +39,12 @@ } }, { - "id": "subscription.type.month", - "defaultMessage": "!!!month", + "id": "pricing.trial.terms.noCreditCard", + "defaultMessage": "!!!No credit card required", "file": "src/components/subscription/SubscriptionForm.js", "start": { "line": 26, - "column": 15 + "column": 16 }, "end": { "line": 29, @@ -52,133 +52,16 @@ } }, { - "id": "subscription.type.year", - "defaultMessage": "!!!year", + "id": "pricing.trial.terms.automaticTrialEnd", + "defaultMessage": "!!!Your free trial ends automatically after 14 days", "file": "src/components/subscription/SubscriptionForm.js", "start": { "line": 30, - "column": 14 + "column": 21 }, "end": { "line": 33, "column": 3 } - }, - { - "id": "subscription.includedFeatures", - "defaultMessage": "!!!The Franz Premium Supporter Account includes", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 34, - "column": 20 - }, - "end": { - "line": 37, - "column": 3 - } - }, - { - "id": "subscription.features.onpremise.mattermost", - "defaultMessage": "!!!Add on-premise/hosted services like Mattermost", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 38, - "column": 13 - }, - "end": { - "line": 41, - "column": 3 - } - }, - { - "id": "subscription.features.noInterruptions", - "defaultMessage": "!!!No app delays & nagging to upgrade license", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 42, - "column": 19 - }, - "end": { - "line": 45, - "column": 3 - } - }, - { - "id": "subscription.features.proxy", - "defaultMessage": "!!!Proxy support for services", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 46, - "column": 9 - }, - "end": { - "line": 49, - "column": 3 - } - }, - { - "id": "subscription.features.spellchecker", - "defaultMessage": "!!!Support for Spellchecker", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 50, - "column": 16 - }, - "end": { - "line": 53, - "column": 3 - } - }, - { - "id": "subscription.features.workspaces", - "defaultMessage": "!!!Organize your services in workspaces", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 54, - "column": 14 - }, - "end": { - "line": 57, - "column": 3 - } - }, - { - "id": "subscription.features.ads", - "defaultMessage": "!!!No ads, ever!", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 58, - "column": 7 - }, - "end": { - "line": 61, - "column": 3 - } - }, - { - "id": "subscription.features.comingSoon", - "defaultMessage": "!!!coming soon", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 62, - "column": 14 - }, - "end": { - "line": 65, - "column": 3 - } - }, - { - "id": "subscription.euTaxInfo", - "defaultMessage": "!!!EU residents: local sales tax may apply", - "file": "src/components/subscription/SubscriptionForm.js", - "start": { - "line": 66, - "column": 13 - }, - "end": { - "line": 69, - "column": 3 - } } ] \ No newline at end of file diff --git a/src/i18n/messages/src/helpers/plan-helpers.json b/src/i18n/messages/src/helpers/plan-helpers.json new file mode 100644 index 000000000..de27dfcfd --- /dev/null +++ b/src/i18n/messages/src/helpers/plan-helpers.json @@ -0,0 +1,80 @@ +[ + { + "id": "pricing.plan.pro-yearly", + "defaultMessage": "!!!Franz Professional Yearly", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 5, + "column": 22 + }, + "end": { + "line": 8, + "column": 3 + } + }, + { + "id": "pricing.plan.pro-monthly", + "defaultMessage": "!!!Franz Professional Monthly", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 9, + "column": 23 + }, + "end": { + "line": 12, + "column": 3 + } + }, + { + "id": "pricing.plan.personal-yearly", + "defaultMessage": "!!!Franz Personal Yearly", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 13, + "column": 27 + }, + "end": { + "line": 16, + "column": 3 + } + }, + { + "id": "pricing.plan.personal-monthly", + "defaultMessage": "!!!Franz Personal Monthly", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 20, + "column": 3 + } + }, + { + "id": "pricing.plan.free", + "defaultMessage": "!!!Franz Free", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 21, + "column": 16 + }, + "end": { + "line": 24, + "column": 3 + } + }, + { + "id": "pricing.plan.legacy", + "defaultMessage": "!!!Franz Premium", + "file": "src/helpers/plan-helpers.js", + "start": { + "line": 25, + "column": 18 + }, + "end": { + "line": 28, + "column": 3 + } + } +] \ No newline at end of file diff --git a/src/i18n/messages/src/helpers/pricing-helpers.json b/src/i18n/messages/src/helpers/pricing-helpers.json new file mode 100644 index 000000000..4030a3e3b --- /dev/null +++ b/src/i18n/messages/src/helpers/pricing-helpers.json @@ -0,0 +1,80 @@ +[ + { + "id": "pricing.plan.pro-yearly", + "defaultMessage": "!!!Franz Professional Yearly", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 5, + "column": 22 + }, + "end": { + "line": 8, + "column": 3 + } + }, + { + "id": "pricing.plan.pro-monthly", + "defaultMessage": "!!!Franz Professional Monthly", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 9, + "column": 23 + }, + "end": { + "line": 12, + "column": 3 + } + }, + { + "id": "pricing.plan.personal-yearly", + "defaultMessage": "!!!Franz Personal Yearly", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 13, + "column": 27 + }, + "end": { + "line": 16, + "column": 3 + } + }, + { + "id": "pricing.plan.personal-monthly", + "defaultMessage": "!!!Franz Personal Monthly", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 17, + "column": 28 + }, + "end": { + "line": 20, + "column": 3 + } + }, + { + "id": "pricing.plan.free", + "defaultMessage": "!!!Franz Free", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 21, + "column": 16 + }, + "end": { + "line": 24, + "column": 3 + } + }, + { + "id": "pricing.plan.legacy", + "defaultMessage": "!!!Franz Premium", + "file": "src/helpers/pricing-helpers.js", + "start": { + "line": 25, + "column": 18 + }, + "end": { + "line": 28, + "column": 3 + } + } +] \ No newline at end of file diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index 72c4b4d0b..55ee52b18 100644 --- a/src/stores/AppStore.js +++ b/src/stores/AppStore.js @@ -334,6 +334,8 @@ export default class AppStore extends Store { this.locale = this._getDefaultLocale(); } + moment.locale(this.locale); + debug(`Set locale to "${this.locale}"`); } diff --git a/src/styles/settings.scss b/src/styles/settings.scss index 1baff8b54..0955aaa0c 100644 --- a/src/styles/settings.scss +++ b/src/styles/settings.scss @@ -360,6 +360,7 @@ .account__subscription-button { margin-left: auto; } .franz-form__button { white-space: nowrap; } div { height: auto; } + [data-type="franz-button"] div { height: 100% } .invoices { width: 100%; -- cgit v1.2.3-70-g09d2