aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/auth/Pricing.js122
-rw-r--r--src/components/layout/AppLayout.js4
-rw-r--r--src/components/settings/account/AccountDashboard.js18
-rw-r--r--src/components/subscription/SubscriptionForm.js4
-rw-r--r--src/components/subscription/SubscriptionPopup.js2
-rw-r--r--src/components/subscription/TrialForm.js4
-rw-r--r--src/components/ui/FeatureItem.js1
-rw-r--r--src/components/ui/FeatureList.js74
-rw-r--r--src/components/ui/PremiumFeatureContainer/index.js2
9 files changed, 183 insertions, 48 deletions
diff --git a/src/components/auth/Pricing.js b/src/components/auth/Pricing.js
index aadb18d91..593cb9c4b 100644
--- a/src/components/auth/Pricing.js
+++ b/src/components/auth/Pricing.js
@@ -13,12 +13,20 @@ import { FeatureList } from '../ui/FeatureList';
13 13
14const messages = defineMessages({ 14const messages = defineMessages({
15 headline: { 15 headline: {
16 id: 'pricing.trial.headline', 16 id: 'pricing.trial.headline.pro',
17 defaultMessage: '!!!Franz Professional', 17 defaultMessage: '!!!Hi {name}, welcome to Franz',
18 }, 18 },
19 personalOffer: { 19 specialTreat: {
20 id: 'pricing.trial.subheadline', 20 id: 'pricing.trial.intro.specialTreat',
21 defaultMessage: '!!!Your personal welcome offer:', 21 defaultMessage: '!!!We have a special treat for you.',
22 },
23 tryPro: {
24 id: 'pricing.trial.intro.tryPro',
25 defaultMessage: '!!!Enjoy the full Franz Professional experience completely free for 14 days.',
26 },
27 happyMessaging: {
28 id: 'pricing.trial.intro.happyMessaging',
29 defaultMessage: '!!!Happy messaging,',
22 }, 30 },
23 noStringsAttachedHeadline: { 31 noStringsAttachedHeadline: {
24 id: 'pricing.trial.terms.headline', 32 id: 'pricing.trial.terms.headline',
@@ -32,13 +40,21 @@ const messages = defineMessages({
32 id: 'pricing.trial.terms.automaticTrialEnd', 40 id: 'pricing.trial.terms.automaticTrialEnd',
33 defaultMessage: '!!!Your free trial ends automatically after 14 days', 41 defaultMessage: '!!!Your free trial ends automatically after 14 days',
34 }, 42 },
43 trialWorth: {
44 id: 'pricing.trial.terms.trialWorth',
45 defaultMessage: '!!!Free trial (normally {currency}{price} per month)',
46 },
35 activationError: { 47 activationError: {
36 id: 'pricing.trial.error', 48 id: 'pricing.trial.error',
37 defaultMessage: '!!!Sorry, we could not activate your trial!', 49 defaultMessage: '!!!Sorry, we could not activate your trial!',
38 }, 50 },
39 ctaAccept: { 51 ctaAccept: {
40 id: 'pricing.trial.cta.accept', 52 id: 'pricing.trial.cta.accept',
41 defaultMessage: '!!!Yes, upgrade my account to Franz Professional', 53 defaultMessage: '!!!Start my 14-day Franz Professional Trial ',
54 },
55 ctaStart: {
56 id: 'pricing.trial.cta.start',
57 defaultMessage: '!!!Start using Franz',
42 }, 58 },
43 ctaSkip: { 59 ctaSkip: {
44 id: 'pricing.trial.cta.skip', 60 id: 'pricing.trial.cta.skip',
@@ -58,6 +74,7 @@ const styles = theme => ({
58 welcomeOffer: { 74 welcomeOffer: {
59 textAlign: 'center', 75 textAlign: 'center',
60 fontWeight: 'bold', 76 fontWeight: 'bold',
77 marginBottom: '6 !important',
61 }, 78 },
62 keyTerms: { 79 keyTerms: {
63 textAlign: 'center', 80 textAlign: 'center',
@@ -93,6 +110,34 @@ const styles = theme => ({
93 margin: [20, 0, 0], 110 margin: [20, 0, 0],
94 color: theme.styleTypes.danger.accent, 111 color: theme.styleTypes.danger.accent,
95 }, 112 },
113 priceContainer: {
114 display: 'flex',
115 justifyContent: 'space-evenly',
116 margin: [10, 0, 15],
117 },
118 price: {
119 '& sup': {
120 verticalAlign: 14,
121 fontSize: 20,
122 },
123 },
124 figure: {
125 fontSize: 40,
126 },
127 regularPrice: {
128 position: 'relative',
129
130 '&:before': {
131 content: '" "',
132 position: 'absolute',
133 width: '130%',
134 height: 1,
135 top: 14,
136 left: -12,
137 borderBottom: [3, 'solid', 'red'],
138 transform: 'rotateZ(-20deg)',
139 },
140 },
96}); 141});
97 142
98export default @injectSheet(styles) @observer class Signup extends Component { 143export default @injectSheet(styles) @observer class Signup extends Component {
@@ -101,7 +146,11 @@ export default @injectSheet(styles) @observer class Signup extends Component {
101 isLoadingRequiredData: PropTypes.bool.isRequired, 146 isLoadingRequiredData: PropTypes.bool.isRequired,
102 isActivatingTrial: PropTypes.bool.isRequired, 147 isActivatingTrial: PropTypes.bool.isRequired,
103 trialActivationError: PropTypes.bool.isRequired, 148 trialActivationError: PropTypes.bool.isRequired,
149 canSkipTrial: PropTypes.bool.isRequired,
104 classes: PropTypes.object.isRequired, 150 classes: PropTypes.object.isRequired,
151 currency: PropTypes.string.isRequired,
152 price: PropTypes.number.isRequired,
153 name: PropTypes.string.isRequired,
105 }; 154 };
106 155
107 static contextTypes = { 156 static contextTypes = {
@@ -114,10 +163,16 @@ export default @injectSheet(styles) @observer class Signup extends Component {
114 isLoadingRequiredData, 163 isLoadingRequiredData,
115 isActivatingTrial, 164 isActivatingTrial,
116 trialActivationError, 165 trialActivationError,
166 canSkipTrial,
117 classes, 167 classes,
168 currency,
169 price,
170 name,
118 } = this.props; 171 } = this.props;
119 const { intl } = this.context; 172 const { intl } = this.context;
120 173
174 const [intPart, fractionPart] = (price).toString().split('.');
175
121 return ( 176 return (
122 <div className={classnames('auth__scroll-container', classes.container)}> 177 <div className={classnames('auth__scroll-container', classes.container)}>
123 <div className={classnames('auth__container', 'auth__container--signup', classes.content)}> 178 <div className={classnames('auth__container', 'auth__container--signup', classes.content)}>
@@ -129,30 +184,51 @@ export default @injectSheet(styles) @observer class Signup extends Component {
129 alt="" 184 alt=""
130 /> 185 />
131 )} 186 )}
132 <p className={classes.welcomeOffer}>{intl.formatMessage(messages.personalOffer)}</p> 187 <h1>{intl.formatMessage(messages.headline, { name })}</h1>
133 <h1>{intl.formatMessage(messages.headline)}</h1>
134 <div className="auth__letter"> 188 <div className="auth__letter">
135 <p> 189 <p>
136 We built Franz with a lot of effort, manpower and love, 190 {intl.formatMessage(messages.specialTreat)}
137 to boost up your messaging experience.
138 <br /> 191 <br />
139 </p> 192 </p>
140 <p> 193 <p>
141 Get the free 14 day Franz Professional trial and see your communication evolving. 194 {intl.formatMessage(messages.tryPro)}
142 <br /> 195 <br />
143 </p> 196 </p>
144 <p> 197 <p>
145 Thanks for being a hero. 198 {intl.formatMessage(messages.happyMessaging)}
146 </p> 199 </p>
147 <p> 200 <p>
148 <strong>Stefan Malzner</strong> 201 <strong>Stefan Malzner</strong>
149 </p> 202 </p>
150 </div> 203 </div>
204 <div className={classes.priceContainer}>
205 <p className={classnames(classes.price, classes.regularPrice)}>
206 <span className={classes.figure}>
207 {currency}
208 {intPart}
209 </span>
210 <sup>{fractionPart}</sup>
211 </p>
212 <p className={classnames(classes.price, classes.trialPrice)}>
213 <span className={classes.figure}>
214 {currency}
215 0
216 </span>
217 <sup>00</sup>
218 </p>
219 </div>
151 <div className={classes.keyTerms}> 220 <div className={classes.keyTerms}>
152 <H2> 221 <H2>
153 {intl.formatMessage(messages.noStringsAttachedHeadline)} 222 {intl.formatMessage(messages.noStringsAttachedHeadline)}
154 </H2> 223 </H2>
155 <ul className={classes.keyTermsList}> 224 <ul className={classes.keyTermsList}>
225 <FeatureItem
226 icon="👉"
227 name={intl.formatMessage(messages.trialWorth, {
228 currency,
229 price,
230 })}
231 />
156 <FeatureItem icon="👉" name={intl.formatMessage(messages.noCreditCard)} /> 232 <FeatureItem icon="👉" name={intl.formatMessage(messages.noCreditCard)} />
157 <FeatureItem icon="👉" name={intl.formatMessage(messages.automaticTrialEnd)} /> 233 <FeatureItem icon="👉" name={intl.formatMessage(messages.automaticTrialEnd)} />
158 </ul> 234 </ul>
@@ -161,33 +237,23 @@ export default @injectSheet(styles) @observer class Signup extends Component {
161 <p className={classes.error}>{intl.formatMessage(messages.activationError)}</p> 237 <p className={classes.error}>{intl.formatMessage(messages.activationError)}</p>
162 )} 238 )}
163 <Button 239 <Button
164 label={intl.formatMessage(messages.ctaAccept)} 240 label={intl.formatMessage(!canSkipTrial ? messages.ctaStart : messages.ctaAccept)}
165 className={classes.cta} 241 className={classes.cta}
166 onClick={onSubmit} 242 onClick={onSubmit}
167 busy={isActivatingTrial} 243 busy={isActivatingTrial}
168 disabled={isLoadingRequiredData || isActivatingTrial} 244 disabled={isLoadingRequiredData || isActivatingTrial}
169 /> 245 />
170 <p className={classes.skipLink}> 246 {canSkipTrial && (
171 <a href="#/">{intl.formatMessage(messages.ctaSkip)}</a> 247 <p className={classes.skipLink}>
172 </p> 248 <a href="#/">{intl.formatMessage(messages.ctaSkip)}</a>
249 </p>
250 )}
173 </form> 251 </form>
174 </div> 252 </div>
175 <div className={classes.featureContainer}> 253 <div className={classes.featureContainer}>
176 <H2> 254 <H2>
177 {intl.formatMessage(messages.featuresHeadline)} 255 {intl.formatMessage(messages.featuresHeadline)}
178 </H2> 256 </H2>
179 {/* <ul className={classes.features}>
180 <FeatureItem name="Add unlimited services" className={classes.featureItem} />
181 <FeatureItem name="Spellchecker support" className={classes.featureItem} />
182 <FeatureItem name="Workspaces" className={classes.featureItem} />
183 <FeatureItem name="Add Custom Websites" className={classes.featureItem} />
184 <FeatureItem name="On-premise & other Hosted Services" className={classes.featureItem} />
185 <FeatureItem name="Install 3rd party services" className={classes.featureItem} />
186 <FeatureItem name="Service Proxies" className={classes.featureItem} />
187 <FeatureItem name="Team Management" className={classes.featureItem} />
188 <FeatureItem name="No Waiting Screens" className={classes.featureItem} />
189 <FeatureItem name="Forever ad-free" className={classes.featureItem} />
190 </ul> */}
191 <FeatureList /> 257 <FeatureList />
192 </div> 258 </div>
193 </div> 259 </div>
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index 2b0719f92..80e6daf19 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -19,6 +19,8 @@ import { workspaceStore } from '../../features/workspaces';
19import AppUpdateInfoBar from '../AppUpdateInfoBar'; 19import AppUpdateInfoBar from '../AppUpdateInfoBar';
20import TrialActivationInfoBar from '../TrialActivationInfoBar'; 20import TrialActivationInfoBar from '../TrialActivationInfoBar';
21import Todos from '../../features/todos/containers/TodosScreen'; 21import Todos from '../../features/todos/containers/TodosScreen';
22import PlanSelection from '../../features/planSelection/containers/PlanSelectionScreen';
23import TrialStatusBar from '../../features/trialStatusBar/containers/TrialStatusBarScreen';
22 24
23function createMarkup(HTMLString) { 25function createMarkup(HTMLString) {
24 return { __html: HTMLString }; 26 return { __html: HTMLString };
@@ -189,9 +191,11 @@ class AppLayout extends Component {
189 <QuickSwitch /> 191 <QuickSwitch />
190 {services} 192 {services}
191 {children} 193 {children}
194 <TrialStatusBar />
192 </div> 195 </div>
193 <Todos /> 196 <Todos />
194 </div> 197 </div>
198 <PlanSelection />
195 </div> 199 </div>
196 </ErrorBoundary> 200 </ErrorBoundary>
197 ); 201 );
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js
index f588449f4..83dc34a52 100644
--- a/src/components/settings/account/AccountDashboard.js
+++ b/src/components/settings/account/AccountDashboard.js
@@ -109,6 +109,7 @@ class AccountDashboard extends Component {
109 openBilling: PropTypes.func.isRequired, 109 openBilling: PropTypes.func.isRequired,
110 upgradeToPro: PropTypes.func.isRequired, 110 upgradeToPro: PropTypes.func.isRequired,
111 openInvoices: PropTypes.func.isRequired, 111 openInvoices: PropTypes.func.isRequired,
112 onCloseSubscriptionWindow: PropTypes.func.isRequired,
112 }; 113 };
113 114
114 static contextTypes = { 115 static contextTypes = {
@@ -130,6 +131,7 @@ class AccountDashboard extends Component {
130 openBilling, 131 openBilling,
131 upgradeToPro, 132 upgradeToPro,
132 openInvoices, 133 openInvoices,
134 onCloseSubscriptionWindow,
133 } = this.props; 135 } = this.props;
134 const { intl } = this.context; 136 const { intl } = this.context;
135 137
@@ -215,7 +217,9 @@ class AccountDashboard extends Component {
215 {intl.formatMessage(messages.yourLicense)} 217 {intl.formatMessage(messages.yourLicense)}
216 </H2> 218 </H2>
217 <p> 219 <p>
218 {isPremiumOverrideUser ? 'Franz Premium' : planName} 220 Franz
221 {' '}
222 {isPremiumOverrideUser ? 'Premium' : planName}
219 {user.team.isTrial && ( 223 {user.team.isTrial && (
220 <> 224 <>
221 {' – '} 225 {' – '}
@@ -238,14 +242,16 @@ class AccountDashboard extends Component {
238 </p> 242 </p>
239 </> 243 </>
240 )} 244 )}
241 <div className="manage-user-links"> 245 {!isProUser && (
242 {!isProUser && ( 246 <div className="manage-user-links">
243 <Button 247 <Button
244 label={intl.formatMessage(messages.upgradeAccountToPro)} 248 label={intl.formatMessage(messages.upgradeAccountToPro)}
245 className="franz-form__button--primary" 249 className="franz-form__button--primary"
246 onClick={upgradeToPro} 250 onClick={upgradeToPro}
247 /> 251 />
248 )} 252 </div>
253 )}
254 <div className="manage-user-links">
249 <Button 255 <Button
250 label={intl.formatMessage(messages.manageSubscriptionButtonLabel)} 256 label={intl.formatMessage(messages.manageSubscriptionButtonLabel)}
251 className="franz-form__button--inverted" 257 className="franz-form__button--inverted"
@@ -263,7 +269,9 @@ class AccountDashboard extends Component {
263 {!user.isPremium && ( 269 {!user.isPremium && (
264 <div className="account franz-form"> 270 <div className="account franz-form">
265 <div className="account__box"> 271 <div className="account__box">
266 <SubscriptionForm /> 272 <SubscriptionForm
273 onCloseWindow={onCloseSubscriptionWindow}
274 />
267 </div> 275 </div>
268 </div> 276 </div>
269 )} 277 )}
diff --git a/src/components/subscription/SubscriptionForm.js b/src/components/subscription/SubscriptionForm.js
index effd04f7a..ec486e5d0 100644
--- a/src/components/subscription/SubscriptionForm.js
+++ b/src/components/subscription/SubscriptionForm.js
@@ -30,7 +30,8 @@ const messages = defineMessages({
30 30
31const styles = () => ({ 31const styles = () => ({
32 activateTrialButton: { 32 activateTrialButton: {
33 margin: [40, 0, 50], 33 margin: [40, 'auto', 50],
34 display: 'flex',
34 }, 35 },
35}); 36});
36 37
@@ -62,7 +63,6 @@ export default @injectSheet(styles) @observer class SubscriptionForm extends Com
62 className={classes.activateTrialButton} 63 className={classes.activateTrialButton}
63 busy={isActivatingTrial} 64 busy={isActivatingTrial}
64 onClick={selectPlan} 65 onClick={selectPlan}
65 stretch
66 /> 66 />
67 <div className="subscription__premium-info"> 67 <div className="subscription__premium-info">
68 <H3> 68 <H3>
diff --git a/src/components/subscription/SubscriptionPopup.js b/src/components/subscription/SubscriptionPopup.js
index 12ef8a6e9..12a51ad7b 100644
--- a/src/components/subscription/SubscriptionPopup.js
+++ b/src/components/subscription/SubscriptionPopup.js
@@ -59,8 +59,10 @@ export default @observer class SubscriptionPopup extends Component {
59 className="subscription-popup__webview" 59 className="subscription-popup__webview"
60 60
61 autosize 61 autosize
62 allowpopups
62 src={encodeURI(url)} 63 src={encodeURI(url)}
63 onDidNavigate={completeCheck} 64 onDidNavigate={completeCheck}
65 onDidNavigateInPage={completeCheck}
64 /> 66 />
65 </div> 67 </div>
66 <div className="subscription-popup__toolbar franz-form"> 68 <div className="subscription-popup__toolbar franz-form">
diff --git a/src/components/subscription/TrialForm.js b/src/components/subscription/TrialForm.js
index 6ccdf20ae..d61b779ed 100644
--- a/src/components/subscription/TrialForm.js
+++ b/src/components/subscription/TrialForm.js
@@ -43,7 +43,8 @@ const messages = defineMessages({
43 43
44const styles = theme => ({ 44const styles = theme => ({
45 activateTrialButton: { 45 activateTrialButton: {
46 margin: [40, 0, 10], 46 margin: [40, 'auto', 10],
47 display: 'flex',
47 }, 48 },
48 allOptionsButton: { 49 allOptionsButton: {
49 margin: [0, 0, 40], 50 margin: [0, 0, 40],
@@ -93,7 +94,6 @@ export default @injectSheet(styles) @observer class TrialForm extends Component
93 className={classes.activateTrialButton} 94 className={classes.activateTrialButton}
94 busy={isActivatingTrial} 95 busy={isActivatingTrial}
95 onClick={activateTrial} 96 onClick={activateTrial}
96 stretch
97 /> 97 />
98 <Button 98 <Button
99 label={intl.formatMessage(messages.allOptionsButton)} 99 label={intl.formatMessage(messages.allOptionsButton)}
diff --git a/src/components/ui/FeatureItem.js b/src/components/ui/FeatureItem.js
index 7c482c4d4..4926df470 100644
--- a/src/components/ui/FeatureItem.js
+++ b/src/components/ui/FeatureItem.js
@@ -10,6 +10,7 @@ const styles = theme => ({
10 padding: [8, 0], 10 padding: [8, 0],
11 display: 'flex', 11 display: 'flex',
12 alignItems: 'center', 12 alignItems: 'center',
13 textAlign: 'left',
13 }, 14 },
14 featureIcon: { 15 featureIcon: {
15 fill: theme.brandSuccess, 16 fill: theme.brandSuccess,
diff --git a/src/components/ui/FeatureList.js b/src/components/ui/FeatureList.js
index 62944ad75..7ba8b54d7 100644
--- a/src/components/ui/FeatureList.js
+++ b/src/components/ui/FeatureList.js
@@ -3,12 +3,33 @@ 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';
6 7
7const messages = defineMessages({ 8const messages = defineMessages({
9 availableRecipes: {
10 id: 'pricing.features.recipes',
11 defaultMessage: '!!!Choose from more than 70 Services',
12 },
13 accountSync: {
14 id: 'pricing.features.accountSync',
15 defaultMessage: '!!!Account Synchronisation',
16 },
17 desktopNotifications: {
18 id: 'pricing.features.desktopNotifications',
19 defaultMessage: '!!!Desktop Notifications',
20 },
8 unlimitedServices: { 21 unlimitedServices: {
9 id: 'pricing.features.unlimitedServices', 22 id: 'pricing.features.unlimitedServices',
10 defaultMessage: '!!!Add unlimited services', 23 defaultMessage: '!!!Add unlimited services',
11 }, 24 },
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 },
12 spellchecker: { 33 spellchecker: {
13 id: 'pricing.features.spellchecker', 34 id: 'pricing.features.spellchecker',
14 defaultMessage: '!!!Spellchecker support', 35 defaultMessage: '!!!Spellchecker support',
@@ -51,11 +72,13 @@ export class FeatureList extends Component {
51 static propTypes = { 72 static propTypes = {
52 className: PropTypes.string, 73 className: PropTypes.string,
53 featureClassName: PropTypes.string, 74 featureClassName: PropTypes.string,
75 plan: PropTypes.oneOf(PLANS),
54 }; 76 };
55 77
56 static defaultProps = { 78 static defaultProps = {
57 className: '', 79 className: '',
58 featureClassName: '', 80 featureClassName: '',
81 plan: false,
59 } 82 }
60 83
61 static contextTypes = { 84 static contextTypes = {
@@ -66,21 +89,52 @@ export class FeatureList extends Component {
66 const { 89 const {
67 className, 90 className,
68 featureClassName, 91 featureClassName,
92 plan,
69 } = this.props; 93 } = this.props;
70 const { intl } = this.context; 94 const { intl } = this.context;
71 95
96 const features = [];
97 if (plan === PLANS.FREE) {
98 features.push(
99 messages.upToThreeServices,
100 messages.availableRecipes,
101 messages.accountSync,
102 messages.desktopNotifications,
103 );
104 } else if (plan === PLANS.PERSONAL) {
105 features.push(
106 messages.upToSixServices,
107 messages.spellchecker,
108 messages.appDelays,
109 messages.adFree,
110 );
111 } else if (plan === PLANS.PRO) {
112 features.push(
113 messages.unlimitedServices,
114 messages.workspaces,
115 messages.customWebsites,
116 // messages.onPremise,
117 messages.thirdPartyServices,
118 // messages.serviceProxies,
119 );
120 } else {
121 features.push(
122 messages.unlimitedServices,
123 messages.spellchecker,
124 messages.workspaces,
125 messages.customWebsites,
126 messages.onPremise,
127 messages.thirdPartyServices,
128 messages.serviceProxies,
129 messages.teamManagement,
130 messages.appDelays,
131 messages.adFree,
132 );
133 }
134
72 return ( 135 return (
73 <ul className={className}> 136 <ul className={className}>
74 <FeatureItem name={intl.formatMessage(messages.unlimitedServices)} className={featureClassName} /> 137 {features.map(feature => <FeatureItem name={intl.formatMessage(feature)} className={featureClassName} />)}
75 <FeatureItem name={intl.formatMessage(messages.spellchecker)} className={featureClassName} />
76 <FeatureItem name={intl.formatMessage(messages.workspaces)} className={featureClassName} />
77 <FeatureItem name={intl.formatMessage(messages.customWebsites)} className={featureClassName} />
78 <FeatureItem name={intl.formatMessage(messages.onPremise)} className={featureClassName} />
79 <FeatureItem name={intl.formatMessage(messages.thirdPartyServices)} className={featureClassName} />
80 <FeatureItem name={intl.formatMessage(messages.serviceProxies)} className={featureClassName} />
81 <FeatureItem name={intl.formatMessage(messages.teamManagement)} className={featureClassName} />
82 <FeatureItem name={intl.formatMessage(messages.appDelays)} className={featureClassName} />
83 <FeatureItem name={intl.formatMessage(messages.adFree)} className={featureClassName} />
84 </ul> 138 </ul>
85 ); 139 );
86 } 140 }
diff --git a/src/components/ui/PremiumFeatureContainer/index.js b/src/components/ui/PremiumFeatureContainer/index.js
index 7ba353be3..611c50468 100644
--- a/src/components/ui/PremiumFeatureContainer/index.js
+++ b/src/components/ui/PremiumFeatureContainer/index.js
@@ -90,7 +90,7 @@ PremiumFeatureContainer.wrappedComponent.propTypes = {
90 children: oneOrManyChildElements.isRequired, 90 children: oneOrManyChildElements.isRequired,
91 stores: PropTypes.shape({ 91 stores: PropTypes.shape({
92 user: PropTypes.instanceOf(UserStore).isRequired, 92 user: PropTypes.instanceOf(UserStore).isRequired,
93 features: PropTypes.instanceOf(FeatureStore).isRequired, 93 features: PropTypes.instanceOf(FeaturesStore).isRequired,
94 }).isRequired, 94 }).isRequired,
95 actions: PropTypes.shape({ 95 actions: PropTypes.shape({
96 ui: PropTypes.shape({ 96 ui: PropTypes.shape({