aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/layout/AppLayout.js2
-rw-r--r--src/components/services/content/ServiceView.js136
-rw-r--r--src/components/services/content/ServiceWebview.js145
-rw-r--r--src/components/services/content/Services.js7
-rw-r--r--src/components/services/content/WebviewCrashHandler.js7
-rw-r--r--src/components/settings/account/AccountDashboard.js75
-rw-r--r--src/components/settings/user/EditUserForm.js25
-rw-r--r--src/components/subscription/SubscriptionForm.js60
-rw-r--r--src/components/subscription/SubscriptionPopup.js3
-rw-r--r--src/components/ui/Modal/index.js26
-rw-r--r--src/components/ui/Modal/styles.js1
11 files changed, 251 insertions, 236 deletions
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index bce792e56..593149e72 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -7,6 +7,7 @@ import { TitleBar } from 'electron-react-titlebar';
7import InfoBar from '../ui/InfoBar'; 7import InfoBar from '../ui/InfoBar';
8import { Component as DelayApp } from '../../features/delayApp'; 8import { Component as DelayApp } from '../../features/delayApp';
9import { Component as BasicAuth } from '../../features/basicAuth'; 9import { Component as BasicAuth } from '../../features/basicAuth';
10import { Component as ShareFranz } from '../../features/shareFranz';
10import ErrorBoundary from '../util/ErrorBoundary'; 11import ErrorBoundary from '../util/ErrorBoundary';
11 12
12// import globalMessages from '../../i18n/globalMessages'; 13// import globalMessages from '../../i18n/globalMessages';
@@ -164,6 +165,7 @@ export default @observer class AppLayout extends Component {
164 )} 165 )}
165 {isDelayAppScreenVisible && (<DelayApp />)} 166 {isDelayAppScreenVisible && (<DelayApp />)}
166 <BasicAuth /> 167 <BasicAuth />
168 <ShareFranz />
167 {services} 169 {services}
168 </div> 170 </div>
169 </div> 171 </div>
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js
new file mode 100644
index 000000000..5afc54f9d
--- /dev/null
+++ b/src/components/services/content/ServiceView.js
@@ -0,0 +1,136 @@
1import React, { Component, Fragment } from 'react';
2import PropTypes from 'prop-types';
3import { autorun } from 'mobx';
4import { observer } from 'mobx-react';
5import classnames from 'classnames';
6
7import ServiceModel from '../../../models/Service';
8import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl';
9import WebviewLoader from '../../ui/WebviewLoader';
10import WebviewCrashHandler from './WebviewCrashHandler';
11import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler';
12import ServiceDisabled from './ServiceDisabled';
13import ServiceWebview from './ServiceWebview';
14
15export default @observer class ServiceView extends Component {
16 static propTypes = {
17 service: PropTypes.instanceOf(ServiceModel).isRequired,
18 setWebviewReference: PropTypes.func.isRequired,
19 detachService: PropTypes.func.isRequired,
20 reload: PropTypes.func.isRequired,
21 edit: PropTypes.func.isRequired,
22 enable: PropTypes.func.isRequired,
23 isActive: PropTypes.bool,
24 };
25
26 static defaultProps = {
27 isActive: false,
28 };
29
30 state = {
31 forceRepaint: false,
32 targetUrl: '',
33 statusBarVisible: false,
34 };
35
36 autorunDisposer = null;
37
38 componentDidMount() {
39 this.autorunDisposer = autorun(() => {
40 if (this.props.service.isActive) {
41 this.setState({ forceRepaint: true });
42 setTimeout(() => {
43 this.setState({ forceRepaint: false });
44 }, 100);
45 }
46 });
47 }
48
49 componentWillUnmount() {
50 this.autorunDisposer();
51 }
52
53 updateTargetUrl = (event) => {
54 let visible = true;
55 if (event.url === '' || event.url === '#') {
56 visible = false;
57 }
58 this.setState({
59 targetUrl: event.url,
60 statusBarVisible: visible,
61 });
62 };
63
64 render() {
65 const {
66 detachService,
67 service,
68 setWebviewReference,
69 reload,
70 edit,
71 enable,
72 } = this.props;
73
74 const webviewClasses = classnames({
75 services__webview: true,
76 'services__webview-wrapper': true,
77 'is-active': service.isActive,
78 'services__webview--force-repaint': this.state.forceRepaint,
79 });
80
81 let statusBar = null;
82 if (this.state.statusBarVisible) {
83 statusBar = (
84 <StatusBarTargetUrl text={this.state.targetUrl} />
85 );
86 }
87
88 return (
89 <div className={webviewClasses}>
90 {service.isActive && service.isEnabled && (
91 <Fragment>
92 {service.hasCrashed && (
93 <WebviewCrashHandler
94 name={service.recipe.name}
95 webview={service.webview}
96 reload={reload}
97 />
98 )}
99 {service.isEnabled && service.isLoading && service.isFirstLoad && (
100 <WebviewLoader
101 loaded={false}
102 name={service.name}
103 />
104 )}
105 {service.isError && (
106 <WebviewErrorHandler
107 name={service.recipe.name}
108 errorMessage={service.errorMessage}
109 reload={reload}
110 edit={edit}
111 />
112 )}
113 </Fragment>
114 )}
115 {!service.isEnabled ? (
116 <Fragment>
117 {service.isActive && (
118 <ServiceDisabled
119 name={service.recipe.name}
120 webview={service.webview}
121 enable={enable}
122 />
123 )}
124 </Fragment>
125 ) : (
126 <ServiceWebview
127 service={service}
128 setWebviewReference={setWebviewReference}
129 detachService={detachService}
130 />
131 )}
132 {statusBar}
133 </div>
134 );
135 }
136}
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js
index bb577e4cc..7252c695f 100644
--- a/src/components/services/content/ServiceWebview.js
+++ b/src/components/services/content/ServiceWebview.js
@@ -1,145 +1,50 @@
1import React, { Component, Fragment } from 'react'; 1import React, { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { autorun } from 'mobx';
4import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
5import Webview from 'react-electron-web-view'; 4import ElectronWebView from 'react-electron-web-view';
6import classnames from 'classnames';
7 5
8import ServiceModel from '../../../models/Service'; 6import ServiceModel from '../../../models/Service';
9import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl';
10import WebviewLoader from '../../ui/WebviewLoader';
11import WebviewCrashHandler from './WebviewCrashHandler';
12import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler';
13import ServiceDisabled from './ServiceDisabled';
14 7
15export default @observer class ServiceWebview extends Component { 8@observer
9class ServiceWebview extends Component {
16 static propTypes = { 10 static propTypes = {
17 service: PropTypes.instanceOf(ServiceModel).isRequired, 11 service: PropTypes.instanceOf(ServiceModel).isRequired,
18 setWebviewReference: PropTypes.func.isRequired, 12 setWebviewReference: PropTypes.func.isRequired,
19 reload: PropTypes.func.isRequired, 13 detachService: PropTypes.func.isRequired,
20 edit: PropTypes.func.isRequired,
21 enable: PropTypes.func.isRequired,
22 isActive: PropTypes.bool,
23 }; 14 };
24 15
25 static defaultProps = {
26 isActive: false,
27 };
28
29 state = {
30 forceRepaint: false,
31 targetUrl: '',
32 statusBarVisible: false,
33 };
34
35 autorunDisposer = null;
36
37 webview = null; 16 webview = null;
38 17
39 componentDidMount() {
40 this.autorunDisposer = autorun(() => {
41 if (this.props.service.isActive) {
42 this.setState({ forceRepaint: true });
43 setTimeout(() => {
44 this.setState({ forceRepaint: false });
45 }, 100);
46 }
47 });
48 }
49
50 componentWillUnmount() { 18 componentWillUnmount() {
51 this.autorunDisposer(); 19 const { service, detachService } = this.props;
52 } 20 detachService({ service });
53
54 updateTargetUrl = (event) => {
55 let visible = true;
56 if (event.url === '' || event.url === '#') {
57 visible = false;
58 }
59 this.setState({
60 targetUrl: event.url,
61 statusBarVisible: visible,
62 });
63 } 21 }
64 22
65 render() { 23 render() {
66 const { 24 const {
67 service, 25 service,
68 setWebviewReference, 26 setWebviewReference,
69 reload,
70 edit,
71 enable,
72 } = this.props; 27 } = this.props;
73 28
74 const webviewClasses = classnames({
75 services__webview: true,
76 'services__webview-wrapper': true,
77 'is-active': service.isActive,
78 'services__webview--force-repaint': this.state.forceRepaint,
79 });
80
81 let statusBar = null;
82 if (this.state.statusBarVisible) {
83 statusBar = (
84 <StatusBarTargetUrl text={this.state.targetUrl} />
85 );
86 }
87
88 return ( 29 return (
89 <div className={webviewClasses}> 30 <ElectronWebView
90 {service.isActive && service.isEnabled && ( 31 ref={(webview) => { this.webview = webview; }}
91 <Fragment> 32 autosize
92 {service.hasCrashed && ( 33 src={service.url}
93 <WebviewCrashHandler 34 preload="./webview/recipe.js"
94 name={service.recipe.name} 35 partition={`persist:service-${service.id}`}
95 webview={service.webview} 36 onDidAttach={() => {
96 reload={reload} 37 setWebviewReference({
97 /> 38 serviceId: service.id,
98 )} 39 webview: this.webview.view,
99 {service.isEnabled && service.isLoading && service.isFirstLoad && ( 40 });
100 <WebviewLoader 41 }}
101 loaded={false} 42 onUpdateTargetUrl={this.updateTargetUrl}
102 name={service.name} 43 useragent={service.userAgent}
103 /> 44 allowpopups
104 )} 45 />
105 {service.isError && (
106 <WebviewErrorHandler
107 name={service.recipe.name}
108 errorMessage={service.errorMessage}
109 reload={reload}
110 edit={edit}
111 />
112 )}
113 </Fragment>
114 )}
115 {!service.isEnabled ? (
116 <Fragment>
117 {service.isActive && (
118 <ServiceDisabled
119 name={service.recipe.name}
120 webview={service.webview}
121 enable={enable}
122 />
123 )}
124 </Fragment>
125 ) : (
126 <Webview
127 ref={(element) => { this.webview = element; }}
128 autosize
129 src={service.url}
130 preload="./webview/recipe.js"
131 partition={`persist:service-${service.id}`}
132 onDidAttach={() => setWebviewReference({
133 serviceId: service.id,
134 webview: this.webview.view,
135 })}
136 onUpdateTargetUrl={this.updateTargetUrl}
137 useragent={service.userAgent}
138 allowpopups
139 />
140 )}
141 {statusBar}
142 </div>
143 ); 46 );
144 } 47 }
145} 48}
49
50export default ServiceWebview;
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js
index 54f16ba12..8f8c38a11 100644
--- a/src/components/services/content/Services.js
+++ b/src/components/services/content/Services.js
@@ -4,7 +4,7 @@ import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { Link } from 'react-router'; 4import { Link } from 'react-router';
5import { defineMessages, intlShape } from 'react-intl'; 5import { defineMessages, intlShape } from 'react-intl';
6 6
7import Webview from './ServiceWebview'; 7import ServiceView from './ServiceView';
8import Appear from '../../ui/effects/Appear'; 8import Appear from '../../ui/effects/Appear';
9 9
10const messages = defineMessages({ 10const messages = defineMessages({
@@ -22,6 +22,7 @@ export default @observer class Services extends Component {
22 static propTypes = { 22 static propTypes = {
23 services: MobxPropTypes.arrayOrObservableArray, 23 services: MobxPropTypes.arrayOrObservableArray,
24 setWebviewReference: PropTypes.func.isRequired, 24 setWebviewReference: PropTypes.func.isRequired,
25 detachService: PropTypes.func.isRequired,
25 handleIPCMessage: PropTypes.func.isRequired, 26 handleIPCMessage: PropTypes.func.isRequired,
26 openWindow: PropTypes.func.isRequired, 27 openWindow: PropTypes.func.isRequired,
27 reload: PropTypes.func.isRequired, 28 reload: PropTypes.func.isRequired,
@@ -42,6 +43,7 @@ export default @observer class Services extends Component {
42 services, 43 services,
43 handleIPCMessage, 44 handleIPCMessage,
44 setWebviewReference, 45 setWebviewReference,
46 detachService,
45 openWindow, 47 openWindow,
46 reload, 48 reload,
47 openSettings, 49 openSettings,
@@ -71,11 +73,12 @@ export default @observer class Services extends Component {
71 </Appear> 73 </Appear>
72 )} 74 )}
73 {services.map(service => ( 75 {services.map(service => (
74 <Webview 76 <ServiceView
75 key={service.id} 77 key={service.id}
76 service={service} 78 service={service}
77 handleIPCMessage={handleIPCMessage} 79 handleIPCMessage={handleIPCMessage}
78 setWebviewReference={setWebviewReference} 80 setWebviewReference={setWebviewReference}
81 detachService={detachService}
79 openWindow={openWindow} 82 openWindow={openWindow}
80 reload={() => reload({ serviceId: service.id })} 83 reload={() => reload({ serviceId: service.id })}
81 edit={() => openSettings({ path: `services/edit/${service.id}` })} 84 edit={() => openSettings({ path: `services/edit/${service.id}` })}
diff --git a/src/components/services/content/WebviewCrashHandler.js b/src/components/services/content/WebviewCrashHandler.js
index 42bc3c877..7a69dba87 100644
--- a/src/components/services/content/WebviewCrashHandler.js
+++ b/src/components/services/content/WebviewCrashHandler.js
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
5import ms from 'ms';
5 6
6import Button from '../../ui/Button'; 7import Button from '../../ui/Button';
7 8
@@ -35,12 +36,12 @@ export default @observer class WebviewCrashHandler extends Component {
35 }; 36 };
36 37
37 state = { 38 state = {
38 countdown: 10000, 39 countdown: ms('10s'),
39 } 40 }
40 41
41 countdownInterval = null; 42 countdownInterval = null;
42 43
43 countdownIntervalTimeout = 1000; 44 countdownIntervalTimeout = ms('1s');
44 45
45 46
46 componentDidMount() { 47 componentDidMount() {
@@ -75,7 +76,7 @@ export default @observer class WebviewCrashHandler extends Component {
75 <p className="footnote"> 76 <p className="footnote">
76 {intl.formatMessage(messages.autoReload, { 77 {intl.formatMessage(messages.autoReload, {
77 name, 78 name,
78 seconds: this.state.countdown / 1000, 79 seconds: this.state.countdown / ms('1s'),
79 })} 80 })}
80 </p> 81 </p>
81 </div> 82 </div>
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js
index 9c9543749..181b95c8c 100644
--- a/src/components/settings/account/AccountDashboard.js
+++ b/src/components/settings/account/AccountDashboard.js
@@ -44,10 +44,6 @@ const messages = defineMessages({
44 id: 'settings.account.accountType.premium', 44 id: 'settings.account.accountType.premium',
45 defaultMessage: '!!!Premium Supporter Account', 45 defaultMessage: '!!!Premium Supporter Account',
46 }, 46 },
47 accountTypeEnterprise: {
48 id: 'settings.account.accountType.enterprise',
49 defaultMessage: '!!!Enterprise Account',
50 },
51 accountEditButton: { 47 accountEditButton: {
52 id: 'settings.account.account.editButton', 48 id: 'settings.account.account.editButton',
53 defaultMessage: '!!!Edit Account', 49 defaultMessage: '!!!Edit Account',
@@ -169,15 +165,9 @@ export default @observer class AccountDashboard extends Component {
169 {user.organization && `${user.organization}, `} 165 {user.organization && `${user.organization}, `}
170 {user.email} 166 {user.email}
171 <br /> 167 <br />
172 {!user.isEnterprise && !user.isPremium && (
173 <span className="badge badge">{intl.formatMessage(messages.accountTypeBasic)}</span>
174 )}
175 {user.isPremium && ( 168 {user.isPremium && (
176 <span className="badge badge--premium">{intl.formatMessage(messages.accountTypePremium)}</span> 169 <span className="badge badge--premium">{intl.formatMessage(messages.accountTypePremium)}</span>
177 )} 170 )}
178 {user.isEnterprise && (
179 <span className="badge badge--success">{intl.formatMessage(messages.accountTypeEnterprise)}</span>
180 )}
181 </div> 171 </div>
182 <Link to="/settings/user/edit" className="button"> 172 <Link to="/settings/user/edit" className="button">
183 {intl.formatMessage(messages.accountEditButton)} 173 {intl.formatMessage(messages.accountEditButton)}
@@ -235,34 +225,7 @@ export default @observer class AccountDashboard extends Component {
235 ) 225 )
236 )} 226 )}
237 227
238 {user.isEnterprise && ( 228 {!user.isPremium && (
239 <div className="account">
240 <div className="account__box">
241 <h2>{user.company.name}</h2>
242 <p>
243 Technical contact:&nbsp;
244 <Link
245 className="link"
246 target="_blank"
247 to={`mailto:${user.company.contact.technical}?subject=Franz`}
248 >
249 {user.company.contact.technical}
250 </Link>
251 <br />
252 General contact:&nbsp;
253 <Link
254 className="link"
255 target="_blank"
256 to={`mailto:${user.company.contact.default}?subject=Franz`}
257 >
258 {user.company.contact.default}
259 </Link>
260 </p>
261 </div>
262 </div>
263 )}
264
265 {!user.isEnterprise && !user.isPremium && (
266 isLoadingPlans ? ( 229 isLoadingPlans ? (
267 <Loader /> 230 <Loader />
268 ) : ( 231 ) : (
@@ -277,27 +240,25 @@ export default @observer class AccountDashboard extends Component {
277 ) 240 )
278 )} 241 )}
279 242
280 {!user.isEnterprise && ( 243 <div className="account franz-form">
281 <div className="account franz-form"> 244 <div className="account__box">
282 <div className="account__box"> 245 <h2>{intl.formatMessage(messages.headlineDangerZone)}</h2>
283 <h2>{intl.formatMessage(messages.headlineDangerZone)}</h2> 246 {!isDeleteAccountSuccessful && (
284 {!isDeleteAccountSuccessful && ( 247 <div className="account__subscription">
285 <div className="account__subscription"> 248 <p>{intl.formatMessage(messages.deleteInfo)}</p>
286 <p>{intl.formatMessage(messages.deleteInfo)}</p> 249 <Button
287 <Button 250 label={intl.formatMessage(messages.deleteAccount)}
288 label={intl.formatMessage(messages.deleteAccount)} 251 buttonType="danger"
289 buttonType="danger" 252 onClick={() => deleteAccount()}
290 onClick={() => deleteAccount()} 253 loaded={!isLoadingDeleteAccount}
291 loaded={!isLoadingDeleteAccount} 254 />
292 />
293 </div>
294 )}
295 {isDeleteAccountSuccessful && (
296 <p>{intl.formatMessage(messages.deleteEmailSent)}</p>
297 )}
298 </div> 255 </div>
256 )}
257 {isDeleteAccountSuccessful && (
258 <p>{intl.formatMessage(messages.deleteEmailSent)}</p>
259 )}
299 </div> 260 </div>
300 )} 261 </div>
301 </Fragment> 262 </Fragment>
302 )} 263 )}
303 </div> 264 </div>
diff --git a/src/components/settings/user/EditUserForm.js b/src/components/settings/user/EditUserForm.js
index 0e3ac6b10..a1a353e57 100644
--- a/src/components/settings/user/EditUserForm.js
+++ b/src/components/settings/user/EditUserForm.js
@@ -3,11 +3,10 @@ import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
5import { Link } from 'react-router'; 5import { Link } from 'react-router';
6 6import { Input } from '@meetfranz/forms';
7// import { Link } from 'react-router';
8 7
9import Form from '../../../lib/Form'; 8import Form from '../../../lib/Form';
10import Input from '../../ui/Input'; 9// import Input from '../../ui/Input';
11import Button from '../../ui/Button'; 10import Button from '../../ui/Button';
12import Radio from '../../ui/Radio'; 11import Radio from '../../ui/Radio';
13import Infobox from '../../ui/Infobox'; 12import Infobox from '../../ui/Infobox';
@@ -39,13 +38,12 @@ const messages = defineMessages({
39 }, 38 },
40}); 39});
41 40
42export default @observer class EditServiceForm extends Component { 41export default @observer class EditUserForm extends Component {
43 static propTypes = { 42 static propTypes = {
44 status: MobxPropTypes.observableArray.isRequired, 43 status: MobxPropTypes.observableArray.isRequired,
45 form: PropTypes.instanceOf(Form).isRequired, 44 form: PropTypes.instanceOf(Form).isRequired,
46 onSubmit: PropTypes.func.isRequired, 45 onSubmit: PropTypes.func.isRequired,
47 isSaving: PropTypes.bool.isRequired, 46 isSaving: PropTypes.bool.isRequired,
48 isEnterprise: PropTypes.bool.isRequired,
49 }; 47 };
50 48
51 static contextTypes = { 49 static contextTypes = {
@@ -68,7 +66,6 @@ export default @observer class EditServiceForm extends Component {
68 // user, 66 // user,
69 status, 67 status,
70 form, 68 form,
71 isEnterprise,
72 isSaving, 69 isSaving,
73 } = this.props; 70 } = this.props;
74 const { intl } = this.context; 71 const { intl } = this.context;
@@ -98,23 +95,21 @@ export default @observer class EditServiceForm extends Component {
98 )} 95 )}
99 <h2>{intl.formatMessage(messages.headlineAccount)}</h2> 96 <h2>{intl.formatMessage(messages.headlineAccount)}</h2>
100 <div className="grid__row"> 97 <div className="grid__row">
101 <Input field={form.$('firstname')} focus /> 98 <Input {...form.$('firstname').bind()} focus />
102 <Input field={form.$('lastname')} /> 99 <Input {...form.$('lastname').bind()} />
103 </div> 100 </div>
104 <Input field={form.$('email')} /> 101 <Input {...form.$('email').bind()} />
105 {!isEnterprise && ( 102 <Radio field={form.$('accountType')} />
106 <Radio field={form.$('accountType')} /> 103 {form.$('accountType').value === 'company' && (
107 )}
108 {!isEnterprise && form.$('accountType').value === 'company' && (
109 <Input field={form.$('organization')} /> 104 <Input field={form.$('organization')} />
110 )} 105 )}
111 <h2>{intl.formatMessage(messages.headlinePassword)}</h2> 106 <h2>{intl.formatMessage(messages.headlinePassword)}</h2>
112 <Input 107 <Input
113 field={form.$('oldPassword')} 108 {...form.$('oldPassword').bind()}
114 showPasswordToggle 109 showPasswordToggle
115 /> 110 />
116 <Input 111 <Input
117 field={form.$('newPassword')} 112 {...form.$('newPassword').bind()}
118 showPasswordToggle 113 showPasswordToggle
119 scorePassword 114 scorePassword
120 /> 115 />
diff --git a/src/components/subscription/SubscriptionForm.js b/src/components/subscription/SubscriptionForm.js
index 90da8ddc3..7a818d100 100644
--- a/src/components/subscription/SubscriptionForm.js
+++ b/src/components/subscription/SubscriptionForm.js
@@ -35,31 +35,29 @@ const messages = defineMessages({
35 id: 'subscription.includedFeatures', 35 id: 'subscription.includedFeatures',
36 defaultMessage: '!!!The Franz Premium Supporter Account includes', 36 defaultMessage: '!!!The Franz Premium Supporter Account includes',
37 }, 37 },
38 features: { 38 onpremise: {
39 onpremise: { 39 id: 'subscription.features.onpremise.mattermost',
40 id: 'subscription.features.onpremise.mattermost', 40 defaultMessage: '!!!Add on-premise/hosted services like Mattermost',
41 defaultMessage: '!!!Add on-premise/hosted services like Mattermost', 41 },
42 }, 42 noInterruptions: {
43 noInterruptions: { 43 id: 'subscription.features.noInterruptions',
44 id: 'subscription.features.noInterruptions', 44 defaultMessage: '!!!No app delays & nagging to upgrade license',
45 defaultMessage: '!!!No app delays & nagging to upgrade license', 45 },
46 }, 46 proxy: {
47 proxy: { 47 id: 'subscription.features.proxy',
48 id: 'subscription.features.proxy', 48 defaultMessage: '!!!Proxy support for services',
49 defaultMessage: '!!!Proxy support for services', 49 },
50 }, 50 spellchecker: {
51 spellchecker: { 51 id: 'subscription.features.spellchecker',
52 id: 'subscription.features.spellchecker', 52 defaultMessage: '!!!Support for Spellchecker',
53 defaultMessage: '!!!Support for Spellchecker', 53 },
54 }, 54 ads: {
55 ads: { 55 id: 'subscription.features.ads',
56 id: 'subscription.features.ads', 56 defaultMessage: '!!!No ads, ever!',
57 defaultMessage: '!!!No ads, ever!', 57 },
58 }, 58 comingSoon: {
59 comingSoon: { 59 id: 'subscription.features.comingSoon',
60 id: 'subscription.features.comingSoon', 60 defaultMessage: '!!!coming soon',
61 defaultMessage: '!!!coming soon',
62 },
63 }, 61 },
64 euTaxInfo: { 62 euTaxInfo: {
65 id: 'subscription.euTaxInfo', 63 id: 'subscription.euTaxInfo',
@@ -85,7 +83,7 @@ export default @observer class SubscriptionForm extends Component {
85 showSkipOption: false, 83 showSkipOption: false,
86 skipAction: () => null, 84 skipAction: () => null,
87 skipButtonLabel: '', 85 skipButtonLabel: '',
88 } 86 };
89 87
90 static contextTypes = { 88 static contextTypes = {
91 intl: intlShape, 89 intl: intlShape,
@@ -162,18 +160,18 @@ export default @observer class SubscriptionForm extends Component {
162 </p> 160 </p>
163 <div className="subscription"> 161 <div className="subscription">
164 <ul className="subscription__premium-features"> 162 <ul className="subscription__premium-features">
165 <li>{intl.formatMessage(messages.features.onpremise)}</li> 163 <li>{intl.formatMessage(messages.onpremise)}</li>
166 <li> 164 <li>
167 {intl.formatMessage(messages.features.noInterruptions)} 165 {intl.formatMessage(messages.noInterruptions)}
168 </li> 166 </li>
169 <li> 167 <li>
170 {intl.formatMessage(messages.features.spellchecker)} 168 {intl.formatMessage(messages.spellchecker)}
171 </li> 169 </li>
172 <li> 170 <li>
173 {intl.formatMessage(messages.features.proxy)} 171 {intl.formatMessage(messages.proxy)}
174 </li> 172 </li>
175 <li> 173 <li>
176 {intl.formatMessage(messages.features.ads)} 174 {intl.formatMessage(messages.ads)}
177 </li> 175 </li>
178 </ul> 176 </ul>
179 </div> 177 </div>
diff --git a/src/components/subscription/SubscriptionPopup.js b/src/components/subscription/SubscriptionPopup.js
index b5d7c4b2d..0f6f0260f 100644
--- a/src/components/subscription/SubscriptionPopup.js
+++ b/src/components/subscription/SubscriptionPopup.js
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
5import Webview from 'react-electron-web-view'; 5import Webview from 'react-electron-web-view';
6import ms from 'ms';
6 7
7import Button from '../ui/Button'; 8import Button from '../ui/Button';
8 9
@@ -42,7 +43,7 @@ export default @observer class SubscriptionPopup extends Component {
42 43
43 setTimeout(() => { 44 setTimeout(() => {
44 this.props.closeWindow(); 45 this.props.closeWindow();
45 }, 4000); 46 }, ms('4s'));
46 } 47 }
47 48
48 render() { 49 render() {
diff --git a/src/components/ui/Modal/index.js b/src/components/ui/Modal/index.js
index d84e4c713..0b7154760 100644
--- a/src/components/ui/Modal/index.js
+++ b/src/components/ui/Modal/index.js
@@ -3,9 +3,12 @@ import ReactModal from 'react-modal';
3import PropTypes from 'prop-types'; 3import PropTypes from 'prop-types';
4import classnames from 'classnames'; 4import classnames from 'classnames';
5import injectCSS from 'react-jss'; 5import injectCSS from 'react-jss';
6import { Icon } from '@meetfranz/ui';
6 7
7import styles from './styles'; 8import styles from './styles';
8 9
10// ReactModal.setAppElement('#root');
11
9export default @injectCSS(styles) class Modal extends Component { 12export default @injectCSS(styles) class Modal extends Component {
10 static propTypes = { 13 static propTypes = {
11 children: PropTypes.node.isRequired, 14 children: PropTypes.node.isRequired,
@@ -14,11 +17,15 @@ export default @injectCSS(styles) class Modal extends Component {
14 isOpen: PropTypes.bool.isRequired, 17 isOpen: PropTypes.bool.isRequired,
15 portal: PropTypes.string, 18 portal: PropTypes.string,
16 close: PropTypes.func.isRequired, 19 close: PropTypes.func.isRequired,
20 shouldCloseOnOverlayClick: PropTypes.bool,
21 showClose: PropTypes.bool,
17 } 22 }
18 23
19 static defaultProps = { 24 static defaultProps = {
20 className: null, 25 className: null,
21 portal: 'modal-portal', 26 portal: 'modal-portal',
27 shouldCloseOnOverlayClick: false,
28 showClose: true,
22 } 29 }
23 30
24 render() { 31 render() {
@@ -29,6 +36,8 @@ export default @injectCSS(styles) class Modal extends Component {
29 isOpen, 36 isOpen,
30 portal, 37 portal,
31 close, 38 close,
39 shouldCloseOnOverlayClick,
40 showClose,
32 } = this.props; 41 } = this.props;
33 42
34 return ( 43 return (
@@ -42,14 +51,17 @@ export default @injectCSS(styles) class Modal extends Component {
42 overlayClassName={classes.overlay} 51 overlayClassName={classes.overlay}
43 portal={portal} 52 portal={portal}
44 onRequestClose={close} 53 onRequestClose={close}
54 shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}
45 > 55 >
46 {/* <button 56 {showClose && close && (
47 type="button" 57 <button
48 className={classnames({ 58 type="button"
49 [`${classes.close}`]: true, 59 className={classes.close}
50 'mdi mdi-close': true, 60 onClick={close}
51 })} 61 >
52 /> */} 62 <Icon icon="mdiClose" size={1.5} />
63 </button>
64 )}
53 <div className={classes.content}> 65 <div className={classes.content}>
54 {children} 66 {children}
55 </div> 67 </div>
diff --git a/src/components/ui/Modal/styles.js b/src/components/ui/Modal/styles.js
index 56fecbf55..49b970c97 100644
--- a/src/components/ui/Modal/styles.js
+++ b/src/components/ui/Modal/styles.js
@@ -28,5 +28,6 @@ export default theme => ({
28 position: 'absolute', 28 position: 'absolute',
29 top: 0, 29 top: 0,
30 right: 0, 30 right: 0,
31 padding: 20,
31 }, 32 },
32}); 33});