aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/ui
diff options
context:
space:
mode:
authorLibravatar Vijay A <avijayr@protonmail.com>2021-07-17 20:32:22 +0530
committerLibravatar Vijay Raghavan Aravamudhan <vraravam@users.noreply.github.com>2021-07-20 16:02:15 +0000
commit45373f655f68fdd0b320cde175b6108454ad4731 (patch)
treec1ccb0c73639d754b68a36a1977b74471fe4b566 /src/components/ui
parentNew Crowdin updates (#1668) (diff)
downloadferdium-app-45373f655f68fdd0b320cde175b6108454ad4731.tar.gz
ferdium-app-45373f655f68fdd0b320cde175b6108454ad4731.tar.zst
ferdium-app-45373f655f68fdd0b320cde175b6108454ad4731.zip
Removed Franz paid plans features:
- serviceLimit - planSelection - trialStatusBar and other Franz features that were for different tiers of subscription.
Diffstat (limited to 'src/components/ui')
-rw-r--r--src/components/ui/ActivateTrialButton/index.js107
-rw-r--r--src/components/ui/FeatureList.js81
-rw-r--r--src/components/ui/PremiumFeatureContainer/index.js101
-rw-r--r--src/components/ui/PremiumFeatureContainer/styles.js34
-rw-r--r--src/components/ui/UpgradeButton/index.js83
5 files changed, 17 insertions, 389 deletions
diff --git a/src/components/ui/ActivateTrialButton/index.js b/src/components/ui/ActivateTrialButton/index.js
deleted file mode 100644
index 8f4d21f64..000000000
--- a/src/components/ui/ActivateTrialButton/index.js
+++ /dev/null
@@ -1,107 +0,0 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { inject, observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl';
5import classnames from 'classnames';
6
7import { Button } from '@meetfranz/forms';
8
9import UserStore from '../../../stores/UserStore';
10import UIStore from '../../../stores/UIStore';
11
12const messages = defineMessages({
13 action: {
14 id: 'feature.delayApp.upgrade.action',
15 defaultMessage: '!!!Get a Franz Supporter License',
16 },
17 actionTrial: {
18 id: 'feature.delayApp.trial.action',
19 defaultMessage: '!!!Yes, I want the free 14 day trial of Franz Professional',
20 },
21 shortAction: {
22 id: 'feature.delayApp.upgrade.actionShort',
23 defaultMessage: '!!!Upgrade account',
24 },
25 shortActionTrial: {
26 id: 'feature.delayApp.trial.actionShort',
27 defaultMessage: '!!!Activate the free Franz Professional trial',
28 },
29 noStringsAttachedHeadline: {
30 id: 'pricing.trial.terms.headline',
31 defaultMessage: '!!!No strings attached',
32 },
33 noCreditCard: {
34 id: 'pricing.trial.terms.noCreditCard',
35 defaultMessage: '!!!No credit card required',
36 },
37 automaticTrialEnd: {
38 id: 'pricing.trial.terms.automaticTrialEnd',
39 defaultMessage: '!!!Your free trial ends automatically after 14 days',
40 },
41});
42
43@inject('stores', 'actions') @observer
44class ActivateTrialButton extends Component {
45 static propTypes = {
46 className: PropTypes.string,
47 short: PropTypes.bool,
48 gaEventInfo: PropTypes.shape({
49 category: PropTypes.string.isRequired,
50 event: PropTypes.string.isRequired,
51 label: PropTypes.string,
52 }),
53 };
54
55 static defaultProps = {
56 className: '',
57 short: false,
58 gaEventInfo: null,
59 }
60
61 static contextTypes = {
62 intl: intlShape,
63 };
64
65 handleCTAClick() {
66 const { actions } = this.props;
67
68 actions.ui.openSettings({ path: 'user' });
69 }
70
71 render() {
72 const { stores, className, short } = this.props;
73 const { intl } = this.context;
74
75 const { hadSubscription } = stores.user.data;
76
77 let label;
78 if (hadSubscription) {
79 label = short ? messages.shortAction : messages.action;
80 } else {
81 label = short ? messages.shortActionTrial : messages.actionTrial;
82 }
83
84 return (
85 <Button
86 label={intl.formatMessage(label)}
87 className={classnames({
88 [className]: className,
89 })}
90 buttonType="inverted"
91 onClick={this.handleCTAClick.bind(this)}
92 busy={stores.user.activateTrialRequest.isExecuting}
93 />
94 );
95 }
96}
97
98export default ActivateTrialButton;
99
100ActivateTrialButton.wrappedComponent.propTypes = {
101 stores: PropTypes.shape({
102 user: PropTypes.instanceOf(UserStore).isRequired,
103 }).isRequired,
104 actions: PropTypes.shape({
105 ui: PropTypes.instanceOf(UIStore).isRequired,
106 }).isRequired,
107};
diff --git a/src/components/ui/FeatureList.js b/src/components/ui/FeatureList.js
index 72c799819..ada15244b 100644
--- a/src/components/ui/FeatureList.js
+++ b/src/components/ui/FeatureList.js
@@ -3,12 +3,11 @@ import PropTypes from 'prop-types';
3import { defineMessages, intlShape } from 'react-intl'; 3import { defineMessages, intlShape } from 'react-intl';
4 4
5import { FeatureItem } from './FeatureItem'; 5import { FeatureItem } from './FeatureItem';
6import { PLANS } from '../../config';
7 6
8const messages = defineMessages({ 7const messages = defineMessages({
9 availableRecipes: { 8 availableRecipes: {
10 id: 'pricing.features.recipes', 9 id: 'pricing.features.recipes',
11 defaultMessage: '!!!Choose from more than 70 Services', 10 defaultMessage: '!!!Choose from more than 70 Services', // TODO: Make this dynamic
12 }, 11 },
13 accountSync: { 12 accountSync: {
14 id: 'pricing.features.accountSync', 13 id: 'pricing.features.accountSync',
@@ -22,14 +21,6 @@ const messages = defineMessages({
22 id: 'pricing.features.unlimitedServices', 21 id: 'pricing.features.unlimitedServices',
23 defaultMessage: '!!!Add unlimited services', 22 defaultMessage: '!!!Add unlimited services',
24 }, 23 },
25 upToThreeServices: {
26 id: 'pricing.features.upToThreeServices',
27 defaultMessage: '!!!Add up to 3 services',
28 },
29 upToSixServices: {
30 id: 'pricing.features.upToSixServices',
31 defaultMessage: '!!!Add up to 6 services',
32 },
33 spellchecker: { 24 spellchecker: {
34 id: 'pricing.features.spellchecker', 25 id: 'pricing.features.spellchecker',
35 defaultMessage: '!!!Spellchecker support', 26 defaultMessage: '!!!Spellchecker support',
@@ -58,31 +49,17 @@ const messages = defineMessages({
58 id: 'pricing.features.teamManagement', 49 id: 'pricing.features.teamManagement',
59 defaultMessage: '!!!Team Management', 50 defaultMessage: '!!!Team Management',
60 }, 51 },
61 appDelays: {
62 id: 'pricing.features.appDelays',
63 defaultMessage: '!!!No Waiting Screens',
64 },
65 adFree: {
66 id: 'pricing.features.adFree',
67 defaultMessage: '!!!Forever ad-free',
68 },
69 appDelayEnabled: {
70 id: 'pricing.features.appDelaysEnabled',
71 defaultMessage: '!!!Occasional Waiting Screens',
72 },
73}); 52});
74 53
75export class FeatureList extends Component { 54export class FeatureList extends Component {
76 static propTypes = { 55 static propTypes = {
77 className: PropTypes.string, 56 className: PropTypes.string,
78 featureClassName: PropTypes.string, 57 featureClassName: PropTypes.string,
79 plan: PropTypes.oneOf(Object.keys(PLANS)),
80 }; 58 };
81 59
82 static defaultProps = { 60 static defaultProps = {
83 className: '', 61 className: '',
84 featureClassName: '', 62 featureClassName: '',
85 plan: false,
86 } 63 }
87 64
88 static contextTypes = { 65 static contextTypes = {
@@ -93,49 +70,25 @@ export class FeatureList extends Component {
93 const { 70 const {
94 className, 71 className,
95 featureClassName, 72 featureClassName,
96 plan,
97 } = this.props; 73 } = this.props;
98 const { intl } = this.context; 74 const { intl } = this.context;
99 75
100 const features = []; 76 const features = [
101 if (plan === PLANS.FREE) { 77 messages.availableRecipes,
102 features.push( 78 messages.accountSync,
103 messages.appDelayEnabled, 79 messages.desktopNotifications,
104 messages.upToThreeServices, 80
105 messages.availableRecipes, 81 messages.spellchecker,
106 messages.accountSync, 82
107 messages.desktopNotifications, 83 messages.workspaces,
108 ); 84 messages.customWebsites,
109 } else if (plan === PLANS.PERSONAL) { 85 messages.thirdPartyServices,
110 features.push( 86
111 messages.upToSixServices, 87 messages.unlimitedServices,
112 messages.spellchecker, 88 messages.onPremise,
113 messages.appDelays, 89 messages.serviceProxies,
114 messages.adFree, 90 messages.teamManagement,
115 ); 91 ];
116 } else if (plan === PLANS.PRO) {
117 features.push(
118 messages.unlimitedServices,
119 messages.workspaces,
120 messages.customWebsites,
121 // messages.onPremise,
122 messages.thirdPartyServices,
123 // messages.serviceProxies,
124 );
125 } else {
126 features.push(
127 messages.unlimitedServices,
128 messages.spellchecker,
129 messages.workspaces,
130 messages.customWebsites,
131 messages.onPremise,
132 messages.thirdPartyServices,
133 messages.serviceProxies,
134 messages.teamManagement,
135 messages.appDelays,
136 messages.adFree,
137 );
138 }
139 92
140 return ( 93 return (
141 <ul className={className}> 94 <ul className={className}>
diff --git a/src/components/ui/PremiumFeatureContainer/index.js b/src/components/ui/PremiumFeatureContainer/index.js
deleted file mode 100644
index 1e100f9d8..000000000
--- a/src/components/ui/PremiumFeatureContainer/index.js
+++ /dev/null
@@ -1,101 +0,0 @@
1import React, { Component } from 'react';
2import { inject, observer } from 'mobx-react';
3import PropTypes from 'prop-types';
4import { defineMessages, intlShape } from 'react-intl';
5import injectSheet from 'react-jss';
6
7import { oneOrManyChildElements } from '../../../prop-types';
8
9import UserStore from '../../../stores/UserStore';
10
11import styles from './styles';
12import FeaturesStore from '../../../stores/FeaturesStore';
13import UIStore from '../../../stores/UIStore';
14
15const messages = defineMessages({
16 action: {
17 id: 'premiumFeature.button.upgradeAccount',
18 defaultMessage: '!!!Upgrade account',
19 },
20});
21
22@inject('stores', 'actions') @injectSheet(styles) @observer
23class PremiumFeatureContainer extends Component {
24 static propTypes = {
25 classes: PropTypes.object.isRequired,
26 condition: PropTypes.oneOfType([
27 PropTypes.bool,
28 PropTypes.func,
29 ]),
30 gaEventInfo: PropTypes.shape({
31 category: PropTypes.string.isRequired,
32 event: PropTypes.string.isRequired,
33 label: PropTypes.string,
34 }),
35 };
36
37 static defaultProps = {
38 condition: null,
39 gaEventInfo: null,
40 };
41
42 static contextTypes = {
43 intl: intlShape,
44 };
45
46 render() {
47 const {
48 classes,
49 children,
50 actions,
51 condition,
52 stores,
53 } = this.props;
54
55 const { intl } = this.context;
56
57 let showWrapper = !!condition;
58
59 if (condition === null) {
60 showWrapper = !stores.user.data.isPremium;
61 } else if (typeof condition === 'function') {
62 showWrapper = condition({
63 isPremium: stores.user.data.isPremium,
64 features: stores.features.features,
65 });
66 }
67
68 return showWrapper ? (
69 <div className={classes.container}>
70 <div className={classes.titleContainer}>
71 <p className={classes.title}>Premium Feature</p>
72 <button
73 className={classes.actionButton}
74 type="button"
75 onClick={() => {
76 actions.ui.openSettings({ path: 'user' });
77 }}
78 >
79 {intl.formatMessage(messages.action)}
80 </button>
81 </div>
82 <div className={classes.content}>
83 {children}
84 </div>
85 </div>
86 ) : children;
87 }
88}
89
90PremiumFeatureContainer.wrappedComponent.propTypes = {
91 children: oneOrManyChildElements.isRequired,
92 stores: PropTypes.shape({
93 user: PropTypes.instanceOf(UserStore).isRequired,
94 features: PropTypes.instanceOf(FeaturesStore).isRequired,
95 }).isRequired,
96 actions: PropTypes.shape({
97 ui: PropTypes.instanceOf(UIStore).isRequired,
98 }).isRequired,
99};
100
101export default PremiumFeatureContainer;
diff --git a/src/components/ui/PremiumFeatureContainer/styles.js b/src/components/ui/PremiumFeatureContainer/styles.js
deleted file mode 100644
index 41881e044..000000000
--- a/src/components/ui/PremiumFeatureContainer/styles.js
+++ /dev/null
@@ -1,34 +0,0 @@
1export default theme => ({
2 container: {
3 background: theme.colorSubscriptionContainerBackground,
4 border: theme.colorSubscriptionContainerBorder,
5 margin: [0, 0, 20, -20],
6 padding: 20,
7 'border-radius': theme.borderRadius,
8 pointerEvents: 'none',
9 height: 'auto',
10 },
11 titleContainer: {
12 display: 'flex',
13 },
14 title: {
15 'font-weight': 'bold',
16 color: theme.colorSubscriptionContainerTitle,
17 },
18 actionButton: {
19 background: theme.colorSubscriptionContainerActionButtonBackground,
20 color: theme.colorSubscriptionContainerActionButtonColor,
21 'margin-left': 'auto',
22 'border-radius': theme.borderRadiusSmall,
23 padding: [4, 8],
24 'font-size': 12,
25 pointerEvents: 'initial',
26 },
27 content: {
28 opacity: 0.5,
29 'margin-top': 20,
30 '& > :last-child': {
31 'margin-bottom': 0,
32 },
33 },
34});
diff --git a/src/components/ui/UpgradeButton/index.js b/src/components/ui/UpgradeButton/index.js
deleted file mode 100644
index eade46cfd..000000000
--- a/src/components/ui/UpgradeButton/index.js
+++ /dev/null
@@ -1,83 +0,0 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { inject, observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl';
5
6import { Button } from '@meetfranz/forms';
7
8import UserStore from '../../../stores/UserStore';
9import ActivateTrialButton from '../ActivateTrialButton';
10import UIStore from '../../../stores/UIStore';
11
12const messages = defineMessages({
13 upgradeToPro: {
14 id: 'global.upgradeButton.upgradeToPro',
15 defaultMessage: '!!!Upgrade to Franz Professional',
16 },
17});
18
19@inject('stores', 'actions') @observer
20class UpgradeButton extends Component {
21 static propTypes = {
22 // eslint-disable-next-line
23 classes: PropTypes.object.isRequired,
24 className: PropTypes.string,
25 gaEventInfo: PropTypes.shape({
26 category: PropTypes.string.isRequired,
27 event: PropTypes.string.isRequired,
28 label: PropTypes.string,
29 }),
30 requiresPro: PropTypes.bool,
31 };
32
33 static defaultProps = {
34 className: '',
35 gaEventInfo: null,
36 requiresPro: false,
37 }
38
39 static contextTypes = {
40 intl: intlShape,
41 };
42
43 handleCTAClick() {
44 const { actions } = this.props;
45
46 actions.ui.openSettings({ path: 'user' });
47 }
48
49 render() {
50 const { stores, requiresPro } = this.props;
51 const { intl } = this.context;
52
53 const { isPremium, isPersonal } = stores.user;
54
55 if (isPremium && isPersonal && requiresPro) {
56 return (
57 <Button
58 label={intl.formatMessage(messages.upgradeToPro)}
59 onClick={this.handleCTAClick.bind(this)}
60 className={this.props.className}
61 buttonType="inverted"
62 />
63 );
64 }
65
66 if (!isPremium) {
67 return <ActivateTrialButton {...this.props} />;
68 }
69
70 return null;
71 }
72}
73
74export default UpgradeButton;
75
76UpgradeButton.wrappedComponent.propTypes = {
77 stores: PropTypes.shape({
78 user: PropTypes.instanceOf(UserStore).isRequired,
79 }).isRequired,
80 actions: PropTypes.shape({
81 ui: PropTypes.instanceOf(UIStore).isRequired,
82 }).isRequired,
83};