aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2019-08-05 13:24:35 +0200
committerLibravatar Stefan Malzner <stefan@adlk.io>2019-08-05 13:24:35 +0200
commit76559f2895012803aed3256ce521b9cfff2f63b8 (patch)
treef511ed44ab8cb16af257e58ff960da1fd60c5876 /src/components
parentAdd trial onboarding during signup (diff)
downloadferdium-app-76559f2895012803aed3256ce521b9cfff2f63b8.tar.gz
ferdium-app-76559f2895012803aed3256ce521b9cfff2f63b8.tar.zst
ferdium-app-76559f2895012803aed3256ce521b9cfff2f63b8.zip
WIP: add option to activate trial
Diffstat (limited to 'src/components')
-rw-r--r--src/components/TrialActivationInfoBar.js94
-rw-r--r--src/components/layout/AppLayout.js37
-rw-r--r--src/components/services/content/Services.js61
-rw-r--r--src/components/settings/account/AccountDashboard.js134
-rw-r--r--src/components/settings/settings/EditSettingsForm.js2
5 files changed, 226 insertions, 102 deletions
diff --git a/src/components/TrialActivationInfoBar.js b/src/components/TrialActivationInfoBar.js
new file mode 100644
index 000000000..acdf51d08
--- /dev/null
+++ b/src/components/TrialActivationInfoBar.js
@@ -0,0 +1,94 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { defineMessages, intlShape } from 'react-intl';
4import ms from 'ms';
5import injectSheet from 'react-jss';
6import classnames from 'classnames';
7
8import InfoBar from './ui/InfoBar';
9
10const messages = defineMessages({
11 message: {
12 id: 'infobar.trialActivated',
13 defaultMessage: '!!!Your trial was successfully activated. Happy messaging!',
14 },
15});
16
17const styles = {
18 notification: {
19 height: 'auto',
20 position: 'absolute',
21 top: -50,
22 transition: 'top 0.3s',
23 zIndex: 300,
24 width: 'calc(100% - 300px)',
25 },
26 show: {
27 top: 0,
28 },
29};
30
31@injectSheet(styles)
32class TrialActivationInfoBar extends Component {
33 static propTypes = {
34 // eslint-disable-next-line
35 classes: PropTypes.object.isRequired,
36 };
37
38 static contextTypes = {
39 intl: intlShape,
40 };
41
42 state = {
43 showing: false,
44 removed: false,
45 }
46
47 componentDidMount() {
48 setTimeout(() => {
49 this.setState({
50 showing: true,
51 });
52 }, 0);
53
54 setTimeout(() => {
55 this.setState({
56 showing: false,
57 });
58 }, ms('6s'));
59
60 setTimeout(() => {
61 this.setState({
62 removed: true,
63 });
64 }, ms('7s'));
65 }
66
67 render() {
68 const { classes } = this.props;
69 const { showing, removed } = this.state;
70 const { intl } = this.context;
71
72 if (removed) return null;
73
74 return (
75 <div
76 className={classnames({
77 [classes.notification]: true,
78 [classes.show]: showing,
79 })}
80 >
81 <InfoBar
82 type="primary"
83 position="top"
84 sticky
85 >
86 <span className="mdi mdi-information" />
87 {intl.formatMessage(messages.message)}
88 </InfoBar>
89 </div>
90 );
91 }
92}
93
94export default TrialActivationInfoBar;
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index ebb9849ea..1976f5a50 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -17,6 +17,7 @@ import { isWindows } from '../../environment';
17import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator'; 17import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator';
18import { workspaceStore } from '../../features/workspaces'; 18import { workspaceStore } from '../../features/workspaces';
19import AppUpdateInfoBar from '../AppUpdateInfoBar'; 19import AppUpdateInfoBar from '../AppUpdateInfoBar';
20import TrialActivationInfoBar from '../TrialActivationInfoBar';
20 21
21function createMarkup(HTMLString) { 22function createMarkup(HTMLString) {
22 return { __html: HTMLString }; 23 return { __html: HTMLString };
@@ -57,7 +58,6 @@ class AppLayout extends Component {
57 services: PropTypes.element.isRequired, 58 services: PropTypes.element.isRequired,
58 children: PropTypes.element, 59 children: PropTypes.element,
59 news: MobxPropTypes.arrayOrObservableArray.isRequired, 60 news: MobxPropTypes.arrayOrObservableArray.isRequired,
60 // isOnline: PropTypes.bool.isRequired,
61 showServicesUpdatedInfoBar: PropTypes.bool.isRequired, 61 showServicesUpdatedInfoBar: PropTypes.bool.isRequired,
62 appUpdateIsDownloaded: PropTypes.bool.isRequired, 62 appUpdateIsDownloaded: PropTypes.bool.isRequired,
63 nextAppReleaseVersion: PropTypes.string, 63 nextAppReleaseVersion: PropTypes.string,
@@ -69,6 +69,7 @@ class AppLayout extends Component {
69 retryRequiredRequests: PropTypes.func.isRequired, 69 retryRequiredRequests: PropTypes.func.isRequired,
70 areRequiredRequestsLoading: PropTypes.bool.isRequired, 70 areRequiredRequestsLoading: PropTypes.bool.isRequired,
71 isDelayAppScreenVisible: PropTypes.bool.isRequired, 71 isDelayAppScreenVisible: PropTypes.bool.isRequired,
72 hasActivatedTrial: PropTypes.bool.isRequired,
72 }; 73 };
73 74
74 static defaultProps = { 75 static defaultProps = {
@@ -88,7 +89,6 @@ class AppLayout extends Component {
88 sidebar, 89 sidebar,
89 services, 90 services,
90 children, 91 children,
91 // isOnline,
92 news, 92 news,
93 showServicesUpdatedInfoBar, 93 showServicesUpdatedInfoBar,
94 appUpdateIsDownloaded, 94 appUpdateIsDownloaded,
@@ -101,6 +101,7 @@ class AppLayout extends Component {
101 retryRequiredRequests, 101 retryRequiredRequests,
102 areRequiredRequestsLoading, 102 areRequiredRequestsLoading,
103 isDelayAppScreenVisible, 103 isDelayAppScreenVisible,
104 hasActivatedTrial,
104 } = this.props; 105 } = this.props;
105 106
106 const { intl } = this.context; 107 const { intl } = this.context;
@@ -125,26 +126,20 @@ class AppLayout extends Component {
125 <span dangerouslySetInnerHTML={createMarkup(item.message)} /> 126 <span dangerouslySetInnerHTML={createMarkup(item.message)} />
126 </InfoBar> 127 </InfoBar>
127 ))} 128 ))}
128 {/* {!isOnline && ( 129 {hasActivatedTrial && (
129 <InfoBar 130 <TrialActivationInfoBar />
130 type="danger" 131 )}
131 sticky
132 >
133 <span className="mdi mdi-flash" />
134 {intl.formatMessage(globalMessages.notConnectedToTheInternet)}
135 </InfoBar>
136 )} */}
137 {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( 132 {!areRequiredRequestsSuccessful && showRequiredRequestsError && (
138 <InfoBar 133 <InfoBar
139 type="danger" 134 type="danger"
140 ctaLabel="Try again" 135 ctaLabel="Try again"
141 ctaLoading={areRequiredRequestsLoading} 136 ctaLoading={areRequiredRequestsLoading}
142 sticky 137 sticky
143 onClick={retryRequiredRequests} 138 onClick={retryRequiredRequests}
144 > 139 >
145 <span className="mdi mdi-flash" /> 140 <span className="mdi mdi-flash" />
146 {intl.formatMessage(messages.requiredRequestsFailed)} 141 {intl.formatMessage(messages.requiredRequestsFailed)}
147 </InfoBar> 142 </InfoBar>
148 )} 143 )}
149 {showServicesUpdatedInfoBar && ( 144 {showServicesUpdatedInfoBar && (
150 <InfoBar 145 <InfoBar
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js
index 7f1624003..b71ddd8e6 100644
--- a/src/components/services/content/Services.js
+++ b/src/components/services/content/Services.js
@@ -26,7 +26,8 @@ const styles = {
26 confettiContainer: { 26 confettiContainer: {
27 position: 'absolute', 27 position: 'absolute',
28 width: '100%', 28 width: '100%',
29 zIndex: 0, 29 zIndex: 9999,
30 pointerEvents: 'none',
30 }, 31 },
31}; 32};
32 33
@@ -41,6 +42,7 @@ export default @observer @injectSheet(styles) class Services extends Component {
41 openSettings: PropTypes.func.isRequired, 42 openSettings: PropTypes.func.isRequired,
42 update: PropTypes.func.isRequired, 43 update: PropTypes.func.isRequired,
43 userHasCompletedSignup: PropTypes.bool.isRequired, 44 userHasCompletedSignup: PropTypes.bool.isRequired,
45 hasActivatedTrial: PropTypes.bool.isRequired,
44 classes: PropTypes.object.isRequired, 46 classes: PropTypes.object.isRequired,
45 }; 47 };
46 48
@@ -75,6 +77,7 @@ export default @observer @injectSheet(styles) class Services extends Component {
75 openSettings, 77 openSettings,
76 update, 78 update,
77 userHasCompletedSignup, 79 userHasCompletedSignup,
80 hasActivatedTrial,
78 classes, 81 classes,
79 } = this.props; 82 } = this.props;
80 83
@@ -84,37 +87,37 @@ export default @observer @injectSheet(styles) class Services extends Component {
84 87
85 const { intl } = this.context; 88 const { intl } = this.context;
86 89
90 console.log('hasActivatedTrial', hasActivatedTrial, (userHasCompletedSignup || hasActivatedTrial));
91
87 return ( 92 return (
88 <div className="services"> 93 <div className="services">
94 {(userHasCompletedSignup || hasActivatedTrial) && (
95 <div className={classes.confettiContainer}>
96 <Confetti
97 width={window.width}
98 height={window.height}
99 numberOfPieces={showConfetti ? 200 : 0}
100 />
101 </div>
102 )}
89 {services.length === 0 && ( 103 {services.length === 0 && (
90 <> 104 <Appear
91 {userHasCompletedSignup && ( 105 timeout={1500}
92 <div className={classes.confettiContainer}> 106 transitionName="slideUp"
93 <Confetti 107 >
94 width={window.width} 108 <div className="services__no-service">
95 height={window.height} 109 <img src="./assets/images/logo.svg" alt="" />
96 numberOfPieces={showConfetti ? 200 : 0} 110 <h1>{intl.formatMessage(messages.welcome)}</h1>
97 /> 111 <Appear
98 </div> 112 timeout={300}
99 )} 113 transitionName="slideUp"
100 <Appear 114 >
101 timeout={1500} 115 <Link to="/settings/recipes" className="button">
102 transitionName="slideUp" 116 {intl.formatMessage(messages.getStarted)}
103 > 117 </Link>
104 <div className="services__no-service"> 118 </Appear>
105 <img src="./assets/images/logo.svg" alt="" /> 119 </div>
106 <h1>{intl.formatMessage(messages.welcome)}</h1> 120 </Appear>
107 <Appear
108 timeout={300}
109 transitionName="slideUp"
110 >
111 <Link to="/settings/recipes" className="button">
112 {intl.formatMessage(messages.getStarted)}
113 </Link>
114 </Appear>
115 </div>
116 </Appear>
117 </>
118 )} 121 )}
119 {services.map(service => ( 122 {services.map(service => (
120 <ServiceView 123 <ServiceView
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js
index 3f6964b6b..0366dc1ee 100644
--- a/src/components/settings/account/AccountDashboard.js
+++ b/src/components/settings/account/AccountDashboard.js
@@ -135,62 +135,96 @@ export default @observer class AccountDashboard extends Component {
135 )} 135 )}
136 136
137 {!userInfoRequestFailed && ( 137 {!userInfoRequestFailed && (
138 <Fragment> 138 <>
139 {!isLoading && ( 139 {!isLoading && (
140 <div className="account"> 140 <>
141 <div className="account__box account__box--flex"> 141 <div className="account">
142 <div className="account__avatar"> 142 <div className="account__box account__box--flex">
143 <img 143 <div className="account__avatar">
144 src="./assets/images/logo.svg" 144 <img
145 alt="" 145 src="./assets/images/logo.svg"
146 /> 146 alt=""
147 </div> 147 />
148 <div className="account__info"> 148 </div>
149 <h2> 149 <div className="account__info">
150 <span className="username">{`${user.firstname} ${user.lastname}`}</span> 150 <h2>
151 {user.isPremium && ( 151 <span className="username">{`${user.firstname} ${user.lastname}`}</span>
152 <> 152 {user.isPremium && (
153 {' '}
154 <ProBadge />
155 <span className="badge badge--premium">{intl.formatMessage(messages.accountTypePremium)}</span>
156 </>
157 )}
158 </h2>
159 {user.organization && `${user.organization}, `}
160 {user.email}
161 {user.isPremium && (
162 <div className="manage-user-links">
163 <Button
164 label={intl.formatMessage(messages.accountEditButton)}
165 className="franz-form__button--inverted"
166 onClick={openEditAccount}
167 />
168 {user.isSubscriptionOwner && (
169 <> 153 <>
170 <Button 154 {' '}
171 label={intl.formatMessage(messages.manageSubscriptionButtonLabel)} 155 <ProBadge />
172 className="franz-form__button--inverted" 156 {/* <span className="badge badge--premium">{intl.formatMessage(messages.accountTypePremium)}</span> */}
173 onClick={openBilling}
174 />
175 <Button
176 label={intl.formatMessage(messages.invoicesButton)}
177 className="franz-form__button--inverted"
178 onClick={openInvoices}
179 />
180 </> 157 </>
181 )} 158 )}
182 </div> 159 </h2>
160 <p>
161 {user.organization && `${user.organization}, `}
162 {user.email}
163 </p>
164 {user.isPremium && (
165 <div className="manage-user-links">
166 <Button
167 label={intl.formatMessage(messages.accountEditButton)}
168 className="franz-form__button--inverted"
169 onClick={openEditAccount}
170 />
171 {/* {user.isSubscriptionOwner && (
172 <>
173 <Button
174 label={intl.formatMessage(messages.manageSubscriptionButtonLabel)}
175 className="franz-form__button--inverted"
176 onClick={openBilling}
177 />
178 <Button
179 label={intl.formatMessage(messages.invoicesButton)}
180 className="franz-form__button--inverted"
181 onClick={openInvoices}
182 />
183 </>
184 )} */}
185 </div>
186 )}
187 </div>
188 {!user.isPremium && (
189 <Button
190 label={intl.formatMessage(messages.accountEditButton)}
191 className="franz-form__button--inverted"
192 onClick={openEditAccount}
193 />
183 )} 194 )}
184 </div> 195 </div>
185 {!user.isPremium && (
186 <Button
187 label={intl.formatMessage(messages.accountEditButton)}
188 className="franz-form__button--inverted"
189 onClick={openEditAccount}
190 />
191 )}
192 </div> 196 </div>
193 </div> 197 {user.isSubscriptionOwner && (
198 <div className="account">
199 <div className="account__box">
200 <h2>
201 Your license: {user.team.plan}
202 </h2>
203 {user.team.isTrial && (
204 <>
205 <p>
206 Trial ends in 14 days
207 </p>
208 </>
209 )}
210 {user.isPremium && (
211 <div className="manage-user-links">
212 <Button
213 label={intl.formatMessage(messages.manageSubscriptionButtonLabel)}
214 className="franz-form__button--inverted"
215 onClick={openBilling}
216 />
217 <Button
218 label={intl.formatMessage(messages.invoicesButton)}
219 className="franz-form__button--inverted"
220 onClick={openInvoices}
221 />
222 </div>
223 )}
224 </div>
225 </div>
226 )}
227 </>
194 )} 228 )}
195 229
196 {!user.isPremium && ( 230 {!user.isPremium && (
@@ -227,7 +261,7 @@ export default @observer class AccountDashboard extends Component {
227 )} 261 )}
228 </div> 262 </div>
229 </div> 263 </div>
230 </Fragment> 264 </>
231 )} 265 )}
232 </div> 266 </div>
233 <ReactTooltip place="right" type="dark" effect="solid" /> 267 <ReactTooltip place="right" type="dark" effect="solid" />
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index 6d0811b1b..3f9e0a6bc 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -143,8 +143,6 @@ export default @observer class EditSettingsForm extends Component {
143 updateButtonLabelMessage = messages.buttonSearchForUpdate; 143 updateButtonLabelMessage = messages.buttonSearchForUpdate;
144 } 144 }
145 145
146 console.log('isSpellcheckerIncludedInCurrentPlan', isSpellcheckerIncludedInCurrentPlan);
147
148 return ( 146 return (
149 <div className="settings__main"> 147 <div className="settings__main">
150 <div className="settings__header"> 148 <div className="settings__header">