diff options
111 files changed, 4142 insertions, 1498 deletions
@@ -17,7 +17,7 @@ | |||
17 | "extensions": [".js", ".jsx"] | 17 | "extensions": [".js", ".jsx"] |
18 | }], | 18 | }], |
19 | "react/forbid-prop-types": 0, | 19 | "react/forbid-prop-types": 0, |
20 | "react/destructuring-assignment": 1, | 20 | "react/destructuring-assignment": 0, |
21 | "prefer-destructuring": 1, | 21 | "prefer-destructuring": 1, |
22 | "no-underscore-dangle": 0, | 22 | "no-underscore-dangle": 0, |
23 | "max-len": 0, | 23 | "max-len": 0, |
diff --git a/package-lock.json b/package-lock.json index 607ebc31a..048425eb6 100644 --- a/package-lock.json +++ b/package-lock.json | |||
@@ -2149,9 +2149,9 @@ | |||
2149 | } | 2149 | } |
2150 | }, | 2150 | }, |
2151 | "@mdi/js": { | 2151 | "@mdi/js": { |
2152 | "version": "3.4.93", | 2152 | "version": "4.2.95", |
2153 | "resolved": "https://registry.npmjs.org/@mdi/js/-/js-3.4.93.tgz", | 2153 | "resolved": "https://registry.npmjs.org/@mdi/js/-/js-4.2.95.tgz", |
2154 | "integrity": "sha512-SEzolEqT8ErlWdHz4AAtQ1lTfAnM6j67Ppm6k5s/I1aIuuoFP/D8d/z838C28xHO1KOqrsS1fw2wlf6fRiEEJA==" | 2154 | "integrity": "sha512-3qqOZx2HkrQEUc9fr5MiQWlokwmO8TK5bQZ2EP1Rg0q2Q507jy+fUeL8lb9ko2ossYqoPnugIr7jI0/O7uhlrA==" |
2155 | }, | 2155 | }, |
2156 | "@mdi/react": { | 2156 | "@mdi/react": { |
2157 | "version": "1.1.0", | 2157 | "version": "1.1.0", |
@@ -2178,6 +2178,10 @@ | |||
2178 | "react-loader": "^2.4.5" | 2178 | "react-loader": "^2.4.5" |
2179 | }, | 2179 | }, |
2180 | "dependencies": { | 2180 | "dependencies": { |
2181 | "@mdi/js": { | ||
2182 | "version": "3.9.97", | ||
2183 | "bundled": true | ||
2184 | }, | ||
2181 | "@meetfranz/theme": { | 2185 | "@meetfranz/theme": { |
2182 | "version": "1.0.14", | 2186 | "version": "1.0.14", |
2183 | "bundled": true, | 2187 | "bundled": true, |
@@ -2202,6 +2206,10 @@ | |||
2202 | "react-loader": "^2.4.5" | 2206 | "react-loader": "^2.4.5" |
2203 | }, | 2207 | }, |
2204 | "dependencies": { | 2208 | "dependencies": { |
2209 | "@mdi/js": { | ||
2210 | "version": "3.9.97", | ||
2211 | "bundled": true | ||
2212 | }, | ||
2205 | "@meetfranz/theme": { | 2213 | "@meetfranz/theme": { |
2206 | "version": "1.0.14", | 2214 | "version": "1.0.14", |
2207 | "bundled": true, | 2215 | "bundled": true, |
@@ -16748,6 +16756,14 @@ | |||
16748 | "react-transition-group": "^1.2.0" | 16756 | "react-transition-group": "^1.2.0" |
16749 | } | 16757 | } |
16750 | }, | 16758 | }, |
16759 | "react-confetti": { | ||
16760 | "version": "3.1.0", | ||
16761 | "resolved": "https://registry.npmjs.org/react-confetti/-/react-confetti-3.1.0.tgz", | ||
16762 | "integrity": "sha512-T1DKt09C9rrf2BJ0OxFu8saPohFalOJfOgci11/ePz6DxbY+0cd/3CMimxj/ZITl7jQWnmC/bNWBgGheke3WZQ==", | ||
16763 | "requires": { | ||
16764 | "tween-functions": "^1.2.0" | ||
16765 | } | ||
16766 | }, | ||
16751 | "react-dom": { | 16767 | "react-dom": { |
16752 | "version": "16.6.3", | 16768 | "version": "16.6.3", |
16753 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.6.3.tgz", | 16769 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.6.3.tgz", |
@@ -19899,6 +19915,11 @@ | |||
19899 | "safe-buffer": "^5.0.1" | 19915 | "safe-buffer": "^5.0.1" |
19900 | } | 19916 | } |
19901 | }, | 19917 | }, |
19918 | "tween-functions": { | ||
19919 | "version": "1.2.0", | ||
19920 | "resolved": "https://registry.npmjs.org/tween-functions/-/tween-functions-1.2.0.tgz", | ||
19921 | "integrity": "sha1-GuOlDnxguz3vd06scHrLynO7w/8=" | ||
19922 | }, | ||
19902 | "tweetnacl": { | 19923 | "tweetnacl": { |
19903 | "version": "0.14.5", | 19924 | "version": "0.14.5", |
19904 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", | 19925 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", |
diff --git a/package.json b/package.json index 639d078a0..d30fa08c5 100644 --- a/package.json +++ b/package.json | |||
@@ -36,6 +36,7 @@ | |||
36 | "dependencies": { | 36 | "dependencies": { |
37 | "@babel/polyfill": "7.4.4", | 37 | "@babel/polyfill": "7.4.4", |
38 | "@babel/runtime": "7.4.5", | 38 | "@babel/runtime": "7.4.5", |
39 | "@mdi/js": "4.2.95", | ||
39 | "@meetfranz/electron-notification-state": "1.0.0", | 40 | "@meetfranz/electron-notification-state": "1.0.0", |
40 | "@meetfranz/forms": "file:packages/forms", | 41 | "@meetfranz/forms": "file:packages/forms", |
41 | "@meetfranz/theme": "file:packages/theme", | 42 | "@meetfranz/theme": "file:packages/theme", |
@@ -71,6 +72,7 @@ | |||
71 | "prop-types": "^15.5.10", | 72 | "prop-types": "^15.5.10", |
72 | "react": "16.6.3", | 73 | "react": "16.6.3", |
73 | "react-addons-css-transition-group": "15.6.2", | 74 | "react-addons-css-transition-group": "15.6.2", |
75 | "react-confetti": "3.1.0", | ||
74 | "react-dom": "16.6.3", | 76 | "react-dom": "16.6.3", |
75 | "react-dropzone": "7.0.1", | 77 | "react-dropzone": "7.0.1", |
76 | "react-electron-web-view": "^2.0.1", | 78 | "react-electron-web-view": "^2.0.1", |
diff --git a/packages/forms/package.json b/packages/forms/package.json index d50f4c756..bb76462d8 100644 --- a/packages/forms/package.json +++ b/packages/forms/package.json | |||
@@ -1,6 +1,6 @@ | |||
1 | { | 1 | { |
2 | "name": "@meetfranz/forms", | 2 | "name": "@meetfranz/forms", |
3 | "version": "1.0.16", | 3 | "version": "1.1.0", |
4 | "description": "React form components for Franz", | 4 | "description": "React form components for Franz", |
5 | "main": "lib/index.js", | 5 | "main": "lib/index.js", |
6 | "scripts": { | 6 | "scripts": { |
@@ -35,5 +35,5 @@ | |||
35 | "react-dom": "16.7.0", | 35 | "react-dom": "16.7.0", |
36 | "react-jss": "^8.6.1" | 36 | "react-jss": "^8.6.1" |
37 | }, | 37 | }, |
38 | "gitHead": "9f2ab40b7602bc3df26ebb093b484b9917768f69" | 38 | "gitHead": "e1e46986d902adc4c19ee009016290f9733a7d61" |
39 | } | 39 | } |
diff --git a/packages/forms/src/button/index.tsx b/packages/forms/src/button/index.tsx index 9faedc8f1..b53c2da05 100644 --- a/packages/forms/src/button/index.tsx +++ b/packages/forms/src/button/index.tsx | |||
@@ -1,4 +1,3 @@ | |||
1 | import * as mdiIcons from '@mdi/js'; | ||
2 | import Icon from '@mdi/react'; | 1 | import Icon from '@mdi/react'; |
3 | import { Theme } from '@meetfranz/theme'; | 2 | import { Theme } from '@meetfranz/theme'; |
4 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
@@ -21,7 +20,7 @@ interface IProps extends IFormField, IWithStyle { | |||
21 | stretch?: boolean; | 20 | stretch?: boolean; |
22 | loaded?: boolean; | 21 | loaded?: boolean; |
23 | busy?: boolean; | 22 | busy?: boolean; |
24 | icon?: keyof typeof mdiIcons; | 23 | icon?: string; |
25 | href?: string; | 24 | href?: string; |
26 | target?: string; | 25 | target?: string; |
27 | } | 26 | } |
@@ -175,7 +174,7 @@ class ButtonComponent extends Component<IProps> { | |||
175 | onClick, | 174 | onClick, |
176 | buttonType, | 175 | buttonType, |
177 | loaded, | 176 | loaded, |
178 | icon: iconName, | 177 | icon, |
179 | busy: busyProp, | 178 | busy: busyProp, |
180 | href, | 179 | href, |
181 | target, | 180 | target, |
@@ -185,13 +184,6 @@ class ButtonComponent extends Component<IProps> { | |||
185 | busy, | 184 | busy, |
186 | } = this.state; | 185 | } = this.state; |
187 | 186 | ||
188 | let icon = ''; | ||
189 | if (iconName && mdiIcons[iconName]) { | ||
190 | icon = mdiIcons[iconName]; | ||
191 | } else if (iconName && !mdiIcons[iconName]) { | ||
192 | console.warn(`Icon '${iconName}' was not found`); | ||
193 | } | ||
194 | |||
195 | let showLoader = false; | 187 | let showLoader = false; |
196 | if (loaded) { | 188 | if (loaded) { |
197 | showLoader = !loaded; | 189 | showLoader = !loaded; |
diff --git a/packages/theme/src/themes/dark/index.ts b/packages/theme/src/themes/dark/index.ts index d29345298..e94f54c55 100644 --- a/packages/theme/src/themes/dark/index.ts +++ b/packages/theme/src/themes/dark/index.ts | |||
@@ -11,6 +11,8 @@ export const colorBackgroundSubscriptionContainer = legacyStyles.themeBrandInfo; | |||
11 | export const colorHeadline = legacyStyles.darkThemeTextColor; | 11 | export const colorHeadline = legacyStyles.darkThemeTextColor; |
12 | export const colorText = legacyStyles.darkThemeTextColor; | 12 | export const colorText = legacyStyles.darkThemeTextColor; |
13 | 13 | ||
14 | export const defaultContentBorder = legacyStyles.themeGrayDark; | ||
15 | |||
14 | // Loader | 16 | // Loader |
15 | export const colorFullscreenLoaderSpinner = '#FFF'; | 17 | export const colorFullscreenLoaderSpinner = '#FFF'; |
16 | export const colorWebviewLoaderBackground = color(legacyStyles.darkThemeGrayDarkest).alpha(0.5).rgb().string(); | 18 | export const colorWebviewLoaderBackground = color(legacyStyles.darkThemeGrayDarkest).alpha(0.5).rgb().string(); |
@@ -119,6 +121,16 @@ export const announcements = merge({}, defaultStyles.announcements, { | |||
119 | }, | 121 | }, |
120 | }); | 122 | }); |
121 | 123 | ||
124 | // Signup | ||
125 | export const signup = merge({}, defaultStyles.signup, { | ||
126 | pricing: { | ||
127 | feature: { | ||
128 | background: legacyStyles.darkThemeGrayLight, | ||
129 | border: color(legacyStyles.darkThemeGrayLight).lighten(0.2).hex(), | ||
130 | }, | ||
131 | }, | ||
132 | }); | ||
133 | |||
122 | // Todos | 134 | // Todos |
123 | export const todos = merge({}, defaultStyles.todos, { | 135 | export const todos = merge({}, defaultStyles.todos, { |
124 | todosLayer: { | 136 | todosLayer: { |
diff --git a/packages/theme/src/themes/default/index.ts b/packages/theme/src/themes/default/index.ts index 9f9c39f9a..4e042afce 100644 --- a/packages/theme/src/themes/default/index.ts +++ b/packages/theme/src/themes/default/index.ts | |||
@@ -28,6 +28,8 @@ export const colorHeadline = legacyStyles.themeGrayDark; | |||
28 | 28 | ||
29 | export const colorText = legacyStyles.themeTextColor; | 29 | export const colorText = legacyStyles.themeTextColor; |
30 | 30 | ||
31 | export const defaultContentBorder = color(legacyStyles.themeGrayLighter).darken(0.1).rgb().string(); | ||
32 | |||
31 | // Subscription Container Component | 33 | // Subscription Container Component |
32 | export const colorSubscriptionContainerBackground = 'none'; | 34 | export const colorSubscriptionContainerBackground = 'none'; |
33 | export const colorSubscriptionContainerBorder = `1px solid ${brandPrimary}`; | 35 | export const colorSubscriptionContainerBorder = `1px solid ${brandPrimary}`; |
@@ -208,6 +210,16 @@ export const announcements = { | |||
208 | }, | 210 | }, |
209 | }; | 211 | }; |
210 | 212 | ||
213 | // Signup | ||
214 | export const signup = { | ||
215 | pricing: { | ||
216 | feature: { | ||
217 | background: legacyStyles.themeGrayLightest, | ||
218 | border: legacyStyles.themeGrayLighter, | ||
219 | }, | ||
220 | }, | ||
221 | }; | ||
222 | |||
211 | // Todos | 223 | // Todos |
212 | export const todos = { | 224 | export const todos = { |
213 | todosLayer: { | 225 | todosLayer: { |
@@ -223,5 +235,5 @@ export const todos = { | |||
223 | }, | 235 | }, |
224 | resizeHandler: { | 236 | resizeHandler: { |
225 | backgroundHover: styleTypes.primary.accent, | 237 | backgroundHover: styleTypes.primary.accent, |
226 | } | 238 | }, |
227 | }; | 239 | }; |
diff --git a/packages/ui/package.json b/packages/ui/package.json index a851ed9cf..4f42b21b5 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json | |||
@@ -1,6 +1,6 @@ | |||
1 | { | 1 | { |
2 | "name": "@meetfranz/ui", | 2 | "name": "@meetfranz/ui", |
3 | "version": "0.0.9", | 3 | "version": "1.0.0", |
4 | "description": "React UI components for Franz", | 4 | "description": "React UI components for Franz", |
5 | "main": "lib/index.js", | 5 | "main": "lib/index.js", |
6 | "scripts": { | 6 | "scripts": { |
@@ -34,5 +34,5 @@ | |||
34 | "react-dom": "16.7.0", | 34 | "react-dom": "16.7.0", |
35 | "react-jss": "^8.6.1" | 35 | "react-jss": "^8.6.1" |
36 | }, | 36 | }, |
37 | "gitHead": "9f2ab40b7602bc3df26ebb093b484b9917768f69" | 37 | "gitHead": "e1e46986d902adc4c19ee009016290f9733a7d61" |
38 | } | 38 | } |
diff --git a/packages/ui/src/badge/ProBadge.tsx b/packages/ui/src/badge/ProBadge.tsx index 612e23210..5cc41f5b2 100644 --- a/packages/ui/src/badge/ProBadge.tsx +++ b/packages/ui/src/badge/ProBadge.tsx | |||
@@ -1,15 +1,17 @@ | |||
1 | import { mdiStar } from '@mdi/js'; | ||
1 | import { Theme } from '@meetfranz/theme'; | 2 | import { Theme } from '@meetfranz/theme'; |
2 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
3 | import React, { Component } from 'react'; | 4 | import React, { Component } from 'react'; |
4 | import injectStyle from 'react-jss'; | 5 | import injectStyle from 'react-jss'; |
5 | 6 | ||
6 | import { Icon, Badge } from '../'; | 7 | import { Badge, Icon } from '../'; |
7 | import { IWithStyle } from '../typings/generic'; | 8 | import { IWithStyle } from '../typings/generic'; |
8 | 9 | ||
9 | interface IProps extends IWithStyle { | 10 | interface IProps extends IWithStyle { |
10 | badgeClasses?: string; | 11 | badgeClasses?: string; |
11 | iconClasses?: string; | 12 | iconClasses?: string; |
12 | inverted?: boolean; | 13 | inverted?: boolean; |
14 | className?: string; | ||
13 | } | 15 | } |
14 | 16 | ||
15 | const styles = (theme: Theme) => ({ | 17 | const styles = (theme: Theme) => ({ |
@@ -37,6 +39,7 @@ class ProBadgeComponent extends Component<IProps> { | |||
37 | badgeClasses, | 39 | badgeClasses, |
38 | iconClasses, | 40 | iconClasses, |
39 | inverted, | 41 | inverted, |
42 | className, | ||
40 | } = this.props; | 43 | } = this.props; |
41 | 44 | ||
42 | return ( | 45 | return ( |
@@ -46,10 +49,11 @@ class ProBadgeComponent extends Component<IProps> { | |||
46 | classes.badge, | 49 | classes.badge, |
47 | inverted && classes.invertedBadge, | 50 | inverted && classes.invertedBadge, |
48 | badgeClasses, | 51 | badgeClasses, |
52 | className, | ||
49 | ])} | 53 | ])} |
50 | > | 54 | > |
51 | <Icon | 55 | <Icon |
52 | icon="mdiStar" | 56 | icon={mdiStar} |
53 | className={classnames([ | 57 | className={classnames([ |
54 | classes.icon, | 58 | classes.icon, |
55 | inverted && classes.invertedIcon, | 59 | inverted && classes.invertedIcon, |
diff --git a/packages/ui/src/icon/index.tsx b/packages/ui/src/icon/index.tsx index e30d3396d..af467c085 100644 --- a/packages/ui/src/icon/index.tsx +++ b/packages/ui/src/icon/index.tsx | |||
@@ -1,4 +1,3 @@ | |||
1 | import * as mdiIcons from '@mdi/js'; | ||
2 | import MdiIcon from '@mdi/react'; | 1 | import MdiIcon from '@mdi/react'; |
3 | import { Theme } from '@meetfranz/theme'; | 2 | import { Theme } from '@meetfranz/theme'; |
4 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
@@ -8,7 +7,7 @@ import injectStyle from 'react-jss'; | |||
8 | import { IWithStyle } from '../typings/generic'; | 7 | import { IWithStyle } from '../typings/generic'; |
9 | 8 | ||
10 | interface IProps extends IWithStyle { | 9 | interface IProps extends IWithStyle { |
11 | icon: keyof typeof mdiIcons; | 10 | icon: string; |
12 | size?: number; | 11 | size?: number; |
13 | className?: string; | 12 | className?: string; |
14 | } | 13 | } |
@@ -27,16 +26,13 @@ class IconComponent extends Component<IProps> { | |||
27 | render() { | 26 | render() { |
28 | const { | 27 | const { |
29 | classes, | 28 | classes, |
30 | icon: iconName, | 29 | icon, |
31 | size, | 30 | size, |
32 | className, | 31 | className, |
33 | } = this.props; | 32 | } = this.props; |
34 | 33 | ||
35 | let icon = ''; | 34 | if (!icon) { |
36 | if (iconName && mdiIcons[iconName]) { | 35 | console.warn('No Icon specified'); |
37 | icon = mdiIcons[iconName]; | ||
38 | } else if (iconName && !mdiIcons[iconName]) { | ||
39 | console.warn(`Icon '${iconName}' was not found`); | ||
40 | } | 36 | } |
41 | 37 | ||
42 | return ( | 38 | return ( |
diff --git a/packages/ui/src/infobox/index.tsx b/packages/ui/src/infobox/index.tsx index 9066a623e..e4c2c5a3e 100644 --- a/packages/ui/src/infobox/index.tsx +++ b/packages/ui/src/infobox/index.tsx | |||
@@ -1,3 +1,4 @@ | |||
1 | import { mdiClose } from '@mdi/js'; | ||
1 | import { Theme } from '@meetfranz/theme'; | 2 | import { Theme } from '@meetfranz/theme'; |
2 | import classnames from 'classnames'; | 3 | import classnames from 'classnames'; |
3 | import React, { Component } from 'react'; | 4 | import React, { Component } from 'react'; |
@@ -48,13 +49,13 @@ const styles = (theme: Theme) => ({ | |||
48 | position: 'relative', | 49 | position: 'relative', |
49 | overflow: 'hidden', | 50 | overflow: 'hidden', |
50 | height: 'auto', | 51 | height: 'auto', |
52 | marginBottom: 30, | ||
51 | }, | 53 | }, |
52 | infobox: { | 54 | infobox: { |
53 | alignItems: 'center', | 55 | alignItems: 'center', |
54 | borderRadius: theme.borderRadiusSmall, | 56 | borderRadius: theme.borderRadiusSmall, |
55 | display: 'flex', | 57 | display: 'flex', |
56 | height: 'auto', | 58 | height: 'auto', |
57 | marginBottom: 30, | ||
58 | padding: '15px 20px', | 59 | padding: '15px 20px', |
59 | top: 0, | 60 | top: 0, |
60 | transition: 'all 0.5s', | 61 | transition: 'all 0.5s', |
@@ -192,7 +193,7 @@ class InfoboxComponent extends Component<IProps, IState> { | |||
192 | onClick={this.dismiss.bind(this)} | 193 | onClick={this.dismiss.bind(this)} |
193 | className={classes.close} | 194 | className={classes.close} |
194 | > | 195 | > |
195 | <Icon icon="mdiClose" /> | 196 | <Icon icon={mdiClose} /> |
196 | </button> | 197 | </button> |
197 | )} | 198 | )} |
198 | </div> | 199 | </div> |
diff --git a/src/actions/user.js b/src/actions/user.js index ccf1fa56a..5d7d9a899 100644 --- a/src/actions/user.js +++ b/src/actions/user.js | |||
@@ -17,6 +17,9 @@ export default { | |||
17 | retrievePassword: { | 17 | retrievePassword: { |
18 | email: PropTypes.string.isRequired, | 18 | email: PropTypes.string.isRequired, |
19 | }, | 19 | }, |
20 | activateTrial: { | ||
21 | planId: PropTypes.string.isRequired, | ||
22 | }, | ||
20 | invite: { | 23 | invite: { |
21 | invites: PropTypes.array.isRequired, | 24 | invites: PropTypes.array.isRequired, |
22 | }, | 25 | }, |
diff --git a/src/api/UserApi.js b/src/api/UserApi.js index edfb88988..8ba8cd1e9 100644 --- a/src/api/UserApi.js +++ b/src/api/UserApi.js | |||
@@ -25,6 +25,10 @@ export default class UserApi { | |||
25 | return this.server.retrievePassword(email); | 25 | return this.server.retrievePassword(email); |
26 | } | 26 | } |
27 | 27 | ||
28 | activateTrial(data) { | ||
29 | return this.server.activateTrial(data); | ||
30 | } | ||
31 | |||
28 | invite(data) { | 32 | invite(data) { |
29 | return this.server.inviteUser(data); | 33 | return this.server.inviteUser(data); |
30 | } | 34 | } |
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js index a9ce202ff..f56c7b6e4 100644 --- a/src/api/server/ServerApi.js +++ b/src/api/server/ServerApi.js | |||
@@ -77,6 +77,20 @@ export default class ServerApi { | |||
77 | return u.token; | 77 | return u.token; |
78 | } | 78 | } |
79 | 79 | ||
80 | async activateTrial(data) { | ||
81 | const request = await sendAuthRequest(`${API_URL}/payment/trial`, { | ||
82 | method: 'POST', | ||
83 | body: JSON.stringify(data), | ||
84 | }); | ||
85 | if (!request.ok) { | ||
86 | throw request; | ||
87 | } | ||
88 | const trial = await request.json(); | ||
89 | |||
90 | debug('ServerApi::signup resolves', trial); | ||
91 | return true; | ||
92 | } | ||
93 | |||
80 | async inviteUser(data) { | 94 | async inviteUser(data) { |
81 | const request = await sendAuthRequest(`${API_URL}/invite`, { | 95 | const request = await sendAuthRequest(`${API_URL}/invite`, { |
82 | method: 'POST', | 96 | method: 'POST', |
@@ -469,7 +483,7 @@ export default class ServerApi { | |||
469 | return services; | 483 | return services; |
470 | } | 484 | } |
471 | } catch (err) { | 485 | } catch (err) { |
472 | throw (new Error('ServerApi::getLegacyServices no config found')); | 486 | console.error('ServerApi::getLegacyServices no config found'); |
473 | } | 487 | } |
474 | 488 | ||
475 | return []; | 489 | return []; |
diff --git a/src/assets/images/workspaces/teaser_dark.png b/src/assets/images/workspaces/teaser_dark.png new file mode 100644 index 000000000..5b6d7334b --- /dev/null +++ b/src/assets/images/workspaces/teaser_dark.png | |||
Binary files differ | |||
diff --git a/src/assets/images/workspaces/teaser_light.png b/src/assets/images/workspaces/teaser_light.png new file mode 100644 index 000000000..635af43fa --- /dev/null +++ b/src/assets/images/workspaces/teaser_light.png | |||
Binary files differ | |||
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 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { defineMessages, intlShape } from 'react-intl'; | ||
4 | import ms from 'ms'; | ||
5 | import injectSheet from 'react-jss'; | ||
6 | import classnames from 'classnames'; | ||
7 | |||
8 | import InfoBar from './ui/InfoBar'; | ||
9 | |||
10 | const messages = defineMessages({ | ||
11 | message: { | ||
12 | id: 'infobar.trialActivated', | ||
13 | defaultMessage: '!!!Your trial was successfully activated. Happy messaging!', | ||
14 | }, | ||
15 | }); | ||
16 | |||
17 | const 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) | ||
32 | class 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 | |||
94 | export default TrialActivationInfoBar; | ||
diff --git a/src/components/auth/Pricing.js b/src/components/auth/Pricing.js index 7ab14f429..cbeaaa5d9 100644 --- a/src/components/auth/Pricing.js +++ b/src/components/auth/Pricing.js | |||
@@ -1,40 +1,107 @@ | |||
1 | import React, { Component } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | // import { Link } from 'react-router'; | 5 | import injectSheet from 'react-jss'; |
6 | import { H2, Loader } from '@meetfranz/ui'; | ||
7 | import classnames from 'classnames'; | ||
8 | |||
9 | import { Button } from '@meetfranz/forms'; | ||
10 | import { FeatureItem } from '../ui/FeatureItem'; | ||
11 | import { FeatureList } from '../ui/FeatureList'; | ||
6 | 12 | ||
7 | // import Button from '../ui/Button'; | ||
8 | import Loader from '../ui/Loader'; | ||
9 | import Appear from '../ui/effects/Appear'; | ||
10 | import SubscriptionForm from '../../containers/subscription/SubscriptionFormScreen'; | ||
11 | 13 | ||
12 | const messages = defineMessages({ | 14 | const messages = defineMessages({ |
13 | headline: { | 15 | headline: { |
14 | id: 'pricing.headline', | 16 | id: 'pricing.trial.headline', |
15 | defaultMessage: '!!!Support Franz', | 17 | defaultMessage: '!!!Franz Professional', |
18 | }, | ||
19 | personalOffer: { | ||
20 | id: 'pricing.trial.subheadline', | ||
21 | defaultMessage: '!!!Your personal welcome offer:', | ||
22 | }, | ||
23 | noStringsAttachedHeadline: { | ||
24 | id: 'pricing.trial.terms.headline', | ||
25 | defaultMessage: '!!!No strings attached', | ||
26 | }, | ||
27 | noCreditCard: { | ||
28 | id: 'pricing.trial.terms.noCreditCard', | ||
29 | defaultMessage: '!!!No credit card required', | ||
16 | }, | 30 | }, |
17 | monthlySupportLabel: { | 31 | automaticTrialEnd: { |
18 | id: 'pricing.support.label', | 32 | id: 'pricing.trial.terms.automaticTrialEnd', |
19 | defaultMessage: '!!!Select your support plan', | 33 | defaultMessage: '!!!Your free trial ends automatically after 14 days', |
20 | }, | 34 | }, |
21 | submitButtonLabel: { | 35 | activationError: { |
22 | id: 'pricing.submit.label', | 36 | id: 'pricing.trial.error', |
23 | defaultMessage: '!!!Support the development of Franz', | 37 | defaultMessage: '!!!Sorry, we could not activate your trial!', |
24 | }, | 38 | }, |
25 | skipPayment: { | 39 | ctaAccept: { |
26 | id: 'pricing.link.skipPayment', | 40 | id: 'pricing.trial.cta.accept', |
27 | defaultMessage: '!!!I don\'t want to support the development of Franz.', | 41 | defaultMessage: '!!!Yes, upgrade my account to Franz Professional', |
42 | }, | ||
43 | ctaSkip: { | ||
44 | id: 'pricing.trial.cta.skip', | ||
45 | defaultMessage: '!!!Continue to Franz', | ||
46 | }, | ||
47 | featuresHeadline: { | ||
48 | id: 'pricing.trial.features.headline', | ||
49 | defaultMessage: '!!!Franz Professional includes:', | ||
28 | }, | 50 | }, |
29 | }); | 51 | }); |
30 | 52 | ||
31 | export default @observer class Signup extends Component { | 53 | const styles = theme => ({ |
54 | container: { | ||
55 | position: 'relative', | ||
56 | marginLeft: -150, | ||
57 | }, | ||
58 | welcomeOffer: { | ||
59 | textAlign: 'center', | ||
60 | fontWeight: 'bold', | ||
61 | }, | ||
62 | keyTerms: { | ||
63 | textAlign: 'center', | ||
64 | }, | ||
65 | content: { | ||
66 | position: 'relative', | ||
67 | zIndex: 20, | ||
68 | }, | ||
69 | featureContainer: { | ||
70 | width: 300, | ||
71 | position: 'absolute', | ||
72 | left: 'calc(100% / 2 + 225px)', | ||
73 | top: 155, | ||
74 | background: theme.signup.pricing.feature.background, | ||
75 | height: 'auto', | ||
76 | padding: 20, | ||
77 | borderTopRightRadius: theme.borderRadius, | ||
78 | borderBottomRightRadius: theme.borderRadius, | ||
79 | zIndex: 10, | ||
80 | }, | ||
81 | featureItem: { | ||
82 | borderBottom: [1, 'solid', theme.signup.pricing.feature.border], | ||
83 | }, | ||
84 | cta: { | ||
85 | marginTop: 40, | ||
86 | width: '100%', | ||
87 | }, | ||
88 | skipLink: { | ||
89 | textAlign: 'center', | ||
90 | marginTop: 10, | ||
91 | }, | ||
92 | error: { | ||
93 | margin: [20, 0, 0], | ||
94 | color: theme.styleTypes.danger.accent, | ||
95 | }, | ||
96 | }); | ||
97 | |||
98 | export default @observer @injectSheet(styles) class Signup extends Component { | ||
32 | static propTypes = { | 99 | static propTypes = { |
33 | donor: MobxPropTypes.objectOrObservableObject.isRequired, | 100 | onSubmit: PropTypes.func.isRequired, |
34 | isLoading: PropTypes.bool.isRequired, | 101 | isLoadingRequiredData: PropTypes.bool.isRequired, |
35 | isLoadingUser: PropTypes.bool.isRequired, | 102 | isActivatingTrial: PropTypes.bool.isRequired, |
36 | onCloseSubscriptionWindow: PropTypes.func.isRequired, | 103 | trialActivationError: PropTypes.bool.isRequired, |
37 | skipAction: PropTypes.func.isRequired, | 104 | classes: PropTypes.object.isRequired, |
38 | }; | 105 | }; |
39 | 106 | ||
40 | static contextTypes = { | 107 | static contextTypes = { |
@@ -43,70 +110,37 @@ export default @observer class Signup extends Component { | |||
43 | 110 | ||
44 | render() { | 111 | render() { |
45 | const { | 112 | const { |
46 | donor, | 113 | onSubmit, |
47 | isLoading, | 114 | isLoadingRequiredData, |
48 | isLoadingUser, | 115 | isActivatingTrial, |
49 | onCloseSubscriptionWindow, | 116 | trialActivationError, |
50 | skipAction, | 117 | classes, |
51 | } = this.props; | 118 | } = this.props; |
52 | const { intl } = this.context; | 119 | const { intl } = this.context; |
53 | 120 | ||
54 | return ( | 121 | return ( |
55 | <div className="auth__scroll-container"> | 122 | <div className={classnames('auth__scroll-container', classes.container)}> |
56 | <div className="auth__container auth__container--signup"> | 123 | <div className={classnames('auth__container', 'auth__container--signup', classes.content)}> |
57 | <form className="franz-form auth__form"> | 124 | <form className="franz-form auth__form"> |
58 | <img | 125 | {isLoadingRequiredData ? <Loader /> : ( |
59 | src="./assets/images/sm.png" | 126 | <img |
60 | className="auth__logo auth__logo--sm" | 127 | src="./assets/images/sm.png" |
61 | alt="" | 128 | className="auth__logo auth__logo--sm" |
62 | /> | 129 | alt="" |
130 | /> | ||
131 | )} | ||
132 | <p className={classes.welcomeOffer}>{intl.formatMessage(messages.personalOffer)}</p> | ||
63 | <h1>{intl.formatMessage(messages.headline)}</h1> | 133 | <h1>{intl.formatMessage(messages.headline)}</h1> |
64 | <div className="auth__letter"> | 134 | <div className="auth__letter"> |
65 | {isLoadingUser && ( | 135 | <p> |
66 | <p>Loading</p> | 136 | We built Franz with a lot of effort, manpower and love, |
67 | )} | 137 | to boost up your messaging experience. |
68 | {!isLoadingUser && ( | 138 | <br /> |
69 | donor.amount ? ( | 139 | </p> |
70 | <span> | 140 | <p> |
71 | <p> | 141 | Get the free 14 day Franz Professional trial and see your communication evolving. |
72 | Thank you so much for your previous donation of | 142 | <br /> |
73 | {' '} | 143 | </p> |
74 | <strong> | ||
75 | $ | ||
76 | {donor.amount} | ||
77 | </strong> | ||
78 | . | ||
79 | <br /> | ||
80 | Your support allowed us to get where we are today. | ||
81 | <br /> | ||
82 | </p> | ||
83 | <p> | ||
84 | As an early supporter, you get | ||
85 | {' '} | ||
86 | <strong>a lifetime premium supporter license</strong> | ||
87 | {' '} | ||
88 | without any | ||
89 | additional charges. | ||
90 | </p> | ||
91 | <p> | ||
92 | However, If you want to keep supporting us, you are more than welcome to subscribe to a plan. | ||
93 | <br /> | ||
94 | <br /> | ||
95 | </p> | ||
96 | </span> | ||
97 | ) : ( | ||
98 | <span> | ||
99 | <p> | ||
100 | We built Franz with a lot of effort, manpower and love, | ||
101 | to bring you the best messaging experience. | ||
102 | <br /> | ||
103 | </p> | ||
104 | <p> | ||
105 | Getting a Franz Premium Supporter License will allow us to keep improving Franz for you. | ||
106 | </p> | ||
107 | </span> | ||
108 | ) | ||
109 | )} | ||
110 | <p> | 144 | <p> |
111 | Thanks for being a hero. | 145 | Thanks for being a hero. |
112 | </p> | 146 | </p> |
@@ -114,20 +148,48 @@ export default @observer class Signup extends Component { | |||
114 | <strong>Stefan Malzner</strong> | 148 | <strong>Stefan Malzner</strong> |
115 | </p> | 149 | </p> |
116 | </div> | 150 | </div> |
117 | <Loader loaded={!isLoading}> | 151 | <div className={classes.keyTerms}> |
118 | <Appear transitionName="slideDown"> | 152 | <H2> |
119 | <span className="label">{intl.formatMessage(messages.monthlySupportLabel)}</span> | 153 | {intl.formatMessage(messages.noStringsAttachedHeadline)} |
120 | <SubscriptionForm | 154 | </H2> |
121 | onCloseWindow={onCloseSubscriptionWindow} | 155 | <ul className={classes.keyTermsList}> |
122 | showSkipOption | 156 | <FeatureItem icon="👉" name={intl.formatMessage(messages.noCreditCard)} /> |
123 | skipAction={skipAction} | 157 | <FeatureItem icon="👉" name={intl.formatMessage(messages.automaticTrialEnd)} /> |
124 | hideInfo={Boolean(donor.amount)} | 158 | </ul> |
125 | skipButtonLabel={intl.formatMessage(messages.skipPayment)} | 159 | </div> |
126 | /> | 160 | {trialActivationError && ( |
127 | </Appear> | 161 | <p className={classes.error}>{intl.formatMessage(messages.activationError)}</p> |
128 | </Loader> | 162 | )} |
163 | <Button | ||
164 | label={intl.formatMessage(messages.ctaAccept)} | ||
165 | className={classes.cta} | ||
166 | onClick={onSubmit} | ||
167 | busy={isActivatingTrial} | ||
168 | disabled={isLoadingRequiredData || isActivatingTrial} | ||
169 | /> | ||
170 | <p className={classes.skipLink}> | ||
171 | <a href="#/">{intl.formatMessage(messages.ctaSkip)}</a> | ||
172 | </p> | ||
129 | </form> | 173 | </form> |
130 | </div> | 174 | </div> |
175 | <div className={classes.featureContainer}> | ||
176 | <H2> | ||
177 | {intl.formatMessage(messages.featuresHeadline)} | ||
178 | </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 /> | ||
192 | </div> | ||
131 | </div> | 193 | </div> |
132 | ); | 194 | ); |
133 | } | 195 | } |
diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js index d9b83eeb8..0499d764b 100644 --- a/src/components/auth/Signup.js +++ b/src/components/auth/Signup.js | |||
@@ -7,7 +7,6 @@ import { isDevMode, useLiveAPI } from '../../environment'; | |||
7 | import Form from '../../lib/Form'; | 7 | import Form from '../../lib/Form'; |
8 | import { required, email, minLength } from '../../helpers/validation-helpers'; | 8 | import { required, email, minLength } from '../../helpers/validation-helpers'; |
9 | import Input from '../ui/Input'; | 9 | import Input from '../ui/Input'; |
10 | import Radio from '../ui/Radio'; | ||
11 | import Button from '../ui/Button'; | 10 | import Button from '../ui/Button'; |
12 | import Link from '../ui/Link'; | 11 | import Link from '../ui/Link'; |
13 | import Infobox from '../ui/Infobox'; | 12 | import Infobox from '../ui/Infobox'; |
@@ -31,10 +30,10 @@ const messages = defineMessages({ | |||
31 | id: 'signup.email.label', | 30 | id: 'signup.email.label', |
32 | defaultMessage: '!!!Email address', | 31 | defaultMessage: '!!!Email address', |
33 | }, | 32 | }, |
34 | companyLabel: { | 33 | // companyLabel: { |
35 | id: 'signup.company.label', | 34 | // id: 'signup.company.label', |
36 | defaultMessage: '!!!Company', | 35 | // defaultMessage: '!!!Company', |
37 | }, | 36 | // }, |
38 | passwordLabel: { | 37 | passwordLabel: { |
39 | id: 'signup.password.label', | 38 | id: 'signup.password.label', |
40 | defaultMessage: '!!!Password', | 39 | defaultMessage: '!!!Password', |
@@ -79,20 +78,6 @@ export default @observer class Signup extends Component { | |||
79 | 78 | ||
80 | form = new Form({ | 79 | form = new Form({ |
81 | fields: { | 80 | fields: { |
82 | accountType: { | ||
83 | value: 'individual', | ||
84 | validators: [required], | ||
85 | options: [{ | ||
86 | value: 'individual', | ||
87 | label: 'Individual', | ||
88 | }, { | ||
89 | value: 'non-profit', | ||
90 | label: 'Non-Profit', | ||
91 | }, { | ||
92 | value: 'company', | ||
93 | label: 'Company', | ||
94 | }], | ||
95 | }, | ||
96 | firstname: { | 81 | firstname: { |
97 | label: this.context.intl.formatMessage(messages.firstnameLabel), | 82 | label: this.context.intl.formatMessage(messages.firstnameLabel), |
98 | value: '', | 83 | value: '', |
@@ -108,10 +93,6 @@ export default @observer class Signup extends Component { | |||
108 | value: '', | 93 | value: '', |
109 | validators: [required, email], | 94 | validators: [required, email], |
110 | }, | 95 | }, |
111 | organization: { | ||
112 | label: this.context.intl.formatMessage(messages.companyLabel), | ||
113 | value: '', // TODO: make required when accountType: company | ||
114 | }, | ||
115 | password: { | 96 | password: { |
116 | label: this.context.intl.formatMessage(messages.passwordLabel), | 97 | label: this.context.intl.formatMessage(messages.passwordLabel), |
117 | value: '', | 98 | value: '', |
@@ -151,7 +132,6 @@ export default @observer class Signup extends Component { | |||
151 | In Dev Mode your data is not persistent. Please use the live app for accesing the production API. | 132 | In Dev Mode your data is not persistent. Please use the live app for accesing the production API. |
152 | </Infobox> | 133 | </Infobox> |
153 | )} | 134 | )} |
154 | <Radio field={form.$('accountType')} showLabel={false} /> | ||
155 | <div className="grid__row"> | 135 | <div className="grid__row"> |
156 | <Input field={form.$('firstname')} focus /> | 136 | <Input field={form.$('firstname')} focus /> |
157 | <Input field={form.$('lastname')} /> | 137 | <Input field={form.$('lastname')} /> |
@@ -162,9 +142,6 @@ export default @observer class Signup extends Component { | |||
162 | showPasswordToggle | 142 | showPasswordToggle |
163 | scorePassword | 143 | scorePassword |
164 | /> | 144 | /> |
165 | {form.$('accountType').value === 'company' && ( | ||
166 | <Input field={form.$('organization')} /> | ||
167 | )} | ||
168 | {error.code === 'email-duplicate' && ( | 145 | {error.code === 'email-duplicate' && ( |
169 | <p className="error-message center">{intl.formatMessage(messages.emailDuplicate)}</p> | 146 | <p className="error-message center">{intl.formatMessage(messages.emailDuplicate)}</p> |
170 | )} | 147 | )} |
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js index dbf7d3c21..941e60bfd 100644 --- a/src/components/layout/AppLayout.js +++ b/src/components/layout/AppLayout.js | |||
@@ -17,6 +17,7 @@ import { isWindows } from '../../environment'; | |||
17 | import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator'; | 17 | import WorkspaceSwitchingIndicator from '../../features/workspaces/components/WorkspaceSwitchingIndicator'; |
18 | import { workspaceStore } from '../../features/workspaces'; | 18 | import { workspaceStore } from '../../features/workspaces'; |
19 | import AppUpdateInfoBar from '../AppUpdateInfoBar'; | 19 | import AppUpdateInfoBar from '../AppUpdateInfoBar'; |
20 | import TrialActivationInfoBar from '../TrialActivationInfoBar'; | ||
20 | import Todos from '../../features/todos/containers/TodosScreen'; | 21 | import Todos from '../../features/todos/containers/TodosScreen'; |
21 | 22 | ||
22 | function createMarkup(HTMLString) { | 23 | function createMarkup(HTMLString) { |
@@ -70,6 +71,7 @@ class AppLayout extends Component { | |||
70 | retryRequiredRequests: PropTypes.func.isRequired, | 71 | retryRequiredRequests: PropTypes.func.isRequired, |
71 | areRequiredRequestsLoading: PropTypes.bool.isRequired, | 72 | areRequiredRequestsLoading: PropTypes.bool.isRequired, |
72 | isDelayAppScreenVisible: PropTypes.bool.isRequired, | 73 | isDelayAppScreenVisible: PropTypes.bool.isRequired, |
74 | hasActivatedTrial: PropTypes.bool.isRequired, | ||
73 | }; | 75 | }; |
74 | 76 | ||
75 | static defaultProps = { | 77 | static defaultProps = { |
@@ -89,7 +91,6 @@ class AppLayout extends Component { | |||
89 | sidebar, | 91 | sidebar, |
90 | services, | 92 | services, |
91 | children, | 93 | children, |
92 | // isOnline, | ||
93 | news, | 94 | news, |
94 | showServicesUpdatedInfoBar, | 95 | showServicesUpdatedInfoBar, |
95 | appUpdateIsDownloaded, | 96 | appUpdateIsDownloaded, |
@@ -102,6 +103,7 @@ class AppLayout extends Component { | |||
102 | retryRequiredRequests, | 103 | retryRequiredRequests, |
103 | areRequiredRequestsLoading, | 104 | areRequiredRequestsLoading, |
104 | isDelayAppScreenVisible, | 105 | isDelayAppScreenVisible, |
106 | hasActivatedTrial, | ||
105 | } = this.props; | 107 | } = this.props; |
106 | 108 | ||
107 | const { intl } = this.context; | 109 | const { intl } = this.context; |
@@ -126,17 +128,20 @@ class AppLayout extends Component { | |||
126 | <span dangerouslySetInnerHTML={createMarkup(item.message)} /> | 128 | <span dangerouslySetInnerHTML={createMarkup(item.message)} /> |
127 | </InfoBar> | 129 | </InfoBar> |
128 | ))} | 130 | ))} |
131 | {hasActivatedTrial && ( | ||
132 | <TrialActivationInfoBar /> | ||
133 | )} | ||
129 | {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( | 134 | {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( |
130 | <InfoBar | 135 | <InfoBar |
131 | type="danger" | 136 | type="danger" |
132 | ctaLabel="Try again" | 137 | ctaLabel="Try again" |
133 | ctaLoading={areRequiredRequestsLoading} | 138 | ctaLoading={areRequiredRequestsLoading} |
134 | sticky | 139 | sticky |
135 | onClick={retryRequiredRequests} | 140 | onClick={retryRequiredRequests} |
136 | > | 141 | > |
137 | <span className="mdi mdi-flash" /> | 142 | <span className="mdi mdi-flash" /> |
138 | {intl.formatMessage(messages.requiredRequestsFailed)} | 143 | {intl.formatMessage(messages.requiredRequestsFailed)} |
139 | </InfoBar> | 144 | </InfoBar> |
140 | )} | 145 | )} |
141 | {showServicesUpdatedInfoBar && ( | 146 | {showServicesUpdatedInfoBar && ( |
142 | <InfoBar | 147 | <InfoBar |
diff --git a/src/components/services/content/ServiceRestricted.js b/src/components/services/content/ServiceRestricted.js new file mode 100644 index 000000000..4b8d926aa --- /dev/null +++ b/src/components/services/content/ServiceRestricted.js | |||
@@ -0,0 +1,78 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | |||
6 | import { serviceLimitStore } from '../../../features/serviceLimit'; | ||
7 | import Button from '../../ui/Button'; | ||
8 | import { RESTRICTION_TYPES } from '../../../models/Service'; | ||
9 | |||
10 | const messages = defineMessages({ | ||
11 | headlineServiceLimit: { | ||
12 | id: 'service.restrictedHandler.serviceLimit.headline', | ||
13 | defaultMessage: '!!!You have reached your service limit.', | ||
14 | }, | ||
15 | textServiceLimit: { | ||
16 | id: 'service.restrictedHandler.serviceLimit.text', | ||
17 | defaultMessage: '!!!Please upgrade your account to use more than {count} services.', | ||
18 | }, | ||
19 | headlineCustomUrl: { | ||
20 | id: 'service.restrictedHandler.customUrl.headline', | ||
21 | defaultMessage: '!!!Franz Professional Plan required', | ||
22 | }, | ||
23 | textCustomUrl: { | ||
24 | id: 'service.restrictedHandler.customUrl.text', | ||
25 | defaultMessage: '!!!Please upgrade to the Franz Professional plan to use custom urls & self hosted services.', | ||
26 | }, | ||
27 | action: { | ||
28 | id: 'service.restrictedHandler.action', | ||
29 | defaultMessage: '!!!Upgrade Account', | ||
30 | }, | ||
31 | }); | ||
32 | |||
33 | export default @observer class ServiceRestricted extends Component { | ||
34 | static propTypes = { | ||
35 | name: PropTypes.string.isRequired, | ||
36 | upgrade: PropTypes.func.isRequired, | ||
37 | type: PropTypes.number.isRequired, | ||
38 | }; | ||
39 | |||
40 | static contextTypes = { | ||
41 | intl: intlShape, | ||
42 | }; | ||
43 | |||
44 | countdownInterval = null; | ||
45 | |||
46 | countdownIntervalTimeout = 1000; | ||
47 | |||
48 | render() { | ||
49 | const { | ||
50 | name, | ||
51 | upgrade, | ||
52 | type, | ||
53 | } = this.props; | ||
54 | const { intl } = this.context; | ||
55 | |||
56 | return ( | ||
57 | <div className="services__info-layer"> | ||
58 | {type === RESTRICTION_TYPES.SERVICE_LIMIT && ( | ||
59 | <> | ||
60 | <h1>{intl.formatMessage(messages.headlineServiceLimit)}</h1> | ||
61 | <p>{intl.formatMessage(messages.textServiceLimit, { count: serviceLimitStore.serviceLimit })}</p> | ||
62 | </> | ||
63 | )} | ||
64 | {type === RESTRICTION_TYPES.CUSTOM_URL && ( | ||
65 | <> | ||
66 | <h1>{intl.formatMessage(messages.headlineCustomUrl)}</h1> | ||
67 | <p>{intl.formatMessage(messages.textCustomUrl)}</p> | ||
68 | </> | ||
69 | )} | ||
70 | <Button | ||
71 | label={intl.formatMessage(messages.action, { name })} | ||
72 | buttonType="inverted" | ||
73 | onClick={() => upgrade()} | ||
74 | /> | ||
75 | </div> | ||
76 | ); | ||
77 | } | ||
78 | } | ||
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js index 13148b9b3..f65f51346 100644 --- a/src/components/services/content/ServiceView.js +++ b/src/components/services/content/ServiceView.js | |||
@@ -10,6 +10,7 @@ import WebviewLoader from '../../ui/WebviewLoader'; | |||
10 | import WebviewCrashHandler from './WebviewCrashHandler'; | 10 | import WebviewCrashHandler from './WebviewCrashHandler'; |
11 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; | 11 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; |
12 | import ServiceDisabled from './ServiceDisabled'; | 12 | import ServiceDisabled from './ServiceDisabled'; |
13 | import ServiceRestricted from './ServiceRestricted'; | ||
13 | import ServiceWebview from './ServiceWebview'; | 14 | import ServiceWebview from './ServiceWebview'; |
14 | 15 | ||
15 | export default @observer class ServiceView extends Component { | 16 | export default @observer class ServiceView extends Component { |
@@ -21,6 +22,7 @@ export default @observer class ServiceView extends Component { | |||
21 | edit: PropTypes.func.isRequired, | 22 | edit: PropTypes.func.isRequired, |
22 | enable: PropTypes.func.isRequired, | 23 | enable: PropTypes.func.isRequired, |
23 | isActive: PropTypes.bool, | 24 | isActive: PropTypes.bool, |
25 | upgrade: PropTypes.func.isRequired, | ||
24 | }; | 26 | }; |
25 | 27 | ||
26 | static defaultProps = { | 28 | static defaultProps = { |
@@ -72,6 +74,7 @@ export default @observer class ServiceView extends Component { | |||
72 | reload, | 74 | reload, |
73 | edit, | 75 | edit, |
74 | enable, | 76 | enable, |
77 | upgrade, | ||
75 | } = this.props; | 78 | } = this.props; |
76 | 79 | ||
77 | const webviewClasses = classnames({ | 80 | const webviewClasses = classnames({ |
@@ -99,7 +102,7 @@ export default @observer class ServiceView extends Component { | |||
99 | reload={reload} | 102 | reload={reload} |
100 | /> | 103 | /> |
101 | )} | 104 | )} |
102 | {service.isEnabled && service.isLoading && service.isFirstLoad && ( | 105 | {service.isEnabled && service.isLoading && service.isFirstLoad && !service.isServiceAccessRestricted && ( |
103 | <WebviewLoader | 106 | <WebviewLoader |
104 | loaded={false} | 107 | loaded={false} |
105 | name={service.name} | 108 | name={service.name} |
@@ -126,11 +129,21 @@ export default @observer class ServiceView extends Component { | |||
126 | )} | 129 | )} |
127 | </Fragment> | 130 | </Fragment> |
128 | ) : ( | 131 | ) : ( |
129 | <ServiceWebview | 132 | <> |
130 | service={service} | 133 | {service.isServiceAccessRestricted ? ( |
131 | setWebviewReference={setWebviewReference} | 134 | <ServiceRestricted |
132 | detachService={detachService} | 135 | name={service.recipe.name} |
133 | /> | 136 | upgrade={upgrade} |
137 | type={service.restrictionType} | ||
138 | /> | ||
139 | ) : ( | ||
140 | <ServiceWebview | ||
141 | service={service} | ||
142 | setWebviewReference={setWebviewReference} | ||
143 | detachService={detachService} | ||
144 | /> | ||
145 | )} | ||
146 | </> | ||
134 | )} | 147 | )} |
135 | {statusBar} | 148 | {statusBar} |
136 | </div> | 149 | </div> |
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js index 8f8c38a11..73c27bfb6 100644 --- a/src/components/services/content/Services.js +++ b/src/components/services/content/Services.js | |||
@@ -3,6 +3,9 @@ import PropTypes from 'prop-types'; | |||
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; |
4 | import { Link } from 'react-router'; | 4 | import { Link } from 'react-router'; |
5 | import { defineMessages, intlShape } from 'react-intl'; | 5 | import { defineMessages, intlShape } from 'react-intl'; |
6 | import Confetti from 'react-confetti'; | ||
7 | import ms from 'ms'; | ||
8 | import injectSheet from 'react-jss'; | ||
6 | 9 | ||
7 | import ServiceView from './ServiceView'; | 10 | import ServiceView from './ServiceView'; |
8 | import Appear from '../../ui/effects/Appear'; | 11 | import Appear from '../../ui/effects/Appear'; |
@@ -18,7 +21,17 @@ const messages = defineMessages({ | |||
18 | }, | 21 | }, |
19 | }); | 22 | }); |
20 | 23 | ||
21 | export default @observer class Services extends Component { | 24 | |
25 | const styles = { | ||
26 | confettiContainer: { | ||
27 | position: 'absolute', | ||
28 | width: '100%', | ||
29 | zIndex: 9999, | ||
30 | pointerEvents: 'none', | ||
31 | }, | ||
32 | }; | ||
33 | |||
34 | export default @observer @injectSheet(styles) class Services extends Component { | ||
22 | static propTypes = { | 35 | static propTypes = { |
23 | services: MobxPropTypes.arrayOrObservableArray, | 36 | services: MobxPropTypes.arrayOrObservableArray, |
24 | setWebviewReference: PropTypes.func.isRequired, | 37 | setWebviewReference: PropTypes.func.isRequired, |
@@ -28,6 +41,9 @@ export default @observer class Services extends Component { | |||
28 | reload: PropTypes.func.isRequired, | 41 | reload: PropTypes.func.isRequired, |
29 | openSettings: PropTypes.func.isRequired, | 42 | openSettings: PropTypes.func.isRequired, |
30 | update: PropTypes.func.isRequired, | 43 | update: PropTypes.func.isRequired, |
44 | userHasCompletedSignup: PropTypes.bool.isRequired, | ||
45 | hasActivatedTrial: PropTypes.bool.isRequired, | ||
46 | classes: PropTypes.object.isRequired, | ||
31 | }; | 47 | }; |
32 | 48 | ||
33 | static defaultProps = { | 49 | static defaultProps = { |
@@ -38,6 +54,18 @@ export default @observer class Services extends Component { | |||
38 | intl: intlShape, | 54 | intl: intlShape, |
39 | }; | 55 | }; |
40 | 56 | ||
57 | state = { | ||
58 | showConfetti: true, | ||
59 | } | ||
60 | |||
61 | componentDidMount() { | ||
62 | window.setTimeout(() => { | ||
63 | this.setState({ | ||
64 | showConfetti: false, | ||
65 | }); | ||
66 | }, ms('8s')); | ||
67 | } | ||
68 | |||
41 | render() { | 69 | render() { |
42 | const { | 70 | const { |
43 | services, | 71 | services, |
@@ -48,11 +76,28 @@ export default @observer class Services extends Component { | |||
48 | reload, | 76 | reload, |
49 | openSettings, | 77 | openSettings, |
50 | update, | 78 | update, |
79 | userHasCompletedSignup, | ||
80 | hasActivatedTrial, | ||
81 | classes, | ||
51 | } = this.props; | 82 | } = this.props; |
83 | |||
84 | const { | ||
85 | showConfetti, | ||
86 | } = this.state; | ||
87 | |||
52 | const { intl } = this.context; | 88 | const { intl } = this.context; |
53 | 89 | ||
54 | return ( | 90 | return ( |
55 | <div className="services"> | 91 | <div className="services"> |
92 | {(userHasCompletedSignup || hasActivatedTrial) && ( | ||
93 | <div className={classes.confettiContainer}> | ||
94 | <Confetti | ||
95 | width={window.width} | ||
96 | height={window.height} | ||
97 | numberOfPieces={showConfetti ? 200 : 0} | ||
98 | /> | ||
99 | </div> | ||
100 | )} | ||
56 | {services.length === 0 && ( | 101 | {services.length === 0 && ( |
57 | <Appear | 102 | <Appear |
58 | timeout={1500} | 103 | timeout={1500} |
@@ -89,6 +134,7 @@ export default @observer class Services extends Component { | |||
89 | }, | 134 | }, |
90 | redirect: false, | 135 | redirect: false, |
91 | })} | 136 | })} |
137 | upgrade={() => openSettings({ path: 'user' })} | ||
92 | /> | 138 | /> |
93 | ))} | 139 | ))} |
94 | </div> | 140 | </div> |
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js index 3f6964b6b..4fd1e8163 100644 --- a/src/components/settings/account/AccountDashboard.js +++ b/src/components/settings/account/AccountDashboard.js | |||
@@ -1,14 +1,18 @@ | |||
1 | import React, { Component, Fragment } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import ReactTooltip from 'react-tooltip'; | 5 | import ReactTooltip from 'react-tooltip'; |
6 | import { ProBadge } from '@meetfranz/ui'; | 6 | import { |
7 | ProBadge, H1, H2, | ||
8 | } from '@meetfranz/ui'; | ||
9 | import moment from 'moment'; | ||
7 | 10 | ||
8 | import Loader from '../../ui/Loader'; | 11 | import Loader from '../../ui/Loader'; |
9 | import Button from '../../ui/Button'; | 12 | import Button from '../../ui/Button'; |
10 | import Infobox from '../../ui/Infobox'; | 13 | import Infobox from '../../ui/Infobox'; |
11 | import SubscriptionForm from '../../../containers/subscription/SubscriptionFormScreen'; | 14 | import SubscriptionForm from '../../../containers/subscription/SubscriptionFormScreen'; |
15 | import { i18nPlanName } from '../../../helpers/plan-helpers'; | ||
12 | 16 | ||
13 | const messages = defineMessages({ | 17 | const messages = defineMessages({ |
14 | headline: { | 18 | headline: { |
@@ -19,10 +23,6 @@ const messages = defineMessages({ | |||
19 | id: 'settings.account.headlineSubscription', | 23 | id: 'settings.account.headlineSubscription', |
20 | defaultMessage: '!!!Your Subscription', | 24 | defaultMessage: '!!!Your Subscription', |
21 | }, | 25 | }, |
22 | headlineUpgrade: { | ||
23 | id: 'settings.account.headlineUpgrade', | ||
24 | defaultMessage: '!!!Upgrade your Account', | ||
25 | }, | ||
26 | headlineDangerZone: { | 26 | headlineDangerZone: { |
27 | id: 'settings.account.headlineDangerZone', | 27 | id: 'settings.account.headlineDangerZone', |
28 | defaultMessage: '!!Danger Zone', | 28 | defaultMessage: '!!Danger Zone', |
@@ -31,6 +31,10 @@ const messages = defineMessages({ | |||
31 | id: 'settings.account.manageSubscription.label', | 31 | id: 'settings.account.manageSubscription.label', |
32 | defaultMessage: '!!!Manage your subscription', | 32 | defaultMessage: '!!!Manage your subscription', |
33 | }, | 33 | }, |
34 | upgradeAccountToPro: { | ||
35 | id: 'settings.account.upgradeToPro.label', | ||
36 | defaultMessage: '!!!Upgrade to Franz Professional', | ||
37 | }, | ||
34 | accountTypeBasic: { | 38 | accountTypeBasic: { |
35 | id: 'settings.account.accountType.basic', | 39 | id: 'settings.account.accountType.basic', |
36 | defaultMessage: '!!!Basic Account', | 40 | defaultMessage: '!!!Basic Account', |
@@ -71,21 +75,38 @@ const messages = defineMessages({ | |||
71 | id: 'settings.account.deleteEmailSent', | 75 | id: 'settings.account.deleteEmailSent', |
72 | defaultMessage: '!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!', | 76 | defaultMessage: '!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!', |
73 | }, | 77 | }, |
78 | trial: { | ||
79 | id: 'settings.account.trial', | ||
80 | defaultMessage: '!!!Free Trial', | ||
81 | }, | ||
82 | yourLicense: { | ||
83 | id: 'settings.account.yourLicense', | ||
84 | defaultMessage: '!!!Your Franz License:', | ||
85 | }, | ||
86 | trialEndsIn: { | ||
87 | id: 'settings.account.trialEndsIn', | ||
88 | defaultMessage: '!!!Your free trial ends in {duration}.', | ||
89 | }, | ||
90 | trialUpdateBillingInformation: { | ||
91 | id: 'settings.account.trialUpdateBillingInfo', | ||
92 | defaultMessage: '!!!Please update your billing info to continue using {license} after your trial period.', | ||
93 | }, | ||
74 | }); | 94 | }); |
75 | 95 | ||
76 | export default @observer class AccountDashboard extends Component { | 96 | @observer |
97 | class AccountDashboard extends Component { | ||
77 | static propTypes = { | 98 | static propTypes = { |
78 | user: MobxPropTypes.observableObject.isRequired, | 99 | user: MobxPropTypes.observableObject.isRequired, |
100 | isProUser: PropTypes.bool.isRequired, | ||
79 | isLoading: PropTypes.bool.isRequired, | 101 | isLoading: PropTypes.bool.isRequired, |
80 | isLoadingPlans: PropTypes.bool.isRequired, | ||
81 | userInfoRequestFailed: PropTypes.bool.isRequired, | 102 | userInfoRequestFailed: PropTypes.bool.isRequired, |
82 | retryUserInfoRequest: PropTypes.func.isRequired, | 103 | retryUserInfoRequest: PropTypes.func.isRequired, |
83 | onCloseSubscriptionWindow: PropTypes.func.isRequired, | ||
84 | deleteAccount: PropTypes.func.isRequired, | 104 | deleteAccount: PropTypes.func.isRequired, |
85 | isLoadingDeleteAccount: PropTypes.bool.isRequired, | 105 | isLoadingDeleteAccount: PropTypes.bool.isRequired, |
86 | isDeleteAccountSuccessful: PropTypes.bool.isRequired, | 106 | isDeleteAccountSuccessful: PropTypes.bool.isRequired, |
87 | openEditAccount: PropTypes.func.isRequired, | 107 | openEditAccount: PropTypes.func.isRequired, |
88 | openBilling: PropTypes.func.isRequired, | 108 | openBilling: PropTypes.func.isRequired, |
109 | upgradeToPro: PropTypes.func.isRequired, | ||
89 | openInvoices: PropTypes.func.isRequired, | 110 | openInvoices: PropTypes.func.isRequired, |
90 | }; | 111 | }; |
91 | 112 | ||
@@ -96,20 +117,26 @@ export default @observer class AccountDashboard extends Component { | |||
96 | render() { | 117 | render() { |
97 | const { | 118 | const { |
98 | user, | 119 | user, |
120 | isProUser, | ||
99 | isLoading, | 121 | isLoading, |
100 | isLoadingPlans, | ||
101 | userInfoRequestFailed, | 122 | userInfoRequestFailed, |
102 | retryUserInfoRequest, | 123 | retryUserInfoRequest, |
103 | onCloseSubscriptionWindow, | ||
104 | deleteAccount, | 124 | deleteAccount, |
105 | isLoadingDeleteAccount, | 125 | isLoadingDeleteAccount, |
106 | isDeleteAccountSuccessful, | 126 | isDeleteAccountSuccessful, |
107 | openEditAccount, | 127 | openEditAccount, |
108 | openBilling, | 128 | openBilling, |
129 | upgradeToPro, | ||
109 | openInvoices, | 130 | openInvoices, |
110 | } = this.props; | 131 | } = this.props; |
111 | const { intl } = this.context; | 132 | const { intl } = this.context; |
112 | 133 | ||
134 | let planName = ''; | ||
135 | |||
136 | if (user.team && user.team.plan) { | ||
137 | planName = i18nPlanName(user.team.plan, intl); | ||
138 | } | ||
139 | |||
113 | return ( | 140 | return ( |
114 | <div className="settings__main"> | 141 | <div className="settings__main"> |
115 | <div className="settings__header"> | 142 | <div className="settings__header"> |
@@ -135,82 +162,115 @@ export default @observer class AccountDashboard extends Component { | |||
135 | )} | 162 | )} |
136 | 163 | ||
137 | {!userInfoRequestFailed && ( | 164 | {!userInfoRequestFailed && ( |
138 | <Fragment> | 165 | <> |
139 | {!isLoading && ( | 166 | {!isLoading && ( |
140 | <div className="account"> | 167 | <> |
141 | <div className="account__box account__box--flex"> | 168 | <div className="account"> |
142 | <div className="account__avatar"> | 169 | <div className="account__box account__box--flex"> |
143 | <img | 170 | <div className="account__avatar"> |
144 | src="./assets/images/logo.svg" | 171 | <img |
145 | alt="" | 172 | src="./assets/images/logo.svg" |
146 | /> | 173 | alt="" |
147 | </div> | 174 | /> |
148 | <div className="account__info"> | 175 | </div> |
149 | <h2> | 176 | <div className="account__info"> |
150 | <span className="username">{`${user.firstname} ${user.lastname}`}</span> | 177 | <H1> |
178 | <span className="username">{`${user.firstname} ${user.lastname}`}</span> | ||
179 | {user.isPremium && ( | ||
180 | <> | ||
181 | {' '} | ||
182 | <ProBadge /> | ||
183 | </> | ||
184 | )} | ||
185 | </H1> | ||
186 | <p> | ||
187 | {user.organization && `${user.organization}, `} | ||
188 | {user.email} | ||
189 | </p> | ||
151 | {user.isPremium && ( | 190 | {user.isPremium && ( |
191 | <div className="manage-user-links"> | ||
192 | <Button | ||
193 | label={intl.formatMessage(messages.accountEditButton)} | ||
194 | className="franz-form__button--inverted" | ||
195 | onClick={openEditAccount} | ||
196 | /> | ||
197 | </div> | ||
198 | )} | ||
199 | </div> | ||
200 | {!user.isPremium && ( | ||
201 | <Button | ||
202 | label={intl.formatMessage(messages.accountEditButton)} | ||
203 | className="franz-form__button--inverted" | ||
204 | onClick={openEditAccount} | ||
205 | /> | ||
206 | )} | ||
207 | </div> | ||
208 | </div> | ||
209 | {user.isPremium && user.isSubscriptionOwner && ( | ||
210 | <div className="account"> | ||
211 | <div className="account__box"> | ||
212 | <H2> | ||
213 | {intl.formatMessage(messages.yourLicense)} | ||
214 | </H2> | ||
215 | <p> | ||
216 | {planName} | ||
217 | {user.team.isTrial && ( | ||
218 | <> | ||
219 | {' – '} | ||
220 | {intl.formatMessage(messages.trial)} | ||
221 | </> | ||
222 | )} | ||
223 | </p> | ||
224 | {user.team.isTrial && ( | ||
152 | <> | 225 | <> |
153 | {' '} | 226 | <br /> |
154 | <ProBadge /> | 227 | <p> |
155 | <span className="badge badge--premium">{intl.formatMessage(messages.accountTypePremium)}</span> | 228 | {intl.formatMessage(messages.trialEndsIn, { |
229 | duration: moment.duration(moment().diff(user.team.trialEnd)).humanize(), | ||
230 | })} | ||
231 | </p> | ||
232 | <p> | ||
233 | {intl.formatMessage(messages.trialUpdateBillingInformation, { | ||
234 | license: planName, | ||
235 | })} | ||
236 | </p> | ||
156 | </> | 237 | </> |
157 | )} | 238 | )} |
158 | </h2> | ||
159 | {user.organization && `${user.organization}, `} | ||
160 | {user.email} | ||
161 | {user.isPremium && ( | ||
162 | <div className="manage-user-links"> | 239 | <div className="manage-user-links"> |
240 | {!isProUser && ( | ||
241 | <Button | ||
242 | label={intl.formatMessage(messages.upgradeAccountToPro)} | ||
243 | className="franz-form__button--primary" | ||
244 | onClick={upgradeToPro} | ||
245 | /> | ||
246 | )} | ||
163 | <Button | 247 | <Button |
164 | label={intl.formatMessage(messages.accountEditButton)} | 248 | label={intl.formatMessage(messages.manageSubscriptionButtonLabel)} |
165 | className="franz-form__button--inverted" | 249 | className="franz-form__button--inverted" |
166 | onClick={openEditAccount} | 250 | onClick={openBilling} |
251 | /> | ||
252 | <Button | ||
253 | label={intl.formatMessage(messages.invoicesButton)} | ||
254 | className="franz-form__button--inverted" | ||
255 | onClick={openInvoices} | ||
167 | /> | 256 | /> |
168 | {user.isSubscriptionOwner && ( | ||
169 | <> | ||
170 | <Button | ||
171 | label={intl.formatMessage(messages.manageSubscriptionButtonLabel)} | ||
172 | className="franz-form__button--inverted" | ||
173 | onClick={openBilling} | ||
174 | /> | ||
175 | <Button | ||
176 | label={intl.formatMessage(messages.invoicesButton)} | ||
177 | className="franz-form__button--inverted" | ||
178 | onClick={openInvoices} | ||
179 | /> | ||
180 | </> | ||
181 | )} | ||
182 | </div> | 257 | </div> |
183 | )} | 258 | </div> |
184 | </div> | 259 | </div> |
185 | {!user.isPremium && ( | 260 | )} |
186 | <Button | 261 | {!user.isPremium && ( |
187 | label={intl.formatMessage(messages.accountEditButton)} | 262 | <div className="account franz-form"> |
188 | className="franz-form__button--inverted" | 263 | <div className="account__box"> |
189 | onClick={openEditAccount} | 264 | <SubscriptionForm /> |
190 | /> | 265 | </div> |
191 | )} | ||
192 | </div> | ||
193 | </div> | ||
194 | )} | ||
195 | |||
196 | {!user.isPremium && ( | ||
197 | isLoadingPlans ? ( | ||
198 | <Loader /> | ||
199 | ) : ( | ||
200 | <div className="account franz-form"> | ||
201 | <div className="account__box"> | ||
202 | <h2>{intl.formatMessage(messages.headlineUpgrade)}</h2> | ||
203 | <SubscriptionForm | ||
204 | onCloseWindow={onCloseSubscriptionWindow} | ||
205 | /> | ||
206 | </div> | 266 | </div> |
207 | </div> | 267 | )} |
208 | ) | 268 | </> |
209 | )} | 269 | )} |
210 | 270 | ||
211 | <div className="account franz-form"> | 271 | <div className="account franz-form"> |
212 | <div className="account__box"> | 272 | <div className="account__box"> |
213 | <h2>{intl.formatMessage(messages.headlineDangerZone)}</h2> | 273 | <H2>{intl.formatMessage(messages.headlineDangerZone)}</H2> |
214 | {!isDeleteAccountSuccessful && ( | 274 | {!isDeleteAccountSuccessful && ( |
215 | <div className="account__subscription"> | 275 | <div className="account__subscription"> |
216 | <p>{intl.formatMessage(messages.deleteInfo)}</p> | 276 | <p>{intl.formatMessage(messages.deleteInfo)}</p> |
@@ -227,7 +287,7 @@ export default @observer class AccountDashboard extends Component { | |||
227 | )} | 287 | )} |
228 | </div> | 288 | </div> |
229 | </div> | 289 | </div> |
230 | </Fragment> | 290 | </> |
231 | )} | 291 | )} |
232 | </div> | 292 | </div> |
233 | <ReactTooltip place="right" type="dark" effect="solid" /> | 293 | <ReactTooltip place="right" type="dark" effect="solid" /> |
@@ -235,3 +295,5 @@ export default @observer class AccountDashboard extends Component { | |||
235 | ); | 295 | ); |
236 | } | 296 | } |
237 | } | 297 | } |
298 | |||
299 | export default AccountDashboard; | ||
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js index df4b3b3b2..4696b82eb 100644 --- a/src/components/settings/navigation/SettingsNavigation.js +++ b/src/components/settings/navigation/SettingsNavigation.js | |||
@@ -8,6 +8,7 @@ import Link from '../../ui/Link'; | |||
8 | import { workspaceStore } from '../../../features/workspaces'; | 8 | import { workspaceStore } from '../../../features/workspaces'; |
9 | import UIStore from '../../../stores/UIStore'; | 9 | import UIStore from '../../../stores/UIStore'; |
10 | import UserStore from '../../../stores/UserStore'; | 10 | import UserStore from '../../../stores/UserStore'; |
11 | import { serviceLimitStore } from '../../../features/serviceLimit'; | ||
11 | 12 | ||
12 | const messages = defineMessages({ | 13 | const messages = defineMessages({ |
13 | availableServices: { | 14 | availableServices: { |
@@ -80,7 +81,12 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp | |||
80 | > | 81 | > |
81 | {intl.formatMessage(messages.yourServices)} | 82 | {intl.formatMessage(messages.yourServices)} |
82 | {' '} | 83 | {' '} |
83 | <span className="badge">{serviceCount}</span> | 84 | <span className="badge"> |
85 | {serviceCount} | ||
86 | {serviceLimitStore.serviceLimit !== 0 && ( | ||
87 | `/${serviceLimitStore.serviceLimit}` | ||
88 | )} | ||
89 | </span> | ||
84 | </Link> | 90 | </Link> |
85 | {workspaceStore.isFeatureEnabled ? ( | 91 | {workspaceStore.isFeatureEnabled ? ( |
86 | <Link | 92 | <Link |
diff --git a/src/components/settings/recipes/RecipeItem.js b/src/components/settings/recipes/RecipeItem.js index 3bb0852b2..12e3775f6 100644 --- a/src/components/settings/recipes/RecipeItem.js +++ b/src/components/settings/recipes/RecipeItem.js | |||
@@ -19,7 +19,7 @@ export default @observer class RecipeItem extends Component { | |||
19 | className="recipe-teaser" | 19 | className="recipe-teaser" |
20 | onClick={onClick} | 20 | onClick={onClick} |
21 | > | 21 | > |
22 | {recipe.local && ( | 22 | {recipe.isDevRecipe && ( |
23 | <span className="recipe-teaser__dev-badge">dev</span> | 23 | <span className="recipe-teaser__dev-badge">dev</span> |
24 | )} | 24 | )} |
25 | <img | 25 | <img |
diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js index 00cd725cf..08988024a 100644 --- a/src/components/settings/recipes/RecipesDashboard.js +++ b/src/components/settings/recipes/RecipesDashboard.js | |||
@@ -4,12 +4,17 @@ import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | |||
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import { Link } from 'react-router'; | 5 | import { Link } from 'react-router'; |
6 | 6 | ||
7 | import { Button, Input } from '@meetfranz/forms'; | ||
8 | import injectSheet from 'react-jss'; | ||
9 | import { H3, H2, ProBadge } from '@meetfranz/ui'; | ||
7 | import SearchInput from '../../ui/SearchInput'; | 10 | import SearchInput from '../../ui/SearchInput'; |
8 | import Infobox from '../../ui/Infobox'; | 11 | import Infobox from '../../ui/Infobox'; |
9 | import RecipeItem from './RecipeItem'; | 12 | import RecipeItem from './RecipeItem'; |
10 | import Loader from '../../ui/Loader'; | 13 | import Loader from '../../ui/Loader'; |
11 | import Appear from '../../ui/effects/Appear'; | 14 | import Appear from '../../ui/effects/Appear'; |
12 | import { FRANZ_SERVICE_REQUEST } from '../../../config'; | 15 | import { FRANZ_SERVICE_REQUEST } from '../../../config'; |
16 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; | ||
17 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; | ||
13 | 18 | ||
14 | const messages = defineMessages({ | 19 | const messages = defineMessages({ |
15 | headline: { | 20 | headline: { |
@@ -28,9 +33,9 @@ const messages = defineMessages({ | |||
28 | id: 'settings.recipes.all', | 33 | id: 'settings.recipes.all', |
29 | defaultMessage: '!!!All services', | 34 | defaultMessage: '!!!All services', |
30 | }, | 35 | }, |
31 | devRecipes: { | 36 | customRecipes: { |
32 | id: 'settings.recipes.dev', | 37 | id: 'settings.recipes.custom', |
33 | defaultMessage: '!!!Development', | 38 | defaultMessage: '!!!Custom Services', |
34 | }, | 39 | }, |
35 | nothingFound: { | 40 | nothingFound: { |
36 | id: 'settings.recipes.nothingFound', | 41 | id: 'settings.recipes.nothingFound', |
@@ -44,9 +49,61 @@ const messages = defineMessages({ | |||
44 | id: 'settings.recipes.missingService', | 49 | id: 'settings.recipes.missingService', |
45 | defaultMessage: '!!!Missing a service?', | 50 | defaultMessage: '!!!Missing a service?', |
46 | }, | 51 | }, |
52 | customRecipeIntro: { | ||
53 | id: 'settings.recipes.customService.intro', | ||
54 | defaultMessage: '!!!To add a custom service, copy the recipe folder into:', | ||
55 | }, | ||
56 | openFolder: { | ||
57 | id: 'settings.recipes.customService.openFolder', | ||
58 | defaultMessage: '!!!Open directory', | ||
59 | }, | ||
60 | openDevDocs: { | ||
61 | id: 'settings.recipes.customService.openDevDocs', | ||
62 | defaultMessage: '!!!Developer Documentation', | ||
63 | }, | ||
64 | headlineCustomRecipes: { | ||
65 | id: 'settings.recipes.customService.headline.customRecipes', | ||
66 | defaultMessage: '!!!Custom Service Recipes', | ||
67 | }, | ||
68 | headlineCommunityRecipes: { | ||
69 | id: 'settings.recipes.customService.headline.communityRecipes', | ||
70 | defaultMessage: '!!!Community Services', | ||
71 | }, | ||
72 | headlineDevRecipes: { | ||
73 | id: 'settings.recipes.customService.headline.devRecipes', | ||
74 | defaultMessage: '!!!Your Development Service Recipes', | ||
75 | }, | ||
47 | }); | 76 | }); |
48 | 77 | ||
49 | export default @observer class RecipesDashboard extends Component { | 78 | const styles = { |
79 | devRecipeIntroContainer: { | ||
80 | textAlign: 'center', | ||
81 | width: '100%', | ||
82 | height: 'auto', | ||
83 | margin: [40, 0], | ||
84 | }, | ||
85 | path: { | ||
86 | marginTop: 20, | ||
87 | |||
88 | '& > div': { | ||
89 | fontFamily: 'SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace', | ||
90 | }, | ||
91 | }, | ||
92 | actionContainer: { | ||
93 | '& button': { | ||
94 | margin: [0, 10], | ||
95 | }, | ||
96 | }, | ||
97 | devRecipeList: { | ||
98 | marginTop: 20, | ||
99 | height: 'auto', | ||
100 | }, | ||
101 | proBadge: { | ||
102 | marginLeft: '10px !important', | ||
103 | }, | ||
104 | }; | ||
105 | |||
106 | export default @injectSheet(styles) @observer class RecipesDashboard extends Component { | ||
50 | static propTypes = { | 107 | static propTypes = { |
51 | recipes: MobxPropTypes.arrayOrObservableArray.isRequired, | 108 | recipes: MobxPropTypes.arrayOrObservableArray.isRequired, |
52 | isLoading: PropTypes.bool.isRequired, | 109 | isLoading: PropTypes.bool.isRequired, |
@@ -55,12 +112,18 @@ export default @observer class RecipesDashboard extends Component { | |||
55 | searchRecipes: PropTypes.func.isRequired, | 112 | searchRecipes: PropTypes.func.isRequired, |
56 | resetSearch: PropTypes.func.isRequired, | 113 | resetSearch: PropTypes.func.isRequired, |
57 | serviceStatus: MobxPropTypes.arrayOrObservableArray.isRequired, | 114 | serviceStatus: MobxPropTypes.arrayOrObservableArray.isRequired, |
58 | devRecipesCount: PropTypes.number.isRequired, | ||
59 | searchNeedle: PropTypes.string, | 115 | searchNeedle: PropTypes.string, |
116 | recipeFilter: PropTypes.string, | ||
117 | recipeDirectory: PropTypes.string.isRequired, | ||
118 | openRecipeDirectory: PropTypes.func.isRequired, | ||
119 | openDevDocs: PropTypes.func.isRequired, | ||
120 | classes: PropTypes.object.isRequired, | ||
121 | isCommunityRecipesIncludedInCurrentPlan: PropTypes.bool.isRequired, | ||
60 | }; | 122 | }; |
61 | 123 | ||
62 | static defaultProps = { | 124 | static defaultProps = { |
63 | searchNeedle: '', | 125 | searchNeedle: '', |
126 | recipeFilter: 'all', | ||
64 | } | 127 | } |
65 | 128 | ||
66 | static contextTypes = { | 129 | static contextTypes = { |
@@ -76,16 +139,26 @@ export default @observer class RecipesDashboard extends Component { | |||
76 | searchRecipes, | 139 | searchRecipes, |
77 | resetSearch, | 140 | resetSearch, |
78 | serviceStatus, | 141 | serviceStatus, |
79 | devRecipesCount, | ||
80 | searchNeedle, | 142 | searchNeedle, |
143 | recipeFilter, | ||
144 | recipeDirectory, | ||
145 | openRecipeDirectory, | ||
146 | openDevDocs, | ||
147 | classes, | ||
148 | isCommunityRecipesIncludedInCurrentPlan, | ||
81 | } = this.props; | 149 | } = this.props; |
82 | const { intl } = this.context; | 150 | const { intl } = this.context; |
83 | 151 | ||
152 | |||
153 | const communityRecipes = recipes.filter(r => !r.isDevRecipe); | ||
154 | const devRecipes = recipes.filter(r => r.isDevRecipe); | ||
155 | |||
84 | return ( | 156 | return ( |
85 | <div className="settings__main"> | 157 | <div className="settings__main"> |
86 | <div className="settings__header"> | 158 | <div className="settings__header"> |
87 | <h1>{intl.formatMessage(messages.headline)}</h1> | 159 | <h1>{intl.formatMessage(messages.headline)}</h1> |
88 | </div> | 160 | </div> |
161 | <LimitReachedInfobox /> | ||
89 | <div className="settings__body recipes"> | 162 | <div className="settings__body recipes"> |
90 | {serviceStatus.length > 0 && serviceStatus.includes('created') && ( | 163 | {serviceStatus.length > 0 && serviceStatus.includes('created') && ( |
91 | <Appear> | 164 | <Appear> |
@@ -122,20 +195,14 @@ export default @observer class RecipesDashboard extends Component { | |||
122 | > | 195 | > |
123 | {intl.formatMessage(messages.allRecipes)} | 196 | {intl.formatMessage(messages.allRecipes)} |
124 | </Link> | 197 | </Link> |
125 | {devRecipesCount > 0 && ( | 198 | <Link |
126 | <Link | 199 | to="/settings/recipes/dev" |
127 | to="/settings/recipes/dev" | 200 | className="badge" |
128 | className="badge" | 201 | activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} |
129 | activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} | 202 | onClick={() => resetSearch()} |
130 | onClick={() => resetSearch()} | 203 | > |
131 | > | 204 | {intl.formatMessage(messages.customRecipes)} |
132 | {intl.formatMessage(messages.devRecipes)} | 205 | </Link> |
133 | {' '} | ||
134 | ( | ||
135 | {devRecipesCount} | ||
136 | ) | ||
137 | </Link> | ||
138 | )} | ||
139 | <a href={FRANZ_SERVICE_REQUEST} target="_blank" className="link recipes__service-request"> | 206 | <a href={FRANZ_SERVICE_REQUEST} target="_blank" className="link recipes__service-request"> |
140 | {intl.formatMessage(messages.missingService)} | 207 | {intl.formatMessage(messages.missingService)} |
141 | {' '} | 208 | {' '} |
@@ -146,23 +213,78 @@ export default @observer class RecipesDashboard extends Component { | |||
146 | {isLoading ? ( | 213 | {isLoading ? ( |
147 | <Loader /> | 214 | <Loader /> |
148 | ) : ( | 215 | ) : ( |
149 | <div className="recipes__list"> | 216 | <> |
150 | {hasLoadedRecipes && recipes.length === 0 && ( | 217 | {recipeFilter === 'dev' && ( |
151 | <p className="align-middle settings__empty-state"> | 218 | <> |
152 | <span className="emoji"> | 219 | <H2> |
153 | <img src="./assets/images/emoji/dontknow.png" alt="" /> | 220 | {intl.formatMessage(messages.headlineCustomRecipes)} |
154 | </span> | 221 | {!isCommunityRecipesIncludedInCurrentPlan && ( |
155 | {intl.formatMessage(messages.nothingFound)} | 222 | <ProBadge className={classes.proBadge} /> |
156 | </p> | 223 | )} |
224 | </H2> | ||
225 | <div className={classes.devRecipeIntroContainer}> | ||
226 | <p> | ||
227 | {intl.formatMessage(messages.customRecipeIntro)} | ||
228 | </p> | ||
229 | <Input | ||
230 | value={recipeDirectory} | ||
231 | className={classes.path} | ||
232 | showLabel={false} | ||
233 | /> | ||
234 | <div className={classes.actionContainer}> | ||
235 | <Button | ||
236 | onClick={openRecipeDirectory} | ||
237 | buttonType="secondary" | ||
238 | label={intl.formatMessage(messages.openFolder)} | ||
239 | /> | ||
240 | <Button | ||
241 | onClick={openDevDocs} | ||
242 | buttonType="secondary" | ||
243 | label={intl.formatMessage(messages.openDevDocs)} | ||
244 | /> | ||
245 | </div> | ||
246 | </div> | ||
247 | </> | ||
248 | )} | ||
249 | <PremiumFeatureContainer | ||
250 | condition={(recipeFilter === 'dev' && communityRecipes.length > 0) && !isCommunityRecipesIncludedInCurrentPlan} | ||
251 | > | ||
252 | {recipeFilter === 'dev' && communityRecipes.length > 0 && ( | ||
253 | <H3>{intl.formatMessage(messages.headlineCommunityRecipes)}</H3> | ||
254 | )} | ||
255 | <div className="recipes__list"> | ||
256 | {hasLoadedRecipes && recipes.length === 0 && recipeFilter !== 'dev' && ( | ||
257 | <p className="align-middle settings__empty-state"> | ||
258 | <span className="emoji"> | ||
259 | <img src="./assets/images/emoji/dontknow.png" alt="" /> | ||
260 | </span> | ||
261 | {intl.formatMessage(messages.nothingFound)} | ||
262 | </p> | ||
263 | )} | ||
264 | {communityRecipes.map(recipe => ( | ||
265 | <RecipeItem | ||
266 | key={recipe.id} | ||
267 | recipe={recipe} | ||
268 | onClick={() => showAddServiceInterface({ recipeId: recipe.id })} | ||
269 | /> | ||
270 | ))} | ||
271 | </div> | ||
272 | </PremiumFeatureContainer> | ||
273 | {recipeFilter === 'dev' && devRecipes.length > 0 && ( | ||
274 | <div className={classes.devRecipeList}> | ||
275 | <H3>{intl.formatMessage(messages.headlineDevRecipes)}</H3> | ||
276 | <div className="recipes__list"> | ||
277 | {devRecipes.map(recipe => ( | ||
278 | <RecipeItem | ||
279 | key={recipe.id} | ||
280 | recipe={recipe} | ||
281 | onClick={() => showAddServiceInterface({ recipeId: recipe.id })} | ||
282 | /> | ||
283 | ))} | ||
284 | </div> | ||
285 | </div> | ||
157 | )} | 286 | )} |
158 | {recipes.map(recipe => ( | 287 | </> |
159 | <RecipeItem | ||
160 | key={recipe.id} | ||
161 | recipe={recipe} | ||
162 | onClick={() => showAddServiceInterface({ recipeId: recipe.id })} | ||
163 | /> | ||
164 | ))} | ||
165 | </div> | ||
166 | )} | 288 | )} |
167 | </div> | 289 | </div> |
168 | </div> | 290 | </div> |
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index 4ba2eb844..5cde0db8e 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js | |||
@@ -17,6 +17,8 @@ import ImageUpload from '../../ui/ImageUpload'; | |||
17 | import Select from '../../ui/Select'; | 17 | import Select from '../../ui/Select'; |
18 | 18 | ||
19 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; | 19 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; |
20 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; | ||
21 | import { serviceLimitStore } from '../../../features/serviceLimit'; | ||
20 | 22 | ||
21 | const messages = defineMessages({ | 23 | const messages = defineMessages({ |
22 | saveService: { | 24 | saveService: { |
@@ -128,8 +130,8 @@ export default @observer class EditServiceForm extends Component { | |||
128 | isSaving: PropTypes.bool.isRequired, | 130 | isSaving: PropTypes.bool.isRequired, |
129 | isDeleting: PropTypes.bool.isRequired, | 131 | isDeleting: PropTypes.bool.isRequired, |
130 | isProxyFeatureEnabled: PropTypes.bool.isRequired, | 132 | isProxyFeatureEnabled: PropTypes.bool.isRequired, |
131 | isProxyPremiumFeature: PropTypes.bool.isRequired, | 133 | isServiceProxyIncludedInCurrentPlan: PropTypes.bool.isRequired, |
132 | isSpellcheckerPremiumFeature: PropTypes.bool.isRequired, | 134 | isSpellcheckerIncludedInCurrentPlan: PropTypes.bool.isRequired, |
133 | }; | 135 | }; |
134 | 136 | ||
135 | static defaultProps = { | 137 | static defaultProps = { |
@@ -192,8 +194,8 @@ export default @observer class EditServiceForm extends Component { | |||
192 | isDeleting, | 194 | isDeleting, |
193 | onDelete, | 195 | onDelete, |
194 | isProxyFeatureEnabled, | 196 | isProxyFeatureEnabled, |
195 | isProxyPremiumFeature, | 197 | isServiceProxyIncludedInCurrentPlan, |
196 | isSpellcheckerPremiumFeature, | 198 | isSpellcheckerIncludedInCurrentPlan, |
197 | } = this.props; | 199 | } = this.props; |
198 | const { intl } = this.context; | 200 | const { intl } = this.context; |
199 | 201 | ||
@@ -252,6 +254,7 @@ export default @observer class EditServiceForm extends Component { | |||
252 | )} | 254 | )} |
253 | </span> | 255 | </span> |
254 | </div> | 256 | </div> |
257 | <LimitReachedInfobox /> | ||
255 | <div className="settings__body"> | 258 | <div className="settings__body"> |
256 | <form onSubmit={e => this.submit(e)} id="form"> | 259 | <form onSubmit={e => this.submit(e)} id="form"> |
257 | <div className="service-name"> | 260 | <div className="service-name"> |
@@ -342,7 +345,7 @@ export default @observer class EditServiceForm extends Component { | |||
342 | </div> | 345 | </div> |
343 | 346 | ||
344 | <PremiumFeatureContainer | 347 | <PremiumFeatureContainer |
345 | condition={isSpellcheckerPremiumFeature} | 348 | condition={!isSpellcheckerIncludedInCurrentPlan} |
346 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} | 349 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} |
347 | > | 350 | > |
348 | <div className="settings__settings-group"> | 351 | <div className="settings__settings-group"> |
@@ -352,7 +355,7 @@ export default @observer class EditServiceForm extends Component { | |||
352 | 355 | ||
353 | {isProxyFeatureEnabled && ( | 356 | {isProxyFeatureEnabled && ( |
354 | <PremiumFeatureContainer | 357 | <PremiumFeatureContainer |
355 | condition={isProxyPremiumFeature} | 358 | condition={!isServiceProxyIncludedInCurrentPlan} |
356 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'proxy' }} | 359 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'proxy' }} |
357 | > | 360 | > |
358 | <div className="settings__settings-group"> | 361 | <div className="settings__settings-group"> |
@@ -418,7 +421,7 @@ export default @observer class EditServiceForm extends Component { | |||
418 | type="submit" | 421 | type="submit" |
419 | label={intl.formatMessage(messages.saveService)} | 422 | label={intl.formatMessage(messages.saveService)} |
420 | htmlForm="form" | 423 | htmlForm="form" |
421 | disabled={action !== 'edit' && form.isPristine && requiresUserInput} | 424 | disabled={action !== 'edit' && ((form.isPristine && requiresUserInput) || serviceLimitStore.userHasReachedServiceLimit)} |
422 | /> | 425 | /> |
423 | )} | 426 | )} |
424 | </div> | 427 | </div> |
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js index 53bae12df..78038e86a 100644 --- a/src/components/settings/services/ServicesDashboard.js +++ b/src/components/settings/services/ServicesDashboard.js | |||
@@ -9,6 +9,7 @@ import Infobox from '../../ui/Infobox'; | |||
9 | import Loader from '../../ui/Loader'; | 9 | import Loader from '../../ui/Loader'; |
10 | import ServiceItem from './ServiceItem'; | 10 | import ServiceItem from './ServiceItem'; |
11 | import Appear from '../../ui/effects/Appear'; | 11 | import Appear from '../../ui/effects/Appear'; |
12 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; | ||
12 | 13 | ||
13 | const messages = defineMessages({ | 14 | const messages = defineMessages({ |
14 | headline: { | 15 | headline: { |
@@ -91,6 +92,7 @@ export default @observer class ServicesDashboard extends Component { | |||
91 | <div className="settings__header"> | 92 | <div className="settings__header"> |
92 | <h1>{intl.formatMessage(messages.headline)}</h1> | 93 | <h1>{intl.formatMessage(messages.headline)}</h1> |
93 | </div> | 94 | </div> |
95 | <LimitReachedInfobox /> | ||
94 | <div className="settings__body"> | 96 | <div className="settings__body"> |
95 | {!isLoading && ( | 97 | {!isLoading && ( |
96 | <SearchInput | 98 | <SearchInput |
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index efd453356..3f9e0a6bc 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js | |||
@@ -100,7 +100,7 @@ export default @observer class EditSettingsForm extends Component { | |||
100 | isClearingAllCache: PropTypes.bool.isRequired, | 100 | isClearingAllCache: PropTypes.bool.isRequired, |
101 | onClearAllCache: PropTypes.func.isRequired, | 101 | onClearAllCache: PropTypes.func.isRequired, |
102 | cacheSize: PropTypes.string.isRequired, | 102 | cacheSize: PropTypes.string.isRequired, |
103 | isSpellcheckerPremiumFeature: PropTypes.bool.isRequired, | 103 | isSpellcheckerIncludedInCurrentPlan: PropTypes.bool.isRequired, |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static contextTypes = { | 106 | static contextTypes = { |
@@ -130,7 +130,7 @@ export default @observer class EditSettingsForm extends Component { | |||
130 | isClearingAllCache, | 130 | isClearingAllCache, |
131 | onClearAllCache, | 131 | onClearAllCache, |
132 | cacheSize, | 132 | cacheSize, |
133 | isSpellcheckerPremiumFeature, | 133 | isSpellcheckerIncludedInCurrentPlan, |
134 | } = this.props; | 134 | } = this.props; |
135 | const { intl } = this.context; | 135 | const { intl } = this.context; |
136 | 136 | ||
@@ -173,7 +173,7 @@ export default @observer class EditSettingsForm extends Component { | |||
173 | <h2 id="language">{intl.formatMessage(messages.headlineLanguage)}</h2> | 173 | <h2 id="language">{intl.formatMessage(messages.headlineLanguage)}</h2> |
174 | <Select field={form.$('locale')} showLabel={false} /> | 174 | <Select field={form.$('locale')} showLabel={false} /> |
175 | <PremiumFeatureContainer | 175 | <PremiumFeatureContainer |
176 | condition={isSpellcheckerPremiumFeature} | 176 | condition={!isSpellcheckerIncludedInCurrentPlan} |
177 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} | 177 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} |
178 | > | 178 | > |
179 | <Fragment> | 179 | <Fragment> |
diff --git a/src/components/settings/team/TeamDashboard.js b/src/components/settings/team/TeamDashboard.js index 82c517fcb..990ee52e7 100644 --- a/src/components/settings/team/TeamDashboard.js +++ b/src/components/settings/team/TeamDashboard.js | |||
@@ -133,13 +133,13 @@ export default @injectSheet(styles) @observer class TeamDashboard extends Compon | |||
133 | </div> | 133 | </div> |
134 | <img className={classes.image} src="https://cdn.franzinfra.com/announcements/assets/teams.png" alt="Franz for Teams" /> | 134 | <img className={classes.image} src="https://cdn.franzinfra.com/announcements/assets/teams.png" alt="Franz for Teams" /> |
135 | </div> | 135 | </div> |
136 | <Button | ||
137 | label={intl.formatMessage(messages.manageButton)} | ||
138 | onClick={openTeamManagement} | ||
139 | className={classes.cta} | ||
140 | /> | ||
141 | </> | 136 | </> |
142 | </PremiumFeatureContainer> | 137 | </PremiumFeatureContainer> |
138 | <Button | ||
139 | label={intl.formatMessage(messages.manageButton)} | ||
140 | onClick={openTeamManagement} | ||
141 | className={classes.cta} | ||
142 | /> | ||
143 | </> | 143 | </> |
144 | )} | 144 | )} |
145 | </> | 145 | </> |
diff --git a/src/components/subscription/SubscriptionForm.js b/src/components/subscription/SubscriptionForm.js index 50f1e0522..cdfbbe60d 100644 --- a/src/components/subscription/SubscriptionForm.js +++ b/src/components/subscription/SubscriptionForm.js | |||
@@ -1,214 +1,78 @@ | |||
1 | import React, { Component, Fragment } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import injectSheet from 'react-jss'; | ||
5 | 6 | ||
6 | import Form from '../../lib/Form'; | 7 | import { H3, H2 } from '@meetfranz/ui'; |
7 | import Radio from '../ui/Radio'; | ||
8 | import Button from '../ui/Button'; | ||
9 | import Loader from '../ui/Loader'; | ||
10 | 8 | ||
11 | import { required } from '../../helpers/validation-helpers'; | 9 | import { Button } from '@meetfranz/forms'; |
10 | import { FeatureList } from '../ui/FeatureList'; | ||
12 | 11 | ||
13 | const messages = defineMessages({ | 12 | const messages = defineMessages({ |
14 | submitButtonLabel: { | 13 | submitButtonLabel: { |
15 | id: 'subscription.submit.label', | 14 | id: 'subscription.cta.choosePlan', |
16 | defaultMessage: '!!!Support the development of Franz', | 15 | defaultMessage: '!!!Choose your plan', |
17 | }, | 16 | }, |
18 | paymentSessionError: { | 17 | teaserHeadline: { |
19 | id: 'subscription.paymentSessionError', | 18 | id: 'settings.account.headlineUpgradeAccount', |
20 | defaultMessage: '!!!Could not initialize payment form', | 19 | defaultMessage: '!!!Upgrade your account and get the full Franz experience', |
21 | }, | 20 | }, |
22 | typeFree: { | 21 | teaserText: { |
23 | id: 'subscription.type.free', | 22 | id: 'subscription.teaser.intro', |
24 | defaultMessage: '!!!free', | 23 | defaultMessage: '!!!Franz 5 comes with a wide range of new features to boost up your everyday communication - batteries included. Check out our new plans and find out which one suits you most!', |
25 | }, | ||
26 | typeMonthly: { | ||
27 | id: 'subscription.type.month', | ||
28 | defaultMessage: '!!!month', | ||
29 | }, | ||
30 | typeYearly: { | ||
31 | id: 'subscription.type.year', | ||
32 | defaultMessage: '!!!year', | ||
33 | }, | 24 | }, |
34 | includedFeatures: { | 25 | includedFeatures: { |
35 | id: 'subscription.includedFeatures', | 26 | id: 'subscription.teaser.includedFeatures', |
36 | defaultMessage: '!!!The Franz Premium Supporter Account includes', | 27 | defaultMessage: '!!!Paid Franz Plans include:', |
37 | }, | ||
38 | onpremise: { | ||
39 | id: 'subscription.features.onpremise.mattermost', | ||
40 | defaultMessage: '!!!Add on-premise/hosted services like Mattermost', | ||
41 | }, | ||
42 | noInterruptions: { | ||
43 | id: 'subscription.features.noInterruptions', | ||
44 | defaultMessage: '!!!No app delays & nagging to upgrade license', | ||
45 | }, | ||
46 | proxy: { | ||
47 | id: 'subscription.features.proxy', | ||
48 | defaultMessage: '!!!Proxy support for services', | ||
49 | }, | ||
50 | spellchecker: { | ||
51 | id: 'subscription.features.spellchecker', | ||
52 | defaultMessage: '!!!Support for Spellchecker', | ||
53 | }, | 28 | }, |
54 | workspaces: { | 29 | }); |
55 | id: 'subscription.features.workspaces', | 30 | |
56 | defaultMessage: '!!!Organize your services in workspaces', | 31 | const styles = () => ({ |
57 | }, | 32 | activateTrialButton: { |
58 | ads: { | 33 | margin: [40, 0, 50], |
59 | id: 'subscription.features.ads', | ||
60 | defaultMessage: '!!!No ads, ever!', | ||
61 | }, | ||
62 | comingSoon: { | ||
63 | id: 'subscription.features.comingSoon', | ||
64 | defaultMessage: '!!!coming soon', | ||
65 | }, | ||
66 | euTaxInfo: { | ||
67 | id: 'subscription.euTaxInfo', | ||
68 | defaultMessage: '!!!EU residents: local sales tax may apply', | ||
69 | }, | 34 | }, |
70 | }); | 35 | }); |
71 | 36 | ||
72 | export default @observer class SubscriptionForm extends Component { | 37 | export default @observer @injectSheet(styles) class SubscriptionForm extends Component { |
73 | static propTypes = { | 38 | static propTypes = { |
74 | plan: MobxPropTypes.objectOrObservableObject.isRequired, | 39 | selectPlan: PropTypes.func.isRequired, |
75 | isLoading: PropTypes.bool.isRequired, | 40 | isActivatingTrial: PropTypes.bool.isRequired, |
76 | handlePayment: PropTypes.func.isRequired, | 41 | classes: PropTypes.object.isRequired, |
77 | retryPlanRequest: PropTypes.func.isRequired, | ||
78 | isCreatingHostedPage: PropTypes.bool.isRequired, | ||
79 | error: PropTypes.bool.isRequired, | ||
80 | showSkipOption: PropTypes.bool, | ||
81 | skipAction: PropTypes.func, | ||
82 | skipButtonLabel: PropTypes.string, | ||
83 | hideInfo: PropTypes.bool.isRequired, | ||
84 | }; | ||
85 | |||
86 | static defaultProps = { | ||
87 | showSkipOption: false, | ||
88 | skipAction: () => null, | ||
89 | skipButtonLabel: '', | ||
90 | }; | 42 | }; |
91 | 43 | ||
92 | static contextTypes = { | 44 | static contextTypes = { |
93 | intl: intlShape, | 45 | intl: intlShape, |
94 | }; | 46 | }; |
95 | 47 | ||
96 | componentWillMount() { | ||
97 | this.form = this.prepareForm(); | ||
98 | } | ||
99 | |||
100 | prepareForm() { | ||
101 | const { intl } = this.context; | ||
102 | |||
103 | const form = { | ||
104 | fields: { | ||
105 | paymentTier: { | ||
106 | value: 'year', | ||
107 | validators: [required], | ||
108 | options: [{ | ||
109 | value: 'month', | ||
110 | label: `€ ${Object.hasOwnProperty.call(this.props.plan, 'month') | ||
111 | ? `${this.props.plan.month.price} / ${intl.formatMessage(messages.typeMonthly)}` | ||
112 | : 'monthly'}`, | ||
113 | }, { | ||
114 | value: 'year', | ||
115 | label: `€ ${Object.hasOwnProperty.call(this.props.plan, 'year') | ||
116 | ? `${this.props.plan.year.price} / ${intl.formatMessage(messages.typeYearly)}` | ||
117 | : 'yearly'}`, | ||
118 | }], | ||
119 | }, | ||
120 | }, | ||
121 | }; | ||
122 | |||
123 | if (this.props.showSkipOption) { | ||
124 | form.fields.paymentTier.options.unshift({ | ||
125 | value: 'skip', | ||
126 | label: `€ 0 / ${intl.formatMessage(messages.typeFree)}`, | ||
127 | }); | ||
128 | } | ||
129 | |||
130 | return new Form(form, this.context.intl); | ||
131 | } | ||
132 | |||
133 | render() { | 48 | render() { |
134 | const { | 49 | const { |
135 | isLoading, | 50 | isActivatingTrial, |
136 | isCreatingHostedPage, | 51 | selectPlan, |
137 | handlePayment, | 52 | classes, |
138 | retryPlanRequest, | ||
139 | error, | ||
140 | showSkipOption, | ||
141 | skipAction, | ||
142 | skipButtonLabel, | ||
143 | hideInfo, | ||
144 | } = this.props; | 53 | } = this.props; |
145 | const { intl } = this.context; | 54 | const { intl } = this.context; |
146 | 55 | ||
147 | if (error) { | 56 | return ( |
148 | return ( | 57 | <> |
58 | <H2>{intl.formatMessage(messages.teaserHeadline)}</H2> | ||
59 | <p>{intl.formatMessage(messages.teaserText)}</p> | ||
149 | <Button | 60 | <Button |
150 | label="Reload" | 61 | label={intl.formatMessage(messages.submitButtonLabel)} |
151 | onClick={retryPlanRequest} | 62 | className={classes.activateTrialButton} |
152 | isLoaded={!isLoading} | 63 | busy={isActivatingTrial} |
64 | onClick={selectPlan} | ||
65 | stretch | ||
153 | /> | 66 | /> |
154 | ); | 67 | <div className="subscription__premium-info"> |
155 | } | 68 | <H3> |
156 | 69 | {intl.formatMessage(messages.includedFeatures)} | |
157 | return ( | 70 | </H3> |
158 | <Loader loaded={!isLoading}> | 71 | <div className="subscription"> |
159 | <Radio field={this.form.$('paymentTier')} showLabel={false} className="paymentTiers" /> | 72 | <FeatureList /> |
160 | {!hideInfo && ( | ||
161 | <div className="subscription__premium-info"> | ||
162 | <p> | ||
163 | <strong>{intl.formatMessage(messages.includedFeatures)}</strong> | ||
164 | </p> | ||
165 | <div className="subscription"> | ||
166 | <ul className="subscription__premium-features"> | ||
167 | <li>{intl.formatMessage(messages.onpremise)}</li> | ||
168 | <li> | ||
169 | {intl.formatMessage(messages.noInterruptions)} | ||
170 | </li> | ||
171 | <li> | ||
172 | {intl.formatMessage(messages.spellchecker)} | ||
173 | </li> | ||
174 | <li> | ||
175 | {intl.formatMessage(messages.proxy)} | ||
176 | </li> | ||
177 | <li> | ||
178 | {intl.formatMessage(messages.workspaces)} | ||
179 | </li> | ||
180 | <li> | ||
181 | {intl.formatMessage(messages.ads)} | ||
182 | </li> | ||
183 | </ul> | ||
184 | </div> | ||
185 | </div> | 73 | </div> |
186 | )} | 74 | </div> |
187 | <Fragment> | 75 | </> |
188 | {error.code === 'no-payment-session' && ( | ||
189 | <p className="error-message center">{intl.formatMessage(messages.paymentSessionError)}</p> | ||
190 | )} | ||
191 | </Fragment> | ||
192 | {showSkipOption && this.form.$('paymentTier').value === 'skip' ? ( | ||
193 | <Button | ||
194 | label={skipButtonLabel} | ||
195 | className="auth__button" | ||
196 | onClick={skipAction} | ||
197 | /> | ||
198 | ) : ( | ||
199 | <Button | ||
200 | label={intl.formatMessage(messages.submitButtonLabel)} | ||
201 | className="auth__button" | ||
202 | loaded={!isCreatingHostedPage} | ||
203 | onClick={() => handlePayment(this.form.$('paymentTier').value)} | ||
204 | /> | ||
205 | )} | ||
206 | {this.form.$('paymentTier').value !== 'skip' && ( | ||
207 | <p className="legal"> | ||
208 | {intl.formatMessage(messages.euTaxInfo)} | ||
209 | </p> | ||
210 | )} | ||
211 | </Loader> | ||
212 | ); | 76 | ); |
213 | } | 77 | } |
214 | } | 78 | } |
diff --git a/src/components/subscription/SubscriptionPopup.js b/src/components/subscription/SubscriptionPopup.js index 0f6f0260f..12ef8a6e9 100644 --- a/src/components/subscription/SubscriptionPopup.js +++ b/src/components/subscription/SubscriptionPopup.js | |||
@@ -43,7 +43,7 @@ export default @observer class SubscriptionPopup extends Component { | |||
43 | 43 | ||
44 | setTimeout(() => { | 44 | setTimeout(() => { |
45 | this.props.closeWindow(); | 45 | this.props.closeWindow(); |
46 | }, ms('4s')); | 46 | }, ms('1s')); |
47 | } | 47 | } |
48 | 48 | ||
49 | render() { | 49 | render() { |
@@ -61,8 +61,6 @@ export default @observer class SubscriptionPopup extends Component { | |||
61 | autosize | 61 | autosize |
62 | src={encodeURI(url)} | 62 | src={encodeURI(url)} |
63 | onDidNavigate={completeCheck} | 63 | onDidNavigate={completeCheck} |
64 | // onNewWindow={(event, url, frameName, options) => | ||
65 | // openWindow({ event, url, frameName, options })} | ||
66 | /> | 64 | /> |
67 | </div> | 65 | </div> |
68 | <div className="subscription-popup__toolbar franz-form"> | 66 | <div className="subscription-popup__toolbar franz-form"> |
diff --git a/src/components/subscription/TrialForm.js b/src/components/subscription/TrialForm.js new file mode 100644 index 000000000..9ed548f16 --- /dev/null +++ b/src/components/subscription/TrialForm.js | |||
@@ -0,0 +1,115 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | import injectSheet from 'react-jss'; | ||
6 | |||
7 | import { H3, H2 } from '@meetfranz/ui'; | ||
8 | |||
9 | import { Button } from '@meetfranz/forms'; | ||
10 | import { FeatureList } from '../ui/FeatureList'; | ||
11 | import { FeatureItem } from '../ui/FeatureItem'; | ||
12 | |||
13 | const messages = defineMessages({ | ||
14 | submitButtonLabel: { | ||
15 | id: 'subscription.cta.activateTrial', | ||
16 | defaultMessage: '!!!Yes, start the free Franz Professional trial', | ||
17 | }, | ||
18 | allOptionsButton: { | ||
19 | id: 'subscription.cta.allOptions', | ||
20 | defaultMessage: '!!!See all options', | ||
21 | }, | ||
22 | teaserHeadline: { | ||
23 | id: 'settings.account.headlineTrialUpgrade', | ||
24 | defaultMessage: '!!!Get the free 14 day Franz Professional Trial', | ||
25 | }, | ||
26 | includedFeatures: { | ||
27 | id: 'subscription.includedProFeatures', | ||
28 | defaultMessage: '!!!The Franz Professional Plan includes:', | ||
29 | }, | ||
30 | noStringsAttachedHeadline: { | ||
31 | id: 'pricing.trial.terms.headline', | ||
32 | defaultMessage: '!!!No strings attached', | ||
33 | }, | ||
34 | noCreditCard: { | ||
35 | id: 'pricing.trial.terms.noCreditCard', | ||
36 | defaultMessage: '!!!No credit card required', | ||
37 | }, | ||
38 | automaticTrialEnd: { | ||
39 | id: 'pricing.trial.terms.automaticTrialEnd', | ||
40 | defaultMessage: '!!!Your free trial ends automatically after 14 days', | ||
41 | }, | ||
42 | }); | ||
43 | |||
44 | const styles = theme => ({ | ||
45 | activateTrialButton: { | ||
46 | margin: [40, 0, 10], | ||
47 | }, | ||
48 | allOptionsButton: { | ||
49 | margin: [0, 0, 40], | ||
50 | background: 'none', | ||
51 | border: 'none', | ||
52 | color: theme.colorText, | ||
53 | }, | ||
54 | keyTerms: { | ||
55 | marginTop: 20, | ||
56 | }, | ||
57 | }); | ||
58 | |||
59 | export default @observer @injectSheet(styles) class TrialForm extends Component { | ||
60 | static propTypes = { | ||
61 | activateTrial: PropTypes.func.isRequired, | ||
62 | isActivatingTrial: PropTypes.bool.isRequired, | ||
63 | showAllOptions: PropTypes.func.isRequired, | ||
64 | classes: PropTypes.object.isRequired, | ||
65 | }; | ||
66 | |||
67 | static contextTypes = { | ||
68 | intl: intlShape, | ||
69 | }; | ||
70 | |||
71 | render() { | ||
72 | const { | ||
73 | isActivatingTrial, | ||
74 | activateTrial, | ||
75 | showAllOptions, | ||
76 | classes, | ||
77 | } = this.props; | ||
78 | const { intl } = this.context; | ||
79 | |||
80 | return ( | ||
81 | <> | ||
82 | <H2>{intl.formatMessage(messages.teaserHeadline)}</H2> | ||
83 | <H3 className={classes.keyTerms}> | ||
84 | {intl.formatMessage(messages.noStringsAttachedHeadline)} | ||
85 | </H3> | ||
86 | <ul> | ||
87 | <FeatureItem icon="👉" name={intl.formatMessage(messages.noCreditCard)} /> | ||
88 | <FeatureItem icon="👉" name={intl.formatMessage(messages.automaticTrialEnd)} /> | ||
89 | </ul> | ||
90 | |||
91 | <Button | ||
92 | label={intl.formatMessage(messages.submitButtonLabel)} | ||
93 | className={classes.activateTrialButton} | ||
94 | busy={isActivatingTrial} | ||
95 | onClick={activateTrial} | ||
96 | stretch | ||
97 | /> | ||
98 | <Button | ||
99 | label={intl.formatMessage(messages.allOptionsButton)} | ||
100 | className={classes.allOptionsButton} | ||
101 | onClick={showAllOptions} | ||
102 | stretch | ||
103 | /> | ||
104 | <div className="subscription__premium-info"> | ||
105 | <H3> | ||
106 | {intl.formatMessage(messages.includedFeatures)} | ||
107 | </H3> | ||
108 | <div className="subscription"> | ||
109 | <FeatureList /> | ||
110 | </div> | ||
111 | </div> | ||
112 | </> | ||
113 | ); | ||
114 | } | ||
115 | } | ||
diff --git a/src/components/ui/ActivateTrialButton/index.js b/src/components/ui/ActivateTrialButton/index.js new file mode 100644 index 000000000..c3e5f4a6f --- /dev/null +++ b/src/components/ui/ActivateTrialButton/index.js | |||
@@ -0,0 +1,115 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { inject, observer } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | import classnames from 'classnames'; | ||
6 | |||
7 | import { Button } from '@meetfranz/forms'; | ||
8 | import { gaEvent } from '../../../lib/analytics'; | ||
9 | |||
10 | import UserStore from '../../../stores/UserStore'; | ||
11 | |||
12 | const 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 | }); | ||
30 | |||
31 | @inject('stores', 'actions') @observer | ||
32 | class ActivateTrialButton extends Component { | ||
33 | static propTypes = { | ||
34 | // eslint-disable-next-line | ||
35 | classes: PropTypes.object.isRequired, | ||
36 | className: PropTypes.string, | ||
37 | short: PropTypes.bool, | ||
38 | gaEventInfo: PropTypes.shape({ | ||
39 | category: PropTypes.string.isRequired, | ||
40 | event: PropTypes.string.isRequired, | ||
41 | label: PropTypes.string, | ||
42 | }), | ||
43 | }; | ||
44 | |||
45 | static defaultProps = { | ||
46 | className: '', | ||
47 | short: false, | ||
48 | gaEventInfo: null, | ||
49 | } | ||
50 | |||
51 | static contextTypes = { | ||
52 | intl: intlShape, | ||
53 | }; | ||
54 | |||
55 | handleCTAClick() { | ||
56 | const { actions, stores, gaEventInfo } = this.props; | ||
57 | const { hadSubscription } = stores.user.data; | ||
58 | const { defaultTrialPlan } = stores.features.features; | ||
59 | |||
60 | let label = ''; | ||
61 | if (!hadSubscription) { | ||
62 | actions.user.activateTrial({ planId: defaultTrialPlan }); | ||
63 | |||
64 | label = 'Start Trial'; | ||
65 | } else { | ||
66 | actions.ui.openSettings({ path: 'user' }); | ||
67 | |||
68 | label = 'Upgrade Account'; | ||
69 | } | ||
70 | |||
71 | if (gaEventInfo) { | ||
72 | const { category, event } = gaEventInfo; | ||
73 | gaEvent(category, event, label); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | render() { | ||
78 | const { stores, className, short } = this.props; | ||
79 | const { intl } = this.context; | ||
80 | |||
81 | const { hadSubscription } = stores.user.data; | ||
82 | |||
83 | let label; | ||
84 | if (hadSubscription) { | ||
85 | label = short ? messages.shortAction : messages.action; | ||
86 | } else { | ||
87 | label = short ? messages.shortActionTrial : messages.actionTrial; | ||
88 | } | ||
89 | |||
90 | return ( | ||
91 | <Button | ||
92 | label={intl.formatMessage(label)} | ||
93 | className={classnames({ | ||
94 | [className]: className, | ||
95 | })} | ||
96 | buttonType="inverted" | ||
97 | onClick={this.handleCTAClick.bind(this)} | ||
98 | busy={stores.user.activateTrialRequest.isExecuting} | ||
99 | /> | ||
100 | ); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | export default ActivateTrialButton; | ||
105 | |||
106 | ActivateTrialButton.wrappedComponent.propTypes = { | ||
107 | stores: PropTypes.shape({ | ||
108 | user: PropTypes.instanceOf(UserStore).isRequired, | ||
109 | }).isRequired, | ||
110 | actions: PropTypes.shape({ | ||
111 | ui: PropTypes.shape({ | ||
112 | openSettings: PropTypes.func.isRequired, | ||
113 | }).isRequired, | ||
114 | }).isRequired, | ||
115 | }; | ||
diff --git a/src/components/ui/FeatureItem.js b/src/components/ui/FeatureItem.js new file mode 100644 index 000000000..7c482c4d4 --- /dev/null +++ b/src/components/ui/FeatureItem.js | |||
@@ -0,0 +1,37 @@ | |||
1 | import React from 'react'; | ||
2 | import injectSheet from 'react-jss'; | ||
3 | import { Icon } from '@meetfranz/ui'; | ||
4 | import classnames from 'classnames'; | ||
5 | import { mdiCheckCircle } from '@mdi/js'; | ||
6 | |||
7 | const styles = theme => ({ | ||
8 | featureItem: { | ||
9 | borderBottom: [1, 'solid', theme.defaultContentBorder], | ||
10 | padding: [8, 0], | ||
11 | display: 'flex', | ||
12 | alignItems: 'center', | ||
13 | }, | ||
14 | featureIcon: { | ||
15 | fill: theme.brandSuccess, | ||
16 | marginRight: 10, | ||
17 | }, | ||
18 | }); | ||
19 | |||
20 | export const FeatureItem = injectSheet(styles)(({ | ||
21 | classes, className, name, icon, | ||
22 | }) => ( | ||
23 | <li className={classnames({ | ||
24 | [classes.featureItem]: true, | ||
25 | [className]: className, | ||
26 | })} | ||
27 | > | ||
28 | {icon ? ( | ||
29 | <span className={classes.featureIcon}>{icon}</span> | ||
30 | ) : ( | ||
31 | <Icon icon={mdiCheckCircle} className={classes.featureIcon} size={1.5} /> | ||
32 | )} | ||
33 | {name} | ||
34 | </li> | ||
35 | )); | ||
36 | |||
37 | export default FeatureItem; | ||
diff --git a/src/components/ui/FeatureList.js b/src/components/ui/FeatureList.js new file mode 100644 index 000000000..62944ad75 --- /dev/null +++ b/src/components/ui/FeatureList.js | |||
@@ -0,0 +1,89 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { defineMessages, intlShape } from 'react-intl'; | ||
4 | |||
5 | import { FeatureItem } from './FeatureItem'; | ||
6 | |||
7 | const messages = defineMessages({ | ||
8 | unlimitedServices: { | ||
9 | id: 'pricing.features.unlimitedServices', | ||
10 | defaultMessage: '!!!Add unlimited services', | ||
11 | }, | ||
12 | spellchecker: { | ||
13 | id: 'pricing.features.spellchecker', | ||
14 | defaultMessage: '!!!Spellchecker support', | ||
15 | }, | ||
16 | workspaces: { | ||
17 | id: 'pricing.features.workspaces', | ||
18 | defaultMessage: '!!!Workspaces', | ||
19 | }, | ||
20 | customWebsites: { | ||
21 | id: 'pricing.features.customWebsites', | ||
22 | defaultMessage: '!!!Add Custom Websites', | ||
23 | }, | ||
24 | onPremise: { | ||
25 | id: 'pricing.features.onPremise', | ||
26 | defaultMessage: '!!!On-premise & other Hosted Services', | ||
27 | }, | ||
28 | thirdPartyServices: { | ||
29 | id: 'pricing.features.thirdPartyServices', | ||
30 | defaultMessage: '!!!Install 3rd party services', | ||
31 | }, | ||
32 | serviceProxies: { | ||
33 | id: 'pricing.features.serviceProxies', | ||
34 | defaultMessage: '!!!Service Proxies', | ||
35 | }, | ||
36 | teamManagement: { | ||
37 | id: 'pricing.features.teamManagement', | ||
38 | defaultMessage: '!!!Team Management', | ||
39 | }, | ||
40 | appDelays: { | ||
41 | id: 'pricing.features.appDelays', | ||
42 | defaultMessage: '!!!No Waiting Screens', | ||
43 | }, | ||
44 | adFree: { | ||
45 | id: 'pricing.features.adFree', | ||
46 | defaultMessage: '!!!Forever ad-free', | ||
47 | }, | ||
48 | }); | ||
49 | |||
50 | export class FeatureList extends Component { | ||
51 | static propTypes = { | ||
52 | className: PropTypes.string, | ||
53 | featureClassName: PropTypes.string, | ||
54 | }; | ||
55 | |||
56 | static defaultProps = { | ||
57 | className: '', | ||
58 | featureClassName: '', | ||
59 | } | ||
60 | |||
61 | static contextTypes = { | ||
62 | intl: intlShape, | ||
63 | }; | ||
64 | |||
65 | render() { | ||
66 | const { | ||
67 | className, | ||
68 | featureClassName, | ||
69 | } = this.props; | ||
70 | const { intl } = this.context; | ||
71 | |||
72 | return ( | ||
73 | <ul className={className}> | ||
74 | <FeatureItem name={intl.formatMessage(messages.unlimitedServices)} 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> | ||
85 | ); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | export default FeatureList; | ||
diff --git a/src/components/ui/Modal/index.js b/src/components/ui/Modal/index.js index 0b7154760..63d858c47 100644 --- a/src/components/ui/Modal/index.js +++ b/src/components/ui/Modal/index.js | |||
@@ -5,6 +5,7 @@ import classnames from 'classnames'; | |||
5 | import injectCSS from 'react-jss'; | 5 | import injectCSS from 'react-jss'; |
6 | import { Icon } from '@meetfranz/ui'; | 6 | import { Icon } from '@meetfranz/ui'; |
7 | 7 | ||
8 | import { mdiClose } from '@mdi/js'; | ||
8 | import styles from './styles'; | 9 | import styles from './styles'; |
9 | 10 | ||
10 | // ReactModal.setAppElement('#root'); | 11 | // ReactModal.setAppElement('#root'); |
@@ -59,7 +60,7 @@ export default @injectCSS(styles) class Modal extends Component { | |||
59 | className={classes.close} | 60 | className={classes.close} |
60 | onClick={close} | 61 | onClick={close} |
61 | > | 62 | > |
62 | <Icon icon="mdiClose" size={1.5} /> | 63 | <Icon icon={mdiClose} size={1.5} /> |
63 | </button> | 64 | </button> |
64 | )} | 65 | )} |
65 | <div className={classes.content}> | 66 | <div className={classes.content}> |
diff --git a/src/components/ui/PremiumFeatureContainer/index.js b/src/components/ui/PremiumFeatureContainer/index.js index 3c1e0fac3..8d2746e22 100644 --- a/src/components/ui/PremiumFeatureContainer/index.js +++ b/src/components/ui/PremiumFeatureContainer/index.js | |||
@@ -10,6 +10,7 @@ import UserStore from '../../../stores/UserStore'; | |||
10 | 10 | ||
11 | import styles from './styles'; | 11 | import styles from './styles'; |
12 | import { gaEvent } from '../../../lib/analytics'; | 12 | import { gaEvent } from '../../../lib/analytics'; |
13 | import { FeatureStore } from '../../../features/utils/FeatureStore'; | ||
13 | 14 | ||
14 | const messages = defineMessages({ | 15 | const messages = defineMessages({ |
15 | action: { | 16 | action: { |
@@ -22,7 +23,10 @@ const messages = defineMessages({ | |||
22 | class PremiumFeatureContainer extends Component { | 23 | class PremiumFeatureContainer extends Component { |
23 | static propTypes = { | 24 | static propTypes = { |
24 | classes: PropTypes.object.isRequired, | 25 | classes: PropTypes.object.isRequired, |
25 | condition: PropTypes.bool, | 26 | condition: PropTypes.oneOfType([ |
27 | PropTypes.bool, | ||
28 | PropTypes.func, | ||
29 | ]), | ||
26 | gaEventInfo: PropTypes.shape({ | 30 | gaEventInfo: PropTypes.shape({ |
27 | category: PropTypes.string.isRequired, | 31 | category: PropTypes.string.isRequired, |
28 | event: PropTypes.string.isRequired, | 32 | event: PropTypes.string.isRequired, |
@@ -31,7 +35,7 @@ class PremiumFeatureContainer extends Component { | |||
31 | }; | 35 | }; |
32 | 36 | ||
33 | static defaultProps = { | 37 | static defaultProps = { |
34 | condition: true, | 38 | condition: null, |
35 | gaEventInfo: null, | 39 | gaEventInfo: null, |
36 | }; | 40 | }; |
37 | 41 | ||
@@ -51,7 +55,18 @@ class PremiumFeatureContainer extends Component { | |||
51 | 55 | ||
52 | const { intl } = this.context; | 56 | const { intl } = this.context; |
53 | 57 | ||
54 | return !stores.user.data.isPremium && !!condition ? ( | 58 | let showWrapper = !!condition; |
59 | |||
60 | if (condition === null) { | ||
61 | showWrapper = !stores.user.data.isPremium; | ||
62 | } else if (typeof condition === 'function') { | ||
63 | showWrapper = condition({ | ||
64 | isPremium: stores.user.data.isPremium, | ||
65 | features: stores.features.features, | ||
66 | }); | ||
67 | } | ||
68 | |||
69 | return showWrapper ? ( | ||
55 | <div className={classes.container}> | 70 | <div className={classes.container}> |
56 | <div className={classes.titleContainer}> | 71 | <div className={classes.titleContainer}> |
57 | <p className={classes.title}>Premium Feature</p> | 72 | <p className={classes.title}>Premium Feature</p> |
@@ -81,6 +96,7 @@ PremiumFeatureContainer.wrappedComponent.propTypes = { | |||
81 | children: oneOrManyChildElements.isRequired, | 96 | children: oneOrManyChildElements.isRequired, |
82 | stores: PropTypes.shape({ | 97 | stores: PropTypes.shape({ |
83 | user: PropTypes.instanceOf(UserStore).isRequired, | 98 | user: PropTypes.instanceOf(UserStore).isRequired, |
99 | features: PropTypes.instanceOf(FeatureStore).isRequired, | ||
84 | }).isRequired, | 100 | }).isRequired, |
85 | actions: PropTypes.shape({ | 101 | actions: PropTypes.shape({ |
86 | ui: PropTypes.shape({ | 102 | ui: PropTypes.shape({ |
diff --git a/src/config.js b/src/config.js index 471f8d5a6..fba739ddd 100644 --- a/src/config.js +++ b/src/config.js | |||
@@ -19,7 +19,8 @@ export const DEV_WS_API = 'wss://dev.franzinfra.com'; | |||
19 | export const LIVE_WS_API = 'wss://api.franzinfra.com'; | 19 | export const LIVE_WS_API = 'wss://api.franzinfra.com'; |
20 | 20 | ||
21 | export const LOCAL_API_WEBSITE = 'http://localhost:3333'; | 21 | export const LOCAL_API_WEBSITE = 'http://localhost:3333'; |
22 | export const DEV_API_WEBSITE = 'https://meetfranz.com'; | 22 | // export const DEV_API_WEBSITE = 'https://meetfranz.com';t |
23 | export const DEV_API_WEBSITE = 'http://hash-3ac3ccd2472269cf585c58a4f6973d86f3c9e7bd.franzstaging.com/'; // TODO: revert me | ||
23 | export const LIVE_API_WEBSITE = 'https://meetfranz.com'; | 24 | export const LIVE_API_WEBSITE = 'https://meetfranz.com'; |
24 | 25 | ||
25 | export const STATS_API = 'https://stats.franzinfra.com'; | 26 | export const STATS_API = 'https://stats.franzinfra.com'; |
@@ -49,16 +50,16 @@ export const DEFAULT_APP_SETTINGS = { | |||
49 | }; | 50 | }; |
50 | 51 | ||
51 | export const DEFAULT_FEATURES_CONFIG = { | 52 | export const DEFAULT_FEATURES_CONFIG = { |
52 | isSpellcheckerPremiumFeature: false, | 53 | isSpellcheckerIncludedInCurrentPlan: true, |
53 | needToWaitToProceed: false, | 54 | needToWaitToProceed: false, |
54 | needToWaitToProceedConfig: { | 55 | needToWaitToProceedConfig: { |
55 | delayOffset: ms('1h'), | 56 | delayOffset: ms('1h'), |
56 | wait: ms('10s'), | 57 | wait: ms('10s'), |
57 | }, | 58 | }, |
58 | isServiceProxyEnabled: false, | 59 | isServiceProxyEnabled: false, |
59 | isServiceProxyPremiumFeature: true, | 60 | isServiceProxyIncludedInCurrentPlan: false, |
60 | isAnnouncementsEnabled: true, | 61 | isAnnouncementsEnabled: true, |
61 | isWorkspacePremiumFeature: true, | 62 | isWorkspaceIncludedInCurrentPlan: true, |
62 | isWorkspaceEnabled: false, | 63 | isWorkspaceEnabled: false, |
63 | }; | 64 | }; |
64 | 65 | ||
@@ -71,6 +72,7 @@ export const DEFAULT_WINDOW_OPTIONS = { | |||
71 | 72 | ||
72 | export const FRANZ_SERVICE_REQUEST = 'https://bit.ly/franz-plugin-docs'; | 73 | export const FRANZ_SERVICE_REQUEST = 'https://bit.ly/franz-plugin-docs'; |
73 | export const FRANZ_TRANSLATION = 'https://bit.ly/franz-translate'; | 74 | export const FRANZ_TRANSLATION = 'https://bit.ly/franz-translate'; |
75 | export const FRANZ_DEV_DOCS = 'http://bit.ly/franz-dev-hub'; | ||
74 | 76 | ||
75 | export const FILE_SYSTEM_SETTINGS_TYPES = [ | 77 | export const FILE_SYSTEM_SETTINGS_TYPES = [ |
76 | 'app', | 78 | 'app', |
@@ -87,3 +89,25 @@ export const ALLOWED_PROTOCOLS = [ | |||
87 | 'http:', | 89 | 'http:', |
88 | 'ftp:', | 90 | 'ftp:', |
89 | ]; | 91 | ]; |
92 | |||
93 | export const PLANS = { | ||
94 | PERSONAL: 'PERSONAL', | ||
95 | PRO: 'PRO', | ||
96 | LEGACY: 'LEGACY', | ||
97 | FREE: 'FREE', | ||
98 | }; | ||
99 | |||
100 | export const PLANS_MAPPING = { | ||
101 | 'franz-personal-monthly': PLANS.PERSONAL, | ||
102 | 'franz-personal-yearly': PLANS.PERSONAL, | ||
103 | 'franz-pro-monthly': PLANS.PRO, | ||
104 | 'franz-pro-yearly': PLANS.PRO, | ||
105 | 'franz-supporter-license': PLANS.LEGACY, | ||
106 | 'franz-supporter-license-x1': PLANS.LEGACY, | ||
107 | 'franz-supporter-license-x2': PLANS.LEGACY, | ||
108 | 'franz-supporter-license-year': PLANS.LEGACY, | ||
109 | 'franz-supporter-license-year-x1': PLANS.LEGACY, | ||
110 | 'franz-supporter-license-year-x2': PLANS.LEGACY, | ||
111 | 'franz-supporter-license-year-2019': PLANS.LEGACY, | ||
112 | free: PLANS.FREE, | ||
113 | }; | ||
diff --git a/src/containers/auth/PricingScreen.js b/src/containers/auth/PricingScreen.js index 8d179a170..af1651931 100644 --- a/src/containers/auth/PricingScreen.js +++ b/src/containers/auth/PricingScreen.js | |||
@@ -5,7 +5,6 @@ import { RouterStore } from 'mobx-react-router'; | |||
5 | 5 | ||
6 | import Pricing from '../../components/auth/Pricing'; | 6 | import Pricing from '../../components/auth/Pricing'; |
7 | import UserStore from '../../stores/UserStore'; | 7 | import UserStore from '../../stores/UserStore'; |
8 | import PaymentStore from '../../stores/PaymentStore'; | ||
9 | 8 | ||
10 | import { globalError as globalErrorPropType } from '../../prop-types'; | 9 | import { globalError as globalErrorPropType } from '../../prop-types'; |
11 | 10 | ||
@@ -14,20 +13,40 @@ export default @inject('stores', 'actions') @observer class PricingScreen extend | |||
14 | error: globalErrorPropType.isRequired, | 13 | error: globalErrorPropType.isRequired, |
15 | }; | 14 | }; |
16 | 15 | ||
16 | async submit() { | ||
17 | const { | ||
18 | actions, | ||
19 | stores, | ||
20 | } = this.props; | ||
21 | |||
22 | const { activateTrialRequest } = stores.user; | ||
23 | const { defaultTrialPlan } = stores.features.features; | ||
24 | |||
25 | actions.user.activateTrial({ planId: defaultTrialPlan }); | ||
26 | await activateTrialRequest._promise; | ||
27 | |||
28 | if (!activateTrialRequest.isError) { | ||
29 | stores.router.push('/'); | ||
30 | stores.user.hasCompletedSignup = true; | ||
31 | } | ||
32 | } | ||
33 | |||
17 | render() { | 34 | render() { |
18 | const { actions, stores, error } = this.props; | 35 | const { |
36 | error, | ||
37 | stores, | ||
38 | } = this.props; | ||
19 | 39 | ||
20 | const nextStepRoute = stores.user.legacyServices.length ? stores.user.importRoute : stores.user.inviteRoute; | 40 | const { getUserInfoRequest, activateTrialRequest } = stores.user; |
41 | const { featuresRequest } = stores.features; | ||
21 | 42 | ||
22 | return ( | 43 | return ( |
23 | <Pricing | 44 | <Pricing |
24 | donor={stores.user.data.donor || {}} | 45 | onSubmit={this.submit.bind(this)} |
25 | onSubmit={actions.user.signup} | 46 | isLoadingRequiredData={(getUserInfoRequest.isExecuting || !getUserInfoRequest.wasExecuted) || (featuresRequest.isExecuting || !featuresRequest.wasExecuted)} |
26 | onCloseSubscriptionWindow={() => this.props.stores.router.push(nextStepRoute)} | 47 | isActivatingTrial={activateTrialRequest.isExecuting} |
27 | isLoading={stores.payment.plansRequest.isExecuting} | 48 | trialActivationError={activateTrialRequest.isError} |
28 | isLoadingUser={stores.user.getUserInfoRequest.isExecuting} | ||
29 | error={error} | 49 | error={error} |
30 | skipAction={() => this.props.stores.router.push(nextStepRoute)} | ||
31 | /> | 50 | /> |
32 | ); | 51 | ); |
33 | } | 52 | } |
@@ -36,12 +55,11 @@ export default @inject('stores', 'actions') @observer class PricingScreen extend | |||
36 | PricingScreen.wrappedComponent.propTypes = { | 55 | PricingScreen.wrappedComponent.propTypes = { |
37 | actions: PropTypes.shape({ | 56 | actions: PropTypes.shape({ |
38 | user: PropTypes.shape({ | 57 | user: PropTypes.shape({ |
39 | signup: PropTypes.func.isRequired, | 58 | activateTrial: PropTypes.func.isRequired, |
40 | }).isRequired, | 59 | }).isRequired, |
41 | }).isRequired, | 60 | }).isRequired, |
42 | stores: PropTypes.shape({ | 61 | stores: PropTypes.shape({ |
43 | user: PropTypes.instanceOf(UserStore).isRequired, | 62 | user: PropTypes.instanceOf(UserStore).isRequired, |
44 | payment: PropTypes.instanceOf(PaymentStore).isRequired, | ||
45 | router: PropTypes.instanceOf(RouterStore).isRequired, | 63 | router: PropTypes.instanceOf(RouterStore).isRequired, |
46 | }).isRequired, | 64 | }).isRequired, |
47 | }; | 65 | }; |
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index cf3da71e8..a14a98554 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js | |||
@@ -10,6 +10,7 @@ import FeaturesStore from '../../stores/FeaturesStore'; | |||
10 | import UIStore from '../../stores/UIStore'; | 10 | import UIStore from '../../stores/UIStore'; |
11 | import NewsStore from '../../stores/NewsStore'; | 11 | import NewsStore from '../../stores/NewsStore'; |
12 | import SettingsStore from '../../stores/SettingsStore'; | 12 | import SettingsStore from '../../stores/SettingsStore'; |
13 | import UserStore from '../../stores/UserStore'; | ||
13 | import RequestStore from '../../stores/RequestStore'; | 14 | import RequestStore from '../../stores/RequestStore'; |
14 | import GlobalErrorStore from '../../stores/GlobalErrorStore'; | 15 | import GlobalErrorStore from '../../stores/GlobalErrorStore'; |
15 | 16 | ||
@@ -39,6 +40,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e | |||
39 | settings, | 40 | settings, |
40 | globalError, | 41 | globalError, |
41 | requests, | 42 | requests, |
43 | user, | ||
42 | } = this.props.stores; | 44 | } = this.props.stores; |
43 | 45 | ||
44 | const { | 46 | const { |
@@ -125,6 +127,8 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e | |||
125 | reload={reload} | 127 | reload={reload} |
126 | openSettings={openSettings} | 128 | openSettings={openSettings} |
127 | update={updateService} | 129 | update={updateService} |
130 | userHasCompletedSignup={user.hasCompletedSignup} | ||
131 | hasActivatedTrial={user.hasActivatedTrial} | ||
128 | /> | 132 | /> |
129 | ); | 133 | ); |
130 | 134 | ||
@@ -149,6 +153,7 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e | |||
149 | retryRequiredRequests={retryRequiredRequests} | 153 | retryRequiredRequests={retryRequiredRequests} |
150 | areRequiredRequestsLoading={requests.areRequiredRequestsLoading} | 154 | areRequiredRequestsLoading={requests.areRequiredRequestsLoading} |
151 | isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible} | 155 | isDelayAppScreenVisible={delayAppState.isDelayAppScreenVisible} |
156 | hasActivatedTrial={user.hasActivatedTrial} | ||
152 | > | 157 | > |
153 | {React.Children.count(children) > 0 ? children : null} | 158 | {React.Children.count(children) > 0 ? children : null} |
154 | </AppLayout> | 159 | </AppLayout> |
@@ -166,6 +171,7 @@ AppLayoutContainer.wrappedComponent.propTypes = { | |||
166 | ui: PropTypes.instanceOf(UIStore).isRequired, | 171 | ui: PropTypes.instanceOf(UIStore).isRequired, |
167 | news: PropTypes.instanceOf(NewsStore).isRequired, | 172 | news: PropTypes.instanceOf(NewsStore).isRequired, |
168 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | 173 | settings: PropTypes.instanceOf(SettingsStore).isRequired, |
174 | user: PropTypes.instanceOf(UserStore).isRequired, | ||
169 | requests: PropTypes.instanceOf(RequestStore).isRequired, | 175 | requests: PropTypes.instanceOf(RequestStore).isRequired, |
170 | globalError: PropTypes.instanceOf(GlobalErrorStore).isRequired, | 176 | globalError: PropTypes.instanceOf(GlobalErrorStore).isRequired, |
171 | }).isRequired, | 177 | }).isRequired, |
diff --git a/src/containers/settings/AccountScreen.js b/src/containers/settings/AccountScreen.js index 66076504f..2b5eba91c 100644 --- a/src/containers/settings/AccountScreen.js +++ b/src/containers/settings/AccountScreen.js | |||
@@ -26,7 +26,7 @@ export default @inject('stores', 'actions') @observer class AccountScreen extend | |||
26 | handleWebsiteLink(route) { | 26 | handleWebsiteLink(route) { |
27 | const { actions, stores } = this.props; | 27 | const { actions, stores } = this.props; |
28 | 28 | ||
29 | const url = `${WEBSITE}${route}?authToken=${stores.user.authToken}&utm_source=app&utm_medium=account_dashboard`; | 29 | const url = stores.user.getAuthURL(`${WEBSITE}${route}?utm_source=app&utm_medium=account_dashboard`); |
30 | 30 | ||
31 | actions.app.openExternalUrl({ url }); | 31 | actions.app.openExternalUrl({ url }); |
32 | } | 32 | } |
@@ -42,6 +42,7 @@ export default @inject('stores', 'actions') @observer class AccountScreen extend | |||
42 | <ErrorBoundary> | 42 | <ErrorBoundary> |
43 | <AccountDashboard | 43 | <AccountDashboard |
44 | user={user.data} | 44 | user={user.data} |
45 | isProUser={user.isPro} | ||
45 | isLoading={isLoadingUserInfo} | 46 | isLoading={isLoadingUserInfo} |
46 | isLoadingPlans={isLoadingPlans} | 47 | isLoadingPlans={isLoadingPlans} |
47 | userInfoRequestFailed={user.getUserInfoRequest.wasExecuted && user.getUserInfoRequest.isError} | 48 | userInfoRequestFailed={user.getUserInfoRequest.wasExecuted && user.getUserInfoRequest.isError} |
@@ -51,6 +52,7 @@ export default @inject('stores', 'actions') @observer class AccountScreen extend | |||
51 | isLoadingDeleteAccount={user.deleteAccountRequest.isExecuting} | 52 | isLoadingDeleteAccount={user.deleteAccountRequest.isExecuting} |
52 | isDeleteAccountSuccessful={user.deleteAccountRequest.wasExecuted && !user.deleteAccountRequest.isError} | 53 | isDeleteAccountSuccessful={user.deleteAccountRequest.wasExecuted && !user.deleteAccountRequest.isError} |
53 | openEditAccount={() => this.handleWebsiteLink('/user/profile')} | 54 | openEditAccount={() => this.handleWebsiteLink('/user/profile')} |
55 | upgradeToPro={() => this.handleWebsiteLink('/inapp/user/licenses')} | ||
54 | openBilling={() => this.handleWebsiteLink('/user/billing')} | 56 | openBilling={() => this.handleWebsiteLink('/user/billing')} |
55 | openInvoices={() => this.handleWebsiteLink('/user/invoices')} | 57 | openInvoices={() => this.handleWebsiteLink('/user/invoices')} |
56 | /> | 58 | /> |
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js index 870ca4ecd..e4ff03bb3 100644 --- a/src/containers/settings/EditServiceScreen.js +++ b/src/containers/settings/EditServiceScreen.js | |||
@@ -330,8 +330,8 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex | |||
330 | onSubmit={d => this.onSubmit(d)} | 330 | onSubmit={d => this.onSubmit(d)} |
331 | onDelete={() => this.deleteService()} | 331 | onDelete={() => this.deleteService()} |
332 | isProxyFeatureEnabled={proxyFeature.isEnabled} | 332 | isProxyFeatureEnabled={proxyFeature.isEnabled} |
333 | isProxyPremiumFeature={proxyFeature.isPremium} | 333 | isServiceProxyIncludedInCurrentPlan={proxyFeature.isIncludedInCurrentPlan} |
334 | isSpellcheckerPremiumFeature={spellcheckerFeature.isPremium} | 334 | isSpellcheckerIncludedInCurrentPlan={spellcheckerFeature.isIncludedInCurrentPlan} |
335 | /> | 335 | /> |
336 | </ErrorBoundary> | 336 | </ErrorBoundary> |
337 | ); | 337 | ); |
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index 97c1fa3b1..67d52f102 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js | |||
@@ -159,8 +159,8 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
159 | }, | 159 | }, |
160 | enableSpellchecking: { | 160 | enableSpellchecking: { |
161 | label: intl.formatMessage(messages.enableSpellchecking), | 161 | label: intl.formatMessage(messages.enableSpellchecking), |
162 | value: !this.props.stores.user.data.isPremium && spellcheckerConfig.isPremium ? false : settings.all.app.enableSpellchecking, | 162 | value: !this.props.stores.user.data.isPremium && !spellcheckerConfig.isIncludedInCurrentPlan ? false : settings.all.app.enableSpellchecking, |
163 | default: !this.props.stores.user.data.isPremium && spellcheckerConfig.isPremium ? false : DEFAULT_APP_SETTINGS.enableSpellchecking, | 163 | default: !this.props.stores.user.data.isPremium && !spellcheckerConfig.isIncludedInCurrentPlan ? false : DEFAULT_APP_SETTINGS.enableSpellchecking, |
164 | }, | 164 | }, |
165 | spellcheckerLanguage: { | 165 | spellcheckerLanguage: { |
166 | label: intl.formatMessage(globalMessages.spellcheckerLanguage), | 166 | label: intl.formatMessage(globalMessages.spellcheckerLanguage), |
@@ -223,7 +223,7 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e | |||
223 | cacheSize={cacheSize} | 223 | cacheSize={cacheSize} |
224 | isClearingAllCache={isClearingAllCache} | 224 | isClearingAllCache={isClearingAllCache} |
225 | onClearAllCache={clearAllCache} | 225 | onClearAllCache={clearAllCache} |
226 | isSpellcheckerPremiumFeature={spellcheckerConfig.isPremium} | 226 | isSpellcheckerIncludedInCurrentPlan={spellcheckerConfig.isIncludedInCurrentPlan} |
227 | /> | 227 | /> |
228 | </ErrorBoundary> | 228 | </ErrorBoundary> |
229 | ); | 229 | ); |
diff --git a/src/containers/settings/RecipesScreen.js b/src/containers/settings/RecipesScreen.js index eda5ae54c..132820b6f 100644 --- a/src/containers/settings/RecipesScreen.js +++ b/src/containers/settings/RecipesScreen.js | |||
@@ -1,7 +1,9 @@ | |||
1 | import { remote, shell } from 'electron'; | ||
1 | import React, { Component } from 'react'; | 2 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 3 | import PropTypes from 'prop-types'; |
3 | import { autorun } from 'mobx'; | 4 | import { autorun } from 'mobx'; |
4 | import { inject, observer } from 'mobx-react'; | 5 | import { inject, observer } from 'mobx-react'; |
6 | import path from 'path'; | ||
5 | 7 | ||
6 | import RecipePreviewsStore from '../../stores/RecipePreviewsStore'; | 8 | import RecipePreviewsStore from '../../stores/RecipePreviewsStore'; |
7 | import RecipeStore from '../../stores/RecipesStore'; | 9 | import RecipeStore from '../../stores/RecipesStore'; |
@@ -10,6 +12,11 @@ import UserStore from '../../stores/UserStore'; | |||
10 | 12 | ||
11 | import RecipesDashboard from '../../components/settings/recipes/RecipesDashboard'; | 13 | import RecipesDashboard from '../../components/settings/recipes/RecipesDashboard'; |
12 | import ErrorBoundary from '../../components/util/ErrorBoundary'; | 14 | import ErrorBoundary from '../../components/util/ErrorBoundary'; |
15 | import { FRANZ_DEV_DOCS } from '../../config'; | ||
16 | import { gaEvent } from '../../lib/analytics'; | ||
17 | import { communityRecipesStore } from '../../features/communityRecipes'; | ||
18 | |||
19 | const { app } = remote; | ||
13 | 20 | ||
14 | export default @inject('stores', 'actions') @observer class RecipesScreen extends Component { | 21 | export default @inject('stores', 'actions') @observer class RecipesScreen extends Component { |
15 | static propTypes = { | 22 | static propTypes = { |
@@ -67,9 +74,16 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend | |||
67 | 74 | ||
68 | render() { | 75 | render() { |
69 | const { | 76 | const { |
70 | recipePreviews, recipes, services, user, | 77 | recipePreviews, |
78 | recipes, | ||
79 | services, | ||
80 | user, | ||
71 | } = this.props.stores; | 81 | } = this.props.stores; |
72 | const { showAddServiceInterface } = this.props.actions.service; | 82 | |
83 | const { | ||
84 | app: appActions, | ||
85 | service: serviceActions, | ||
86 | } = this.props.actions; | ||
73 | 87 | ||
74 | const { filter } = this.props.params; | 88 | const { filter } = this.props.params; |
75 | let recipeFilter; | 89 | let recipeFilter; |
@@ -77,7 +91,7 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend | |||
77 | if (filter === 'all') { | 91 | if (filter === 'all') { |
78 | recipeFilter = recipePreviews.all; | 92 | recipeFilter = recipePreviews.all; |
79 | } else if (filter === 'dev') { | 93 | } else if (filter === 'dev') { |
80 | recipeFilter = recipePreviews.dev; | 94 | recipeFilter = communityRecipesStore.communityRecipes; |
81 | } else { | 95 | } else { |
82 | recipeFilter = recipePreviews.featured; | 96 | recipeFilter = recipePreviews.featured; |
83 | } | 97 | } |
@@ -89,6 +103,8 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend | |||
89 | || recipes.installRecipeRequest.isExecuting | 103 | || recipes.installRecipeRequest.isExecuting |
90 | || recipePreviews.searchRecipePreviewsRequest.isExecuting; | 104 | || recipePreviews.searchRecipePreviewsRequest.isExecuting; |
91 | 105 | ||
106 | const recipeDirectory = path.join(app.getPath('userData'), 'recipes', 'dev'); | ||
107 | |||
92 | return ( | 108 | return ( |
93 | <ErrorBoundary> | 109 | <ErrorBoundary> |
94 | <RecipesDashboard | 110 | <RecipesDashboard |
@@ -97,12 +113,23 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend | |||
97 | addedServiceCount={services.all.length} | 113 | addedServiceCount={services.all.length} |
98 | isPremium={user.data.isPremium} | 114 | isPremium={user.data.isPremium} |
99 | hasLoadedRecipes={recipePreviews.featuredRecipePreviewsRequest.wasExecuted} | 115 | hasLoadedRecipes={recipePreviews.featuredRecipePreviewsRequest.wasExecuted} |
100 | showAddServiceInterface={showAddServiceInterface} | 116 | showAddServiceInterface={serviceActions.showAddServiceInterface} |
101 | searchRecipes={e => this.searchRecipes(e)} | 117 | searchRecipes={e => this.searchRecipes(e)} |
102 | resetSearch={() => this.resetSearch()} | 118 | resetSearch={() => this.resetSearch()} |
103 | searchNeedle={this.state.needle} | 119 | searchNeedle={this.state.needle} |
104 | serviceStatus={services.actionStatus} | 120 | serviceStatus={services.actionStatus} |
105 | devRecipesCount={recipePreviews.dev.length} | 121 | recipeFilter={filter} |
122 | recipeDirectory={recipeDirectory} | ||
123 | openRecipeDirectory={() => { | ||
124 | shell.openItem(recipeDirectory); | ||
125 | gaEvent('Recipe', 'open-recipe-folder', 'Open Folder'); | ||
126 | }} | ||
127 | openDevDocs={() => { | ||
128 | appActions.openExternalUrl({ url: FRANZ_DEV_DOCS }); | ||
129 | gaEvent('Recipe', 'open-dev-docs', 'Developer Documentation'); | ||
130 | }} | ||
131 | isCommunityRecipesIncludedInCurrentPlan={communityRecipesStore.isCommunityRecipesIncludedInCurrentPlan} | ||
132 | isUserPremiumUser={user.isPremium} | ||
106 | /> | 133 | /> |
107 | </ErrorBoundary> | 134 | </ErrorBoundary> |
108 | ); | 135 | ); |
@@ -117,6 +144,9 @@ RecipesScreen.wrappedComponent.propTypes = { | |||
117 | user: PropTypes.instanceOf(UserStore).isRequired, | 144 | user: PropTypes.instanceOf(UserStore).isRequired, |
118 | }).isRequired, | 145 | }).isRequired, |
119 | actions: PropTypes.shape({ | 146 | actions: PropTypes.shape({ |
147 | app: PropTypes.shape({ | ||
148 | openExternalUrl: PropTypes.func.isRequired, | ||
149 | }).isRequired, | ||
120 | service: PropTypes.shape({ | 150 | service: PropTypes.shape({ |
121 | showAddServiceInterface: PropTypes.func.isRequired, | 151 | showAddServiceInterface: PropTypes.func.isRequired, |
122 | }).isRequired, | 152 | }).isRequired, |
diff --git a/src/containers/settings/TeamScreen.js b/src/containers/settings/TeamScreen.js index c69d5ad08..b7b1b78cb 100644 --- a/src/containers/settings/TeamScreen.js +++ b/src/containers/settings/TeamScreen.js | |||
@@ -14,7 +14,6 @@ export default @inject('stores', 'actions') @observer class TeamScreen extends C | |||
14 | const { actions, stores } = this.props; | 14 | const { actions, stores } = this.props; |
15 | 15 | ||
16 | const url = `${WEBSITE}${route}?authToken=${stores.user.authToken}&utm_source=app&utm_medium=account_dashboard`; | 16 | const url = `${WEBSITE}${route}?authToken=${stores.user.authToken}&utm_source=app&utm_medium=account_dashboard`; |
17 | console.log(url); | ||
18 | 17 | ||
19 | actions.app.openExternalUrl({ url }); | 18 | actions.app.openExternalUrl({ url }); |
20 | } | 19 | } |
diff --git a/src/containers/subscription/SubscriptionFormScreen.js b/src/containers/subscription/SubscriptionFormScreen.js index aa1166f5e..e9e457084 100644 --- a/src/containers/subscription/SubscriptionFormScreen.js +++ b/src/containers/subscription/SubscriptionFormScreen.js | |||
@@ -1,4 +1,3 @@ | |||
1 | import { remote } from 'electron'; | ||
2 | import React, { Component } from 'react'; | 1 | import React, { Component } from 'react'; |
3 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
4 | import { inject, observer } from 'mobx-react'; | 3 | import { inject, observer } from 'mobx-react'; |
@@ -6,96 +5,50 @@ import { inject, observer } from 'mobx-react'; | |||
6 | import PaymentStore from '../../stores/PaymentStore'; | 5 | import PaymentStore from '../../stores/PaymentStore'; |
7 | 6 | ||
8 | import SubscriptionForm from '../../components/subscription/SubscriptionForm'; | 7 | import SubscriptionForm from '../../components/subscription/SubscriptionForm'; |
9 | 8 | import TrialForm from '../../components/subscription/TrialForm'; | |
10 | const { BrowserWindow } = remote; | ||
11 | 9 | ||
12 | export default @inject('stores', 'actions') @observer class SubscriptionFormScreen extends Component { | 10 | export default @inject('stores', 'actions') @observer class SubscriptionFormScreen extends Component { |
13 | static propTypes = { | 11 | async openBrowser() { |
14 | onCloseWindow: PropTypes.func, | ||
15 | content: PropTypes.node, | ||
16 | showSkipOption: PropTypes.bool, | ||
17 | skipAction: PropTypes.func, | ||
18 | skipButtonLabel: PropTypes.string, | ||
19 | hideInfo: PropTypes.bool, | ||
20 | } | ||
21 | |||
22 | static defaultProps = { | ||
23 | onCloseWindow: () => null, | ||
24 | content: '', | ||
25 | showSkipOption: false, | ||
26 | skipAction: () => null, | ||
27 | skipButtonLabel: '', | ||
28 | hideInfo: false, | ||
29 | } | ||
30 | |||
31 | async handlePayment(plan) { | ||
32 | const { | 12 | const { |
33 | actions, | 13 | actions, |
34 | stores, | 14 | stores, |
35 | onCloseWindow, | ||
36 | } = this.props; | 15 | } = this.props; |
37 | 16 | ||
38 | const interval = plan; | 17 | const { |
39 | 18 | user, | |
40 | const { id } = stores.payment.plan[interval]; | 19 | features, |
41 | actions.payment.createHostedPage({ | 20 | } = stores; |
42 | planId: id, | ||
43 | }); | ||
44 | |||
45 | const hostedPage = await stores.payment.createHostedPageRequest; | ||
46 | 21 | ||
47 | if (hostedPage.url) { | 22 | let hostedPageURL = !user.data.hadSubscription ? features.features.planSelectionURL : features.features.subscribeURL; |
48 | if (hostedPage.legacyCheckoutFlow) { | 23 | hostedPageURL = user.getAuthURL(hostedPageURL); |
49 | const paymentWindow = new BrowserWindow({ | ||
50 | parent: remote.getCurrentWindow(), | ||
51 | modal: true, | ||
52 | title: '🔒 Franz Supporter License', | ||
53 | width: 600, | ||
54 | height: window.innerHeight - 100, | ||
55 | maxWidth: 600, | ||
56 | minWidth: 600, | ||
57 | webPreferences: { | ||
58 | nodeIntegration: true, | ||
59 | webviewTag: true, | ||
60 | }, | ||
61 | }); | ||
62 | paymentWindow.loadURL(`file://${__dirname}/../../index.html#/payment/${encodeURIComponent(hostedPage.url)}`); | ||
63 | 24 | ||
64 | paymentWindow.on('closed', () => { | 25 | actions.app.openExternalUrl({ url: hostedPageURL }); |
65 | onCloseWindow(); | ||
66 | }); | ||
67 | } else { | ||
68 | actions.app.openExternalUrl({ | ||
69 | url: hostedPage.url, | ||
70 | }); | ||
71 | } | ||
72 | } | ||
73 | } | 26 | } |
74 | 27 | ||
75 | render() { | 28 | render() { |
76 | const { | 29 | const { |
77 | content, | ||
78 | actions, | 30 | actions, |
79 | stores, | 31 | stores, |
80 | showSkipOption, | ||
81 | skipAction, | ||
82 | skipButtonLabel, | ||
83 | hideInfo, | ||
84 | } = this.props; | 32 | } = this.props; |
33 | |||
34 | const { data: user } = stores.user; | ||
35 | |||
36 | if (user.hadSubscription) { | ||
37 | return ( | ||
38 | <SubscriptionForm | ||
39 | plan={stores.payment.plan} | ||
40 | selectPlan={() => this.openBrowser()} | ||
41 | isActivatingTrial={stores.user.activateTrialRequest.isExecuting || stores.user.getUserInfoRequest.isExecuting} | ||
42 | /> | ||
43 | ); | ||
44 | } | ||
45 | |||
85 | return ( | 46 | return ( |
86 | <SubscriptionForm | 47 | <TrialForm |
87 | plan={stores.payment.plan} | 48 | plan={stores.payment.plan} |
88 | isLoading={stores.payment.plansRequest.isExecuting} | 49 | activateTrial={() => actions.user.activateTrial({ planId: stores.features.features.defaultTrialPlan })} |
89 | retryPlanRequest={() => stores.payment.plansRequest.reload()} | 50 | showAllOptions={() => this.openBrowser()} |
90 | isCreatingHostedPage={stores.payment.createHostedPageRequest.isExecuting} | 51 | isActivatingTrial={stores.user.activateTrialRequest.isExecuting || stores.user.getUserInfoRequest.isExecuting} |
91 | handlePayment={price => this.handlePayment(price)} | ||
92 | content={content} | ||
93 | error={stores.payment.plansRequest.isError} | ||
94 | showSkipOption={showSkipOption} | ||
95 | skipAction={skipAction} | ||
96 | skipButtonLabel={skipButtonLabel} | ||
97 | hideInfo={hideInfo} | ||
98 | openExternalUrl={actions.app.openExternalUrl} | ||
99 | /> | 52 | /> |
100 | ); | 53 | ); |
101 | } | 54 | } |
diff --git a/src/containers/subscription/SubscriptionPopupScreen.js b/src/containers/subscription/SubscriptionPopupScreen.js index f76d6c5a6..0de5a87c4 100644 --- a/src/containers/subscription/SubscriptionPopupScreen.js +++ b/src/containers/subscription/SubscriptionPopupScreen.js | |||
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; | |||
3 | import { inject, observer } from 'mobx-react'; | 3 | import { inject, observer } from 'mobx-react'; |
4 | 4 | ||
5 | import SubscriptionPopup from '../../components/subscription/SubscriptionPopup'; | 5 | import SubscriptionPopup from '../../components/subscription/SubscriptionPopup'; |
6 | import { isDevMode } from '../../environment'; | ||
6 | 7 | ||
7 | 8 | ||
8 | export default @inject('stores', 'actions') @observer class SubscriptionPopupScreen extends Component { | 9 | export default @inject('stores', 'actions') @observer class SubscriptionPopupScreen extends Component { |
@@ -13,7 +14,7 @@ export default @inject('stores', 'actions') @observer class SubscriptionPopupScr | |||
13 | completeCheck(event) { | 14 | completeCheck(event) { |
14 | const { url } = event; | 15 | const { url } = event; |
15 | 16 | ||
16 | if ((url.includes('recurly') && url.includes('confirmation')) || (url.includes('meetfranz') && url.includes('success'))) { | 17 | if ((url.includes('recurly') && url.includes('confirmation')) || ((url.includes('meetfranz') || isDevMode) && url.includes('success'))) { |
17 | this.setState({ | 18 | this.setState({ |
18 | complete: true, | 19 | complete: true, |
19 | }); | 20 | }); |
diff --git a/src/features/basicAuth/Component.js b/src/features/basicAuth/Component.js index a8252acb7..ba9ae2273 100644 --- a/src/features/basicAuth/Component.js +++ b/src/features/basicAuth/Component.js | |||
@@ -27,7 +27,6 @@ export default @injectSheet(styles) @observer class BasicAuthModal extends Compo | |||
27 | e.preventDefault(); | 27 | e.preventDefault(); |
28 | 28 | ||
29 | const values = Form.values(); | 29 | const values = Form.values(); |
30 | console.log('form submit', values); | ||
31 | 30 | ||
32 | sendCredentials(values.user, values.password); | 31 | sendCredentials(values.user, values.password); |
33 | resetState(); | 32 | resetState(); |
diff --git a/src/features/communityRecipes/index.js b/src/features/communityRecipes/index.js new file mode 100644 index 000000000..4d050f90e --- /dev/null +++ b/src/features/communityRecipes/index.js | |||
@@ -0,0 +1,28 @@ | |||
1 | import { reaction } from 'mobx'; | ||
2 | import { CommunityRecipesStore } from './store'; | ||
3 | |||
4 | const debug = require('debug')('Franz:feature:communityRecipes'); | ||
5 | |||
6 | export const DEFAULT_SERVICE_LIMIT = 3; | ||
7 | |||
8 | export const communityRecipesStore = new CommunityRecipesStore(); | ||
9 | |||
10 | export default function initCommunityRecipes(stores, actions) { | ||
11 | const { features } = stores; | ||
12 | |||
13 | communityRecipesStore.start(stores, actions); | ||
14 | |||
15 | // Toggle communityRecipe premium status | ||
16 | reaction( | ||
17 | () => ( | ||
18 | features.features.isCommunityRecipesIncludedInCurrentPlan | ||
19 | ), | ||
20 | (isPremiumFeature) => { | ||
21 | debug('Community recipes is premium feature: ', isPremiumFeature); | ||
22 | communityRecipesStore.isCommunityRecipesIncludedInCurrentPlan = isPremiumFeature; | ||
23 | }, | ||
24 | { | ||
25 | fireImmediately: true, | ||
26 | }, | ||
27 | ); | ||
28 | } | ||
diff --git a/src/features/communityRecipes/store.js b/src/features/communityRecipes/store.js new file mode 100644 index 000000000..4d45c3b33 --- /dev/null +++ b/src/features/communityRecipes/store.js | |||
@@ -0,0 +1,31 @@ | |||
1 | import { computed, observable } from 'mobx'; | ||
2 | import { FeatureStore } from '../utils/FeatureStore'; | ||
3 | |||
4 | const debug = require('debug')('Franz:feature:communityRecipes:store'); | ||
5 | |||
6 | export class CommunityRecipesStore extends FeatureStore { | ||
7 | @observable isCommunityRecipesIncludedInCurrentPlan = false; | ||
8 | |||
9 | start(stores, actions) { | ||
10 | debug('start'); | ||
11 | this.stores = stores; | ||
12 | this.actions = actions; | ||
13 | } | ||
14 | |||
15 | stop() { | ||
16 | debug('stop'); | ||
17 | super.stop(); | ||
18 | } | ||
19 | |||
20 | @computed get communityRecipes() { | ||
21 | if (!this.stores) return []; | ||
22 | |||
23 | return this.stores.recipePreviews.dev.map((r) => { | ||
24 | r.isDevRecipe = !!r.author.find(a => a.email === this.stores.user.data.email); | ||
25 | |||
26 | return r; | ||
27 | }); | ||
28 | } | ||
29 | } | ||
30 | |||
31 | export default CommunityRecipesStore; | ||
diff --git a/src/features/delayApp/Component.js b/src/features/delayApp/Component.js index ff0f1f2f8..de5653f04 100644 --- a/src/features/delayApp/Component.js +++ b/src/features/delayApp/Component.js | |||
@@ -4,29 +4,39 @@ import { inject, observer } from 'mobx-react'; | |||
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import injectSheet from 'react-jss'; | 5 | import injectSheet from 'react-jss'; |
6 | 6 | ||
7 | import { Button } from '@meetfranz/forms'; | ||
7 | import { gaEvent } from '../../lib/analytics'; | 8 | import { gaEvent } from '../../lib/analytics'; |
8 | 9 | ||
9 | import Button from '../../components/ui/Button'; | 10 | // import Button from '../../components/ui/Button'; |
10 | 11 | ||
11 | import { config } from '.'; | 12 | import { config } from '.'; |
12 | import styles from './styles'; | 13 | import styles from './styles'; |
14 | import UserStore from '../../stores/UserStore'; | ||
13 | 15 | ||
14 | const messages = defineMessages({ | 16 | const messages = defineMessages({ |
15 | headline: { | 17 | headline: { |
16 | id: 'feature.delayApp.headline', | 18 | id: 'feature.delayApp.headline', |
17 | defaultMessage: '!!!Please purchase license to skip waiting', | 19 | defaultMessage: '!!!Please purchase license to skip waiting', |
18 | }, | 20 | }, |
21 | headlineTrial: { | ||
22 | id: 'feature.delayApp.trial.headline', | ||
23 | defaultMessage: '!!!Get the free Franz Professional 14 day trial and skip the line', | ||
24 | }, | ||
19 | action: { | 25 | action: { |
20 | id: 'feature.delayApp.action', | 26 | id: 'feature.delayApp.upgrade.action', |
21 | defaultMessage: '!!!Get a Franz Supporter License', | 27 | defaultMessage: '!!!Get a Franz Supporter License', |
22 | }, | 28 | }, |
29 | actionTrial: { | ||
30 | id: 'feature.delayApp.trial.action', | ||
31 | defaultMessage: '!!!Yes, I want the free 14 day trial of Franz Professional', | ||
32 | }, | ||
23 | text: { | 33 | text: { |
24 | id: 'feature.delayApp.text', | 34 | id: 'feature.delayApp.text', |
25 | defaultMessage: '!!!Franz will continue in {seconds} seconds.', | 35 | defaultMessage: '!!!Franz will continue in {seconds} seconds.', |
26 | }, | 36 | }, |
27 | }); | 37 | }); |
28 | 38 | ||
29 | export default @inject('actions') @injectSheet(styles) @observer class DelayApp extends Component { | 39 | export default @inject('stores', 'actions') @injectSheet(styles) @observer class DelayApp extends Component { |
30 | static propTypes = { | 40 | static propTypes = { |
31 | // eslint-disable-next-line | 41 | // eslint-disable-next-line |
32 | classes: PropTypes.object.isRequired, | 42 | classes: PropTypes.object.isRequired, |
@@ -62,25 +72,37 @@ export default @inject('actions') @injectSheet(styles) @observer class DelayApp | |||
62 | } | 72 | } |
63 | 73 | ||
64 | handleCTAClick() { | 74 | handleCTAClick() { |
65 | const { actions } = this.props; | 75 | const { actions, stores } = this.props; |
76 | const { hadSubscription } = stores.user.data; | ||
77 | const { defaultTrialPlan } = stores.features.features; | ||
78 | |||
79 | if (!hadSubscription) { | ||
80 | console.log('directly activate trial'); | ||
81 | actions.user.activateTrial({ planId: defaultTrialPlan }); | ||
66 | 82 | ||
67 | actions.ui.openSettings({ path: 'user' }); | 83 | gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature'); |
84 | } else { | ||
85 | actions.ui.openSettings({ path: 'user' }); | ||
68 | 86 | ||
69 | gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature'); | 87 | gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature'); |
88 | } | ||
70 | } | 89 | } |
71 | 90 | ||
72 | render() { | 91 | render() { |
73 | const { classes } = this.props; | 92 | const { classes, stores } = this.props; |
74 | const { intl } = this.context; | 93 | const { intl } = this.context; |
75 | 94 | ||
95 | const { hadSubscription } = stores.user.data; | ||
96 | |||
76 | return ( | 97 | return ( |
77 | <div className={`${classes.container}`}> | 98 | <div className={`${classes.container}`}> |
78 | <h1 className={classes.headline}>{intl.formatMessage(messages.headline)}</h1> | 99 | <h1 className={classes.headline}>{intl.formatMessage(hadSubscription ? messages.headline : messages.headlineTrial)}</h1> |
79 | <Button | 100 | <Button |
80 | label={intl.formatMessage(messages.action)} | 101 | label={intl.formatMessage(hadSubscription ? messages.action : messages.actionTrial)} |
81 | className={classes.button} | 102 | className={classes.button} |
82 | buttonType="inverted" | 103 | buttonType="inverted" |
83 | onClick={this.handleCTAClick.bind(this)} | 104 | onClick={this.handleCTAClick.bind(this)} |
105 | busy={stores.user.activateTrialRequest.isExecuting} | ||
84 | /> | 106 | /> |
85 | <p className="footnote"> | 107 | <p className="footnote"> |
86 | {intl.formatMessage(messages.text, { | 108 | {intl.formatMessage(messages.text, { |
@@ -93,6 +115,9 @@ export default @inject('actions') @injectSheet(styles) @observer class DelayApp | |||
93 | } | 115 | } |
94 | 116 | ||
95 | DelayApp.wrappedComponent.propTypes = { | 117 | DelayApp.wrappedComponent.propTypes = { |
118 | stores: PropTypes.shape({ | ||
119 | user: PropTypes.instanceOf(UserStore).isRequired, | ||
120 | }).isRequired, | ||
96 | actions: PropTypes.shape({ | 121 | actions: PropTypes.shape({ |
97 | ui: PropTypes.shape({ | 122 | ui: PropTypes.shape({ |
98 | openSettings: PropTypes.func.isRequired, | 123 | openSettings: PropTypes.func.isRequired, |
diff --git a/src/features/delayApp/index.js b/src/features/delayApp/index.js index 39fae3b20..627537de7 100644 --- a/src/features/delayApp/index.js +++ b/src/features/delayApp/index.js | |||
@@ -44,7 +44,7 @@ export default function init(stores) { | |||
44 | config.delayDuration = globalConfig.wait !== undefined ? globalConfig.wait : DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.wait; | 44 | config.delayDuration = globalConfig.wait !== undefined ? globalConfig.wait : DEFAULT_FEATURES_CONFIG.needToWaitToProceedConfig.wait; |
45 | 45 | ||
46 | autorun(() => { | 46 | autorun(() => { |
47 | if (stores.services.all.length === 0) { | 47 | if (stores.services.allDisplayed.length === 0) { |
48 | debug('seas', stores.services.all.length); | 48 | debug('seas', stores.services.all.length); |
49 | shownAfterLaunch = true; | 49 | shownAfterLaunch = true; |
50 | return; | 50 | return; |
diff --git a/src/features/serviceLimit/components/LimitReachedInfobox.js b/src/features/serviceLimit/components/LimitReachedInfobox.js new file mode 100644 index 000000000..fc54dcf85 --- /dev/null +++ b/src/features/serviceLimit/components/LimitReachedInfobox.js | |||
@@ -0,0 +1,78 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { inject, observer } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | import injectSheet from 'react-jss'; | ||
6 | import { Infobox } from '@meetfranz/ui'; | ||
7 | |||
8 | import { gaEvent } from '../../../lib/analytics'; | ||
9 | |||
10 | const messages = defineMessages({ | ||
11 | limitReached: { | ||
12 | id: 'feature.serviceLimit.limitReached', | ||
13 | defaultMessage: '!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.', | ||
14 | }, | ||
15 | action: { | ||
16 | id: 'premiumFeature.button.upgradeAccount', | ||
17 | defaultMessage: '!!!Upgrade account', | ||
18 | }, | ||
19 | }); | ||
20 | |||
21 | const styles = theme => ({ | ||
22 | container: { | ||
23 | height: 'auto', | ||
24 | background: theme.styleTypes.primary.accent, | ||
25 | color: theme.styleTypes.primary.contrast, | ||
26 | borderRadius: 0, | ||
27 | marginBottom: 0, | ||
28 | |||
29 | '& > div': { | ||
30 | marginBottom: 0, | ||
31 | }, | ||
32 | |||
33 | '& button': { | ||
34 | color: theme.styleTypes.primary.contrast, | ||
35 | }, | ||
36 | }, | ||
37 | }); | ||
38 | |||
39 | |||
40 | @inject('stores', 'actions') @injectSheet(styles) @observer | ||
41 | class LimitReachedInfobox extends Component { | ||
42 | static propTypes = { | ||
43 | classes: PropTypes.object.isRequired, | ||
44 | stores: PropTypes.object.isRequired, | ||
45 | actions: PropTypes.object.isRequired, | ||
46 | }; | ||
47 | |||
48 | static contextTypes = { | ||
49 | intl: intlShape, | ||
50 | }; | ||
51 | |||
52 | render() { | ||
53 | const { classes, stores, actions } = this.props; | ||
54 | const { intl } = this.context; | ||
55 | |||
56 | const { | ||
57 | serviceLimit, | ||
58 | } = stores; | ||
59 | |||
60 | if (!serviceLimit.userHasReachedServiceLimit) return null; | ||
61 | |||
62 | return ( | ||
63 | <Infobox | ||
64 | icon="mdiInformation" | ||
65 | className={classes.container} | ||
66 | ctaLabel={intl.formatMessage(messages.action)} | ||
67 | ctaOnClick={() => { | ||
68 | actions.ui.openSettings({ path: 'user' }); | ||
69 | gaEvent('Service Limit', 'upgrade', 'Upgrade account'); | ||
70 | }} | ||
71 | > | ||
72 | {intl.formatMessage(messages.limitReached, { amount: serviceLimit.serviceCount, limit: serviceLimit.serviceLimit })} | ||
73 | </Infobox> | ||
74 | ); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | export default LimitReachedInfobox; | ||
diff --git a/src/features/serviceLimit/index.js b/src/features/serviceLimit/index.js new file mode 100644 index 000000000..92ad8bb98 --- /dev/null +++ b/src/features/serviceLimit/index.js | |||
@@ -0,0 +1,33 @@ | |||
1 | import { reaction } from 'mobx'; | ||
2 | import { ServiceLimitStore } from './store'; | ||
3 | |||
4 | const debug = require('debug')('Franz:feature:serviceLimit'); | ||
5 | |||
6 | export const DEFAULT_SERVICE_LIMIT = 3; | ||
7 | |||
8 | let store = null; | ||
9 | |||
10 | export const serviceLimitStore = new ServiceLimitStore(); | ||
11 | |||
12 | export default function initServiceLimit(stores, actions) { | ||
13 | const { features } = stores; | ||
14 | |||
15 | // Toggle serviceLimit feature | ||
16 | reaction( | ||
17 | () => ( | ||
18 | features.features.isServiceLimitEnabled | ||
19 | ), | ||
20 | (isEnabled) => { | ||
21 | if (isEnabled) { | ||
22 | debug('Initializing `serviceLimit` feature'); | ||
23 | store = serviceLimitStore.start(stores, actions); | ||
24 | } else if (store) { | ||
25 | debug('Disabling `serviceLimit` feature'); | ||
26 | serviceLimitStore.stop(); | ||
27 | } | ||
28 | }, | ||
29 | { | ||
30 | fireImmediately: true, | ||
31 | }, | ||
32 | ); | ||
33 | } | ||
diff --git a/src/features/serviceLimit/store.js b/src/features/serviceLimit/store.js new file mode 100644 index 000000000..9836c5f51 --- /dev/null +++ b/src/features/serviceLimit/store.js | |||
@@ -0,0 +1,41 @@ | |||
1 | import { computed, observable } from 'mobx'; | ||
2 | import { FeatureStore } from '../utils/FeatureStore'; | ||
3 | import { DEFAULT_SERVICE_LIMIT } from '.'; | ||
4 | |||
5 | const debug = require('debug')('Franz:feature:serviceLimit:store'); | ||
6 | |||
7 | export class ServiceLimitStore extends FeatureStore { | ||
8 | @observable isServiceLimitEnabled = false; | ||
9 | |||
10 | start(stores, actions) { | ||
11 | debug('start'); | ||
12 | this.stores = stores; | ||
13 | this.actions = actions; | ||
14 | |||
15 | this.isServiceLimitEnabled = true; | ||
16 | } | ||
17 | |||
18 | stop() { | ||
19 | super.stop(); | ||
20 | |||
21 | this.isServiceLimitEnabled = false; | ||
22 | } | ||
23 | |||
24 | @computed get userHasReachedServiceLimit() { | ||
25 | if (!this.isServiceLimitEnabled) return false; | ||
26 | |||
27 | return this.serviceLimit !== 0 && this.serviceCount >= this.serviceLimit; | ||
28 | } | ||
29 | |||
30 | @computed get serviceLimit() { | ||
31 | if (!this.isServiceLimitEnabled || this.stores.features.features.serviceLimitCount === 0) return 0; | ||
32 | |||
33 | return this.stores.features.features.serviceLimitCount || DEFAULT_SERVICE_LIMIT; | ||
34 | } | ||
35 | |||
36 | @computed get serviceCount() { | ||
37 | return this.stores.services.all.length; | ||
38 | } | ||
39 | } | ||
40 | |||
41 | export default ServiceLimitStore; | ||
diff --git a/src/features/serviceProxy/index.js b/src/features/serviceProxy/index.js index 4bea327ad..55c600de4 100644 --- a/src/features/serviceProxy/index.js +++ b/src/features/serviceProxy/index.js | |||
@@ -9,17 +9,17 @@ const debug = require('debug')('Franz:feature:serviceProxy'); | |||
9 | 9 | ||
10 | export const config = observable({ | 10 | export const config = observable({ |
11 | isEnabled: DEFAULT_FEATURES_CONFIG.isServiceProxyEnabled, | 11 | isEnabled: DEFAULT_FEATURES_CONFIG.isServiceProxyEnabled, |
12 | isPremium: DEFAULT_FEATURES_CONFIG.isServiceProxyPremiumFeature, | 12 | isPremium: DEFAULT_FEATURES_CONFIG.isServiceProxyIncludedInCurrentPlan, |
13 | }); | 13 | }); |
14 | 14 | ||
15 | export default function init(stores) { | 15 | export default function init(stores) { |
16 | debug('Initializing `serviceProxy` feature'); | 16 | debug('Initializing `serviceProxy` feature'); |
17 | 17 | ||
18 | autorun(() => { | 18 | autorun(() => { |
19 | const { isServiceProxyEnabled, isServiceProxyPremiumFeature } = stores.features.features; | 19 | const { isServiceProxyEnabled, isServiceProxyIncludedInCurrentPlan } = stores.features.features; |
20 | 20 | ||
21 | config.isEnabled = isServiceProxyEnabled !== undefined ? isServiceProxyEnabled : DEFAULT_FEATURES_CONFIG.isServiceProxyEnabled; | 21 | config.isEnabled = isServiceProxyEnabled !== undefined ? isServiceProxyEnabled : DEFAULT_FEATURES_CONFIG.isServiceProxyEnabled; |
22 | config.isPremium = isServiceProxyPremiumFeature !== undefined ? isServiceProxyPremiumFeature : DEFAULT_FEATURES_CONFIG.isServiceProxyPremiumFeature; | 22 | config.isIncludedInCurrentPlan = isServiceProxyIncludedInCurrentPlan !== undefined ? isServiceProxyIncludedInCurrentPlan : DEFAULT_FEATURES_CONFIG.isServiceProxyIncludedInCurrentPlan; |
23 | 23 | ||
24 | const services = stores.services.enabled; | 24 | const services = stores.services.enabled; |
25 | const isPremiumUser = stores.user.data.isPremium; | 25 | const isPremiumUser = stores.user.data.isPremium; |
@@ -30,7 +30,7 @@ export default function init(stores) { | |||
30 | services.forEach((service) => { | 30 | services.forEach((service) => { |
31 | const s = session.fromPartition(`persist:service-${service.id}`); | 31 | const s = session.fromPartition(`persist:service-${service.id}`); |
32 | 32 | ||
33 | if (config.isEnabled && (isPremiumUser || !config.isPremium)) { | 33 | if (config.isEnabled && (isPremiumUser || !config.isIncludedInCurrentPlan)) { |
34 | const serviceProxyConfig = proxySettings[service.id]; | 34 | const serviceProxyConfig = proxySettings[service.id]; |
35 | 35 | ||
36 | if (serviceProxyConfig && serviceProxyConfig.isEnabled && serviceProxyConfig.host) { | 36 | if (serviceProxyConfig && serviceProxyConfig.isEnabled && serviceProxyConfig.host) { |
diff --git a/src/features/shareFranz/Component.js b/src/features/shareFranz/Component.js index 8d1d595c5..a33315e17 100644 --- a/src/features/shareFranz/Component.js +++ b/src/features/shareFranz/Component.js | |||
@@ -6,6 +6,9 @@ import { defineMessages, intlShape } from 'react-intl'; | |||
6 | import { Button } from '@meetfranz/forms'; | 6 | import { Button } from '@meetfranz/forms'; |
7 | import { H1, Icon } from '@meetfranz/ui'; | 7 | import { H1, Icon } from '@meetfranz/ui'; |
8 | 8 | ||
9 | import { | ||
10 | mdiHeart, mdiEmail, mdiFacebookBox, mdiTwitter, | ||
11 | } from '@mdi/js'; | ||
9 | import Modal from '../../components/ui/Modal'; | 12 | import Modal from '../../components/ui/Modal'; |
10 | import { state } from '.'; | 13 | import { state } from '.'; |
11 | import { gaEvent } from '../../lib/analytics'; | 14 | import { gaEvent } from '../../lib/analytics'; |
@@ -75,7 +78,7 @@ const styles = theme => ({ | |||
75 | }, | 78 | }, |
76 | cta: { | 79 | cta: { |
77 | background: theme.styleTypes.primary.contrast, | 80 | background: theme.styleTypes.primary.contrast, |
78 | color: theme.styleTypes.primary.accent, | 81 | color: `${theme.styleTypes.primary.accent} !important`, |
79 | 82 | ||
80 | '& svg': { | 83 | '& svg': { |
81 | fill: theme.styleTypes.primary.accent, | 84 | fill: theme.styleTypes.primary.accent, |
@@ -116,7 +119,7 @@ export default @injectSheet(styles) @inject('stores') @observer class ShareFranz | |||
116 | close={this.close.bind(this)} | 119 | close={this.close.bind(this)} |
117 | > | 120 | > |
118 | <div className={classes.heartContainer}> | 121 | <div className={classes.heartContainer}> |
119 | <Icon icon="mdiHeart" className={classes.heart} size={4} /> | 122 | <Icon icon={mdiHeart} className={classes.heart} size={4} /> |
120 | </div> | 123 | </div> |
121 | <H1 className={classes.headline}> | 124 | <H1 className={classes.headline}> |
122 | {intl.formatMessage(messages.headline)} | 125 | {intl.formatMessage(messages.headline)} |
@@ -126,7 +129,7 @@ export default @injectSheet(styles) @inject('stores') @observer class ShareFranz | |||
126 | <Button | 129 | <Button |
127 | label={intl.formatMessage(messages.actionsEmail)} | 130 | label={intl.formatMessage(messages.actionsEmail)} |
128 | className={classes.cta} | 131 | className={classes.cta} |
129 | icon="mdiEmail" | 132 | icon={mdiEmail} |
130 | href={`mailto:?subject=Meet the cool app Franz&body=${intl.formatMessage(messages.shareTextEmail, { count: serviceCount })}}`} | 133 | href={`mailto:?subject=Meet the cool app Franz&body=${intl.formatMessage(messages.shareTextEmail, { count: serviceCount })}}`} |
131 | target="_blank" | 134 | target="_blank" |
132 | onClick={() => { | 135 | onClick={() => { |
@@ -136,7 +139,7 @@ export default @injectSheet(styles) @inject('stores') @observer class ShareFranz | |||
136 | <Button | 139 | <Button |
137 | label={intl.formatMessage(messages.actionsFacebook)} | 140 | label={intl.formatMessage(messages.actionsFacebook)} |
138 | className={classes.cta} | 141 | className={classes.cta} |
139 | icon="mdiFacebookBox" | 142 | icon={mdiFacebookBox} |
140 | href="https://www.facebook.com/sharer/sharer.php?u=https://www.meetfranz.com?utm_source=facebook&utm_medium=referral&utm_campaign=share-button" | 143 | href="https://www.facebook.com/sharer/sharer.php?u=https://www.meetfranz.com?utm_source=facebook&utm_medium=referral&utm_campaign=share-button" |
141 | target="_blank" | 144 | target="_blank" |
142 | onClick={() => { | 145 | onClick={() => { |
@@ -146,7 +149,7 @@ export default @injectSheet(styles) @inject('stores') @observer class ShareFranz | |||
146 | <Button | 149 | <Button |
147 | label={intl.formatMessage(messages.actionsTwitter)} | 150 | label={intl.formatMessage(messages.actionsTwitter)} |
148 | className={classes.cta} | 151 | className={classes.cta} |
149 | icon="mdiTwitter" | 152 | icon={mdiTwitter} |
150 | href={`http://twitter.com/intent/tweet?status=${intl.formatMessage(messages.shareTextTwitter, { count: serviceCount })}`} | 153 | href={`http://twitter.com/intent/tweet?status=${intl.formatMessage(messages.shareTextTwitter, { count: serviceCount })}`} |
151 | target="_blank" | 154 | target="_blank" |
152 | onClick={() => { | 155 | onClick={() => { |
diff --git a/src/features/spellchecker/index.js b/src/features/spellchecker/index.js index 79a2172b4..a07f9f63a 100644 --- a/src/features/spellchecker/index.js +++ b/src/features/spellchecker/index.js | |||
@@ -5,18 +5,18 @@ import { DEFAULT_FEATURES_CONFIG } from '../../config'; | |||
5 | const debug = require('debug')('Franz:feature:spellchecker'); | 5 | const debug = require('debug')('Franz:feature:spellchecker'); |
6 | 6 | ||
7 | export const config = observable({ | 7 | export const config = observable({ |
8 | isPremium: DEFAULT_FEATURES_CONFIG.isSpellcheckerPremiumFeature, | 8 | isIncludedInCurrentPlan: DEFAULT_FEATURES_CONFIG.isSpellcheckerIncludedInCurrentPlan, |
9 | }); | 9 | }); |
10 | 10 | ||
11 | export default function init(stores) { | 11 | export default function init(stores) { |
12 | debug('Initializing `spellchecker` feature'); | 12 | debug('Initializing `spellchecker` feature'); |
13 | 13 | ||
14 | autorun(() => { | 14 | autorun(() => { |
15 | const { isSpellcheckerPremiumFeature } = stores.features.features; | 15 | const { isSpellcheckerIncludedInCurrentPlan } = stores.features.features; |
16 | 16 | ||
17 | config.isPremium = isSpellcheckerPremiumFeature !== undefined ? isSpellcheckerPremiumFeature : DEFAULT_FEATURES_CONFIG.isSpellcheckerPremiumFeature; | 17 | config.isIncludedInCurrentPlan = isSpellcheckerIncludedInCurrentPlan !== undefined ? isSpellcheckerIncludedInCurrentPlan : DEFAULT_FEATURES_CONFIG.isSpellcheckerIncludedInCurrentPlan; |
18 | 18 | ||
19 | if (!stores.user.data.isPremium && config.isPremium && stores.settings.app.enableSpellchecking) { | 19 | if (!stores.user.data.isPremium && config.isIncludedInCurrentPlan && stores.settings.app.enableSpellchecking) { |
20 | debug('Override settings.spellcheckerEnabled flag to false'); | 20 | debug('Override settings.spellcheckerEnabled flag to false'); |
21 | 21 | ||
22 | Object.assign(stores.settings.app, { | 22 | Object.assign(stores.settings.app, { |
diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index 9dd313109..143955a7b 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js | |||
@@ -4,12 +4,31 @@ import { observer } from 'mobx-react'; | |||
4 | import injectSheet from 'react-jss'; | 4 | import injectSheet from 'react-jss'; |
5 | import Webview from 'react-electron-web-view'; | 5 | import Webview from 'react-electron-web-view'; |
6 | import { Icon } from '@meetfranz/ui'; | 6 | import { Icon } from '@meetfranz/ui'; |
7 | import { defineMessages, intlShape } from 'react-intl'; | ||
7 | 8 | ||
9 | import { mdiChevronRight, mdiCheckAll } from '@mdi/js'; | ||
8 | import * as environment from '../../../environment'; | 10 | import * as environment from '../../../environment'; |
11 | import Appear from '../../../components/ui/effects/Appear'; | ||
12 | import ActivateTrialButton from '../../../components/ui/ActivateTrialButton'; | ||
9 | 13 | ||
10 | const OPEN_TODOS_BUTTON_SIZE = 45; | 14 | const OPEN_TODOS_BUTTON_SIZE = 45; |
11 | const CLOSE_TODOS_BUTTON_SIZE = 35; | 15 | const CLOSE_TODOS_BUTTON_SIZE = 35; |
12 | 16 | ||
17 | const messages = defineMessages({ | ||
18 | premiumInfo: { | ||
19 | id: 'feature.todos.premium.info', | ||
20 | defaultMessage: '!!!The Franz Todos Preview is currently only available for Franz Premium accounts.', | ||
21 | }, | ||
22 | upgradeCTA: { | ||
23 | id: 'feature.todos.premium.upgrade', | ||
24 | defaultMessage: '!!!Upgrade Account', | ||
25 | }, | ||
26 | rolloutInfo: { | ||
27 | id: 'feature.todos.premium.rollout', | ||
28 | defaultMessage: '!!!Franz Todos will be available to everyone soon.', | ||
29 | }, | ||
30 | }); | ||
31 | |||
13 | const styles = theme => ({ | 32 | const styles = theme => ({ |
14 | root: { | 33 | root: { |
15 | background: theme.colorBackground, | 34 | background: theme.colorBackground, |
@@ -47,7 +66,7 @@ const styles = theme => ({ | |||
47 | height: OPEN_TODOS_BUTTON_SIZE, | 66 | height: OPEN_TODOS_BUTTON_SIZE, |
48 | background: theme.todos.toggleButton.background, | 67 | background: theme.todos.toggleButton.background, |
49 | position: 'absolute', | 68 | position: 'absolute', |
50 | bottom: 80, | 69 | bottom: 120, |
51 | right: props => (props.width + (props.isVisible ? -OPEN_TODOS_BUTTON_SIZE / 2 : 0)), | 70 | right: props => (props.width + (props.isVisible ? -OPEN_TODOS_BUTTON_SIZE / 2 : 0)), |
52 | borderRadius: OPEN_TODOS_BUTTON_SIZE / 2, | 71 | borderRadius: OPEN_TODOS_BUTTON_SIZE / 2, |
53 | opacity: props => (props.isVisible ? 0 : 1), | 72 | opacity: props => (props.isVisible ? 0 : 1), |
@@ -71,10 +90,10 @@ const styles = theme => ({ | |||
71 | height: CLOSE_TODOS_BUTTON_SIZE, | 90 | height: CLOSE_TODOS_BUTTON_SIZE, |
72 | background: theme.todos.toggleButton.background, | 91 | background: theme.todos.toggleButton.background, |
73 | position: 'absolute', | 92 | position: 'absolute', |
74 | bottom: 80, | 93 | bottom: 120, |
75 | right: ({ width }) => (width + -CLOSE_TODOS_BUTTON_SIZE / 2), | 94 | right: ({ width }) => (width + -CLOSE_TODOS_BUTTON_SIZE / 2), |
76 | borderRadius: CLOSE_TODOS_BUTTON_SIZE / 2, | 95 | borderRadius: CLOSE_TODOS_BUTTON_SIZE / 2, |
77 | opacity: 0, | 96 | opacity: ({ isTodosIncludedInCurrentPlan }) => (!isTodosIncludedInCurrentPlan ? 1 : 0), |
78 | transition: 'opacity 0.5s', | 97 | transition: 'opacity 0.5s', |
79 | zIndex: 600, | 98 | zIndex: 600, |
80 | display: 'flex', | 99 | display: 'flex', |
@@ -86,6 +105,26 @@ const styles = theme => ({ | |||
86 | fill: theme.todos.toggleButton.textColor, | 105 | fill: theme.todos.toggleButton.textColor, |
87 | }, | 106 | }, |
88 | }, | 107 | }, |
108 | premiumContainer: { | ||
109 | display: 'flex', | ||
110 | flexDirection: 'column', | ||
111 | justifyContent: 'center', | ||
112 | alignItems: 'center', | ||
113 | width: '80%', | ||
114 | maxWidth: 300, | ||
115 | margin: [-50, 'auto', 0], | ||
116 | textAlign: 'center', | ||
117 | }, | ||
118 | premiumIcon: { | ||
119 | marginBottom: 40, | ||
120 | background: theme.styleTypes.primary.accent, | ||
121 | fill: theme.styleTypes.primary.contrast, | ||
122 | padding: 10, | ||
123 | borderRadius: 10, | ||
124 | }, | ||
125 | premiumCTA: { | ||
126 | marginTop: 40, | ||
127 | }, | ||
89 | }); | 128 | }); |
90 | 129 | ||
91 | @injectSheet(styles) @observer | 130 | @injectSheet(styles) @observer |
@@ -99,6 +138,7 @@ class TodosWebview extends Component { | |||
99 | resize: PropTypes.func.isRequired, | 138 | resize: PropTypes.func.isRequired, |
100 | width: PropTypes.number.isRequired, | 139 | width: PropTypes.number.isRequired, |
101 | minWidth: PropTypes.number.isRequired, | 140 | minWidth: PropTypes.number.isRequired, |
141 | isTodosIncludedInCurrentPlan: PropTypes.bool.isRequired, | ||
102 | }; | 142 | }; |
103 | 143 | ||
104 | state = { | 144 | state = { |
@@ -106,6 +146,10 @@ class TodosWebview extends Component { | |||
106 | width: 300, | 146 | width: 300, |
107 | }; | 147 | }; |
108 | 148 | ||
149 | static contextTypes = { | ||
150 | intl: intlShape, | ||
151 | }; | ||
152 | |||
109 | componentWillMount() { | 153 | componentWillMount() { |
110 | const { width } = this.props; | 154 | const { width } = this.props; |
111 | 155 | ||
@@ -182,9 +226,19 @@ class TodosWebview extends Component { | |||
182 | 226 | ||
183 | render() { | 227 | render() { |
184 | const { | 228 | const { |
185 | classes, isVisible, togglePanel, | 229 | classes, |
230 | isVisible, | ||
231 | togglePanel, | ||
232 | isTodosIncludedInCurrentPlan, | ||
186 | } = this.props; | 233 | } = this.props; |
187 | const { width, delta, isDragging } = this.state; | 234 | |
235 | const { | ||
236 | width, | ||
237 | delta, | ||
238 | isDragging, | ||
239 | } = this.state; | ||
240 | |||
241 | const { intl } = this.context; | ||
188 | 242 | ||
189 | return ( | 243 | return ( |
190 | <div | 244 | <div |
@@ -198,7 +252,7 @@ class TodosWebview extends Component { | |||
198 | className={isVisible ? classes.closeTodosButton : classes.openTodosButton} | 252 | className={isVisible ? classes.closeTodosButton : classes.openTodosButton} |
199 | type="button" | 253 | type="button" |
200 | > | 254 | > |
201 | <Icon icon={isVisible ? 'mdiChevronRight' : 'mdiCheckAll'} size={2} /> | 255 | <Icon icon={isVisible ? mdiChevronRight : mdiCheckAll} size={2} /> |
202 | </button> | 256 | </button> |
203 | <div | 257 | <div |
204 | className={classes.resizeHandler} | 258 | className={classes.resizeHandler} |
@@ -211,18 +265,33 @@ class TodosWebview extends Component { | |||
211 | style={{ left: delta }} // This hack is required as resizing with webviews beneath behaves quite bad | 265 | style={{ left: delta }} // This hack is required as resizing with webviews beneath behaves quite bad |
212 | /> | 266 | /> |
213 | )} | 267 | )} |
214 | <Webview | 268 | {isTodosIncludedInCurrentPlan ? ( |
215 | className={classes.webview} | 269 | <Webview |
216 | onDidAttach={() => { | 270 | className={classes.webview} |
217 | const { setTodosWebview } = this.props; | 271 | onDidAttach={() => { |
218 | setTodosWebview(this.webview); | 272 | const { setTodosWebview } = this.props; |
219 | this.startListeningToIpcMessages(); | 273 | setTodosWebview(this.webview); |
220 | }} | 274 | this.startListeningToIpcMessages(); |
221 | partition="persist:todos" | 275 | }} |
222 | preload="./features/todos/preload.js" | 276 | partition="persist:todos" |
223 | ref={(webview) => { this.webview = webview ? webview.view : null; }} | 277 | preload="./features/todos/preload.js" |
224 | src={environment.TODOS_FRONTEND} | 278 | ref={(webview) => { this.webview = webview ? webview.view : null; }} |
225 | /> | 279 | src={environment.TODOS_FRONTEND} |
280 | /> | ||
281 | ) : ( | ||
282 | <Appear> | ||
283 | <div className={classes.premiumContainer}> | ||
284 | <Icon icon={mdiCheckAll} className={classes.premiumIcon} size={5} /> | ||
285 | <p>{intl.formatMessage(messages.premiumInfo)}</p> | ||
286 | <p>{intl.formatMessage(messages.rolloutInfo)}</p> | ||
287 | <ActivateTrialButton | ||
288 | className={classes.premiumCTA} | ||
289 | gaEventInfo={{ category: 'Todos', event: 'upgrade' }} | ||
290 | short | ||
291 | /> | ||
292 | </div> | ||
293 | </Appear> | ||
294 | )} | ||
226 | </div> | 295 | </div> |
227 | ); | 296 | ); |
228 | } | 297 | } |
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js index d071d0677..65afc985b 100644 --- a/src/features/todos/containers/TodosScreen.js +++ b/src/features/todos/containers/TodosScreen.js | |||
@@ -1,12 +1,14 @@ | |||
1 | import React, { Component } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import { observer } from 'mobx-react'; | 2 | import { observer, inject } from 'mobx-react'; |
3 | import PropTypes from 'prop-types'; | ||
3 | 4 | ||
5 | import FeaturesStore from '../../../stores/FeaturesStore'; | ||
4 | import TodosWebview from '../components/TodosWebview'; | 6 | import TodosWebview from '../components/TodosWebview'; |
5 | import ErrorBoundary from '../../../components/util/ErrorBoundary'; | 7 | import ErrorBoundary from '../../../components/util/ErrorBoundary'; |
6 | import { TODOS_MIN_WIDTH, todosStore } from '..'; | 8 | import { TODOS_MIN_WIDTH, todosStore } from '..'; |
7 | import { todoActions } from '../actions'; | 9 | import { todoActions } from '../actions'; |
8 | 10 | ||
9 | @observer | 11 | @inject('stores', 'actions') @observer |
10 | class TodosScreen extends Component { | 12 | class TodosScreen extends Component { |
11 | render() { | 13 | render() { |
12 | if (!todosStore || !todosStore.isFeatureActive) { | 14 | if (!todosStore || !todosStore.isFeatureActive) { |
@@ -23,6 +25,7 @@ class TodosScreen extends Component { | |||
23 | width={todosStore.width} | 25 | width={todosStore.width} |
24 | minWidth={TODOS_MIN_WIDTH} | 26 | minWidth={TODOS_MIN_WIDTH} |
25 | resize={width => todoActions.resize({ width })} | 27 | resize={width => todoActions.resize({ width })} |
28 | isTodosIncludedInCurrentPlan={this.props.stores.features.features.isTodosIncludedInCurrentPlan || false} | ||
26 | /> | 29 | /> |
27 | </ErrorBoundary> | 30 | </ErrorBoundary> |
28 | ); | 31 | ); |
@@ -30,3 +33,9 @@ class TodosScreen extends Component { | |||
30 | } | 33 | } |
31 | 34 | ||
32 | export default TodosScreen; | 35 | export default TodosScreen; |
36 | |||
37 | TodosScreen.wrappedComponent.propTypes = { | ||
38 | stores: PropTypes.shape({ | ||
39 | features: PropTypes.instanceOf(FeaturesStore).isRequired, | ||
40 | }).isRequired, | ||
41 | }; | ||
diff --git a/src/features/todos/store.js b/src/features/todos/store.js index 242b38bf7..170408ebb 100644 --- a/src/features/todos/store.js +++ b/src/features/todos/store.js | |||
@@ -12,6 +12,7 @@ import { createReactions } from '../../stores/lib/Reaction'; | |||
12 | import { createActionBindings } from '../utils/ActionBinding'; | 12 | import { createActionBindings } from '../utils/ActionBinding'; |
13 | import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH, DEFAULT_TODOS_VISIBLE } from '.'; | 13 | import { DEFAULT_TODOS_WIDTH, TODOS_MIN_WIDTH, DEFAULT_TODOS_VISIBLE } from '.'; |
14 | import { IPC } from './constants'; | 14 | import { IPC } from './constants'; |
15 | import { state as delayAppState } from '../delayApp'; | ||
15 | 16 | ||
16 | const debug = require('debug')('Franz:feature:todos:store'); | 17 | const debug = require('debug')('Franz:feature:todos:store'); |
17 | 18 | ||
@@ -29,6 +30,7 @@ export default class TodoStore extends FeatureStore { | |||
29 | } | 30 | } |
30 | 31 | ||
31 | @computed get isTodosPanelVisible() { | 32 | @computed get isTodosPanelVisible() { |
33 | if (this.stores.services.all.length === 0 || delayAppState.isDelayAppScreenVisible) return false; | ||
32 | if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; | 34 | if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; |
33 | 35 | ||
34 | return this.settings.isTodosPanelVisible; | 36 | return this.settings.isTodosPanelVisible; |
diff --git a/src/features/workspaces/components/WorkspaceDrawer.js b/src/features/workspaces/components/WorkspaceDrawer.js index 684e50dd0..e7bc0b157 100644 --- a/src/features/workspaces/components/WorkspaceDrawer.js +++ b/src/features/workspaces/components/WorkspaceDrawer.js | |||
@@ -7,6 +7,7 @@ import { H1, Icon, ProBadge } from '@meetfranz/ui'; | |||
7 | import { Button } from '@meetfranz/forms/lib'; | 7 | import { Button } from '@meetfranz/forms/lib'; |
8 | import ReactTooltip from 'react-tooltip'; | 8 | import ReactTooltip from 'react-tooltip'; |
9 | 9 | ||
10 | import { mdiPlusBox, mdiSettings } from '@mdi/js'; | ||
10 | import WorkspaceDrawerItem from './WorkspaceDrawerItem'; | 11 | import WorkspaceDrawerItem from './WorkspaceDrawerItem'; |
11 | import { workspaceActions } from '../actions'; | 12 | import { workspaceActions } from '../actions'; |
12 | import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../index'; | 13 | import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../index'; |
@@ -159,7 +160,7 @@ class WorkspaceDrawer extends Component { | |||
159 | data-tip={`${intl.formatMessage(messages.workspacesSettingsTooltip)}`} | 160 | data-tip={`${intl.formatMessage(messages.workspacesSettingsTooltip)}`} |
160 | > | 161 | > |
161 | <Icon | 162 | <Icon |
162 | icon="mdiSettings" | 163 | icon={mdiSettings} |
163 | size={1.5} | 164 | size={1.5} |
164 | className={classes.workspacesSettingsButtonIcon} | 165 | className={classes.workspacesSettingsButtonIcon} |
165 | /> | 166 | /> |
@@ -184,7 +185,7 @@ class WorkspaceDrawer extends Component { | |||
184 | className={classes.premiumCtaButton} | 185 | className={classes.premiumCtaButton} |
185 | buttonType="primary" | 186 | buttonType="primary" |
186 | label={intl.formatMessage(messages.premiumCtaButtonLabel)} | 187 | label={intl.formatMessage(messages.premiumCtaButtonLabel)} |
187 | icon="mdiPlusBox" | 188 | icon={mdiPlusBox} |
188 | onClick={() => { | 189 | onClick={() => { |
189 | workspaceActions.openWorkspaceSettings(); | 190 | workspaceActions.openWorkspaceSettings(); |
190 | gaEvent(GA_CATEGORY_WORKSPACES, 'add', 'drawerPremiumCta'); | 191 | gaEvent(GA_CATEGORY_WORKSPACES, 'add', 'drawerPremiumCta'); |
@@ -227,7 +228,7 @@ class WorkspaceDrawer extends Component { | |||
227 | }} | 228 | }} |
228 | > | 229 | > |
229 | <Icon | 230 | <Icon |
230 | icon="mdiPlusBox" | 231 | icon={mdiPlusBox} |
231 | size={1} | 232 | size={1} |
232 | className={classes.workspacesSettingsButtonIcon} | 233 | className={classes.workspacesSettingsButtonIcon} |
233 | /> | 234 | /> |
diff --git a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js index c4a800a7b..a70d1d66f 100644 --- a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js +++ b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js | |||
@@ -21,11 +21,8 @@ const styles = theme => ({ | |||
21 | alignItems: 'flex-start', | 21 | alignItems: 'flex-start', |
22 | position: 'absolute', | 22 | position: 'absolute', |
23 | transition: 'width 0.5s ease', | 23 | transition: 'width 0.5s ease', |
24 | width: '100%', | ||
25 | marginTop: '20px', | ||
26 | }, | ||
27 | wrapperWhenDrawerIsOpen: { | ||
28 | width: `calc(100% - ${theme.workspaces.drawer.width}px)`, | 24 | width: `calc(100% - ${theme.workspaces.drawer.width}px)`, |
25 | marginTop: '20px', | ||
29 | }, | 26 | }, |
30 | component: { | 27 | component: { |
31 | background: 'rgba(20, 20, 20, 0.4)', | 28 | background: 'rgba(20, 20, 20, 0.4)', |
@@ -64,14 +61,13 @@ class WorkspaceSwitchingIndicator extends Component { | |||
64 | render() { | 61 | render() { |
65 | const { classes, theme } = this.props; | 62 | const { classes, theme } = this.props; |
66 | const { intl } = this.context; | 63 | const { intl } = this.context; |
67 | const { isSwitchingWorkspace, isWorkspaceDrawerOpen, nextWorkspace } = workspaceStore; | 64 | const { isSwitchingWorkspace, nextWorkspace } = workspaceStore; |
68 | if (!isSwitchingWorkspace) return null; | 65 | if (!isSwitchingWorkspace) return null; |
69 | const nextWorkspaceName = nextWorkspace ? nextWorkspace.name : 'All services'; | 66 | const nextWorkspaceName = nextWorkspace ? nextWorkspace.name : 'All services'; |
70 | return ( | 67 | return ( |
71 | <div | 68 | <div |
72 | className={classnames([ | 69 | className={classnames([ |
73 | classes.wrapper, | 70 | classes.wrapper, |
74 | isWorkspaceDrawerOpen ? classes.wrapperWhenDrawerIsOpen : null, | ||
75 | ])} | 71 | ])} |
76 | > | 72 | > |
77 | <div className={classes.component}> | 73 | <div className={classes.component}> |
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js index 09c98ab8c..059a681de 100644 --- a/src/features/workspaces/components/WorkspacesDashboard.js +++ b/src/features/workspaces/components/WorkspacesDashboard.js | |||
@@ -1,6 +1,6 @@ | |||
1 | import React, { Component, Fragment } from 'react'; | 1 | import React, { Component, Fragment } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { observer, PropTypes as MobxPropTypes, inject } from 'mobx-react'; |
4 | import { defineMessages, intlShape } from 'react-intl'; | 4 | import { defineMessages, intlShape } from 'react-intl'; |
5 | import injectSheet from 'react-jss'; | 5 | import injectSheet from 'react-jss'; |
6 | import { Infobox } from '@meetfranz/ui'; | 6 | import { Infobox } from '@meetfranz/ui'; |
@@ -12,6 +12,8 @@ import Request from '../../../stores/lib/Request'; | |||
12 | import Appear from '../../../components/ui/effects/Appear'; | 12 | import Appear from '../../../components/ui/effects/Appear'; |
13 | import { workspaceStore } from '../index'; | 13 | import { workspaceStore } from '../index'; |
14 | import PremiumFeatureContainer from '../../../components/ui/PremiumFeatureContainer'; | 14 | import PremiumFeatureContainer from '../../../components/ui/PremiumFeatureContainer'; |
15 | import UIStore from '../../../stores/UIStore'; | ||
16 | import ActivateTrialButton from '../../../components/ui/ActivateTrialButton'; | ||
15 | 17 | ||
16 | const messages = defineMessages({ | 18 | const messages = defineMessages({ |
17 | headline: { | 19 | headline: { |
@@ -62,17 +64,27 @@ const styles = theme => ({ | |||
62 | height: 'auto', | 64 | height: 'auto', |
63 | }, | 65 | }, |
64 | premiumAnnouncement: { | 66 | premiumAnnouncement: { |
65 | padding: '20px', | 67 | padding: 20, |
66 | backgroundColor: '#3498db', | 68 | // backgroundColor: '#3498db', |
67 | marginLeft: '-20px', | 69 | marginLeft: -20, |
68 | marginBottom: '20px', | 70 | marginBottom: 40, |
71 | paddingBottom: 40, | ||
69 | height: 'auto', | 72 | height: 'auto', |
70 | color: 'white', | 73 | display: 'flex', |
71 | borderRadius: theme.borderRadius, | 74 | borderBottom: [1, 'solid', theme.inputBackground], |
75 | }, | ||
76 | teaserImage: { | ||
77 | width: 200, | ||
78 | height: '100%', | ||
79 | float: 'left', | ||
80 | margin: [-8, 0, 0, -20], | ||
81 | }, | ||
82 | upgradeCTA: { | ||
83 | marginTop: 20, | ||
72 | }, | 84 | }, |
73 | }); | 85 | }); |
74 | 86 | ||
75 | @injectSheet(styles) @observer | 87 | @inject('stores') @injectSheet(styles) @observer |
76 | class WorkspacesDashboard extends Component { | 88 | class WorkspacesDashboard extends Component { |
77 | static propTypes = { | 89 | static propTypes = { |
78 | classes: PropTypes.object.isRequired, | 90 | classes: PropTypes.object.isRequired, |
@@ -100,7 +112,9 @@ class WorkspacesDashboard extends Component { | |||
100 | onWorkspaceClick, | 112 | onWorkspaceClick, |
101 | workspaces, | 113 | workspaces, |
102 | } = this.props; | 114 | } = this.props; |
115 | |||
103 | const { intl } = this.context; | 116 | const { intl } = this.context; |
117 | |||
104 | return ( | 118 | return ( |
105 | <div className="settings__main"> | 119 | <div className="settings__main"> |
106 | <div className="settings__header"> | 120 | <div className="settings__header"> |
@@ -138,13 +152,21 @@ class WorkspacesDashboard extends Component { | |||
138 | 152 | ||
139 | {workspaceStore.isPremiumUpgradeRequired && ( | 153 | {workspaceStore.isPremiumUpgradeRequired && ( |
140 | <div className={classes.premiumAnnouncement}> | 154 | <div className={classes.premiumAnnouncement}> |
141 | <h2>{intl.formatMessage(messages.workspaceFeatureHeadline)}</h2> | 155 | <img src={`./assets/images/workspaces/teaser_${this.props.stores.ui.isDarkThemeActive ? 'dark' : 'light'}.png`} className={classes.teaserImage} alt="" /> |
142 | <p>{intl.formatMessage(messages.workspaceFeatureInfo)}</p> | 156 | <div> |
157 | <h2>{intl.formatMessage(messages.workspaceFeatureHeadline)}</h2> | ||
158 | <p>{intl.formatMessage(messages.workspaceFeatureInfo)}</p> | ||
159 | <ActivateTrialButton | ||
160 | className={classes.upgradeCTA} | ||
161 | gaEventInfo={{ category: 'Workspaces', event: 'upgrade' }} | ||
162 | short | ||
163 | /> | ||
164 | </div> | ||
143 | </div> | 165 | </div> |
144 | )} | 166 | )} |
145 | 167 | ||
146 | <PremiumFeatureContainer | 168 | <PremiumFeatureContainer |
147 | condition={workspaceStore.isPremiumFeature} | 169 | condition={() => workspaceStore.isPremiumUpgradeRequired} |
148 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'workspaces' }} | 170 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'workspaces' }} |
149 | > | 171 | > |
150 | {/* ===== Create workspace form ===== */} | 172 | {/* ===== Create workspace form ===== */} |
@@ -207,3 +229,9 @@ class WorkspacesDashboard extends Component { | |||
207 | } | 229 | } |
208 | 230 | ||
209 | export default WorkspacesDashboard; | 231 | export default WorkspacesDashboard; |
232 | |||
233 | WorkspacesDashboard.wrappedComponent.propTypes = { | ||
234 | stores: PropTypes.shape({ | ||
235 | ui: PropTypes.instanceOf(UIStore).isRequired, | ||
236 | }).isRequired, | ||
237 | }; | ||
diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js index a82f6895c..4a1f80b4e 100644 --- a/src/features/workspaces/store.js +++ b/src/features/workspaces/store.js | |||
@@ -253,11 +253,10 @@ export default class WorkspacesStore extends FeatureStore { | |||
253 | }; | 253 | }; |
254 | 254 | ||
255 | _setIsPremiumFeatureReaction = () => { | 255 | _setIsPremiumFeatureReaction = () => { |
256 | const { features, user } = this.stores; | 256 | const { features } = this.stores; |
257 | const { isPremium } = user.data; | 257 | const { isWorkspaceIncludedInCurrentPlan } = features.features; |
258 | const { isWorkspacePremiumFeature } = features.features; | 258 | this.isPremiumFeature = !isWorkspaceIncludedInCurrentPlan; |
259 | this.isPremiumFeature = isWorkspacePremiumFeature; | 259 | this.isPremiumUpgradeRequired = !isWorkspaceIncludedInCurrentPlan; |
260 | this.isPremiumUpgradeRequired = isWorkspacePremiumFeature && !isPremium; | ||
261 | }; | 260 | }; |
262 | 261 | ||
263 | _setWorkspaceBeingEditedReaction = () => { | 262 | _setWorkspaceBeingEditedReaction = () => { |
diff --git a/src/helpers/plan-helpers.js b/src/helpers/plan-helpers.js new file mode 100644 index 000000000..e0f1fd89a --- /dev/null +++ b/src/helpers/plan-helpers.js | |||
@@ -0,0 +1,45 @@ | |||
1 | import { defineMessages } from 'react-intl'; | ||
2 | import { PLANS_MAPPING, PLANS } from '../config'; | ||
3 | |||
4 | const messages = defineMessages({ | ||
5 | [PLANS.PRO]: { | ||
6 | id: 'pricing.plan.pro', | ||
7 | defaultMessage: '!!!Franz Professional', | ||
8 | }, | ||
9 | [PLANS.PERSONAL]: { | ||
10 | id: 'pricing.plan.personal', | ||
11 | defaultMessage: '!!!Franz Personal', | ||
12 | }, | ||
13 | [PLANS.FREE]: { | ||
14 | id: 'pricing.plan.free', | ||
15 | defaultMessage: '!!!Franz Free', | ||
16 | }, | ||
17 | [PLANS.LEGACY]: { | ||
18 | id: 'pricing.plan.legacy', | ||
19 | defaultMessage: '!!!Franz Premium', | ||
20 | }, | ||
21 | }); | ||
22 | |||
23 | export function i18nPlanName(planId, intl) { | ||
24 | if (!planId) { | ||
25 | throw new Error('planId is required'); | ||
26 | } | ||
27 | |||
28 | if (!intl) { | ||
29 | throw new Error('intl context is required'); | ||
30 | } | ||
31 | |||
32 | const plan = PLANS_MAPPING[planId]; | ||
33 | |||
34 | return intl.formatMessage(messages[plan]); | ||
35 | } | ||
36 | |||
37 | export function getPlan(planId) { | ||
38 | if (!planId) { | ||
39 | throw new Error('planId is required'); | ||
40 | } | ||
41 | |||
42 | const plan = PLANS_MAPPING[planId]; | ||
43 | |||
44 | return plan; | ||
45 | } | ||
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index 5959fb059..367184c01 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json | |||
@@ -417,55 +417,120 @@ | |||
417 | { | 417 | { |
418 | "descriptors": [ | 418 | "descriptors": [ |
419 | { | 419 | { |
420 | "defaultMessage": "!!!Support Franz", | 420 | "defaultMessage": "!!!Franz Professional", |
421 | "end": { | 421 | "end": { |
422 | "column": 3, | 422 | "column": 3, |
423 | "line": 16 | 423 | "line": 18 |
424 | }, | 424 | }, |
425 | "file": "src/components/auth/Pricing.js", | 425 | "file": "src/components/auth/Pricing.js", |
426 | "id": "pricing.headline", | 426 | "id": "pricing.trial.headline", |
427 | "start": { | 427 | "start": { |
428 | "column": 12, | 428 | "column": 12, |
429 | "line": 13 | 429 | "line": 15 |
430 | } | 430 | } |
431 | }, | 431 | }, |
432 | { | 432 | { |
433 | "defaultMessage": "!!!Select your support plan", | 433 | "defaultMessage": "!!!Your personal welcome offer:", |
434 | "end": { | 434 | "end": { |
435 | "column": 3, | 435 | "column": 3, |
436 | "line": 20 | 436 | "line": 22 |
437 | }, | 437 | }, |
438 | "file": "src/components/auth/Pricing.js", | 438 | "file": "src/components/auth/Pricing.js", |
439 | "id": "pricing.support.label", | 439 | "id": "pricing.trial.subheadline", |
440 | "start": { | 440 | "start": { |
441 | "column": 23, | 441 | "column": 17, |
442 | "line": 17 | 442 | "line": 19 |
443 | } | 443 | } |
444 | }, | 444 | }, |
445 | { | 445 | { |
446 | "defaultMessage": "!!!Support the development of Franz", | 446 | "defaultMessage": "!!!No strings attached", |
447 | "end": { | 447 | "end": { |
448 | "column": 3, | 448 | "column": 3, |
449 | "line": 24 | 449 | "line": 26 |
450 | }, | 450 | }, |
451 | "file": "src/components/auth/Pricing.js", | 451 | "file": "src/components/auth/Pricing.js", |
452 | "id": "pricing.submit.label", | 452 | "id": "pricing.trial.terms.headline", |
453 | "start": { | ||
454 | "column": 29, | ||
455 | "line": 23 | ||
456 | } | ||
457 | }, | ||
458 | { | ||
459 | "defaultMessage": "!!!No credit card required", | ||
460 | "end": { | ||
461 | "column": 3, | ||
462 | "line": 30 | ||
463 | }, | ||
464 | "file": "src/components/auth/Pricing.js", | ||
465 | "id": "pricing.trial.terms.noCreditCard", | ||
466 | "start": { | ||
467 | "column": 16, | ||
468 | "line": 27 | ||
469 | } | ||
470 | }, | ||
471 | { | ||
472 | "defaultMessage": "!!!Your free trial ends automatically after 14 days", | ||
473 | "end": { | ||
474 | "column": 3, | ||
475 | "line": 34 | ||
476 | }, | ||
477 | "file": "src/components/auth/Pricing.js", | ||
478 | "id": "pricing.trial.terms.automaticTrialEnd", | ||
453 | "start": { | 479 | "start": { |
454 | "column": 21, | 480 | "column": 21, |
455 | "line": 21 | 481 | "line": 31 |
456 | } | 482 | } |
457 | }, | 483 | }, |
458 | { | 484 | { |
459 | "defaultMessage": "!!!I don't want to support the development of Franz.", | 485 | "defaultMessage": "!!!Sorry, we could not activate your trial!", |
460 | "end": { | 486 | "end": { |
461 | "column": 3, | 487 | "column": 3, |
462 | "line": 28 | 488 | "line": 38 |
463 | }, | 489 | }, |
464 | "file": "src/components/auth/Pricing.js", | 490 | "file": "src/components/auth/Pricing.js", |
465 | "id": "pricing.link.skipPayment", | 491 | "id": "pricing.trial.error", |
466 | "start": { | 492 | "start": { |
467 | "column": 15, | 493 | "column": 19, |
468 | "line": 25 | 494 | "line": 35 |
495 | } | ||
496 | }, | ||
497 | { | ||
498 | "defaultMessage": "!!!Yes, upgrade my account to Franz Professional", | ||
499 | "end": { | ||
500 | "column": 3, | ||
501 | "line": 42 | ||
502 | }, | ||
503 | "file": "src/components/auth/Pricing.js", | ||
504 | "id": "pricing.trial.cta.accept", | ||
505 | "start": { | ||
506 | "column": 13, | ||
507 | "line": 39 | ||
508 | } | ||
509 | }, | ||
510 | { | ||
511 | "defaultMessage": "!!!Continue to Franz", | ||
512 | "end": { | ||
513 | "column": 3, | ||
514 | "line": 46 | ||
515 | }, | ||
516 | "file": "src/components/auth/Pricing.js", | ||
517 | "id": "pricing.trial.cta.skip", | ||
518 | "start": { | ||
519 | "column": 11, | ||
520 | "line": 43 | ||
521 | } | ||
522 | }, | ||
523 | { | ||
524 | "defaultMessage": "!!!Franz Professional includes:", | ||
525 | "end": { | ||
526 | "column": 3, | ||
527 | "line": 50 | ||
528 | }, | ||
529 | "file": "src/components/auth/Pricing.js", | ||
530 | "id": "pricing.trial.features.headline", | ||
531 | "start": { | ||
532 | "column": 20, | ||
533 | "line": 47 | ||
469 | } | 534 | } |
470 | } | 535 | } |
471 | ], | 536 | ], |
@@ -477,156 +542,143 @@ | |||
477 | "defaultMessage": "!!!Sign up", | 542 | "defaultMessage": "!!!Sign up", |
478 | "end": { | 543 | "end": { |
479 | "column": 3, | 544 | "column": 3, |
480 | "line": 21 | 545 | "line": 20 |
481 | }, | 546 | }, |
482 | "file": "src/components/auth/Signup.js", | 547 | "file": "src/components/auth/Signup.js", |
483 | "id": "signup.headline", | 548 | "id": "signup.headline", |
484 | "start": { | 549 | "start": { |
485 | "column": 12, | 550 | "column": 12, |
486 | "line": 18 | 551 | "line": 17 |
487 | } | 552 | } |
488 | }, | 553 | }, |
489 | { | 554 | { |
490 | "defaultMessage": "!!!Firstname", | 555 | "defaultMessage": "!!!Firstname", |
491 | "end": { | 556 | "end": { |
492 | "column": 3, | 557 | "column": 3, |
493 | "line": 25 | 558 | "line": 24 |
494 | }, | 559 | }, |
495 | "file": "src/components/auth/Signup.js", | 560 | "file": "src/components/auth/Signup.js", |
496 | "id": "signup.firstname.label", | 561 | "id": "signup.firstname.label", |
497 | "start": { | 562 | "start": { |
498 | "column": 18, | 563 | "column": 18, |
499 | "line": 22 | 564 | "line": 21 |
500 | } | 565 | } |
501 | }, | 566 | }, |
502 | { | 567 | { |
503 | "defaultMessage": "!!!Lastname", | 568 | "defaultMessage": "!!!Lastname", |
504 | "end": { | 569 | "end": { |
505 | "column": 3, | 570 | "column": 3, |
506 | "line": 29 | 571 | "line": 28 |
507 | }, | 572 | }, |
508 | "file": "src/components/auth/Signup.js", | 573 | "file": "src/components/auth/Signup.js", |
509 | "id": "signup.lastname.label", | 574 | "id": "signup.lastname.label", |
510 | "start": { | 575 | "start": { |
511 | "column": 17, | 576 | "column": 17, |
512 | "line": 26 | 577 | "line": 25 |
513 | } | 578 | } |
514 | }, | 579 | }, |
515 | { | 580 | { |
516 | "defaultMessage": "!!!Email address", | 581 | "defaultMessage": "!!!Email address", |
517 | "end": { | 582 | "end": { |
518 | "column": 3, | 583 | "column": 3, |
519 | "line": 33 | 584 | "line": 32 |
520 | }, | 585 | }, |
521 | "file": "src/components/auth/Signup.js", | 586 | "file": "src/components/auth/Signup.js", |
522 | "id": "signup.email.label", | 587 | "id": "signup.email.label", |
523 | "start": { | 588 | "start": { |
524 | "column": 14, | 589 | "column": 14, |
525 | "line": 30 | 590 | "line": 29 |
526 | } | ||
527 | }, | ||
528 | { | ||
529 | "defaultMessage": "!!!Company", | ||
530 | "end": { | ||
531 | "column": 3, | ||
532 | "line": 37 | ||
533 | }, | ||
534 | "file": "src/components/auth/Signup.js", | ||
535 | "id": "signup.company.label", | ||
536 | "start": { | ||
537 | "column": 16, | ||
538 | "line": 34 | ||
539 | } | 591 | } |
540 | }, | 592 | }, |
541 | { | 593 | { |
542 | "defaultMessage": "!!!Password", | 594 | "defaultMessage": "!!!Password", |
543 | "end": { | 595 | "end": { |
544 | "column": 3, | 596 | "column": 3, |
545 | "line": 41 | 597 | "line": 40 |
546 | }, | 598 | }, |
547 | "file": "src/components/auth/Signup.js", | 599 | "file": "src/components/auth/Signup.js", |
548 | "id": "signup.password.label", | 600 | "id": "signup.password.label", |
549 | "start": { | 601 | "start": { |
550 | "column": 17, | 602 | "column": 17, |
551 | "line": 38 | 603 | "line": 37 |
552 | } | 604 | } |
553 | }, | 605 | }, |
554 | { | 606 | { |
555 | "defaultMessage": "!!!By creating a Franz account you accept the", | 607 | "defaultMessage": "!!!By creating a Franz account you accept the", |
556 | "end": { | 608 | "end": { |
557 | "column": 3, | 609 | "column": 3, |
558 | "line": 45 | 610 | "line": 44 |
559 | }, | 611 | }, |
560 | "file": "src/components/auth/Signup.js", | 612 | "file": "src/components/auth/Signup.js", |
561 | "id": "signup.legal.info", | 613 | "id": "signup.legal.info", |
562 | "start": { | 614 | "start": { |
563 | "column": 13, | 615 | "column": 13, |
564 | "line": 42 | 616 | "line": 41 |
565 | } | 617 | } |
566 | }, | 618 | }, |
567 | { | 619 | { |
568 | "defaultMessage": "!!!Terms of service", | 620 | "defaultMessage": "!!!Terms of service", |
569 | "end": { | 621 | "end": { |
570 | "column": 3, | 622 | "column": 3, |
571 | "line": 49 | 623 | "line": 48 |
572 | }, | 624 | }, |
573 | "file": "src/components/auth/Signup.js", | 625 | "file": "src/components/auth/Signup.js", |
574 | "id": "signup.legal.terms", | 626 | "id": "signup.legal.terms", |
575 | "start": { | 627 | "start": { |
576 | "column": 9, | 628 | "column": 9, |
577 | "line": 46 | 629 | "line": 45 |
578 | } | 630 | } |
579 | }, | 631 | }, |
580 | { | 632 | { |
581 | "defaultMessage": "!!!Privacy Statement", | 633 | "defaultMessage": "!!!Privacy Statement", |
582 | "end": { | 634 | "end": { |
583 | "column": 3, | 635 | "column": 3, |
584 | "line": 53 | 636 | "line": 52 |
585 | }, | 637 | }, |
586 | "file": "src/components/auth/Signup.js", | 638 | "file": "src/components/auth/Signup.js", |
587 | "id": "signup.legal.privacy", | 639 | "id": "signup.legal.privacy", |
588 | "start": { | 640 | "start": { |
589 | "column": 11, | 641 | "column": 11, |
590 | "line": 50 | 642 | "line": 49 |
591 | } | 643 | } |
592 | }, | 644 | }, |
593 | { | 645 | { |
594 | "defaultMessage": "!!!Create account", | 646 | "defaultMessage": "!!!Create account", |
595 | "end": { | 647 | "end": { |
596 | "column": 3, | 648 | "column": 3, |
597 | "line": 57 | 649 | "line": 56 |
598 | }, | 650 | }, |
599 | "file": "src/components/auth/Signup.js", | 651 | "file": "src/components/auth/Signup.js", |
600 | "id": "signup.submit.label", | 652 | "id": "signup.submit.label", |
601 | "start": { | 653 | "start": { |
602 | "column": 21, | 654 | "column": 21, |
603 | "line": 54 | 655 | "line": 53 |
604 | } | 656 | } |
605 | }, | 657 | }, |
606 | { | 658 | { |
607 | "defaultMessage": "!!!Already have an account, sign in?", | 659 | "defaultMessage": "!!!Already have an account, sign in?", |
608 | "end": { | 660 | "end": { |
609 | "column": 3, | 661 | "column": 3, |
610 | "line": 61 | 662 | "line": 60 |
611 | }, | 663 | }, |
612 | "file": "src/components/auth/Signup.js", | 664 | "file": "src/components/auth/Signup.js", |
613 | "id": "signup.link.login", | 665 | "id": "signup.link.login", |
614 | "start": { | 666 | "start": { |
615 | "column": 13, | 667 | "column": 13, |
616 | "line": 58 | 668 | "line": 57 |
617 | } | 669 | } |
618 | }, | 670 | }, |
619 | { | 671 | { |
620 | "defaultMessage": "!!!A user with that email address already exists", | 672 | "defaultMessage": "!!!A user with that email address already exists", |
621 | "end": { | 673 | "end": { |
622 | "column": 3, | 674 | "column": 3, |
623 | "line": 65 | 675 | "line": 64 |
624 | }, | 676 | }, |
625 | "file": "src/components/auth/Signup.js", | 677 | "file": "src/components/auth/Signup.js", |
626 | "id": "signup.emailDuplicate", | 678 | "id": "signup.emailDuplicate", |
627 | "start": { | 679 | "start": { |
628 | "column": 18, | 680 | "column": 18, |
629 | "line": 62 | 681 | "line": 61 |
630 | } | 682 | } |
631 | } | 683 | } |
632 | ], | 684 | ], |
@@ -669,39 +721,39 @@ | |||
669 | "defaultMessage": "!!!Your services have been updated.", | 721 | "defaultMessage": "!!!Your services have been updated.", |
670 | "end": { | 722 | "end": { |
671 | "column": 3, | 723 | "column": 3, |
672 | "line": 30 | 724 | "line": 31 |
673 | }, | 725 | }, |
674 | "file": "src/components/layout/AppLayout.js", | 726 | "file": "src/components/layout/AppLayout.js", |
675 | "id": "infobar.servicesUpdated", | 727 | "id": "infobar.servicesUpdated", |
676 | "start": { | 728 | "start": { |
677 | "column": 19, | 729 | "column": 19, |
678 | "line": 27 | 730 | "line": 28 |
679 | } | 731 | } |
680 | }, | 732 | }, |
681 | { | 733 | { |
682 | "defaultMessage": "!!!Reload services", | 734 | "defaultMessage": "!!!Reload services", |
683 | "end": { | 735 | "end": { |
684 | "column": 3, | 736 | "column": 3, |
685 | "line": 34 | 737 | "line": 35 |
686 | }, | 738 | }, |
687 | "file": "src/components/layout/AppLayout.js", | 739 | "file": "src/components/layout/AppLayout.js", |
688 | "id": "infobar.buttonReloadServices", | 740 | "id": "infobar.buttonReloadServices", |
689 | "start": { | 741 | "start": { |
690 | "column": 24, | 742 | "column": 24, |
691 | "line": 31 | 743 | "line": 32 |
692 | } | 744 | } |
693 | }, | 745 | }, |
694 | { | 746 | { |
695 | "defaultMessage": "!!!Could not load services and user information", | 747 | "defaultMessage": "!!!Could not load services and user information", |
696 | "end": { | 748 | "end": { |
697 | "column": 3, | 749 | "column": 3, |
698 | "line": 38 | 750 | "line": 39 |
699 | }, | 751 | }, |
700 | "file": "src/components/layout/AppLayout.js", | 752 | "file": "src/components/layout/AppLayout.js", |
701 | "id": "infobar.requiredRequestsFailed", | 753 | "id": "infobar.requiredRequestsFailed", |
702 | "start": { | 754 | "start": { |
703 | "column": 26, | 755 | "column": 26, |
704 | "line": 35 | 756 | "line": 36 |
705 | } | 757 | } |
706 | } | 758 | } |
707 | ], | 759 | ], |
@@ -894,29 +946,99 @@ | |||
894 | { | 946 | { |
895 | "descriptors": [ | 947 | "descriptors": [ |
896 | { | 948 | { |
897 | "defaultMessage": "!!!Welcome to Franz", | 949 | "defaultMessage": "!!!You have reached your service limit.", |
898 | "end": { | 950 | "end": { |
899 | "column": 3, | 951 | "column": 3, |
900 | "line": 14 | 952 | "line": 14 |
901 | }, | 953 | }, |
954 | "file": "src/components/services/content/ServiceRestricted.js", | ||
955 | "id": "service.restrictedHandler.serviceLimit.headline", | ||
956 | "start": { | ||
957 | "column": 24, | ||
958 | "line": 11 | ||
959 | } | ||
960 | }, | ||
961 | { | ||
962 | "defaultMessage": "!!!Please upgrade your account to use more than {count} services.", | ||
963 | "end": { | ||
964 | "column": 3, | ||
965 | "line": 18 | ||
966 | }, | ||
967 | "file": "src/components/services/content/ServiceRestricted.js", | ||
968 | "id": "service.restrictedHandler.serviceLimit.text", | ||
969 | "start": { | ||
970 | "column": 20, | ||
971 | "line": 15 | ||
972 | } | ||
973 | }, | ||
974 | { | ||
975 | "defaultMessage": "!!!Franz Professional Plan required", | ||
976 | "end": { | ||
977 | "column": 3, | ||
978 | "line": 22 | ||
979 | }, | ||
980 | "file": "src/components/services/content/ServiceRestricted.js", | ||
981 | "id": "service.restrictedHandler.customUrl.headline", | ||
982 | "start": { | ||
983 | "column": 21, | ||
984 | "line": 19 | ||
985 | } | ||
986 | }, | ||
987 | { | ||
988 | "defaultMessage": "!!!Please upgrade to the Franz Professional plan to use custom urls & self hosted services.", | ||
989 | "end": { | ||
990 | "column": 3, | ||
991 | "line": 26 | ||
992 | }, | ||
993 | "file": "src/components/services/content/ServiceRestricted.js", | ||
994 | "id": "service.restrictedHandler.customUrl.text", | ||
995 | "start": { | ||
996 | "column": 17, | ||
997 | "line": 23 | ||
998 | } | ||
999 | }, | ||
1000 | { | ||
1001 | "defaultMessage": "!!!Upgrade Account", | ||
1002 | "end": { | ||
1003 | "column": 3, | ||
1004 | "line": 30 | ||
1005 | }, | ||
1006 | "file": "src/components/services/content/ServiceRestricted.js", | ||
1007 | "id": "service.restrictedHandler.action", | ||
1008 | "start": { | ||
1009 | "column": 10, | ||
1010 | "line": 27 | ||
1011 | } | ||
1012 | } | ||
1013 | ], | ||
1014 | "path": "src/components/services/content/ServiceRestricted.json" | ||
1015 | }, | ||
1016 | { | ||
1017 | "descriptors": [ | ||
1018 | { | ||
1019 | "defaultMessage": "!!!Welcome to Franz", | ||
1020 | "end": { | ||
1021 | "column": 3, | ||
1022 | "line": 17 | ||
1023 | }, | ||
902 | "file": "src/components/services/content/Services.js", | 1024 | "file": "src/components/services/content/Services.js", |
903 | "id": "services.welcome", | 1025 | "id": "services.welcome", |
904 | "start": { | 1026 | "start": { |
905 | "column": 11, | 1027 | "column": 11, |
906 | "line": 11 | 1028 | "line": 14 |
907 | } | 1029 | } |
908 | }, | 1030 | }, |
909 | { | 1031 | { |
910 | "defaultMessage": "!!!Get started", | 1032 | "defaultMessage": "!!!Get started", |
911 | "end": { | 1033 | "end": { |
912 | "column": 3, | 1034 | "column": 3, |
913 | "line": 18 | 1035 | "line": 21 |
914 | }, | 1036 | }, |
915 | "file": "src/components/services/content/Services.js", | 1037 | "file": "src/components/services/content/Services.js", |
916 | "id": "services.getStarted", | 1038 | "id": "services.getStarted", |
917 | "start": { | 1039 | "start": { |
918 | "column": 14, | 1040 | "column": 14, |
919 | "line": 15 | 1041 | "line": 18 |
920 | } | 1042 | } |
921 | } | 1043 | } |
922 | ], | 1044 | ], |
@@ -1107,38 +1229,25 @@ | |||
1107 | "defaultMessage": "!!!Account", | 1229 | "defaultMessage": "!!!Account", |
1108 | "end": { | 1230 | "end": { |
1109 | "column": 3, | 1231 | "column": 3, |
1110 | "line": 17 | 1232 | "line": 21 |
1111 | }, | 1233 | }, |
1112 | "file": "src/components/settings/account/AccountDashboard.js", | 1234 | "file": "src/components/settings/account/AccountDashboard.js", |
1113 | "id": "settings.account.headline", | 1235 | "id": "settings.account.headline", |
1114 | "start": { | 1236 | "start": { |
1115 | "column": 12, | 1237 | "column": 12, |
1116 | "line": 14 | 1238 | "line": 18 |
1117 | } | 1239 | } |
1118 | }, | 1240 | }, |
1119 | { | 1241 | { |
1120 | "defaultMessage": "!!!Your Subscription", | 1242 | "defaultMessage": "!!!Your Subscription", |
1121 | "end": { | 1243 | "end": { |
1122 | "column": 3, | 1244 | "column": 3, |
1123 | "line": 21 | 1245 | "line": 25 |
1124 | }, | 1246 | }, |
1125 | "file": "src/components/settings/account/AccountDashboard.js", | 1247 | "file": "src/components/settings/account/AccountDashboard.js", |
1126 | "id": "settings.account.headlineSubscription", | 1248 | "id": "settings.account.headlineSubscription", |
1127 | "start": { | 1249 | "start": { |
1128 | "column": 24, | 1250 | "column": 24, |
1129 | "line": 18 | ||
1130 | } | ||
1131 | }, | ||
1132 | { | ||
1133 | "defaultMessage": "!!!Upgrade your Account", | ||
1134 | "end": { | ||
1135 | "column": 3, | ||
1136 | "line": 25 | ||
1137 | }, | ||
1138 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1139 | "id": "settings.account.headlineUpgrade", | ||
1140 | "start": { | ||
1141 | "column": 19, | ||
1142 | "line": 22 | 1251 | "line": 22 |
1143 | } | 1252 | } |
1144 | }, | 1253 | }, |
@@ -1169,133 +1278,198 @@ | |||
1169 | } | 1278 | } |
1170 | }, | 1279 | }, |
1171 | { | 1280 | { |
1172 | "defaultMessage": "!!!Basic Account", | 1281 | "defaultMessage": "!!!Upgrade to Franz Professional", |
1173 | "end": { | 1282 | "end": { |
1174 | "column": 3, | 1283 | "column": 3, |
1175 | "line": 37 | 1284 | "line": 37 |
1176 | }, | 1285 | }, |
1177 | "file": "src/components/settings/account/AccountDashboard.js", | 1286 | "file": "src/components/settings/account/AccountDashboard.js", |
1287 | "id": "settings.account.upgradeToPro.label", | ||
1288 | "start": { | ||
1289 | "column": 23, | ||
1290 | "line": 34 | ||
1291 | } | ||
1292 | }, | ||
1293 | { | ||
1294 | "defaultMessage": "!!!Basic Account", | ||
1295 | "end": { | ||
1296 | "column": 3, | ||
1297 | "line": 41 | ||
1298 | }, | ||
1299 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1178 | "id": "settings.account.accountType.basic", | 1300 | "id": "settings.account.accountType.basic", |
1179 | "start": { | 1301 | "start": { |
1180 | "column": 20, | 1302 | "column": 20, |
1181 | "line": 34 | 1303 | "line": 38 |
1182 | } | 1304 | } |
1183 | }, | 1305 | }, |
1184 | { | 1306 | { |
1185 | "defaultMessage": "!!!Premium Supporter Account", | 1307 | "defaultMessage": "!!!Premium Supporter Account", |
1186 | "end": { | 1308 | "end": { |
1187 | "column": 3, | 1309 | "column": 3, |
1188 | "line": 41 | 1310 | "line": 45 |
1189 | }, | 1311 | }, |
1190 | "file": "src/components/settings/account/AccountDashboard.js", | 1312 | "file": "src/components/settings/account/AccountDashboard.js", |
1191 | "id": "settings.account.accountType.premium", | 1313 | "id": "settings.account.accountType.premium", |
1192 | "start": { | 1314 | "start": { |
1193 | "column": 22, | 1315 | "column": 22, |
1194 | "line": 38 | 1316 | "line": 42 |
1195 | } | 1317 | } |
1196 | }, | 1318 | }, |
1197 | { | 1319 | { |
1198 | "defaultMessage": "!!!Edit Account", | 1320 | "defaultMessage": "!!!Edit Account", |
1199 | "end": { | 1321 | "end": { |
1200 | "column": 3, | 1322 | "column": 3, |
1201 | "line": 45 | 1323 | "line": 49 |
1202 | }, | 1324 | }, |
1203 | "file": "src/components/settings/account/AccountDashboard.js", | 1325 | "file": "src/components/settings/account/AccountDashboard.js", |
1204 | "id": "settings.account.account.editButton", | 1326 | "id": "settings.account.account.editButton", |
1205 | "start": { | 1327 | "start": { |
1206 | "column": 21, | 1328 | "column": 21, |
1207 | "line": 42 | 1329 | "line": 46 |
1208 | } | 1330 | } |
1209 | }, | 1331 | }, |
1210 | { | 1332 | { |
1211 | "defaultMessage": "!!Invoices", | 1333 | "defaultMessage": "!!Invoices", |
1212 | "end": { | 1334 | "end": { |
1213 | "column": 3, | 1335 | "column": 3, |
1214 | "line": 49 | 1336 | "line": 53 |
1215 | }, | 1337 | }, |
1216 | "file": "src/components/settings/account/AccountDashboard.js", | 1338 | "file": "src/components/settings/account/AccountDashboard.js", |
1217 | "id": "settings.account.headlineInvoices", | 1339 | "id": "settings.account.headlineInvoices", |
1218 | "start": { | 1340 | "start": { |
1219 | "column": 18, | 1341 | "column": 18, |
1220 | "line": 46 | 1342 | "line": 50 |
1221 | } | 1343 | } |
1222 | }, | 1344 | }, |
1223 | { | 1345 | { |
1224 | "defaultMessage": "!!!Download", | 1346 | "defaultMessage": "!!!Download", |
1225 | "end": { | 1347 | "end": { |
1226 | "column": 3, | 1348 | "column": 3, |
1227 | "line": 53 | 1349 | "line": 57 |
1228 | }, | 1350 | }, |
1229 | "file": "src/components/settings/account/AccountDashboard.js", | 1351 | "file": "src/components/settings/account/AccountDashboard.js", |
1230 | "id": "settings.account.invoiceDownload", | 1352 | "id": "settings.account.invoiceDownload", |
1231 | "start": { | 1353 | "start": { |
1232 | "column": 19, | 1354 | "column": 19, |
1233 | "line": 50 | 1355 | "line": 54 |
1234 | } | 1356 | } |
1235 | }, | 1357 | }, |
1236 | { | 1358 | { |
1237 | "defaultMessage": "!!!Could not load user information", | 1359 | "defaultMessage": "!!!Could not load user information", |
1238 | "end": { | 1360 | "end": { |
1239 | "column": 3, | 1361 | "column": 3, |
1240 | "line": 57 | 1362 | "line": 61 |
1241 | }, | 1363 | }, |
1242 | "file": "src/components/settings/account/AccountDashboard.js", | 1364 | "file": "src/components/settings/account/AccountDashboard.js", |
1243 | "id": "settings.account.userInfoRequestFailed", | 1365 | "id": "settings.account.userInfoRequestFailed", |
1244 | "start": { | 1366 | "start": { |
1245 | "column": 25, | 1367 | "column": 25, |
1246 | "line": 54 | 1368 | "line": 58 |
1247 | } | 1369 | } |
1248 | }, | 1370 | }, |
1249 | { | 1371 | { |
1250 | "defaultMessage": "!!!Try again", | 1372 | "defaultMessage": "!!!Try again", |
1251 | "end": { | 1373 | "end": { |
1252 | "column": 3, | 1374 | "column": 3, |
1253 | "line": 61 | 1375 | "line": 65 |
1254 | }, | 1376 | }, |
1255 | "file": "src/components/settings/account/AccountDashboard.js", | 1377 | "file": "src/components/settings/account/AccountDashboard.js", |
1256 | "id": "settings.account.tryReloadUserInfoRequest", | 1378 | "id": "settings.account.tryReloadUserInfoRequest", |
1257 | "start": { | 1379 | "start": { |
1258 | "column": 28, | 1380 | "column": 28, |
1259 | "line": 58 | 1381 | "line": 62 |
1260 | } | 1382 | } |
1261 | }, | 1383 | }, |
1262 | { | 1384 | { |
1263 | "defaultMessage": "!!!Delete account", | 1385 | "defaultMessage": "!!!Delete account", |
1264 | "end": { | 1386 | "end": { |
1265 | "column": 3, | 1387 | "column": 3, |
1266 | "line": 65 | 1388 | "line": 69 |
1267 | }, | 1389 | }, |
1268 | "file": "src/components/settings/account/AccountDashboard.js", | 1390 | "file": "src/components/settings/account/AccountDashboard.js", |
1269 | "id": "settings.account.deleteAccount", | 1391 | "id": "settings.account.deleteAccount", |
1270 | "start": { | 1392 | "start": { |
1271 | "column": 17, | 1393 | "column": 17, |
1272 | "line": 62 | 1394 | "line": 66 |
1273 | } | 1395 | } |
1274 | }, | 1396 | }, |
1275 | { | 1397 | { |
1276 | "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", | 1398 | "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", |
1277 | "end": { | 1399 | "end": { |
1278 | "column": 3, | 1400 | "column": 3, |
1279 | "line": 69 | 1401 | "line": 73 |
1280 | }, | 1402 | }, |
1281 | "file": "src/components/settings/account/AccountDashboard.js", | 1403 | "file": "src/components/settings/account/AccountDashboard.js", |
1282 | "id": "settings.account.deleteInfo", | 1404 | "id": "settings.account.deleteInfo", |
1283 | "start": { | 1405 | "start": { |
1284 | "column": 14, | 1406 | "column": 14, |
1285 | "line": 66 | 1407 | "line": 70 |
1286 | } | 1408 | } |
1287 | }, | 1409 | }, |
1288 | { | 1410 | { |
1289 | "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", | 1411 | "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", |
1290 | "end": { | 1412 | "end": { |
1291 | "column": 3, | 1413 | "column": 3, |
1292 | "line": 73 | 1414 | "line": 77 |
1293 | }, | 1415 | }, |
1294 | "file": "src/components/settings/account/AccountDashboard.js", | 1416 | "file": "src/components/settings/account/AccountDashboard.js", |
1295 | "id": "settings.account.deleteEmailSent", | 1417 | "id": "settings.account.deleteEmailSent", |
1296 | "start": { | 1418 | "start": { |
1297 | "column": 19, | 1419 | "column": 19, |
1298 | "line": 70 | 1420 | "line": 74 |
1421 | } | ||
1422 | }, | ||
1423 | { | ||
1424 | "defaultMessage": "!!!Free Trial", | ||
1425 | "end": { | ||
1426 | "column": 3, | ||
1427 | "line": 81 | ||
1428 | }, | ||
1429 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1430 | "id": "settings.account.trial", | ||
1431 | "start": { | ||
1432 | "column": 9, | ||
1433 | "line": 78 | ||
1434 | } | ||
1435 | }, | ||
1436 | { | ||
1437 | "defaultMessage": "!!!Your Franz License:", | ||
1438 | "end": { | ||
1439 | "column": 3, | ||
1440 | "line": 85 | ||
1441 | }, | ||
1442 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1443 | "id": "settings.account.yourLicense", | ||
1444 | "start": { | ||
1445 | "column": 15, | ||
1446 | "line": 82 | ||
1447 | } | ||
1448 | }, | ||
1449 | { | ||
1450 | "defaultMessage": "!!!Your free trial ends in {duration}.", | ||
1451 | "end": { | ||
1452 | "column": 3, | ||
1453 | "line": 89 | ||
1454 | }, | ||
1455 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1456 | "id": "settings.account.trialEndsIn", | ||
1457 | "start": { | ||
1458 | "column": 15, | ||
1459 | "line": 86 | ||
1460 | } | ||
1461 | }, | ||
1462 | { | ||
1463 | "defaultMessage": "!!!Please update your billing info to continue using {license} after your trial period.", | ||
1464 | "end": { | ||
1465 | "column": 3, | ||
1466 | "line": 93 | ||
1467 | }, | ||
1468 | "file": "src/components/settings/account/AccountDashboard.js", | ||
1469 | "id": "settings.account.trialUpdateBillingInfo", | ||
1470 | "start": { | ||
1471 | "column": 33, | ||
1472 | "line": 90 | ||
1299 | } | 1473 | } |
1300 | } | 1474 | } |
1301 | ], | 1475 | ], |
@@ -1307,104 +1481,104 @@ | |||
1307 | "defaultMessage": "!!!Available services", | 1481 | "defaultMessage": "!!!Available services", |
1308 | "end": { | 1482 | "end": { |
1309 | "column": 3, | 1483 | "column": 3, |
1310 | "line": 16 | 1484 | "line": 17 |
1311 | }, | 1485 | }, |
1312 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1486 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1313 | "id": "settings.navigation.availableServices", | 1487 | "id": "settings.navigation.availableServices", |
1314 | "start": { | 1488 | "start": { |
1315 | "column": 21, | 1489 | "column": 21, |
1316 | "line": 13 | 1490 | "line": 14 |
1317 | } | 1491 | } |
1318 | }, | 1492 | }, |
1319 | { | 1493 | { |
1320 | "defaultMessage": "!!!Your services", | 1494 | "defaultMessage": "!!!Your services", |
1321 | "end": { | 1495 | "end": { |
1322 | "column": 3, | 1496 | "column": 3, |
1323 | "line": 20 | 1497 | "line": 21 |
1324 | }, | 1498 | }, |
1325 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1499 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1326 | "id": "settings.navigation.yourServices", | 1500 | "id": "settings.navigation.yourServices", |
1327 | "start": { | 1501 | "start": { |
1328 | "column": 16, | 1502 | "column": 16, |
1329 | "line": 17 | 1503 | "line": 18 |
1330 | } | 1504 | } |
1331 | }, | 1505 | }, |
1332 | { | 1506 | { |
1333 | "defaultMessage": "!!!Your workspaces", | 1507 | "defaultMessage": "!!!Your workspaces", |
1334 | "end": { | 1508 | "end": { |
1335 | "column": 3, | 1509 | "column": 3, |
1336 | "line": 24 | 1510 | "line": 25 |
1337 | }, | 1511 | }, |
1338 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1512 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1339 | "id": "settings.navigation.yourWorkspaces", | 1513 | "id": "settings.navigation.yourWorkspaces", |
1340 | "start": { | 1514 | "start": { |
1341 | "column": 18, | 1515 | "column": 18, |
1342 | "line": 21 | 1516 | "line": 22 |
1343 | } | 1517 | } |
1344 | }, | 1518 | }, |
1345 | { | 1519 | { |
1346 | "defaultMessage": "!!!Account", | 1520 | "defaultMessage": "!!!Account", |
1347 | "end": { | 1521 | "end": { |
1348 | "column": 3, | 1522 | "column": 3, |
1349 | "line": 28 | 1523 | "line": 29 |
1350 | }, | 1524 | }, |
1351 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1525 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1352 | "id": "settings.navigation.account", | 1526 | "id": "settings.navigation.account", |
1353 | "start": { | 1527 | "start": { |
1354 | "column": 11, | 1528 | "column": 11, |
1355 | "line": 25 | 1529 | "line": 26 |
1356 | } | 1530 | } |
1357 | }, | 1531 | }, |
1358 | { | 1532 | { |
1359 | "defaultMessage": "!!!Manage Team", | 1533 | "defaultMessage": "!!!Manage Team", |
1360 | "end": { | 1534 | "end": { |
1361 | "column": 3, | 1535 | "column": 3, |
1362 | "line": 32 | 1536 | "line": 33 |
1363 | }, | 1537 | }, |
1364 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1538 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1365 | "id": "settings.navigation.team", | 1539 | "id": "settings.navigation.team", |
1366 | "start": { | 1540 | "start": { |
1367 | "column": 8, | 1541 | "column": 8, |
1368 | "line": 29 | 1542 | "line": 30 |
1369 | } | 1543 | } |
1370 | }, | 1544 | }, |
1371 | { | 1545 | { |
1372 | "defaultMessage": "!!!Settings", | 1546 | "defaultMessage": "!!!Settings", |
1373 | "end": { | 1547 | "end": { |
1374 | "column": 3, | 1548 | "column": 3, |
1375 | "line": 36 | 1549 | "line": 37 |
1376 | }, | 1550 | }, |
1377 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1551 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1378 | "id": "settings.navigation.settings", | 1552 | "id": "settings.navigation.settings", |
1379 | "start": { | 1553 | "start": { |
1380 | "column": 12, | 1554 | "column": 12, |
1381 | "line": 33 | 1555 | "line": 34 |
1382 | } | 1556 | } |
1383 | }, | 1557 | }, |
1384 | { | 1558 | { |
1385 | "defaultMessage": "!!!Invite Friends", | 1559 | "defaultMessage": "!!!Invite Friends", |
1386 | "end": { | 1560 | "end": { |
1387 | "column": 3, | 1561 | "column": 3, |
1388 | "line": 40 | 1562 | "line": 41 |
1389 | }, | 1563 | }, |
1390 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1564 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1391 | "id": "settings.navigation.inviteFriends", | 1565 | "id": "settings.navigation.inviteFriends", |
1392 | "start": { | 1566 | "start": { |
1393 | "column": 17, | 1567 | "column": 17, |
1394 | "line": 37 | 1568 | "line": 38 |
1395 | } | 1569 | } |
1396 | }, | 1570 | }, |
1397 | { | 1571 | { |
1398 | "defaultMessage": "!!!Logout", | 1572 | "defaultMessage": "!!!Logout", |
1399 | "end": { | 1573 | "end": { |
1400 | "column": 3, | 1574 | "column": 3, |
1401 | "line": 44 | 1575 | "line": 45 |
1402 | }, | 1576 | }, |
1403 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 1577 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
1404 | "id": "settings.navigation.logout", | 1578 | "id": "settings.navigation.logout", |
1405 | "start": { | 1579 | "start": { |
1406 | "column": 10, | 1580 | "column": 10, |
1407 | "line": 41 | 1581 | "line": 42 |
1408 | } | 1582 | } |
1409 | } | 1583 | } |
1410 | ], | 1584 | ], |
@@ -1416,104 +1590,182 @@ | |||
1416 | "defaultMessage": "!!!Available Services", | 1590 | "defaultMessage": "!!!Available Services", |
1417 | "end": { | 1591 | "end": { |
1418 | "column": 3, | 1592 | "column": 3, |
1419 | "line": 18 | 1593 | "line": 23 |
1420 | }, | 1594 | }, |
1421 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1595 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1422 | "id": "settings.recipes.headline", | 1596 | "id": "settings.recipes.headline", |
1423 | "start": { | 1597 | "start": { |
1424 | "column": 12, | 1598 | "column": 12, |
1425 | "line": 15 | 1599 | "line": 20 |
1426 | } | 1600 | } |
1427 | }, | 1601 | }, |
1428 | { | 1602 | { |
1429 | "defaultMessage": "!!!Search service", | 1603 | "defaultMessage": "!!!Search service", |
1430 | "end": { | 1604 | "end": { |
1431 | "column": 3, | 1605 | "column": 3, |
1432 | "line": 22 | 1606 | "line": 27 |
1433 | }, | 1607 | }, |
1434 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1608 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1435 | "id": "settings.searchService", | 1609 | "id": "settings.searchService", |
1436 | "start": { | 1610 | "start": { |
1437 | "column": 17, | 1611 | "column": 17, |
1438 | "line": 19 | 1612 | "line": 24 |
1439 | } | 1613 | } |
1440 | }, | 1614 | }, |
1441 | { | 1615 | { |
1442 | "defaultMessage": "!!!Most popular", | 1616 | "defaultMessage": "!!!Most popular", |
1443 | "end": { | 1617 | "end": { |
1444 | "column": 3, | 1618 | "column": 3, |
1445 | "line": 26 | 1619 | "line": 31 |
1446 | }, | 1620 | }, |
1447 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1621 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1448 | "id": "settings.recipes.mostPopular", | 1622 | "id": "settings.recipes.mostPopular", |
1449 | "start": { | 1623 | "start": { |
1450 | "column": 22, | 1624 | "column": 22, |
1451 | "line": 23 | 1625 | "line": 28 |
1452 | } | 1626 | } |
1453 | }, | 1627 | }, |
1454 | { | 1628 | { |
1455 | "defaultMessage": "!!!All services", | 1629 | "defaultMessage": "!!!All services", |
1456 | "end": { | 1630 | "end": { |
1457 | "column": 3, | 1631 | "column": 3, |
1458 | "line": 30 | 1632 | "line": 35 |
1459 | }, | 1633 | }, |
1460 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1634 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1461 | "id": "settings.recipes.all", | 1635 | "id": "settings.recipes.all", |
1462 | "start": { | 1636 | "start": { |
1463 | "column": 14, | 1637 | "column": 14, |
1464 | "line": 27 | 1638 | "line": 32 |
1465 | } | 1639 | } |
1466 | }, | 1640 | }, |
1467 | { | 1641 | { |
1468 | "defaultMessage": "!!!Development", | 1642 | "defaultMessage": "!!!Custom Services", |
1469 | "end": { | 1643 | "end": { |
1470 | "column": 3, | 1644 | "column": 3, |
1471 | "line": 34 | 1645 | "line": 39 |
1472 | }, | 1646 | }, |
1473 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1647 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1474 | "id": "settings.recipes.dev", | 1648 | "id": "settings.recipes.custom", |
1475 | "start": { | 1649 | "start": { |
1476 | "column": 14, | 1650 | "column": 17, |
1477 | "line": 31 | 1651 | "line": 36 |
1478 | } | 1652 | } |
1479 | }, | 1653 | }, |
1480 | { | 1654 | { |
1481 | "defaultMessage": "!!!Sorry, but no service matched your search term.", | 1655 | "defaultMessage": "!!!Sorry, but no service matched your search term.", |
1482 | "end": { | 1656 | "end": { |
1483 | "column": 3, | 1657 | "column": 3, |
1484 | "line": 38 | 1658 | "line": 43 |
1485 | }, | 1659 | }, |
1486 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1660 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1487 | "id": "settings.recipes.nothingFound", | 1661 | "id": "settings.recipes.nothingFound", |
1488 | "start": { | 1662 | "start": { |
1489 | "column": 16, | 1663 | "column": 16, |
1490 | "line": 35 | 1664 | "line": 40 |
1491 | } | 1665 | } |
1492 | }, | 1666 | }, |
1493 | { | 1667 | { |
1494 | "defaultMessage": "!!!Service successfully added", | 1668 | "defaultMessage": "!!!Service successfully added", |
1495 | "end": { | 1669 | "end": { |
1496 | "column": 3, | 1670 | "column": 3, |
1497 | "line": 42 | 1671 | "line": 47 |
1498 | }, | 1672 | }, |
1499 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1673 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1500 | "id": "settings.recipes.servicesSuccessfulAddedInfo", | 1674 | "id": "settings.recipes.servicesSuccessfulAddedInfo", |
1501 | "start": { | 1675 | "start": { |
1502 | "column": 31, | 1676 | "column": 31, |
1503 | "line": 39 | 1677 | "line": 44 |
1504 | } | 1678 | } |
1505 | }, | 1679 | }, |
1506 | { | 1680 | { |
1507 | "defaultMessage": "!!!Missing a service?", | 1681 | "defaultMessage": "!!!Missing a service?", |
1508 | "end": { | 1682 | "end": { |
1509 | "column": 3, | 1683 | "column": 3, |
1510 | "line": 46 | 1684 | "line": 51 |
1511 | }, | 1685 | }, |
1512 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 1686 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
1513 | "id": "settings.recipes.missingService", | 1687 | "id": "settings.recipes.missingService", |
1514 | "start": { | 1688 | "start": { |
1515 | "column": 18, | 1689 | "column": 18, |
1516 | "line": 43 | 1690 | "line": 48 |
1691 | } | ||
1692 | }, | ||
1693 | { | ||
1694 | "defaultMessage": "!!!To add a custom service, copy the recipe folder into:", | ||
1695 | "end": { | ||
1696 | "column": 3, | ||
1697 | "line": 55 | ||
1698 | }, | ||
1699 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1700 | "id": "settings.recipes.customService.intro", | ||
1701 | "start": { | ||
1702 | "column": 21, | ||
1703 | "line": 52 | ||
1704 | } | ||
1705 | }, | ||
1706 | { | ||
1707 | "defaultMessage": "!!!Open directory", | ||
1708 | "end": { | ||
1709 | "column": 3, | ||
1710 | "line": 59 | ||
1711 | }, | ||
1712 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1713 | "id": "settings.recipes.customService.openFolder", | ||
1714 | "start": { | ||
1715 | "column": 14, | ||
1716 | "line": 56 | ||
1717 | } | ||
1718 | }, | ||
1719 | { | ||
1720 | "defaultMessage": "!!!Developer Documentation", | ||
1721 | "end": { | ||
1722 | "column": 3, | ||
1723 | "line": 63 | ||
1724 | }, | ||
1725 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1726 | "id": "settings.recipes.customService.openDevDocs", | ||
1727 | "start": { | ||
1728 | "column": 15, | ||
1729 | "line": 60 | ||
1730 | } | ||
1731 | }, | ||
1732 | { | ||
1733 | "defaultMessage": "!!!Custom Service Recipes", | ||
1734 | "end": { | ||
1735 | "column": 3, | ||
1736 | "line": 67 | ||
1737 | }, | ||
1738 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1739 | "id": "settings.recipes.customService.headline.customRecipes", | ||
1740 | "start": { | ||
1741 | "column": 25, | ||
1742 | "line": 64 | ||
1743 | } | ||
1744 | }, | ||
1745 | { | ||
1746 | "defaultMessage": "!!!Community Services", | ||
1747 | "end": { | ||
1748 | "column": 3, | ||
1749 | "line": 71 | ||
1750 | }, | ||
1751 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1752 | "id": "settings.recipes.customService.headline.communityRecipes", | ||
1753 | "start": { | ||
1754 | "column": 28, | ||
1755 | "line": 68 | ||
1756 | } | ||
1757 | }, | ||
1758 | { | ||
1759 | "defaultMessage": "!!!Your Development Service Recipes", | ||
1760 | "end": { | ||
1761 | "column": 3, | ||
1762 | "line": 75 | ||
1763 | }, | ||
1764 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
1765 | "id": "settings.recipes.customService.headline.devRecipes", | ||
1766 | "start": { | ||
1767 | "column": 22, | ||
1768 | "line": 72 | ||
1517 | } | 1769 | } |
1518 | } | 1770 | } |
1519 | ], | 1771 | ], |
@@ -1525,286 +1777,286 @@ | |||
1525 | "defaultMessage": "!!!Save service", | 1777 | "defaultMessage": "!!!Save service", |
1526 | "end": { | 1778 | "end": { |
1527 | "column": 3, | 1779 | "column": 3, |
1528 | "line": 25 | 1780 | "line": 27 |
1529 | }, | 1781 | }, |
1530 | "file": "src/components/settings/services/EditServiceForm.js", | 1782 | "file": "src/components/settings/services/EditServiceForm.js", |
1531 | "id": "settings.service.form.saveButton", | 1783 | "id": "settings.service.form.saveButton", |
1532 | "start": { | 1784 | "start": { |
1533 | "column": 15, | 1785 | "column": 15, |
1534 | "line": 22 | 1786 | "line": 24 |
1535 | } | 1787 | } |
1536 | }, | 1788 | }, |
1537 | { | 1789 | { |
1538 | "defaultMessage": "!!!Delete Service", | 1790 | "defaultMessage": "!!!Delete Service", |
1539 | "end": { | 1791 | "end": { |
1540 | "column": 3, | 1792 | "column": 3, |
1541 | "line": 29 | 1793 | "line": 31 |
1542 | }, | 1794 | }, |
1543 | "file": "src/components/settings/services/EditServiceForm.js", | 1795 | "file": "src/components/settings/services/EditServiceForm.js", |
1544 | "id": "settings.service.form.deleteButton", | 1796 | "id": "settings.service.form.deleteButton", |
1545 | "start": { | 1797 | "start": { |
1546 | "column": 17, | 1798 | "column": 17, |
1547 | "line": 26 | 1799 | "line": 28 |
1548 | } | 1800 | } |
1549 | }, | 1801 | }, |
1550 | { | 1802 | { |
1551 | "defaultMessage": "!!!Available services", | 1803 | "defaultMessage": "!!!Available services", |
1552 | "end": { | 1804 | "end": { |
1553 | "column": 3, | 1805 | "column": 3, |
1554 | "line": 33 | 1806 | "line": 35 |
1555 | }, | 1807 | }, |
1556 | "file": "src/components/settings/services/EditServiceForm.js", | 1808 | "file": "src/components/settings/services/EditServiceForm.js", |
1557 | "id": "settings.service.form.availableServices", | 1809 | "id": "settings.service.form.availableServices", |
1558 | "start": { | 1810 | "start": { |
1559 | "column": 21, | 1811 | "column": 21, |
1560 | "line": 30 | 1812 | "line": 32 |
1561 | } | 1813 | } |
1562 | }, | 1814 | }, |
1563 | { | 1815 | { |
1564 | "defaultMessage": "!!!Your services", | 1816 | "defaultMessage": "!!!Your services", |
1565 | "end": { | 1817 | "end": { |
1566 | "column": 3, | 1818 | "column": 3, |
1567 | "line": 37 | 1819 | "line": 39 |
1568 | }, | 1820 | }, |
1569 | "file": "src/components/settings/services/EditServiceForm.js", | 1821 | "file": "src/components/settings/services/EditServiceForm.js", |
1570 | "id": "settings.service.form.yourServices", | 1822 | "id": "settings.service.form.yourServices", |
1571 | "start": { | 1823 | "start": { |
1572 | "column": 16, | 1824 | "column": 16, |
1573 | "line": 34 | 1825 | "line": 36 |
1574 | } | 1826 | } |
1575 | }, | 1827 | }, |
1576 | { | 1828 | { |
1577 | "defaultMessage": "!!!Add {name}", | 1829 | "defaultMessage": "!!!Add {name}", |
1578 | "end": { | 1830 | "end": { |
1579 | "column": 3, | 1831 | "column": 3, |
1580 | "line": 41 | 1832 | "line": 43 |
1581 | }, | 1833 | }, |
1582 | "file": "src/components/settings/services/EditServiceForm.js", | 1834 | "file": "src/components/settings/services/EditServiceForm.js", |
1583 | "id": "settings.service.form.addServiceHeadline", | 1835 | "id": "settings.service.form.addServiceHeadline", |
1584 | "start": { | 1836 | "start": { |
1585 | "column": 22, | 1837 | "column": 22, |
1586 | "line": 38 | 1838 | "line": 40 |
1587 | } | 1839 | } |
1588 | }, | 1840 | }, |
1589 | { | 1841 | { |
1590 | "defaultMessage": "!!!Edit {name}", | 1842 | "defaultMessage": "!!!Edit {name}", |
1591 | "end": { | 1843 | "end": { |
1592 | "column": 3, | 1844 | "column": 3, |
1593 | "line": 45 | 1845 | "line": 47 |
1594 | }, | 1846 | }, |
1595 | "file": "src/components/settings/services/EditServiceForm.js", | 1847 | "file": "src/components/settings/services/EditServiceForm.js", |
1596 | "id": "settings.service.form.editServiceHeadline", | 1848 | "id": "settings.service.form.editServiceHeadline", |
1597 | "start": { | 1849 | "start": { |
1598 | "column": 23, | 1850 | "column": 23, |
1599 | "line": 42 | 1851 | "line": 44 |
1600 | } | 1852 | } |
1601 | }, | 1853 | }, |
1602 | { | 1854 | { |
1603 | "defaultMessage": "!!!Hosted", | 1855 | "defaultMessage": "!!!Hosted", |
1604 | "end": { | 1856 | "end": { |
1605 | "column": 3, | 1857 | "column": 3, |
1606 | "line": 49 | 1858 | "line": 51 |
1607 | }, | 1859 | }, |
1608 | "file": "src/components/settings/services/EditServiceForm.js", | 1860 | "file": "src/components/settings/services/EditServiceForm.js", |
1609 | "id": "settings.service.form.tabHosted", | 1861 | "id": "settings.service.form.tabHosted", |
1610 | "start": { | 1862 | "start": { |
1611 | "column": 13, | 1863 | "column": 13, |
1612 | "line": 46 | 1864 | "line": 48 |
1613 | } | 1865 | } |
1614 | }, | 1866 | }, |
1615 | { | 1867 | { |
1616 | "defaultMessage": "!!!Self hosted ⭐️", | 1868 | "defaultMessage": "!!!Self hosted ⭐️", |
1617 | "end": { | 1869 | "end": { |
1618 | "column": 3, | 1870 | "column": 3, |
1619 | "line": 53 | 1871 | "line": 55 |
1620 | }, | 1872 | }, |
1621 | "file": "src/components/settings/services/EditServiceForm.js", | 1873 | "file": "src/components/settings/services/EditServiceForm.js", |
1622 | "id": "settings.service.form.tabOnPremise", | 1874 | "id": "settings.service.form.tabOnPremise", |
1623 | "start": { | 1875 | "start": { |
1624 | "column": 16, | 1876 | "column": 16, |
1625 | "line": 50 | 1877 | "line": 52 |
1626 | } | 1878 | } |
1627 | }, | 1879 | }, |
1628 | { | 1880 | { |
1629 | "defaultMessage": "!!!Use the hosted {name} service.", | 1881 | "defaultMessage": "!!!Use the hosted {name} service.", |
1630 | "end": { | 1882 | "end": { |
1631 | "column": 3, | 1883 | "column": 3, |
1632 | "line": 57 | 1884 | "line": 59 |
1633 | }, | 1885 | }, |
1634 | "file": "src/components/settings/services/EditServiceForm.js", | 1886 | "file": "src/components/settings/services/EditServiceForm.js", |
1635 | "id": "settings.service.form.useHostedService", | 1887 | "id": "settings.service.form.useHostedService", |
1636 | "start": { | 1888 | "start": { |
1637 | "column": 20, | 1889 | "column": 20, |
1638 | "line": 54 | 1890 | "line": 56 |
1639 | } | 1891 | } |
1640 | }, | 1892 | }, |
1641 | { | 1893 | { |
1642 | "defaultMessage": "!!!Could not validate custom {name} server.", | 1894 | "defaultMessage": "!!!Could not validate custom {name} server.", |
1643 | "end": { | 1895 | "end": { |
1644 | "column": 3, | 1896 | "column": 3, |
1645 | "line": 61 | 1897 | "line": 63 |
1646 | }, | 1898 | }, |
1647 | "file": "src/components/settings/services/EditServiceForm.js", | 1899 | "file": "src/components/settings/services/EditServiceForm.js", |
1648 | "id": "settings.service.form.customUrlValidationError", | 1900 | "id": "settings.service.form.customUrlValidationError", |
1649 | "start": { | 1901 | "start": { |
1650 | "column": 28, | 1902 | "column": 28, |
1651 | "line": 58 | 1903 | "line": 60 |
1652 | } | 1904 | } |
1653 | }, | 1905 | }, |
1654 | { | 1906 | { |
1655 | "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", | 1907 | "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", |
1656 | "end": { | 1908 | "end": { |
1657 | "column": 3, | 1909 | "column": 3, |
1658 | "line": 65 | 1910 | "line": 67 |
1659 | }, | 1911 | }, |
1660 | "file": "src/components/settings/services/EditServiceForm.js", | 1912 | "file": "src/components/settings/services/EditServiceForm.js", |
1661 | "id": "settings.service.form.customUrlPremiumInfo", | 1913 | "id": "settings.service.form.customUrlPremiumInfo", |
1662 | "start": { | 1914 | "start": { |
1663 | "column": 24, | 1915 | "column": 24, |
1664 | "line": 62 | 1916 | "line": 64 |
1665 | } | 1917 | } |
1666 | }, | 1918 | }, |
1667 | { | 1919 | { |
1668 | "defaultMessage": "!!!Upgrade your account", | 1920 | "defaultMessage": "!!!Upgrade your account", |
1669 | "end": { | 1921 | "end": { |
1670 | "column": 3, | 1922 | "column": 3, |
1671 | "line": 69 | 1923 | "line": 71 |
1672 | }, | 1924 | }, |
1673 | "file": "src/components/settings/services/EditServiceForm.js", | 1925 | "file": "src/components/settings/services/EditServiceForm.js", |
1674 | "id": "settings.service.form.customUrlUpgradeAccount", | 1926 | "id": "settings.service.form.customUrlUpgradeAccount", |
1675 | "start": { | 1927 | "start": { |
1676 | "column": 27, | 1928 | "column": 27, |
1677 | "line": 66 | 1929 | "line": 68 |
1678 | } | 1930 | } |
1679 | }, | 1931 | }, |
1680 | { | 1932 | { |
1681 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", | 1933 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", |
1682 | "end": { | 1934 | "end": { |
1683 | "column": 3, | 1935 | "column": 3, |
1684 | "line": 73 | 1936 | "line": 75 |
1685 | }, | 1937 | }, |
1686 | "file": "src/components/settings/services/EditServiceForm.js", | 1938 | "file": "src/components/settings/services/EditServiceForm.js", |
1687 | "id": "settings.service.form.indirectMessageInfo", | 1939 | "id": "settings.service.form.indirectMessageInfo", |
1688 | "start": { | 1940 | "start": { |
1689 | "column": 23, | 1941 | "column": 23, |
1690 | "line": 70 | 1942 | "line": 72 |
1691 | } | 1943 | } |
1692 | }, | 1944 | }, |
1693 | { | 1945 | { |
1694 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", | 1946 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", |
1695 | "end": { | 1947 | "end": { |
1696 | "column": 3, | 1948 | "column": 3, |
1697 | "line": 77 | 1949 | "line": 79 |
1698 | }, | 1950 | }, |
1699 | "file": "src/components/settings/services/EditServiceForm.js", | 1951 | "file": "src/components/settings/services/EditServiceForm.js", |
1700 | "id": "settings.service.form.isMutedInfo", | 1952 | "id": "settings.service.form.isMutedInfo", |
1701 | "start": { | 1953 | "start": { |
1702 | "column": 15, | 1954 | "column": 15, |
1703 | "line": 74 | 1955 | "line": 76 |
1704 | } | 1956 | } |
1705 | }, | 1957 | }, |
1706 | { | 1958 | { |
1707 | "defaultMessage": "!!!Notifications", | 1959 | "defaultMessage": "!!!Notifications", |
1708 | "end": { | 1960 | "end": { |
1709 | "column": 3, | 1961 | "column": 3, |
1710 | "line": 81 | 1962 | "line": 83 |
1711 | }, | 1963 | }, |
1712 | "file": "src/components/settings/services/EditServiceForm.js", | 1964 | "file": "src/components/settings/services/EditServiceForm.js", |
1713 | "id": "settings.service.form.headlineNotifications", | 1965 | "id": "settings.service.form.headlineNotifications", |
1714 | "start": { | 1966 | "start": { |
1715 | "column": 25, | 1967 | "column": 25, |
1716 | "line": 78 | 1968 | "line": 80 |
1717 | } | 1969 | } |
1718 | }, | 1970 | }, |
1719 | { | 1971 | { |
1720 | "defaultMessage": "!!!Unread message badges", | 1972 | "defaultMessage": "!!!Unread message badges", |
1721 | "end": { | 1973 | "end": { |
1722 | "column": 3, | 1974 | "column": 3, |
1723 | "line": 85 | 1975 | "line": 87 |
1724 | }, | 1976 | }, |
1725 | "file": "src/components/settings/services/EditServiceForm.js", | 1977 | "file": "src/components/settings/services/EditServiceForm.js", |
1726 | "id": "settings.service.form.headlineBadges", | 1978 | "id": "settings.service.form.headlineBadges", |
1727 | "start": { | 1979 | "start": { |
1728 | "column": 18, | 1980 | "column": 18, |
1729 | "line": 82 | 1981 | "line": 84 |
1730 | } | 1982 | } |
1731 | }, | 1983 | }, |
1732 | { | 1984 | { |
1733 | "defaultMessage": "!!!General", | 1985 | "defaultMessage": "!!!General", |
1734 | "end": { | 1986 | "end": { |
1735 | "column": 3, | 1987 | "column": 3, |
1736 | "line": 89 | 1988 | "line": 91 |
1737 | }, | 1989 | }, |
1738 | "file": "src/components/settings/services/EditServiceForm.js", | 1990 | "file": "src/components/settings/services/EditServiceForm.js", |
1739 | "id": "settings.service.form.headlineGeneral", | 1991 | "id": "settings.service.form.headlineGeneral", |
1740 | "start": { | 1992 | "start": { |
1741 | "column": 19, | 1993 | "column": 19, |
1742 | "line": 86 | 1994 | "line": 88 |
1743 | } | 1995 | } |
1744 | }, | 1996 | }, |
1745 | { | 1997 | { |
1746 | "defaultMessage": "!!!Delete", | 1998 | "defaultMessage": "!!!Delete", |
1747 | "end": { | 1999 | "end": { |
1748 | "column": 3, | 2000 | "column": 3, |
1749 | "line": 93 | 2001 | "line": 95 |
1750 | }, | 2002 | }, |
1751 | "file": "src/components/settings/services/EditServiceForm.js", | 2003 | "file": "src/components/settings/services/EditServiceForm.js", |
1752 | "id": "settings.service.form.iconDelete", | 2004 | "id": "settings.service.form.iconDelete", |
1753 | "start": { | 2005 | "start": { |
1754 | "column": 14, | 2006 | "column": 14, |
1755 | "line": 90 | 2007 | "line": 92 |
1756 | } | 2008 | } |
1757 | }, | 2009 | }, |
1758 | { | 2010 | { |
1759 | "defaultMessage": "!!!Drop your image, or click here", | 2011 | "defaultMessage": "!!!Drop your image, or click here", |
1760 | "end": { | 2012 | "end": { |
1761 | "column": 3, | 2013 | "column": 3, |
1762 | "line": 97 | 2014 | "line": 99 |
1763 | }, | 2015 | }, |
1764 | "file": "src/components/settings/services/EditServiceForm.js", | 2016 | "file": "src/components/settings/services/EditServiceForm.js", |
1765 | "id": "settings.service.form.iconUpload", | 2017 | "id": "settings.service.form.iconUpload", |
1766 | "start": { | 2018 | "start": { |
1767 | "column": 14, | 2019 | "column": 14, |
1768 | "line": 94 | 2020 | "line": 96 |
1769 | } | 2021 | } |
1770 | }, | 2022 | }, |
1771 | { | 2023 | { |
1772 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", | 2024 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", |
1773 | "end": { | 2025 | "end": { |
1774 | "column": 3, | 2026 | "column": 3, |
1775 | "line": 101 | 2027 | "line": 103 |
1776 | }, | 2028 | }, |
1777 | "file": "src/components/settings/services/EditServiceForm.js", | 2029 | "file": "src/components/settings/services/EditServiceForm.js", |
1778 | "id": "settings.service.form.proxy.headline", | 2030 | "id": "settings.service.form.proxy.headline", |
1779 | "start": { | 2031 | "start": { |
1780 | "column": 17, | 2032 | "column": 17, |
1781 | "line": 98 | 2033 | "line": 100 |
1782 | } | 2034 | } |
1783 | }, | 2035 | }, |
1784 | { | 2036 | { |
1785 | "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", | 2037 | "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", |
1786 | "end": { | 2038 | "end": { |
1787 | "column": 3, | 2039 | "column": 3, |
1788 | "line": 105 | 2040 | "line": 107 |
1789 | }, | 2041 | }, |
1790 | "file": "src/components/settings/services/EditServiceForm.js", | 2042 | "file": "src/components/settings/services/EditServiceForm.js", |
1791 | "id": "settings.service.form.proxy.restartInfo", | 2043 | "id": "settings.service.form.proxy.restartInfo", |
1792 | "start": { | 2044 | "start": { |
1793 | "column": 20, | 2045 | "column": 20, |
1794 | "line": 102 | 2046 | "line": 104 |
1795 | } | 2047 | } |
1796 | }, | 2048 | }, |
1797 | { | 2049 | { |
1798 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", | 2050 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", |
1799 | "end": { | 2051 | "end": { |
1800 | "column": 3, | 2052 | "column": 3, |
1801 | "line": 109 | 2053 | "line": 111 |
1802 | }, | 2054 | }, |
1803 | "file": "src/components/settings/services/EditServiceForm.js", | 2055 | "file": "src/components/settings/services/EditServiceForm.js", |
1804 | "id": "settings.service.form.proxy.info", | 2056 | "id": "settings.service.form.proxy.info", |
1805 | "start": { | 2057 | "start": { |
1806 | "column": 13, | 2058 | "column": 13, |
1807 | "line": 106 | 2059 | "line": 108 |
1808 | } | 2060 | } |
1809 | } | 2061 | } |
1810 | ], | 2062 | ], |
@@ -1917,117 +2169,117 @@ | |||
1917 | "defaultMessage": "!!!Your services", | 2169 | "defaultMessage": "!!!Your services", |
1918 | "end": { | 2170 | "end": { |
1919 | "column": 3, | 2171 | "column": 3, |
1920 | "line": 17 | 2172 | "line": 18 |
1921 | }, | 2173 | }, |
1922 | "file": "src/components/settings/services/ServicesDashboard.js", | 2174 | "file": "src/components/settings/services/ServicesDashboard.js", |
1923 | "id": "settings.services.headline", | 2175 | "id": "settings.services.headline", |
1924 | "start": { | 2176 | "start": { |
1925 | "column": 12, | 2177 | "column": 12, |
1926 | "line": 14 | 2178 | "line": 15 |
1927 | } | 2179 | } |
1928 | }, | 2180 | }, |
1929 | { | 2181 | { |
1930 | "defaultMessage": "!!!Search service", | 2182 | "defaultMessage": "!!!Search service", |
1931 | "end": { | 2183 | "end": { |
1932 | "column": 3, | 2184 | "column": 3, |
1933 | "line": 21 | 2185 | "line": 22 |
1934 | }, | 2186 | }, |
1935 | "file": "src/components/settings/services/ServicesDashboard.js", | 2187 | "file": "src/components/settings/services/ServicesDashboard.js", |
1936 | "id": "settings.searchService", | 2188 | "id": "settings.searchService", |
1937 | "start": { | 2189 | "start": { |
1938 | "column": 17, | 2190 | "column": 17, |
1939 | "line": 18 | 2191 | "line": 19 |
1940 | } | 2192 | } |
1941 | }, | 2193 | }, |
1942 | { | 2194 | { |
1943 | "defaultMessage": "!!!You haven't added any services yet.", | 2195 | "defaultMessage": "!!!You haven't added any services yet.", |
1944 | "end": { | 2196 | "end": { |
1945 | "column": 3, | 2197 | "column": 3, |
1946 | "line": 25 | 2198 | "line": 26 |
1947 | }, | 2199 | }, |
1948 | "file": "src/components/settings/services/ServicesDashboard.js", | 2200 | "file": "src/components/settings/services/ServicesDashboard.js", |
1949 | "id": "settings.services.noServicesAdded", | 2201 | "id": "settings.services.noServicesAdded", |
1950 | "start": { | 2202 | "start": { |
1951 | "column": 19, | 2203 | "column": 19, |
1952 | "line": 22 | 2204 | "line": 23 |
1953 | } | 2205 | } |
1954 | }, | 2206 | }, |
1955 | { | 2207 | { |
1956 | "defaultMessage": "!!!Sorry, but no service matched your search term.", | 2208 | "defaultMessage": "!!!Sorry, but no service matched your search term.", |
1957 | "end": { | 2209 | "end": { |
1958 | "column": 3, | 2210 | "column": 3, |
1959 | "line": 29 | 2211 | "line": 30 |
1960 | }, | 2212 | }, |
1961 | "file": "src/components/settings/services/ServicesDashboard.js", | 2213 | "file": "src/components/settings/services/ServicesDashboard.js", |
1962 | "id": "settings.recipes.nothingFound", | 2214 | "id": "settings.recipes.nothingFound", |
1963 | "start": { | 2215 | "start": { |
1964 | "column": 18, | 2216 | "column": 18, |
1965 | "line": 26 | 2217 | "line": 27 |
1966 | } | 2218 | } |
1967 | }, | 2219 | }, |
1968 | { | 2220 | { |
1969 | "defaultMessage": "!!!Discover services", | 2221 | "defaultMessage": "!!!Discover services", |
1970 | "end": { | 2222 | "end": { |
1971 | "column": 3, | 2223 | "column": 3, |
1972 | "line": 33 | 2224 | "line": 34 |
1973 | }, | 2225 | }, |
1974 | "file": "src/components/settings/services/ServicesDashboard.js", | 2226 | "file": "src/components/settings/services/ServicesDashboard.js", |
1975 | "id": "settings.services.discoverServices", | 2227 | "id": "settings.services.discoverServices", |
1976 | "start": { | 2228 | "start": { |
1977 | "column": 20, | 2229 | "column": 20, |
1978 | "line": 30 | 2230 | "line": 31 |
1979 | } | 2231 | } |
1980 | }, | 2232 | }, |
1981 | { | 2233 | { |
1982 | "defaultMessage": "!!!Could not load your services", | 2234 | "defaultMessage": "!!!Could not load your services", |
1983 | "end": { | 2235 | "end": { |
1984 | "column": 3, | 2236 | "column": 3, |
1985 | "line": 37 | 2237 | "line": 38 |
1986 | }, | 2238 | }, |
1987 | "file": "src/components/settings/services/ServicesDashboard.js", | 2239 | "file": "src/components/settings/services/ServicesDashboard.js", |
1988 | "id": "settings.services.servicesRequestFailed", | 2240 | "id": "settings.services.servicesRequestFailed", |
1989 | "start": { | 2241 | "start": { |
1990 | "column": 25, | 2242 | "column": 25, |
1991 | "line": 34 | 2243 | "line": 35 |
1992 | } | 2244 | } |
1993 | }, | 2245 | }, |
1994 | { | 2246 | { |
1995 | "defaultMessage": "!!!Try again", | 2247 | "defaultMessage": "!!!Try again", |
1996 | "end": { | 2248 | "end": { |
1997 | "column": 3, | 2249 | "column": 3, |
1998 | "line": 41 | 2250 | "line": 42 |
1999 | }, | 2251 | }, |
2000 | "file": "src/components/settings/services/ServicesDashboard.js", | 2252 | "file": "src/components/settings/services/ServicesDashboard.js", |
2001 | "id": "settings.account.tryReloadServices", | 2253 | "id": "settings.account.tryReloadServices", |
2002 | "start": { | 2254 | "start": { |
2003 | "column": 21, | 2255 | "column": 21, |
2004 | "line": 38 | 2256 | "line": 39 |
2005 | } | 2257 | } |
2006 | }, | 2258 | }, |
2007 | { | 2259 | { |
2008 | "defaultMessage": "!!!Your changes have been saved", | 2260 | "defaultMessage": "!!!Your changes have been saved", |
2009 | "end": { | 2261 | "end": { |
2010 | "column": 3, | 2262 | "column": 3, |
2011 | "line": 45 | 2263 | "line": 46 |
2012 | }, | 2264 | }, |
2013 | "file": "src/components/settings/services/ServicesDashboard.js", | 2265 | "file": "src/components/settings/services/ServicesDashboard.js", |
2014 | "id": "settings.services.updatedInfo", | 2266 | "id": "settings.services.updatedInfo", |
2015 | "start": { | 2267 | "start": { |
2016 | "column": 15, | 2268 | "column": 15, |
2017 | "line": 42 | 2269 | "line": 43 |
2018 | } | 2270 | } |
2019 | }, | 2271 | }, |
2020 | { | 2272 | { |
2021 | "defaultMessage": "!!!Service has been deleted", | 2273 | "defaultMessage": "!!!Service has been deleted", |
2022 | "end": { | 2274 | "end": { |
2023 | "column": 3, | 2275 | "column": 3, |
2024 | "line": 49 | 2276 | "line": 50 |
2025 | }, | 2277 | }, |
2026 | "file": "src/components/settings/services/ServicesDashboard.js", | 2278 | "file": "src/components/settings/services/ServicesDashboard.js", |
2027 | "id": "settings.services.deletedInfo", | 2279 | "id": "settings.services.deletedInfo", |
2028 | "start": { | 2280 | "start": { |
2029 | "column": 15, | 2281 | "column": 15, |
2030 | "line": 46 | 2282 | "line": 47 |
2031 | } | 2283 | } |
2032 | } | 2284 | } |
2033 | ], | 2285 | ], |
@@ -2441,220 +2693,396 @@ | |||
2441 | { | 2693 | { |
2442 | "descriptors": [ | 2694 | "descriptors": [ |
2443 | { | 2695 | { |
2444 | "defaultMessage": "!!!Support the development of Franz", | 2696 | "defaultMessage": "!!!Choose your plan", |
2697 | "end": { | ||
2698 | "column": 3, | ||
2699 | "line": 16 | ||
2700 | }, | ||
2701 | "file": "src/components/subscription/SubscriptionForm.js", | ||
2702 | "id": "subscription.cta.choosePlan", | ||
2703 | "start": { | ||
2704 | "column": 21, | ||
2705 | "line": 13 | ||
2706 | } | ||
2707 | }, | ||
2708 | { | ||
2709 | "defaultMessage": "!!!Upgrade your account and get the full Franz experience", | ||
2445 | "end": { | 2710 | "end": { |
2446 | "column": 3, | 2711 | "column": 3, |
2712 | "line": 20 | ||
2713 | }, | ||
2714 | "file": "src/components/subscription/SubscriptionForm.js", | ||
2715 | "id": "settings.account.headlineUpgradeAccount", | ||
2716 | "start": { | ||
2717 | "column": 18, | ||
2447 | "line": 17 | 2718 | "line": 17 |
2719 | } | ||
2720 | }, | ||
2721 | { | ||
2722 | "defaultMessage": "!!!Franz 5 comes with a wide range of new features to boost up your everyday communication - batteries included. Check out our new plans and find out which one suits you most!", | ||
2723 | "end": { | ||
2724 | "column": 3, | ||
2725 | "line": 24 | ||
2726 | }, | ||
2727 | "file": "src/components/subscription/SubscriptionForm.js", | ||
2728 | "id": "subscription.teaser.intro", | ||
2729 | "start": { | ||
2730 | "column": 14, | ||
2731 | "line": 21 | ||
2732 | } | ||
2733 | }, | ||
2734 | { | ||
2735 | "defaultMessage": "!!!Paid Franz Plans include:", | ||
2736 | "end": { | ||
2737 | "column": 3, | ||
2738 | "line": 28 | ||
2448 | }, | 2739 | }, |
2449 | "file": "src/components/subscription/SubscriptionForm.js", | 2740 | "file": "src/components/subscription/SubscriptionForm.js", |
2450 | "id": "subscription.submit.label", | 2741 | "id": "subscription.teaser.includedFeatures", |
2742 | "start": { | ||
2743 | "column": 20, | ||
2744 | "line": 25 | ||
2745 | } | ||
2746 | } | ||
2747 | ], | ||
2748 | "path": "src/components/subscription/SubscriptionForm.json" | ||
2749 | }, | ||
2750 | { | ||
2751 | "descriptors": [ | ||
2752 | { | ||
2753 | "defaultMessage": "!!!Cancel", | ||
2754 | "end": { | ||
2755 | "column": 3, | ||
2756 | "line": 14 | ||
2757 | }, | ||
2758 | "file": "src/components/subscription/SubscriptionPopup.js", | ||
2759 | "id": "subscriptionPopup.buttonCancel", | ||
2760 | "start": { | ||
2761 | "column": 16, | ||
2762 | "line": 11 | ||
2763 | } | ||
2764 | }, | ||
2765 | { | ||
2766 | "defaultMessage": "!!!Done", | ||
2767 | "end": { | ||
2768 | "column": 3, | ||
2769 | "line": 18 | ||
2770 | }, | ||
2771 | "file": "src/components/subscription/SubscriptionPopup.js", | ||
2772 | "id": "subscriptionPopup.buttonDone", | ||
2773 | "start": { | ||
2774 | "column": 14, | ||
2775 | "line": 15 | ||
2776 | } | ||
2777 | } | ||
2778 | ], | ||
2779 | "path": "src/components/subscription/SubscriptionPopup.json" | ||
2780 | }, | ||
2781 | { | ||
2782 | "descriptors": [ | ||
2783 | { | ||
2784 | "defaultMessage": "!!!Yes, start the free Franz Professional trial", | ||
2785 | "end": { | ||
2786 | "column": 3, | ||
2787 | "line": 17 | ||
2788 | }, | ||
2789 | "file": "src/components/subscription/TrialForm.js", | ||
2790 | "id": "subscription.cta.activateTrial", | ||
2451 | "start": { | 2791 | "start": { |
2452 | "column": 21, | 2792 | "column": 21, |
2453 | "line": 14 | 2793 | "line": 14 |
2454 | } | 2794 | } |
2455 | }, | 2795 | }, |
2456 | { | 2796 | { |
2457 | "defaultMessage": "!!!Could not initialize payment form", | 2797 | "defaultMessage": "!!!See all options", |
2458 | "end": { | 2798 | "end": { |
2459 | "column": 3, | 2799 | "column": 3, |
2460 | "line": 21 | 2800 | "line": 21 |
2461 | }, | 2801 | }, |
2462 | "file": "src/components/subscription/SubscriptionForm.js", | 2802 | "file": "src/components/subscription/TrialForm.js", |
2463 | "id": "subscription.paymentSessionError", | 2803 | "id": "subscription.cta.allOptions", |
2464 | "start": { | 2804 | "start": { |
2465 | "column": 23, | 2805 | "column": 20, |
2466 | "line": 18 | 2806 | "line": 18 |
2467 | } | 2807 | } |
2468 | }, | 2808 | }, |
2469 | { | 2809 | { |
2470 | "defaultMessage": "!!!free", | 2810 | "defaultMessage": "!!!Get the free 14 day Franz Professional Trial", |
2471 | "end": { | 2811 | "end": { |
2472 | "column": 3, | 2812 | "column": 3, |
2473 | "line": 25 | 2813 | "line": 25 |
2474 | }, | 2814 | }, |
2475 | "file": "src/components/subscription/SubscriptionForm.js", | 2815 | "file": "src/components/subscription/TrialForm.js", |
2476 | "id": "subscription.type.free", | 2816 | "id": "settings.account.headlineTrialUpgrade", |
2477 | "start": { | 2817 | "start": { |
2478 | "column": 12, | 2818 | "column": 18, |
2479 | "line": 22 | 2819 | "line": 22 |
2480 | } | 2820 | } |
2481 | }, | 2821 | }, |
2482 | { | 2822 | { |
2483 | "defaultMessage": "!!!month", | 2823 | "defaultMessage": "!!!The Franz Professional Plan includes:", |
2484 | "end": { | 2824 | "end": { |
2485 | "column": 3, | 2825 | "column": 3, |
2486 | "line": 29 | 2826 | "line": 29 |
2487 | }, | 2827 | }, |
2488 | "file": "src/components/subscription/SubscriptionForm.js", | 2828 | "file": "src/components/subscription/TrialForm.js", |
2489 | "id": "subscription.type.month", | 2829 | "id": "subscription.includedProFeatures", |
2490 | "start": { | 2830 | "start": { |
2491 | "column": 15, | 2831 | "column": 20, |
2492 | "line": 26 | 2832 | "line": 26 |
2493 | } | 2833 | } |
2494 | }, | 2834 | }, |
2495 | { | 2835 | { |
2496 | "defaultMessage": "!!!year", | 2836 | "defaultMessage": "!!!No strings attached", |
2497 | "end": { | 2837 | "end": { |
2498 | "column": 3, | 2838 | "column": 3, |
2499 | "line": 33 | 2839 | "line": 33 |
2500 | }, | 2840 | }, |
2501 | "file": "src/components/subscription/SubscriptionForm.js", | 2841 | "file": "src/components/subscription/TrialForm.js", |
2502 | "id": "subscription.type.year", | 2842 | "id": "pricing.trial.terms.headline", |
2503 | "start": { | 2843 | "start": { |
2504 | "column": 14, | 2844 | "column": 29, |
2505 | "line": 30 | 2845 | "line": 30 |
2506 | } | 2846 | } |
2507 | }, | 2847 | }, |
2508 | { | 2848 | { |
2509 | "defaultMessage": "!!!The Franz Premium Supporter Account includes", | 2849 | "defaultMessage": "!!!No credit card required", |
2510 | "end": { | 2850 | "end": { |
2511 | "column": 3, | 2851 | "column": 3, |
2512 | "line": 37 | 2852 | "line": 37 |
2513 | }, | 2853 | }, |
2514 | "file": "src/components/subscription/SubscriptionForm.js", | 2854 | "file": "src/components/subscription/TrialForm.js", |
2515 | "id": "subscription.includedFeatures", | 2855 | "id": "pricing.trial.terms.noCreditCard", |
2516 | "start": { | 2856 | "start": { |
2517 | "column": 20, | 2857 | "column": 16, |
2518 | "line": 34 | 2858 | "line": 34 |
2519 | } | 2859 | } |
2520 | }, | 2860 | }, |
2521 | { | 2861 | { |
2522 | "defaultMessage": "!!!Add on-premise/hosted services like Mattermost", | 2862 | "defaultMessage": "!!!Your free trial ends automatically after 14 days", |
2523 | "end": { | 2863 | "end": { |
2524 | "column": 3, | 2864 | "column": 3, |
2525 | "line": 41 | 2865 | "line": 41 |
2526 | }, | 2866 | }, |
2527 | "file": "src/components/subscription/SubscriptionForm.js", | 2867 | "file": "src/components/subscription/TrialForm.js", |
2528 | "id": "subscription.features.onpremise.mattermost", | 2868 | "id": "pricing.trial.terms.automaticTrialEnd", |
2529 | "start": { | 2869 | "start": { |
2530 | "column": 13, | 2870 | "column": 21, |
2531 | "line": 38 | 2871 | "line": 38 |
2532 | } | 2872 | } |
2873 | } | ||
2874 | ], | ||
2875 | "path": "src/components/subscription/TrialForm.json" | ||
2876 | }, | ||
2877 | { | ||
2878 | "descriptors": [ | ||
2879 | { | ||
2880 | "defaultMessage": "!!!Your trial was successfully activated. Happy messaging!", | ||
2881 | "end": { | ||
2882 | "column": 3, | ||
2883 | "line": 14 | ||
2884 | }, | ||
2885 | "file": "src/components/TrialActivationInfoBar.js", | ||
2886 | "id": "infobar.trialActivated", | ||
2887 | "start": { | ||
2888 | "column": 11, | ||
2889 | "line": 11 | ||
2890 | } | ||
2891 | } | ||
2892 | ], | ||
2893 | "path": "src/components/TrialActivationInfoBar.json" | ||
2894 | }, | ||
2895 | { | ||
2896 | "descriptors": [ | ||
2897 | { | ||
2898 | "defaultMessage": "!!!Get a Franz Supporter License", | ||
2899 | "end": { | ||
2900 | "column": 3, | ||
2901 | "line": 16 | ||
2902 | }, | ||
2903 | "file": "src/components/ui/ActivateTrialButton/index.js", | ||
2904 | "id": "feature.delayApp.upgrade.action", | ||
2905 | "start": { | ||
2906 | "column": 10, | ||
2907 | "line": 13 | ||
2908 | } | ||
2533 | }, | 2909 | }, |
2534 | { | 2910 | { |
2535 | "defaultMessage": "!!!No app delays & nagging to upgrade license", | 2911 | "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", |
2536 | "end": { | 2912 | "end": { |
2537 | "column": 3, | 2913 | "column": 3, |
2538 | "line": 45 | 2914 | "line": 20 |
2539 | }, | 2915 | }, |
2540 | "file": "src/components/subscription/SubscriptionForm.js", | 2916 | "file": "src/components/ui/ActivateTrialButton/index.js", |
2541 | "id": "subscription.features.noInterruptions", | 2917 | "id": "feature.delayApp.trial.action", |
2542 | "start": { | 2918 | "start": { |
2543 | "column": 19, | 2919 | "column": 15, |
2544 | "line": 42 | 2920 | "line": 17 |
2545 | } | 2921 | } |
2546 | }, | 2922 | }, |
2547 | { | 2923 | { |
2548 | "defaultMessage": "!!!Proxy support for services", | 2924 | "defaultMessage": "!!!Upgrade account", |
2549 | "end": { | 2925 | "end": { |
2550 | "column": 3, | 2926 | "column": 3, |
2551 | "line": 49 | 2927 | "line": 24 |
2552 | }, | 2928 | }, |
2553 | "file": "src/components/subscription/SubscriptionForm.js", | 2929 | "file": "src/components/ui/ActivateTrialButton/index.js", |
2554 | "id": "subscription.features.proxy", | 2930 | "id": "feature.delayApp.upgrade.actionShort", |
2555 | "start": { | 2931 | "start": { |
2556 | "column": 9, | 2932 | "column": 15, |
2557 | "line": 46 | 2933 | "line": 21 |
2558 | } | 2934 | } |
2559 | }, | 2935 | }, |
2560 | { | 2936 | { |
2561 | "defaultMessage": "!!!Support for Spellchecker", | 2937 | "defaultMessage": "!!!Activate the free Franz Professional trial", |
2562 | "end": { | 2938 | "end": { |
2563 | "column": 3, | 2939 | "column": 3, |
2564 | "line": 53 | 2940 | "line": 28 |
2565 | }, | 2941 | }, |
2566 | "file": "src/components/subscription/SubscriptionForm.js", | 2942 | "file": "src/components/ui/ActivateTrialButton/index.js", |
2567 | "id": "subscription.features.spellchecker", | 2943 | "id": "feature.delayApp.trial.actionShort", |
2944 | "start": { | ||
2945 | "column": 20, | ||
2946 | "line": 25 | ||
2947 | } | ||
2948 | } | ||
2949 | ], | ||
2950 | "path": "src/components/ui/ActivateTrialButton/index.json" | ||
2951 | }, | ||
2952 | { | ||
2953 | "descriptors": [ | ||
2954 | { | ||
2955 | "defaultMessage": "!!!Add unlimited services", | ||
2956 | "end": { | ||
2957 | "column": 3, | ||
2958 | "line": 11 | ||
2959 | }, | ||
2960 | "file": "src/components/ui/FeatureList.js", | ||
2961 | "id": "pricing.features.unlimitedServices", | ||
2962 | "start": { | ||
2963 | "column": 21, | ||
2964 | "line": 8 | ||
2965 | } | ||
2966 | }, | ||
2967 | { | ||
2968 | "defaultMessage": "!!!Spellchecker support", | ||
2969 | "end": { | ||
2970 | "column": 3, | ||
2971 | "line": 15 | ||
2972 | }, | ||
2973 | "file": "src/components/ui/FeatureList.js", | ||
2974 | "id": "pricing.features.spellchecker", | ||
2568 | "start": { | 2975 | "start": { |
2569 | "column": 16, | 2976 | "column": 16, |
2570 | "line": 50 | 2977 | "line": 12 |
2571 | } | 2978 | } |
2572 | }, | 2979 | }, |
2573 | { | 2980 | { |
2574 | "defaultMessage": "!!!Organize your services in workspaces", | 2981 | "defaultMessage": "!!!Workspaces", |
2575 | "end": { | 2982 | "end": { |
2576 | "column": 3, | 2983 | "column": 3, |
2577 | "line": 57 | 2984 | "line": 19 |
2578 | }, | 2985 | }, |
2579 | "file": "src/components/subscription/SubscriptionForm.js", | 2986 | "file": "src/components/ui/FeatureList.js", |
2580 | "id": "subscription.features.workspaces", | 2987 | "id": "pricing.features.workspaces", |
2581 | "start": { | 2988 | "start": { |
2582 | "column": 14, | 2989 | "column": 14, |
2583 | "line": 54 | 2990 | "line": 16 |
2584 | } | 2991 | } |
2585 | }, | 2992 | }, |
2586 | { | 2993 | { |
2587 | "defaultMessage": "!!!No ads, ever!", | 2994 | "defaultMessage": "!!!Add Custom Websites", |
2588 | "end": { | 2995 | "end": { |
2589 | "column": 3, | 2996 | "column": 3, |
2590 | "line": 61 | 2997 | "line": 23 |
2591 | }, | 2998 | }, |
2592 | "file": "src/components/subscription/SubscriptionForm.js", | 2999 | "file": "src/components/ui/FeatureList.js", |
2593 | "id": "subscription.features.ads", | 3000 | "id": "pricing.features.customWebsites", |
2594 | "start": { | 3001 | "start": { |
2595 | "column": 7, | 3002 | "column": 18, |
2596 | "line": 58 | 3003 | "line": 20 |
2597 | } | 3004 | } |
2598 | }, | 3005 | }, |
2599 | { | 3006 | { |
2600 | "defaultMessage": "!!!coming soon", | 3007 | "defaultMessage": "!!!On-premise & other Hosted Services", |
2601 | "end": { | 3008 | "end": { |
2602 | "column": 3, | 3009 | "column": 3, |
2603 | "line": 65 | 3010 | "line": 27 |
2604 | }, | 3011 | }, |
2605 | "file": "src/components/subscription/SubscriptionForm.js", | 3012 | "file": "src/components/ui/FeatureList.js", |
2606 | "id": "subscription.features.comingSoon", | 3013 | "id": "pricing.features.onPremise", |
2607 | "start": { | 3014 | "start": { |
2608 | "column": 14, | 3015 | "column": 13, |
2609 | "line": 62 | 3016 | "line": 24 |
2610 | } | 3017 | } |
2611 | }, | 3018 | }, |
2612 | { | 3019 | { |
2613 | "defaultMessage": "!!!EU residents: local sales tax may apply", | 3020 | "defaultMessage": "!!!Install 3rd party services", |
2614 | "end": { | 3021 | "end": { |
2615 | "column": 3, | 3022 | "column": 3, |
2616 | "line": 69 | 3023 | "line": 31 |
2617 | }, | 3024 | }, |
2618 | "file": "src/components/subscription/SubscriptionForm.js", | 3025 | "file": "src/components/ui/FeatureList.js", |
2619 | "id": "subscription.euTaxInfo", | 3026 | "id": "pricing.features.thirdPartyServices", |
2620 | "start": { | 3027 | "start": { |
2621 | "column": 13, | 3028 | "column": 22, |
2622 | "line": 66 | 3029 | "line": 28 |
2623 | } | 3030 | } |
2624 | } | 3031 | }, |
2625 | ], | ||
2626 | "path": "src/components/subscription/SubscriptionForm.json" | ||
2627 | }, | ||
2628 | { | ||
2629 | "descriptors": [ | ||
2630 | { | 3032 | { |
2631 | "defaultMessage": "!!!Cancel", | 3033 | "defaultMessage": "!!!Service Proxies", |
2632 | "end": { | 3034 | "end": { |
2633 | "column": 3, | 3035 | "column": 3, |
2634 | "line": 14 | 3036 | "line": 35 |
2635 | }, | 3037 | }, |
2636 | "file": "src/components/subscription/SubscriptionPopup.js", | 3038 | "file": "src/components/ui/FeatureList.js", |
2637 | "id": "subscriptionPopup.buttonCancel", | 3039 | "id": "pricing.features.serviceProxies", |
2638 | "start": { | 3040 | "start": { |
2639 | "column": 16, | 3041 | "column": 18, |
2640 | "line": 11 | 3042 | "line": 32 |
2641 | } | 3043 | } |
2642 | }, | 3044 | }, |
2643 | { | 3045 | { |
2644 | "defaultMessage": "!!!Done", | 3046 | "defaultMessage": "!!!Team Management", |
2645 | "end": { | 3047 | "end": { |
2646 | "column": 3, | 3048 | "column": 3, |
2647 | "line": 18 | 3049 | "line": 39 |
2648 | }, | 3050 | }, |
2649 | "file": "src/components/subscription/SubscriptionPopup.js", | 3051 | "file": "src/components/ui/FeatureList.js", |
2650 | "id": "subscriptionPopup.buttonDone", | 3052 | "id": "pricing.features.teamManagement", |
2651 | "start": { | 3053 | "start": { |
2652 | "column": 14, | 3054 | "column": 18, |
2653 | "line": 15 | 3055 | "line": 36 |
3056 | } | ||
3057 | }, | ||
3058 | { | ||
3059 | "defaultMessage": "!!!No Waiting Screens", | ||
3060 | "end": { | ||
3061 | "column": 3, | ||
3062 | "line": 43 | ||
3063 | }, | ||
3064 | "file": "src/components/ui/FeatureList.js", | ||
3065 | "id": "pricing.features.appDelays", | ||
3066 | "start": { | ||
3067 | "column": 13, | ||
3068 | "line": 40 | ||
3069 | } | ||
3070 | }, | ||
3071 | { | ||
3072 | "defaultMessage": "!!!Forever ad-free", | ||
3073 | "end": { | ||
3074 | "column": 3, | ||
3075 | "line": 47 | ||
3076 | }, | ||
3077 | "file": "src/components/ui/FeatureList.js", | ||
3078 | "id": "pricing.features.adFree", | ||
3079 | "start": { | ||
3080 | "column": 10, | ||
3081 | "line": 44 | ||
2654 | } | 3082 | } |
2655 | } | 3083 | } |
2656 | ], | 3084 | ], |
2657 | "path": "src/components/subscription/SubscriptionPopup.json" | 3085 | "path": "src/components/ui/FeatureList.json" |
2658 | }, | 3086 | }, |
2659 | { | 3087 | { |
2660 | "descriptors": [ | 3088 | "descriptors": [ |
@@ -2662,13 +3090,13 @@ | |||
2662 | "defaultMessage": "!!!Upgrade account", | 3090 | "defaultMessage": "!!!Upgrade account", |
2663 | "end": { | 3091 | "end": { |
2664 | "column": 3, | 3092 | "column": 3, |
2665 | "line": 18 | 3093 | "line": 19 |
2666 | }, | 3094 | }, |
2667 | "file": "src/components/ui/PremiumFeatureContainer/index.js", | 3095 | "file": "src/components/ui/PremiumFeatureContainer/index.js", |
2668 | "id": "premiumFeature.button.upgradeAccount", | 3096 | "id": "premiumFeature.button.upgradeAccount", |
2669 | "start": { | 3097 | "start": { |
2670 | "column": 10, | 3098 | "column": 10, |
2671 | "line": 15 | 3099 | "line": 16 |
2672 | } | 3100 | } |
2673 | } | 3101 | } |
2674 | ], | 3102 | ], |
@@ -3230,39 +3658,65 @@ | |||
3230 | "defaultMessage": "!!!Please purchase license to skip waiting", | 3658 | "defaultMessage": "!!!Please purchase license to skip waiting", |
3231 | "end": { | 3659 | "end": { |
3232 | "column": 3, | 3660 | "column": 3, |
3233 | "line": 18 | 3661 | "line": 20 |
3234 | }, | 3662 | }, |
3235 | "file": "src/features/delayApp/Component.js", | 3663 | "file": "src/features/delayApp/Component.js", |
3236 | "id": "feature.delayApp.headline", | 3664 | "id": "feature.delayApp.headline", |
3237 | "start": { | 3665 | "start": { |
3238 | "column": 12, | 3666 | "column": 12, |
3239 | "line": 15 | 3667 | "line": 17 |
3668 | } | ||
3669 | }, | ||
3670 | { | ||
3671 | "defaultMessage": "!!!Get the free Franz Professional 14 day trial and skip the line", | ||
3672 | "end": { | ||
3673 | "column": 3, | ||
3674 | "line": 24 | ||
3675 | }, | ||
3676 | "file": "src/features/delayApp/Component.js", | ||
3677 | "id": "feature.delayApp.trial.headline", | ||
3678 | "start": { | ||
3679 | "column": 17, | ||
3680 | "line": 21 | ||
3240 | } | 3681 | } |
3241 | }, | 3682 | }, |
3242 | { | 3683 | { |
3243 | "defaultMessage": "!!!Get a Franz Supporter License", | 3684 | "defaultMessage": "!!!Get a Franz Supporter License", |
3244 | "end": { | 3685 | "end": { |
3245 | "column": 3, | 3686 | "column": 3, |
3246 | "line": 22 | 3687 | "line": 28 |
3247 | }, | 3688 | }, |
3248 | "file": "src/features/delayApp/Component.js", | 3689 | "file": "src/features/delayApp/Component.js", |
3249 | "id": "feature.delayApp.action", | 3690 | "id": "feature.delayApp.upgrade.action", |
3250 | "start": { | 3691 | "start": { |
3251 | "column": 10, | 3692 | "column": 10, |
3252 | "line": 19 | 3693 | "line": 25 |
3694 | } | ||
3695 | }, | ||
3696 | { | ||
3697 | "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", | ||
3698 | "end": { | ||
3699 | "column": 3, | ||
3700 | "line": 32 | ||
3701 | }, | ||
3702 | "file": "src/features/delayApp/Component.js", | ||
3703 | "id": "feature.delayApp.trial.action", | ||
3704 | "start": { | ||
3705 | "column": 15, | ||
3706 | "line": 29 | ||
3253 | } | 3707 | } |
3254 | }, | 3708 | }, |
3255 | { | 3709 | { |
3256 | "defaultMessage": "!!!Franz will continue in {seconds} seconds.", | 3710 | "defaultMessage": "!!!Franz will continue in {seconds} seconds.", |
3257 | "end": { | 3711 | "end": { |
3258 | "column": 3, | 3712 | "column": 3, |
3259 | "line": 26 | 3713 | "line": 36 |
3260 | }, | 3714 | }, |
3261 | "file": "src/features/delayApp/Component.js", | 3715 | "file": "src/features/delayApp/Component.js", |
3262 | "id": "feature.delayApp.text", | 3716 | "id": "feature.delayApp.text", |
3263 | "start": { | 3717 | "start": { |
3264 | "column": 8, | 3718 | "column": 8, |
3265 | "line": 23 | 3719 | "line": 33 |
3266 | } | 3720 | } |
3267 | } | 3721 | } |
3268 | ], | 3722 | ], |
@@ -3271,94 +3725,143 @@ | |||
3271 | { | 3725 | { |
3272 | "descriptors": [ | 3726 | "descriptors": [ |
3273 | { | 3727 | { |
3274 | "defaultMessage": "!!!Franz is better together!", | 3728 | "defaultMessage": "!!!Changes in Franz {version}", |
3729 | "end": { | ||
3730 | "column": 3, | ||
3731 | "line": 23 | ||
3732 | }, | ||
3733 | "file": "src/features/serviceLimit/components/AnnouncementScreen.js", | ||
3734 | "id": "feature.announcements.changelog.headline", | ||
3735 | "start": { | ||
3736 | "column": 12, | ||
3737 | "line": 20 | ||
3738 | } | ||
3739 | } | ||
3740 | ], | ||
3741 | "path": "src/features/serviceLimit/components/AnnouncementScreen.json" | ||
3742 | }, | ||
3743 | { | ||
3744 | "descriptors": [ | ||
3745 | { | ||
3746 | "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.", | ||
3747 | "end": { | ||
3748 | "column": 3, | ||
3749 | "line": 14 | ||
3750 | }, | ||
3751 | "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", | ||
3752 | "id": "feature.serviceLimit.limitReached", | ||
3753 | "start": { | ||
3754 | "column": 16, | ||
3755 | "line": 11 | ||
3756 | } | ||
3757 | }, | ||
3758 | { | ||
3759 | "defaultMessage": "!!!Upgrade account", | ||
3275 | "end": { | 3760 | "end": { |
3276 | "column": 3, | 3761 | "column": 3, |
3277 | "line": 18 | 3762 | "line": 18 |
3278 | }, | 3763 | }, |
3764 | "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", | ||
3765 | "id": "premiumFeature.button.upgradeAccount", | ||
3766 | "start": { | ||
3767 | "column": 10, | ||
3768 | "line": 15 | ||
3769 | } | ||
3770 | } | ||
3771 | ], | ||
3772 | "path": "src/features/serviceLimit/components/LimitReachedInfobox.json" | ||
3773 | }, | ||
3774 | { | ||
3775 | "descriptors": [ | ||
3776 | { | ||
3777 | "defaultMessage": "!!!Franz is better together!", | ||
3778 | "end": { | ||
3779 | "column": 3, | ||
3780 | "line": 21 | ||
3781 | }, | ||
3279 | "file": "src/features/shareFranz/Component.js", | 3782 | "file": "src/features/shareFranz/Component.js", |
3280 | "id": "feature.shareFranz.headline", | 3783 | "id": "feature.shareFranz.headline", |
3281 | "start": { | 3784 | "start": { |
3282 | "column": 12, | 3785 | "column": 12, |
3283 | "line": 15 | 3786 | "line": 18 |
3284 | } | 3787 | } |
3285 | }, | 3788 | }, |
3286 | { | 3789 | { |
3287 | "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.", | 3790 | "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.", |
3288 | "end": { | 3791 | "end": { |
3289 | "column": 3, | 3792 | "column": 3, |
3290 | "line": 22 | 3793 | "line": 25 |
3291 | }, | 3794 | }, |
3292 | "file": "src/features/shareFranz/Component.js", | 3795 | "file": "src/features/shareFranz/Component.js", |
3293 | "id": "feature.shareFranz.text", | 3796 | "id": "feature.shareFranz.text", |
3294 | "start": { | 3797 | "start": { |
3295 | "column": 8, | 3798 | "column": 8, |
3296 | "line": 19 | 3799 | "line": 22 |
3297 | } | 3800 | } |
3298 | }, | 3801 | }, |
3299 | { | 3802 | { |
3300 | "defaultMessage": "!!!Share as email", | 3803 | "defaultMessage": "!!!Share as email", |
3301 | "end": { | 3804 | "end": { |
3302 | "column": 3, | 3805 | "column": 3, |
3303 | "line": 26 | 3806 | "line": 29 |
3304 | }, | 3807 | }, |
3305 | "file": "src/features/shareFranz/Component.js", | 3808 | "file": "src/features/shareFranz/Component.js", |
3306 | "id": "feature.shareFranz.action.email", | 3809 | "id": "feature.shareFranz.action.email", |
3307 | "start": { | 3810 | "start": { |
3308 | "column": 16, | 3811 | "column": 16, |
3309 | "line": 23 | 3812 | "line": 26 |
3310 | } | 3813 | } |
3311 | }, | 3814 | }, |
3312 | { | 3815 | { |
3313 | "defaultMessage": "!!!Share on Facebook", | 3816 | "defaultMessage": "!!!Share on Facebook", |
3314 | "end": { | 3817 | "end": { |
3315 | "column": 3, | 3818 | "column": 3, |
3316 | "line": 30 | 3819 | "line": 33 |
3317 | }, | 3820 | }, |
3318 | "file": "src/features/shareFranz/Component.js", | 3821 | "file": "src/features/shareFranz/Component.js", |
3319 | "id": "feature.shareFranz.action.facebook", | 3822 | "id": "feature.shareFranz.action.facebook", |
3320 | "start": { | 3823 | "start": { |
3321 | "column": 19, | 3824 | "column": 19, |
3322 | "line": 27 | 3825 | "line": 30 |
3323 | } | 3826 | } |
3324 | }, | 3827 | }, |
3325 | { | 3828 | { |
3326 | "defaultMessage": "!!!Share on Twitter", | 3829 | "defaultMessage": "!!!Share on Twitter", |
3327 | "end": { | 3830 | "end": { |
3328 | "column": 3, | 3831 | "column": 3, |
3329 | "line": 34 | 3832 | "line": 37 |
3330 | }, | 3833 | }, |
3331 | "file": "src/features/shareFranz/Component.js", | 3834 | "file": "src/features/shareFranz/Component.js", |
3332 | "id": "feature.shareFranz.action.twitter", | 3835 | "id": "feature.shareFranz.action.twitter", |
3333 | "start": { | 3836 | "start": { |
3334 | "column": 18, | 3837 | "column": 18, |
3335 | "line": 31 | 3838 | "line": 34 |
3336 | } | 3839 | } |
3337 | }, | 3840 | }, |
3338 | { | 3841 | { |
3339 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", | 3842 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", |
3340 | "end": { | 3843 | "end": { |
3341 | "column": 3, | 3844 | "column": 3, |
3342 | "line": 38 | 3845 | "line": 41 |
3343 | }, | 3846 | }, |
3344 | "file": "src/features/shareFranz/Component.js", | 3847 | "file": "src/features/shareFranz/Component.js", |
3345 | "id": "feature.shareFranz.shareText.email", | 3848 | "id": "feature.shareFranz.shareText.email", |
3346 | "start": { | 3849 | "start": { |
3347 | "column": 18, | 3850 | "column": 18, |
3348 | "line": 35 | 3851 | "line": 38 |
3349 | } | 3852 | } |
3350 | }, | 3853 | }, |
3351 | { | 3854 | { |
3352 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", | 3855 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", |
3353 | "end": { | 3856 | "end": { |
3354 | "column": 3, | 3857 | "column": 3, |
3355 | "line": 42 | 3858 | "line": 45 |
3356 | }, | 3859 | }, |
3357 | "file": "src/features/shareFranz/Component.js", | 3860 | "file": "src/features/shareFranz/Component.js", |
3358 | "id": "feature.shareFranz.shareText.twitter", | 3861 | "id": "feature.shareFranz.shareText.twitter", |
3359 | "start": { | 3862 | "start": { |
3360 | "column": 20, | 3863 | "column": 20, |
3361 | "line": 39 | 3864 | "line": 42 |
3362 | } | 3865 | } |
3363 | } | 3866 | } |
3364 | ], | 3867 | ], |
@@ -3367,6 +3870,50 @@ | |||
3367 | { | 3870 | { |
3368 | "descriptors": [ | 3871 | "descriptors": [ |
3369 | { | 3872 | { |
3873 | "defaultMessage": "!!!The Franz Todos Preview is currently only available for Franz Premium accounts.", | ||
3874 | "end": { | ||
3875 | "column": 3, | ||
3876 | "line": 22 | ||
3877 | }, | ||
3878 | "file": "src/features/todos/components/TodosWebview.js", | ||
3879 | "id": "feature.todos.premium.info", | ||
3880 | "start": { | ||
3881 | "column": 15, | ||
3882 | "line": 19 | ||
3883 | } | ||
3884 | }, | ||
3885 | { | ||
3886 | "defaultMessage": "!!!Upgrade Account", | ||
3887 | "end": { | ||
3888 | "column": 3, | ||
3889 | "line": 26 | ||
3890 | }, | ||
3891 | "file": "src/features/todos/components/TodosWebview.js", | ||
3892 | "id": "feature.todos.premium.upgrade", | ||
3893 | "start": { | ||
3894 | "column": 14, | ||
3895 | "line": 23 | ||
3896 | } | ||
3897 | }, | ||
3898 | { | ||
3899 | "defaultMessage": "!!!Franz Todos will be available to everyone soon.", | ||
3900 | "end": { | ||
3901 | "column": 3, | ||
3902 | "line": 30 | ||
3903 | }, | ||
3904 | "file": "src/features/todos/components/TodosWebview.js", | ||
3905 | "id": "feature.todos.premium.rollout", | ||
3906 | "start": { | ||
3907 | "column": 15, | ||
3908 | "line": 27 | ||
3909 | } | ||
3910 | } | ||
3911 | ], | ||
3912 | "path": "src/features/todos/components/TodosWebview.json" | ||
3913 | }, | ||
3914 | { | ||
3915 | "descriptors": [ | ||
3916 | { | ||
3370 | "defaultMessage": "!!!Create workspace", | 3917 | "defaultMessage": "!!!Create workspace", |
3371 | "end": { | 3918 | "end": { |
3372 | "column": 3, | 3919 | "column": 3, |
@@ -3497,104 +4044,104 @@ | |||
3497 | "defaultMessage": "!!!Workspaces", | 4044 | "defaultMessage": "!!!Workspaces", |
3498 | "end": { | 4045 | "end": { |
3499 | "column": 3, | 4046 | "column": 3, |
3500 | "line": 19 | 4047 | "line": 20 |
3501 | }, | 4048 | }, |
3502 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 4049 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
3503 | "id": "workspaceDrawer.headline", | 4050 | "id": "workspaceDrawer.headline", |
3504 | "start": { | 4051 | "start": { |
3505 | "column": 12, | 4052 | "column": 12, |
3506 | "line": 16 | 4053 | "line": 17 |
3507 | } | 4054 | } |
3508 | }, | 4055 | }, |
3509 | { | 4056 | { |
3510 | "defaultMessage": "!!!All services", | 4057 | "defaultMessage": "!!!All services", |
3511 | "end": { | 4058 | "end": { |
3512 | "column": 3, | 4059 | "column": 3, |
3513 | "line": 23 | 4060 | "line": 24 |
3514 | }, | 4061 | }, |
3515 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 4062 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
3516 | "id": "workspaceDrawer.allServices", | 4063 | "id": "workspaceDrawer.allServices", |
3517 | "start": { | 4064 | "start": { |
3518 | "column": 15, | 4065 | "column": 15, |
3519 | "line": 20 | 4066 | "line": 21 |
3520 | } | 4067 | } |
3521 | }, | 4068 | }, |
3522 | { | 4069 | { |
3523 | "defaultMessage": "!!!Workspaces settings", | 4070 | "defaultMessage": "!!!Workspaces settings", |
3524 | "end": { | 4071 | "end": { |
3525 | "column": 3, | 4072 | "column": 3, |
3526 | "line": 27 | 4073 | "line": 28 |
3527 | }, | 4074 | }, |
3528 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 4075 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
3529 | "id": "workspaceDrawer.workspacesSettingsTooltip", | 4076 | "id": "workspaceDrawer.workspacesSettingsTooltip", |
3530 | "start": { | 4077 | "start": { |
3531 | "column": 29, | 4078 | "column": 29, |
3532 | "line": 24 | 4079 | "line": 25 |
3533 | } | 4080 | } |
3534 | }, | 4081 | }, |
3535 | { | 4082 | { |
3536 | "defaultMessage": "!!!Info about workspace feature", | 4083 | "defaultMessage": "!!!Info about workspace feature", |
3537 | "end": { | 4084 | "end": { |
3538 | "column": 3, | 4085 | "column": 3, |
3539 | "line": 31 | 4086 | "line": 32 |
3540 | }, | 4087 | }, |
3541 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 4088 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
3542 | "id": "workspaceDrawer.workspaceFeatureInfo", | 4089 | "id": "workspaceDrawer.workspaceFeatureInfo", |
3543 | "start": { | 4090 | "start": { |
3544 | "column": 24, | 4091 | "column": 24, |
3545 | "line": 28 | 4092 | "line": 29 |
3546 | } | 4093 | } |
3547 | }, | 4094 | }, |
3548 | { | 4095 | { |
3549 | "defaultMessage": "!!!Create your first workspace", | 4096 | "defaultMessage": "!!!Create your first workspace", |
3550 | "end": { | 4097 | "end": { |
3551 | "column": 3, | 4098 | "column": 3, |
3552 | "line": 35 | 4099 | "line": 36 |
3553 | }, | 4100 | }, |
3554 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 4101 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
3555 | "id": "workspaceDrawer.premiumCtaButtonLabel", | 4102 | "id": "workspaceDrawer.premiumCtaButtonLabel", |
3556 | "start": { | 4103 | "start": { |
3557 | "column": 25, | 4104 | "column": 25, |
3558 | "line": 32 | 4105 | "line": 33 |
3559 | } | 4106 | } |
3560 | }, | 4107 | }, |
3561 | { | 4108 | { |
3562 | "defaultMessage": "!!!Reactivate premium account", | 4109 | "defaultMessage": "!!!Reactivate premium account", |
3563 | "end": { | 4110 | "end": { |
3564 | "column": 3, | 4111 | "column": 3, |
3565 | "line": 39 | 4112 | "line": 40 |
3566 | }, | 4113 | }, |
3567 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 4114 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
3568 | "id": "workspaceDrawer.reactivatePremiumAccountLabel", | 4115 | "id": "workspaceDrawer.reactivatePremiumAccountLabel", |
3569 | "start": { | 4116 | "start": { |
3570 | "column": 28, | 4117 | "column": 28, |
3571 | "line": 36 | 4118 | "line": 37 |
3572 | } | 4119 | } |
3573 | }, | 4120 | }, |
3574 | { | 4121 | { |
3575 | "defaultMessage": "!!!add new workspace", | 4122 | "defaultMessage": "!!!add new workspace", |
3576 | "end": { | 4123 | "end": { |
3577 | "column": 3, | 4124 | "column": 3, |
3578 | "line": 43 | 4125 | "line": 44 |
3579 | }, | 4126 | }, |
3580 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 4127 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
3581 | "id": "workspaceDrawer.addNewWorkspaceLabel", | 4128 | "id": "workspaceDrawer.addNewWorkspaceLabel", |
3582 | "start": { | 4129 | "start": { |
3583 | "column": 24, | 4130 | "column": 24, |
3584 | "line": 40 | 4131 | "line": 41 |
3585 | } | 4132 | } |
3586 | }, | 4133 | }, |
3587 | { | 4134 | { |
3588 | "defaultMessage": "!!!Premium feature", | 4135 | "defaultMessage": "!!!Premium feature", |
3589 | "end": { | 4136 | "end": { |
3590 | "column": 3, | 4137 | "column": 3, |
3591 | "line": 47 | 4138 | "line": 48 |
3592 | }, | 4139 | }, |
3593 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 4140 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
3594 | "id": "workspaceDrawer.proFeatureBadge", | 4141 | "id": "workspaceDrawer.proFeatureBadge", |
3595 | "start": { | 4142 | "start": { |
3596 | "column": 23, | 4143 | "column": 23, |
3597 | "line": 44 | 4144 | "line": 45 |
3598 | } | 4145 | } |
3599 | } | 4146 | } |
3600 | ], | 4147 | ], |
@@ -3637,104 +4184,104 @@ | |||
3637 | "defaultMessage": "!!!Your workspaces", | 4184 | "defaultMessage": "!!!Your workspaces", |
3638 | "end": { | 4185 | "end": { |
3639 | "column": 3, | 4186 | "column": 3, |
3640 | "line": 20 | 4187 | "line": 22 |
3641 | }, | 4188 | }, |
3642 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 4189 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
3643 | "id": "settings.workspaces.headline", | 4190 | "id": "settings.workspaces.headline", |
3644 | "start": { | 4191 | "start": { |
3645 | "column": 12, | 4192 | "column": 12, |
3646 | "line": 17 | 4193 | "line": 19 |
3647 | } | 4194 | } |
3648 | }, | 4195 | }, |
3649 | { | 4196 | { |
3650 | "defaultMessage": "!!!You haven't added any workspaces yet.", | 4197 | "defaultMessage": "!!!You haven't added any workspaces yet.", |
3651 | "end": { | 4198 | "end": { |
3652 | "column": 3, | 4199 | "column": 3, |
3653 | "line": 24 | 4200 | "line": 26 |
3654 | }, | 4201 | }, |
3655 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 4202 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
3656 | "id": "settings.workspaces.noWorkspacesAdded", | 4203 | "id": "settings.workspaces.noWorkspacesAdded", |
3657 | "start": { | 4204 | "start": { |
3658 | "column": 19, | 4205 | "column": 19, |
3659 | "line": 21 | 4206 | "line": 23 |
3660 | } | 4207 | } |
3661 | }, | 4208 | }, |
3662 | { | 4209 | { |
3663 | "defaultMessage": "!!!Could not load your workspaces", | 4210 | "defaultMessage": "!!!Could not load your workspaces", |
3664 | "end": { | 4211 | "end": { |
3665 | "column": 3, | 4212 | "column": 3, |
3666 | "line": 28 | 4213 | "line": 30 |
3667 | }, | 4214 | }, |
3668 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 4215 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
3669 | "id": "settings.workspaces.workspacesRequestFailed", | 4216 | "id": "settings.workspaces.workspacesRequestFailed", |
3670 | "start": { | 4217 | "start": { |
3671 | "column": 27, | 4218 | "column": 27, |
3672 | "line": 25 | 4219 | "line": 27 |
3673 | } | 4220 | } |
3674 | }, | 4221 | }, |
3675 | { | 4222 | { |
3676 | "defaultMessage": "!!!Try again", | 4223 | "defaultMessage": "!!!Try again", |
3677 | "end": { | 4224 | "end": { |
3678 | "column": 3, | 4225 | "column": 3, |
3679 | "line": 32 | 4226 | "line": 34 |
3680 | }, | 4227 | }, |
3681 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 4228 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
3682 | "id": "settings.workspaces.tryReloadWorkspaces", | 4229 | "id": "settings.workspaces.tryReloadWorkspaces", |
3683 | "start": { | 4230 | "start": { |
3684 | "column": 23, | 4231 | "column": 23, |
3685 | "line": 29 | 4232 | "line": 31 |
3686 | } | 4233 | } |
3687 | }, | 4234 | }, |
3688 | { | 4235 | { |
3689 | "defaultMessage": "!!!Your changes have been saved", | 4236 | "defaultMessage": "!!!Your changes have been saved", |
3690 | "end": { | 4237 | "end": { |
3691 | "column": 3, | 4238 | "column": 3, |
3692 | "line": 36 | 4239 | "line": 38 |
3693 | }, | 4240 | }, |
3694 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 4241 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
3695 | "id": "settings.workspaces.updatedInfo", | 4242 | "id": "settings.workspaces.updatedInfo", |
3696 | "start": { | 4243 | "start": { |
3697 | "column": 15, | 4244 | "column": 15, |
3698 | "line": 33 | 4245 | "line": 35 |
3699 | } | 4246 | } |
3700 | }, | 4247 | }, |
3701 | { | 4248 | { |
3702 | "defaultMessage": "!!!Workspace has been deleted", | 4249 | "defaultMessage": "!!!Workspace has been deleted", |
3703 | "end": { | 4250 | "end": { |
3704 | "column": 3, | 4251 | "column": 3, |
3705 | "line": 40 | 4252 | "line": 42 |
3706 | }, | 4253 | }, |
3707 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 4254 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
3708 | "id": "settings.workspaces.deletedInfo", | 4255 | "id": "settings.workspaces.deletedInfo", |
3709 | "start": { | 4256 | "start": { |
3710 | "column": 15, | 4257 | "column": 15, |
3711 | "line": 37 | 4258 | "line": 39 |
3712 | } | 4259 | } |
3713 | }, | 4260 | }, |
3714 | { | 4261 | { |
3715 | "defaultMessage": "!!!Info about workspace feature", | 4262 | "defaultMessage": "!!!Info about workspace feature", |
3716 | "end": { | 4263 | "end": { |
3717 | "column": 3, | 4264 | "column": 3, |
3718 | "line": 44 | 4265 | "line": 46 |
3719 | }, | 4266 | }, |
3720 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 4267 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
3721 | "id": "settings.workspaces.workspaceFeatureInfo", | 4268 | "id": "settings.workspaces.workspaceFeatureInfo", |
3722 | "start": { | 4269 | "start": { |
3723 | "column": 24, | 4270 | "column": 24, |
3724 | "line": 41 | 4271 | "line": 43 |
3725 | } | 4272 | } |
3726 | }, | 4273 | }, |
3727 | { | 4274 | { |
3728 | "defaultMessage": "!!!Less is More: Introducing Franz Workspaces", | 4275 | "defaultMessage": "!!!Less is More: Introducing Franz Workspaces", |
3729 | "end": { | 4276 | "end": { |
3730 | "column": 3, | 4277 | "column": 3, |
3731 | "line": 48 | 4278 | "line": 50 |
3732 | }, | 4279 | }, |
3733 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 4280 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
3734 | "id": "settings.workspaces.workspaceFeatureHeadline", | 4281 | "id": "settings.workspaces.workspaceFeatureHeadline", |
3735 | "start": { | 4282 | "start": { |
3736 | "column": 28, | 4283 | "column": 28, |
3737 | "line": 45 | 4284 | "line": 47 |
3738 | } | 4285 | } |
3739 | } | 4286 | } |
3740 | ], | 4287 | ], |
@@ -3761,6 +4308,146 @@ | |||
3761 | { | 4308 | { |
3762 | "descriptors": [ | 4309 | "descriptors": [ |
3763 | { | 4310 | { |
4311 | "defaultMessage": "!!!Franz Professional", | ||
4312 | "end": { | ||
4313 | "column": 3, | ||
4314 | "line": 8 | ||
4315 | }, | ||
4316 | "file": "src/helpers/plan-helpers.js", | ||
4317 | "id": "pricing.plan.pro", | ||
4318 | "start": { | ||
4319 | "column": 15, | ||
4320 | "line": 5 | ||
4321 | } | ||
4322 | }, | ||
4323 | { | ||
4324 | "defaultMessage": "!!!Franz Personal", | ||
4325 | "end": { | ||
4326 | "column": 3, | ||
4327 | "line": 12 | ||
4328 | }, | ||
4329 | "file": "src/helpers/plan-helpers.js", | ||
4330 | "id": "pricing.plan.personal", | ||
4331 | "start": { | ||
4332 | "column": 20, | ||
4333 | "line": 9 | ||
4334 | } | ||
4335 | }, | ||
4336 | { | ||
4337 | "defaultMessage": "!!!Franz Free", | ||
4338 | "end": { | ||
4339 | "column": 3, | ||
4340 | "line": 16 | ||
4341 | }, | ||
4342 | "file": "src/helpers/plan-helpers.js", | ||
4343 | "id": "pricing.plan.free", | ||
4344 | "start": { | ||
4345 | "column": 16, | ||
4346 | "line": 13 | ||
4347 | } | ||
4348 | }, | ||
4349 | { | ||
4350 | "defaultMessage": "!!!Franz Premium", | ||
4351 | "end": { | ||
4352 | "column": 3, | ||
4353 | "line": 20 | ||
4354 | }, | ||
4355 | "file": "src/helpers/plan-helpers.js", | ||
4356 | "id": "pricing.plan.legacy", | ||
4357 | "start": { | ||
4358 | "column": 18, | ||
4359 | "line": 17 | ||
4360 | } | ||
4361 | } | ||
4362 | ], | ||
4363 | "path": "src/helpers/plan-helpers.json" | ||
4364 | }, | ||
4365 | { | ||
4366 | "descriptors": [ | ||
4367 | { | ||
4368 | "defaultMessage": "!!!Franz Professional Yearly", | ||
4369 | "end": { | ||
4370 | "column": 3, | ||
4371 | "line": 8 | ||
4372 | }, | ||
4373 | "file": "src/helpers/pricing-helpers.js", | ||
4374 | "id": "pricing.plan.pro-yearly", | ||
4375 | "start": { | ||
4376 | "column": 22, | ||
4377 | "line": 5 | ||
4378 | } | ||
4379 | }, | ||
4380 | { | ||
4381 | "defaultMessage": "!!!Franz Professional Monthly", | ||
4382 | "end": { | ||
4383 | "column": 3, | ||
4384 | "line": 12 | ||
4385 | }, | ||
4386 | "file": "src/helpers/pricing-helpers.js", | ||
4387 | "id": "pricing.plan.pro-monthly", | ||
4388 | "start": { | ||
4389 | "column": 23, | ||
4390 | "line": 9 | ||
4391 | } | ||
4392 | }, | ||
4393 | { | ||
4394 | "defaultMessage": "!!!Franz Personal Yearly", | ||
4395 | "end": { | ||
4396 | "column": 3, | ||
4397 | "line": 16 | ||
4398 | }, | ||
4399 | "file": "src/helpers/pricing-helpers.js", | ||
4400 | "id": "pricing.plan.personal-yearly", | ||
4401 | "start": { | ||
4402 | "column": 27, | ||
4403 | "line": 13 | ||
4404 | } | ||
4405 | }, | ||
4406 | { | ||
4407 | "defaultMessage": "!!!Franz Personal Monthly", | ||
4408 | "end": { | ||
4409 | "column": 3, | ||
4410 | "line": 20 | ||
4411 | }, | ||
4412 | "file": "src/helpers/pricing-helpers.js", | ||
4413 | "id": "pricing.plan.personal-monthly", | ||
4414 | "start": { | ||
4415 | "column": 28, | ||
4416 | "line": 17 | ||
4417 | } | ||
4418 | }, | ||
4419 | { | ||
4420 | "defaultMessage": "!!!Franz Free", | ||
4421 | "end": { | ||
4422 | "column": 3, | ||
4423 | "line": 24 | ||
4424 | }, | ||
4425 | "file": "src/helpers/pricing-helpers.js", | ||
4426 | "id": "pricing.plan.free", | ||
4427 | "start": { | ||
4428 | "column": 16, | ||
4429 | "line": 21 | ||
4430 | } | ||
4431 | }, | ||
4432 | { | ||
4433 | "defaultMessage": "!!!Franz Premium", | ||
4434 | "end": { | ||
4435 | "column": 3, | ||
4436 | "line": 28 | ||
4437 | }, | ||
4438 | "file": "src/helpers/pricing-helpers.js", | ||
4439 | "id": "pricing.plan.legacy", | ||
4440 | "start": { | ||
4441 | "column": 18, | ||
4442 | "line": 25 | ||
4443 | } | ||
4444 | } | ||
4445 | ], | ||
4446 | "path": "src/helpers/pricing-helpers.json" | ||
4447 | }, | ||
4448 | { | ||
4449 | "descriptors": [ | ||
4450 | { | ||
3764 | "defaultMessage": "!!!Field is required", | 4451 | "defaultMessage": "!!!Field is required", |
3765 | "end": { | 4452 | "end": { |
3766 | "column": 3, | 4453 | "column": 3, |
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index cee42c350..f11d5ca91 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -2,9 +2,14 @@ | |||
2 | "app.errorHandler.action": "Reload", | 2 | "app.errorHandler.action": "Reload", |
3 | "app.errorHandler.headline": "Something went wrong", | 3 | "app.errorHandler.headline": "Something went wrong", |
4 | "feature.announcements.changelog.headline": "Changes in Franz {version}", | 4 | "feature.announcements.changelog.headline": "Changes in Franz {version}", |
5 | "feature.delayApp.action": "Get a Franz Supporter License", | ||
6 | "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", | 5 | "feature.delayApp.headline": "Please purchase a Franz Supporter License to skip waiting", |
7 | "feature.delayApp.text": "Franz will continue in {seconds} seconds.", | 6 | "feature.delayApp.text": "Franz will continue in {seconds} seconds.", |
7 | "feature.delayApp.trial.action": "Yes, I want the free 14 day trial of Franz Professional", | ||
8 | "feature.delayApp.trial.actionShort": "Activate the free Franz Professional trial", | ||
9 | "feature.delayApp.trial.headline": "Get the free Franz Professional 14 day trial and skip the line", | ||
10 | "feature.delayApp.upgrade.action": "Get a Franz Supporter License", | ||
11 | "feature.delayApp.upgrade.actionShort": "Upgrade account", | ||
12 | "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.", | ||
8 | "feature.shareFranz.action.email": "Send as email", | 13 | "feature.shareFranz.action.email": "Send as email", |
9 | "feature.shareFranz.action.facebook": "Share on Facebook", | 14 | "feature.shareFranz.action.facebook": "Share on Facebook", |
10 | "feature.shareFranz.action.twitter": "Share on Twitter", | 15 | "feature.shareFranz.action.twitter": "Share on Twitter", |
@@ -12,6 +17,9 @@ | |||
12 | "feature.shareFranz.shareText.email": "I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", | 17 | "feature.shareFranz.shareText.email": "I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", |
13 | "feature.shareFranz.shareText.twitter": "I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", | 18 | "feature.shareFranz.shareText.twitter": "I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", |
14 | "feature.shareFranz.text": "Tell your friends and colleagues how awesome Franz is and help us to spread the word.", | 19 | "feature.shareFranz.text": "Tell your friends and colleagues how awesome Franz is and help us to spread the word.", |
20 | "feature.todos.premium.info": "The Franz Todos Preview is currently only available for Franz Premium accounts.", | ||
21 | "feature.todos.premium.rollout": "Franz Todos will be available to everyone soon.", | ||
22 | "feature.todos.premium.upgrade": "Upgrade Account", | ||
15 | "global.api.unhealthy": "Can't connect to Franz online services", | 23 | "global.api.unhealthy": "Can't connect to Franz online services", |
16 | "global.notConnectedToTheInternet": "You are not connected to the internet.", | 24 | "global.notConnectedToTheInternet": "You are not connected to the internet.", |
17 | "global.spellchecker.useDefault": "Use System Default ({default})", | 25 | "global.spellchecker.useDefault": "Use System Default ({default})", |
@@ -27,6 +35,7 @@ | |||
27 | "infobar.buttonReloadServices": "Reload services", | 35 | "infobar.buttonReloadServices": "Reload services", |
28 | "infobar.requiredRequestsFailed": "Could not load services and user information", | 36 | "infobar.requiredRequestsFailed": "Could not load services and user information", |
29 | "infobar.servicesUpdated": "Your services have been updated.", | 37 | "infobar.servicesUpdated": "Your services have been updated.", |
38 | "infobar.trialActivated": "Your trial was successfully activated. Happy messaging!", | ||
30 | "infobar.updateAvailable": "A new update for Franz is available.", | 39 | "infobar.updateAvailable": "A new update for Franz is available.", |
31 | "invite.email.label": "Email address", | 40 | "invite.email.label": "Email address", |
32 | "invite.headline.friends": "Invite 3 of your friends or colleagues", | 41 | "invite.headline.friends": "Invite 3 of your friends or colleagues", |
@@ -91,7 +100,7 @@ | |||
91 | "menu.view.toggleDevTools": "Toggle Developer Tools", | 100 | "menu.view.toggleDevTools": "Toggle Developer Tools", |
92 | "menu.view.toggleFullScreen": "Toggle Full Screen", | 101 | "menu.view.toggleFullScreen": "Toggle Full Screen", |
93 | "menu.view.toggleServiceDevTools": "Toggle Service Developer Tools", | 102 | "menu.view.toggleServiceDevTools": "Toggle Service Developer Tools", |
94 | "menu.view.toggleTodosDevTools": "!!!Toggle Todos Developer Tools", | 103 | "menu.view.toggleTodosDevTools": "Toggle Todos Developer Tools", |
95 | "menu.view.zoomIn": "Zoom In", | 104 | "menu.view.zoomIn": "Zoom In", |
96 | "menu.view.zoomOut": "Zoom Out", | 105 | "menu.view.zoomOut": "Zoom Out", |
97 | "menu.window": "Window", | 106 | "menu.window": "Window", |
@@ -110,10 +119,33 @@ | |||
110 | "password.submit.label": "Submit", | 119 | "password.submit.label": "Submit", |
111 | "password.successInfo": "Please check your email", | 120 | "password.successInfo": "Please check your email", |
112 | "premiumFeature.button.upgradeAccount": "Upgrade account", | 121 | "premiumFeature.button.upgradeAccount": "Upgrade account", |
113 | "pricing.headline": "Support Franz", | 122 | "pricing.features.adFree": "Forever ad-free", |
114 | "pricing.link.skipPayment": "I don't want to support the development of Franz.", | 123 | "pricing.features.appDelays": "No Waiting Screens", |
115 | "pricing.submit.label": "I want to support the development of Franz", | 124 | "pricing.features.customWebsites": "Add Custom Websites", |
116 | "pricing.support.label": "Select your support plan", | 125 | "pricing.features.onPremise": "On-premise & other Hosted Services", |
126 | "pricing.features.serviceProxies": "Service Proxies", | ||
127 | "pricing.features.spellchecker": "Spellchecker support", | ||
128 | "pricing.features.teamManagement": "Team Management", | ||
129 | "pricing.features.thirdPartyServices": "Install 3rd party services", | ||
130 | "pricing.features.unlimitedServices": "Add unlimited services", | ||
131 | "pricing.features.workspaces": "Workspaces", | ||
132 | "pricing.plan.free": "Franz Free", | ||
133 | "pricing.plan.legacy": "Franz Premium", | ||
134 | "pricing.plan.personal": "Franz Personal", | ||
135 | "pricing.plan.personal-monthly": "Franz Personal Monthly", | ||
136 | "pricing.plan.personal-yearly": "Franz Personal Yearly", | ||
137 | "pricing.plan.pro": "Franz Professional", | ||
138 | "pricing.plan.pro-monthly": "Franz Professional Monthly", | ||
139 | "pricing.plan.pro-yearly": "Franz Professional Yearly", | ||
140 | "pricing.trial.cta.accept": "Yes, upgrade my account to Franz Professional", | ||
141 | "pricing.trial.cta.skip": "Continue to Franz", | ||
142 | "pricing.trial.error": "Sorry, we could not activate your trial!", | ||
143 | "pricing.trial.features.headline": "Franz Professional includes:", | ||
144 | "pricing.trial.headline": "Franz Professional", | ||
145 | "pricing.trial.subheadline": "Your personal welcome offer:", | ||
146 | "pricing.trial.terms.automaticTrialEnd": "Your free trial ends automatically after 14 days", | ||
147 | "pricing.trial.terms.headline": "No strings attached", | ||
148 | "pricing.trial.terms.noCreditCard": "No credit card required", | ||
117 | "service.crashHandler.action": "Reload {name}", | 149 | "service.crashHandler.action": "Reload {name}", |
118 | "service.crashHandler.autoReload": "Trying to automatically restore {name} in {seconds} seconds", | 150 | "service.crashHandler.autoReload": "Trying to automatically restore {name} in {seconds} seconds", |
119 | "service.crashHandler.headline": "Oh no!", | 151 | "service.crashHandler.headline": "Oh no!", |
@@ -125,6 +157,11 @@ | |||
125 | "service.errorHandler.headline": "Oh no!", | 157 | "service.errorHandler.headline": "Oh no!", |
126 | "service.errorHandler.message": "Error", | 158 | "service.errorHandler.message": "Error", |
127 | "service.errorHandler.text": "{name} has failed to load.", | 159 | "service.errorHandler.text": "{name} has failed to load.", |
160 | "service.restrictedHandler.action": "Upgrade Account", | ||
161 | "service.restrictedHandler.customUrl.headline": "Franz Professional Plan required", | ||
162 | "service.restrictedHandler.customUrl.text": "Please upgrade to the Franz Professional plan to use custom urls & self hosted services.", | ||
163 | "service.restrictedHandler.serviceLimit.headline": "You have reached your service limit.", | ||
164 | "service.restrictedHandler.serviceLimit.text": "Please upgrade your account to use more than {count} services.", | ||
128 | "service.webviewLoader.loading": "Loading", | 165 | "service.webviewLoader.loading": "Loading", |
129 | "services.getStarted": "Get started", | 166 | "services.getStarted": "Get started", |
130 | "services.welcome": "Welcome to Franz", | 167 | "services.welcome": "Welcome to Franz", |
@@ -142,13 +179,19 @@ | |||
142 | "settings.account.headlinePassword": "Change password", | 179 | "settings.account.headlinePassword": "Change password", |
143 | "settings.account.headlineProfile": "Update profile", | 180 | "settings.account.headlineProfile": "Update profile", |
144 | "settings.account.headlineSubscription": "Your subscription", | 181 | "settings.account.headlineSubscription": "Your subscription", |
145 | "settings.account.headlineUpgrade": "Upgrade your account & support Franz", | 182 | "settings.account.headlineTrialUpgrade": "Get the free 14 day Franz Professional Trial", |
183 | "settings.account.headlineUpgradeAccount": "Upgrade your account & get the full Franz experience", | ||
146 | "settings.account.invoiceDownload": "Download", | 184 | "settings.account.invoiceDownload": "Download", |
147 | "settings.account.manageSubscription.label": "Manage your subscription", | 185 | "settings.account.manageSubscription.label": "Manage your subscription", |
148 | "settings.account.successInfo": "Your changes have been saved", | 186 | "settings.account.successInfo": "Your changes have been saved", |
187 | "settings.account.trial": "Free Trial", | ||
188 | "settings.account.trialEndsIn": "Your free trial ends in {duration}.", | ||
189 | "settings.account.trialUpdateBillingInfo": "Please update your billing info to continue using {license} after your trial period.", | ||
149 | "settings.account.tryReloadServices": "Try again", | 190 | "settings.account.tryReloadServices": "Try again", |
150 | "settings.account.tryReloadUserInfoRequest": "Try again", | 191 | "settings.account.tryReloadUserInfoRequest": "Try again", |
192 | "settings.account.upgradeToPro.label": "Upgrade to Franz Professional", | ||
151 | "settings.account.userInfoRequestFailed": "Could not load user information", | 193 | "settings.account.userInfoRequestFailed": "Could not load user information", |
194 | "settings.account.yourLicense": "Your Franz License", | ||
152 | "settings.app.buttonClearAllCache": "Clear cache", | 195 | "settings.app.buttonClearAllCache": "Clear cache", |
153 | "settings.app.buttonInstallUpdate": "Restart & install update", | 196 | "settings.app.buttonInstallUpdate": "Restart & install update", |
154 | "settings.app.buttonSearchForUpdate": "Check for updates", | 197 | "settings.app.buttonSearchForUpdate": "Check for updates", |
@@ -189,7 +232,13 @@ | |||
189 | "settings.navigation.yourServices": "Your services", | 232 | "settings.navigation.yourServices": "Your services", |
190 | "settings.navigation.yourWorkspaces": "Your workspaces", | 233 | "settings.navigation.yourWorkspaces": "Your workspaces", |
191 | "settings.recipes.all": "All services", | 234 | "settings.recipes.all": "All services", |
192 | "settings.recipes.dev": "Development", | 235 | "settings.recipes.custom": "Custom Services", |
236 | "settings.recipes.customService.headline.communityRecipes": "Community Services", | ||
237 | "settings.recipes.customService.headline.customRecipes": "Custom Service Recipes", | ||
238 | "settings.recipes.customService.headline.devRecipes": "Your Development Service Recipes", | ||
239 | "settings.recipes.customService.intro": "To add a custom service, copy the service recipe to:", | ||
240 | "settings.recipes.customService.openDevDocs": "Developer Documentation", | ||
241 | "settings.recipes.customService.openFolder": "Open folder", | ||
193 | "settings.recipes.headline": "Available services", | 242 | "settings.recipes.headline": "Available services", |
194 | "settings.recipes.missingService": "Missing a service?", | 243 | "settings.recipes.missingService": "Missing a service?", |
195 | "settings.recipes.mostPopular": "Most popular", | 244 | "settings.recipes.mostPopular": "Most popular", |
@@ -281,7 +330,6 @@ | |||
281 | "sidebar.openWorkspaceDrawer": "Open workspace drawer", | 330 | "sidebar.openWorkspaceDrawer": "Open workspace drawer", |
282 | "sidebar.settings": "Settings", | 331 | "sidebar.settings": "Settings", |
283 | "sidebar.unmuteApp": "Enable notifications & audio", | 332 | "sidebar.unmuteApp": "Enable notifications & audio", |
284 | "signup.company.label": "Company", | ||
285 | "signup.email.label": "Email address", | 333 | "signup.email.label": "Email address", |
286 | "signup.emailDuplicate": "A user with that email address already exists", | 334 | "signup.emailDuplicate": "A user with that email address already exists", |
287 | "signup.firstname.label": "First Name", | 335 | "signup.firstname.label": "First Name", |
@@ -293,20 +341,12 @@ | |||
293 | "signup.link.login": "Already have an account, sign in?", | 341 | "signup.link.login": "Already have an account, sign in?", |
294 | "signup.password.label": "Password", | 342 | "signup.password.label": "Password", |
295 | "signup.submit.label": "Create account", | 343 | "signup.submit.label": "Create account", |
296 | "subscription.euTaxInfo": "EU residents: local sales tax may apply", | 344 | "subscription.cta.activateTrial": "Yes, start the free Franz Professional trial", |
297 | "subscription.features.ads": "No ads, ever!", | 345 | "subscription.cta.allOptions": "See all options", |
298 | "subscription.features.comingSoon": "coming soon", | 346 | "subscription.cta.choosePlan": "Choose your plan", |
299 | "subscription.features.noInterruptions": "No app delays & nagging to upgrade license", | 347 | "subscription.includedProFeatures": "The Franz Professional Plan includes:", |
300 | "subscription.features.onpremise.mattermost": "Add on-premise/hosted services like Mattermost", | 348 | "subscription.teaser.includedFeatures": "Paid Franz Plans include:", |
301 | "subscription.features.proxy": "Proxy support for services", | 349 | "subscription.teaser.intro": "Franz 5 comes with a wide range of new features to boost up your everyday communication - batteries included. Check out our new plans and find out which one suits you most!", |
302 | "subscription.features.spellchecker": "Support for spellchecker", | ||
303 | "subscription.features.workspaces": "Organize your services in workspaces", | ||
304 | "subscription.includedFeatures": "Paid Franz Premium Supporter Account includes", | ||
305 | "subscription.paymentSessionError": "Could not initialize payment form", | ||
306 | "subscription.submit.label": "I want to support the development of Franz", | ||
307 | "subscription.type.free": "free", | ||
308 | "subscription.type.month": "month", | ||
309 | "subscription.type.year": "year", | ||
310 | "subscriptionPopup.buttonCancel": "Cancel", | 350 | "subscriptionPopup.buttonCancel": "Cancel", |
311 | "subscriptionPopup.buttonDone": "Done", | 351 | "subscriptionPopup.buttonDone": "Done", |
312 | "tabs.item.deleteService": "Delete service", | 352 | "tabs.item.deleteService": "Delete service", |
diff --git a/src/i18n/messages/src/components/TrialActivationInfoBar.json b/src/i18n/messages/src/components/TrialActivationInfoBar.json new file mode 100644 index 000000000..65dd964a6 --- /dev/null +++ b/src/i18n/messages/src/components/TrialActivationInfoBar.json | |||
@@ -0,0 +1,15 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "infobar.trialActivated", | ||
4 | "defaultMessage": "!!!Your trial was successfully activated. Happy messaging!", | ||
5 | "file": "src/components/TrialActivationInfoBar.js", | ||
6 | "start": { | ||
7 | "line": 11, | ||
8 | "column": 11 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 14, | ||
12 | "column": 3 | ||
13 | } | ||
14 | } | ||
15 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/auth/Pricing.json b/src/i18n/messages/src/components/auth/Pricing.json index f711a55b4..f15617ca5 100644 --- a/src/i18n/messages/src/components/auth/Pricing.json +++ b/src/i18n/messages/src/components/auth/Pricing.json | |||
@@ -1,53 +1,118 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "id": "pricing.headline", | 3 | "id": "pricing.trial.headline", |
4 | "defaultMessage": "!!!Support Franz", | 4 | "defaultMessage": "!!!Franz Professional", |
5 | "file": "src/components/auth/Pricing.js", | 5 | "file": "src/components/auth/Pricing.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 13, | 7 | "line": 15, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 16, | 11 | "line": 18, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
15 | { | 15 | { |
16 | "id": "pricing.support.label", | 16 | "id": "pricing.trial.subheadline", |
17 | "defaultMessage": "!!!Select your support plan", | 17 | "defaultMessage": "!!!Your personal welcome offer:", |
18 | "file": "src/components/auth/Pricing.js", | 18 | "file": "src/components/auth/Pricing.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 17, | 20 | "line": 19, |
21 | "column": 23 | 21 | "column": 17 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 20, | 24 | "line": 22, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
28 | { | 28 | { |
29 | "id": "pricing.submit.label", | 29 | "id": "pricing.trial.terms.headline", |
30 | "defaultMessage": "!!!Support the development of Franz", | 30 | "defaultMessage": "!!!No strings attached", |
31 | "file": "src/components/auth/Pricing.js", | 31 | "file": "src/components/auth/Pricing.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 21, | 33 | "line": 23, |
34 | "column": 29 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 26, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "pricing.trial.terms.noCreditCard", | ||
43 | "defaultMessage": "!!!No credit card required", | ||
44 | "file": "src/components/auth/Pricing.js", | ||
45 | "start": { | ||
46 | "line": 27, | ||
47 | "column": 16 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 30, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "pricing.trial.terms.automaticTrialEnd", | ||
56 | "defaultMessage": "!!!Your free trial ends automatically after 14 days", | ||
57 | "file": "src/components/auth/Pricing.js", | ||
58 | "start": { | ||
59 | "line": 31, | ||
34 | "column": 21 | 60 | "column": 21 |
35 | }, | 61 | }, |
36 | "end": { | 62 | "end": { |
37 | "line": 24, | 63 | "line": 34, |
64 | "column": 3 | ||
65 | } | ||
66 | }, | ||
67 | { | ||
68 | "id": "pricing.trial.error", | ||
69 | "defaultMessage": "!!!Sorry, we could not activate your trial!", | ||
70 | "file": "src/components/auth/Pricing.js", | ||
71 | "start": { | ||
72 | "line": 35, | ||
73 | "column": 19 | ||
74 | }, | ||
75 | "end": { | ||
76 | "line": 38, | ||
77 | "column": 3 | ||
78 | } | ||
79 | }, | ||
80 | { | ||
81 | "id": "pricing.trial.cta.accept", | ||
82 | "defaultMessage": "!!!Yes, upgrade my account to Franz Professional", | ||
83 | "file": "src/components/auth/Pricing.js", | ||
84 | "start": { | ||
85 | "line": 39, | ||
86 | "column": 13 | ||
87 | }, | ||
88 | "end": { | ||
89 | "line": 42, | ||
90 | "column": 3 | ||
91 | } | ||
92 | }, | ||
93 | { | ||
94 | "id": "pricing.trial.cta.skip", | ||
95 | "defaultMessage": "!!!Continue to Franz", | ||
96 | "file": "src/components/auth/Pricing.js", | ||
97 | "start": { | ||
98 | "line": 43, | ||
99 | "column": 11 | ||
100 | }, | ||
101 | "end": { | ||
102 | "line": 46, | ||
38 | "column": 3 | 103 | "column": 3 |
39 | } | 104 | } |
40 | }, | 105 | }, |
41 | { | 106 | { |
42 | "id": "pricing.link.skipPayment", | 107 | "id": "pricing.trial.features.headline", |
43 | "defaultMessage": "!!!I don't want to support the development of Franz.", | 108 | "defaultMessage": "!!!Franz Professional includes:", |
44 | "file": "src/components/auth/Pricing.js", | 109 | "file": "src/components/auth/Pricing.js", |
45 | "start": { | 110 | "start": { |
46 | "line": 25, | 111 | "line": 47, |
47 | "column": 15 | 112 | "column": 20 |
48 | }, | 113 | }, |
49 | "end": { | 114 | "end": { |
50 | "line": 28, | 115 | "line": 50, |
51 | "column": 3 | 116 | "column": 3 |
52 | } | 117 | } |
53 | } | 118 | } |
diff --git a/src/i18n/messages/src/components/auth/Signup.json b/src/i18n/messages/src/components/auth/Signup.json index a09745048..2ea71e5ff 100644 --- a/src/i18n/messages/src/components/auth/Signup.json +++ b/src/i18n/messages/src/components/auth/Signup.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Sign up", | 4 | "defaultMessage": "!!!Sign up", |
5 | "file": "src/components/auth/Signup.js", | 5 | "file": "src/components/auth/Signup.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 18, | 7 | "line": 17, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 21, | 11 | "line": 20, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Firstname", | 17 | "defaultMessage": "!!!Firstname", |
18 | "file": "src/components/auth/Signup.js", | 18 | "file": "src/components/auth/Signup.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 22, | 20 | "line": 21, |
21 | "column": 18 | 21 | "column": 18 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 25, | 24 | "line": 24, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Lastname", | 30 | "defaultMessage": "!!!Lastname", |
31 | "file": "src/components/auth/Signup.js", | 31 | "file": "src/components/auth/Signup.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 26, | 33 | "line": 25, |
34 | "column": 17 | 34 | "column": 17 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 29, | 37 | "line": 28, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,24 +43,11 @@ | |||
43 | "defaultMessage": "!!!Email address", | 43 | "defaultMessage": "!!!Email address", |
44 | "file": "src/components/auth/Signup.js", | 44 | "file": "src/components/auth/Signup.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 30, | 46 | "line": 29, |
47 | "column": 14 | 47 | "column": 14 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 33, | 50 | "line": 32, |
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "signup.company.label", | ||
56 | "defaultMessage": "!!!Company", | ||
57 | "file": "src/components/auth/Signup.js", | ||
58 | "start": { | ||
59 | "line": 34, | ||
60 | "column": 16 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 37, | ||
64 | "column": 3 | 51 | "column": 3 |
65 | } | 52 | } |
66 | }, | 53 | }, |
@@ -69,11 +56,11 @@ | |||
69 | "defaultMessage": "!!!Password", | 56 | "defaultMessage": "!!!Password", |
70 | "file": "src/components/auth/Signup.js", | 57 | "file": "src/components/auth/Signup.js", |
71 | "start": { | 58 | "start": { |
72 | "line": 38, | 59 | "line": 37, |
73 | "column": 17 | 60 | "column": 17 |
74 | }, | 61 | }, |
75 | "end": { | 62 | "end": { |
76 | "line": 41, | 63 | "line": 40, |
77 | "column": 3 | 64 | "column": 3 |
78 | } | 65 | } |
79 | }, | 66 | }, |
@@ -82,11 +69,11 @@ | |||
82 | "defaultMessage": "!!!By creating a Franz account you accept the", | 69 | "defaultMessage": "!!!By creating a Franz account you accept the", |
83 | "file": "src/components/auth/Signup.js", | 70 | "file": "src/components/auth/Signup.js", |
84 | "start": { | 71 | "start": { |
85 | "line": 42, | 72 | "line": 41, |
86 | "column": 13 | 73 | "column": 13 |
87 | }, | 74 | }, |
88 | "end": { | 75 | "end": { |
89 | "line": 45, | 76 | "line": 44, |
90 | "column": 3 | 77 | "column": 3 |
91 | } | 78 | } |
92 | }, | 79 | }, |
@@ -95,11 +82,11 @@ | |||
95 | "defaultMessage": "!!!Terms of service", | 82 | "defaultMessage": "!!!Terms of service", |
96 | "file": "src/components/auth/Signup.js", | 83 | "file": "src/components/auth/Signup.js", |
97 | "start": { | 84 | "start": { |
98 | "line": 46, | 85 | "line": 45, |
99 | "column": 9 | 86 | "column": 9 |
100 | }, | 87 | }, |
101 | "end": { | 88 | "end": { |
102 | "line": 49, | 89 | "line": 48, |
103 | "column": 3 | 90 | "column": 3 |
104 | } | 91 | } |
105 | }, | 92 | }, |
@@ -108,11 +95,11 @@ | |||
108 | "defaultMessage": "!!!Privacy Statement", | 95 | "defaultMessage": "!!!Privacy Statement", |
109 | "file": "src/components/auth/Signup.js", | 96 | "file": "src/components/auth/Signup.js", |
110 | "start": { | 97 | "start": { |
111 | "line": 50, | 98 | "line": 49, |
112 | "column": 11 | 99 | "column": 11 |
113 | }, | 100 | }, |
114 | "end": { | 101 | "end": { |
115 | "line": 53, | 102 | "line": 52, |
116 | "column": 3 | 103 | "column": 3 |
117 | } | 104 | } |
118 | }, | 105 | }, |
@@ -121,11 +108,11 @@ | |||
121 | "defaultMessage": "!!!Create account", | 108 | "defaultMessage": "!!!Create account", |
122 | "file": "src/components/auth/Signup.js", | 109 | "file": "src/components/auth/Signup.js", |
123 | "start": { | 110 | "start": { |
124 | "line": 54, | 111 | "line": 53, |
125 | "column": 21 | 112 | "column": 21 |
126 | }, | 113 | }, |
127 | "end": { | 114 | "end": { |
128 | "line": 57, | 115 | "line": 56, |
129 | "column": 3 | 116 | "column": 3 |
130 | } | 117 | } |
131 | }, | 118 | }, |
@@ -134,11 +121,11 @@ | |||
134 | "defaultMessage": "!!!Already have an account, sign in?", | 121 | "defaultMessage": "!!!Already have an account, sign in?", |
135 | "file": "src/components/auth/Signup.js", | 122 | "file": "src/components/auth/Signup.js", |
136 | "start": { | 123 | "start": { |
137 | "line": 58, | 124 | "line": 57, |
138 | "column": 13 | 125 | "column": 13 |
139 | }, | 126 | }, |
140 | "end": { | 127 | "end": { |
141 | "line": 61, | 128 | "line": 60, |
142 | "column": 3 | 129 | "column": 3 |
143 | } | 130 | } |
144 | }, | 131 | }, |
@@ -147,11 +134,11 @@ | |||
147 | "defaultMessage": "!!!A user with that email address already exists", | 134 | "defaultMessage": "!!!A user with that email address already exists", |
148 | "file": "src/components/auth/Signup.js", | 135 | "file": "src/components/auth/Signup.js", |
149 | "start": { | 136 | "start": { |
150 | "line": 62, | 137 | "line": 61, |
151 | "column": 18 | 138 | "column": 18 |
152 | }, | 139 | }, |
153 | "end": { | 140 | "end": { |
154 | "line": 65, | 141 | "line": 64, |
155 | "column": 3 | 142 | "column": 3 |
156 | } | 143 | } |
157 | } | 144 | } |
diff --git a/src/i18n/messages/src/components/layout/AppLayout.json b/src/i18n/messages/src/components/layout/AppLayout.json index b71889155..44cf4fab9 100644 --- a/src/i18n/messages/src/components/layout/AppLayout.json +++ b/src/i18n/messages/src/components/layout/AppLayout.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Your services have been updated.", | 4 | "defaultMessage": "!!!Your services have been updated.", |
5 | "file": "src/components/layout/AppLayout.js", | 5 | "file": "src/components/layout/AppLayout.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 27, | 7 | "line": 28, |
8 | "column": 19 | 8 | "column": 19 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 30, | 11 | "line": 31, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Reload services", | 17 | "defaultMessage": "!!!Reload services", |
18 | "file": "src/components/layout/AppLayout.js", | 18 | "file": "src/components/layout/AppLayout.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 31, | 20 | "line": 32, |
21 | "column": 24 | 21 | "column": 24 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 34, | 24 | "line": 35, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Could not load services and user information", | 30 | "defaultMessage": "!!!Could not load services and user information", |
31 | "file": "src/components/layout/AppLayout.js", | 31 | "file": "src/components/layout/AppLayout.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 35, | 33 | "line": 36, |
34 | "column": 26 | 34 | "column": 26 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 38, | 37 | "line": 39, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | } | 40 | } |
diff --git a/src/i18n/messages/src/components/services/content/ServiceRestricted.json b/src/i18n/messages/src/components/services/content/ServiceRestricted.json new file mode 100644 index 000000000..c1984afe3 --- /dev/null +++ b/src/i18n/messages/src/components/services/content/ServiceRestricted.json | |||
@@ -0,0 +1,67 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "service.restrictedHandler.serviceLimit.headline", | ||
4 | "defaultMessage": "!!!You have reached your service limit.", | ||
5 | "file": "src/components/services/content/ServiceRestricted.js", | ||
6 | "start": { | ||
7 | "line": 11, | ||
8 | "column": 24 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 14, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "service.restrictedHandler.serviceLimit.text", | ||
17 | "defaultMessage": "!!!Please upgrade your account to use more than {count} services.", | ||
18 | "file": "src/components/services/content/ServiceRestricted.js", | ||
19 | "start": { | ||
20 | "line": 15, | ||
21 | "column": 20 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 18, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "service.restrictedHandler.customUrl.headline", | ||
30 | "defaultMessage": "!!!Franz Professional Plan required", | ||
31 | "file": "src/components/services/content/ServiceRestricted.js", | ||
32 | "start": { | ||
33 | "line": 19, | ||
34 | "column": 21 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 22, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "service.restrictedHandler.customUrl.text", | ||
43 | "defaultMessage": "!!!Please upgrade to the Franz Professional plan to use custom urls & self hosted services.", | ||
44 | "file": "src/components/services/content/ServiceRestricted.js", | ||
45 | "start": { | ||
46 | "line": 23, | ||
47 | "column": 17 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 26, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "service.restrictedHandler.action", | ||
56 | "defaultMessage": "!!!Upgrade Account", | ||
57 | "file": "src/components/services/content/ServiceRestricted.js", | ||
58 | "start": { | ||
59 | "line": 27, | ||
60 | "column": 10 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 30, | ||
64 | "column": 3 | ||
65 | } | ||
66 | } | ||
67 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/services/content/Services.json b/src/i18n/messages/src/components/services/content/Services.json index 884ab0c90..eb466c0ac 100644 --- a/src/i18n/messages/src/components/services/content/Services.json +++ b/src/i18n/messages/src/components/services/content/Services.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Welcome to Franz", | 4 | "defaultMessage": "!!!Welcome to Franz", |
5 | "file": "src/components/services/content/Services.js", | 5 | "file": "src/components/services/content/Services.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 11, | 7 | "line": 14, |
8 | "column": 11 | 8 | "column": 11 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 14, | 11 | "line": 17, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Get started", | 17 | "defaultMessage": "!!!Get started", |
18 | "file": "src/components/services/content/Services.js", | 18 | "file": "src/components/services/content/Services.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 15, | 20 | "line": 18, |
21 | "column": 14 | 21 | "column": 14 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 18, | 24 | "line": 21, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | } | 27 | } |
diff --git a/src/i18n/messages/src/components/settings/account/AccountDashboard.json b/src/i18n/messages/src/components/settings/account/AccountDashboard.json index 4969db910..06d53e41d 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 @@ | |||
4 | "defaultMessage": "!!!Account", | 4 | "defaultMessage": "!!!Account", |
5 | "file": "src/components/settings/account/AccountDashboard.js", | 5 | "file": "src/components/settings/account/AccountDashboard.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 14, | 7 | "line": 18, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 17, | 11 | "line": 21, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,21 +17,8 @@ | |||
17 | "defaultMessage": "!!!Your Subscription", | 17 | "defaultMessage": "!!!Your Subscription", |
18 | "file": "src/components/settings/account/AccountDashboard.js", | 18 | "file": "src/components/settings/account/AccountDashboard.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 18, | ||
21 | "column": 24 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 21, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "settings.account.headlineUpgrade", | ||
30 | "defaultMessage": "!!!Upgrade your Account", | ||
31 | "file": "src/components/settings/account/AccountDashboard.js", | ||
32 | "start": { | ||
33 | "line": 22, | 20 | "line": 22, |
34 | "column": 19 | 21 | "column": 24 |
35 | }, | 22 | }, |
36 | "end": { | 23 | "end": { |
37 | "line": 25, | 24 | "line": 25, |
@@ -65,15 +52,28 @@ | |||
65 | } | 52 | } |
66 | }, | 53 | }, |
67 | { | 54 | { |
55 | "id": "settings.account.upgradeToPro.label", | ||
56 | "defaultMessage": "!!!Upgrade to Franz Professional", | ||
57 | "file": "src/components/settings/account/AccountDashboard.js", | ||
58 | "start": { | ||
59 | "line": 34, | ||
60 | "column": 23 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 37, | ||
64 | "column": 3 | ||
65 | } | ||
66 | }, | ||
67 | { | ||
68 | "id": "settings.account.accountType.basic", | 68 | "id": "settings.account.accountType.basic", |
69 | "defaultMessage": "!!!Basic Account", | 69 | "defaultMessage": "!!!Basic Account", |
70 | "file": "src/components/settings/account/AccountDashboard.js", | 70 | "file": "src/components/settings/account/AccountDashboard.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 34, | 72 | "line": 38, |
73 | "column": 20 | 73 | "column": 20 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 37, | 76 | "line": 41, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Premium Supporter Account", | 82 | "defaultMessage": "!!!Premium Supporter Account", |
83 | "file": "src/components/settings/account/AccountDashboard.js", | 83 | "file": "src/components/settings/account/AccountDashboard.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 38, | 85 | "line": 42, |
86 | "column": 22 | 86 | "column": 22 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 41, | 89 | "line": 45, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Edit Account", | 95 | "defaultMessage": "!!!Edit Account", |
96 | "file": "src/components/settings/account/AccountDashboard.js", | 96 | "file": "src/components/settings/account/AccountDashboard.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 42, | 98 | "line": 46, |
99 | "column": 21 | 99 | "column": 21 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 45, | 102 | "line": 49, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | }, | 105 | }, |
@@ -108,11 +108,11 @@ | |||
108 | "defaultMessage": "!!Invoices", | 108 | "defaultMessage": "!!Invoices", |
109 | "file": "src/components/settings/account/AccountDashboard.js", | 109 | "file": "src/components/settings/account/AccountDashboard.js", |
110 | "start": { | 110 | "start": { |
111 | "line": 46, | 111 | "line": 50, |
112 | "column": 18 | 112 | "column": 18 |
113 | }, | 113 | }, |
114 | "end": { | 114 | "end": { |
115 | "line": 49, | 115 | "line": 53, |
116 | "column": 3 | 116 | "column": 3 |
117 | } | 117 | } |
118 | }, | 118 | }, |
@@ -121,11 +121,11 @@ | |||
121 | "defaultMessage": "!!!Download", | 121 | "defaultMessage": "!!!Download", |
122 | "file": "src/components/settings/account/AccountDashboard.js", | 122 | "file": "src/components/settings/account/AccountDashboard.js", |
123 | "start": { | 123 | "start": { |
124 | "line": 50, | 124 | "line": 54, |
125 | "column": 19 | 125 | "column": 19 |
126 | }, | 126 | }, |
127 | "end": { | 127 | "end": { |
128 | "line": 53, | 128 | "line": 57, |
129 | "column": 3 | 129 | "column": 3 |
130 | } | 130 | } |
131 | }, | 131 | }, |
@@ -134,11 +134,11 @@ | |||
134 | "defaultMessage": "!!!Could not load user information", | 134 | "defaultMessage": "!!!Could not load user information", |
135 | "file": "src/components/settings/account/AccountDashboard.js", | 135 | "file": "src/components/settings/account/AccountDashboard.js", |
136 | "start": { | 136 | "start": { |
137 | "line": 54, | 137 | "line": 58, |
138 | "column": 25 | 138 | "column": 25 |
139 | }, | 139 | }, |
140 | "end": { | 140 | "end": { |
141 | "line": 57, | 141 | "line": 61, |
142 | "column": 3 | 142 | "column": 3 |
143 | } | 143 | } |
144 | }, | 144 | }, |
@@ -147,11 +147,11 @@ | |||
147 | "defaultMessage": "!!!Try again", | 147 | "defaultMessage": "!!!Try again", |
148 | "file": "src/components/settings/account/AccountDashboard.js", | 148 | "file": "src/components/settings/account/AccountDashboard.js", |
149 | "start": { | 149 | "start": { |
150 | "line": 58, | 150 | "line": 62, |
151 | "column": 28 | 151 | "column": 28 |
152 | }, | 152 | }, |
153 | "end": { | 153 | "end": { |
154 | "line": 61, | 154 | "line": 65, |
155 | "column": 3 | 155 | "column": 3 |
156 | } | 156 | } |
157 | }, | 157 | }, |
@@ -160,11 +160,11 @@ | |||
160 | "defaultMessage": "!!!Delete account", | 160 | "defaultMessage": "!!!Delete account", |
161 | "file": "src/components/settings/account/AccountDashboard.js", | 161 | "file": "src/components/settings/account/AccountDashboard.js", |
162 | "start": { | 162 | "start": { |
163 | "line": 62, | 163 | "line": 66, |
164 | "column": 17 | 164 | "column": 17 |
165 | }, | 165 | }, |
166 | "end": { | 166 | "end": { |
167 | "line": 65, | 167 | "line": 69, |
168 | "column": 3 | 168 | "column": 3 |
169 | } | 169 | } |
170 | }, | 170 | }, |
@@ -173,11 +173,11 @@ | |||
173 | "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", | 173 | "defaultMessage": "!!!If you don't need your Franz account any longer, you can delete your account and all related data here.", |
174 | "file": "src/components/settings/account/AccountDashboard.js", | 174 | "file": "src/components/settings/account/AccountDashboard.js", |
175 | "start": { | 175 | "start": { |
176 | "line": 66, | 176 | "line": 70, |
177 | "column": 14 | 177 | "column": 14 |
178 | }, | 178 | }, |
179 | "end": { | 179 | "end": { |
180 | "line": 69, | 180 | "line": 73, |
181 | "column": 3 | 181 | "column": 3 |
182 | } | 182 | } |
183 | }, | 183 | }, |
@@ -186,11 +186,63 @@ | |||
186 | "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", | 186 | "defaultMessage": "!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!", |
187 | "file": "src/components/settings/account/AccountDashboard.js", | 187 | "file": "src/components/settings/account/AccountDashboard.js", |
188 | "start": { | 188 | "start": { |
189 | "line": 70, | 189 | "line": 74, |
190 | "column": 19 | 190 | "column": 19 |
191 | }, | 191 | }, |
192 | "end": { | 192 | "end": { |
193 | "line": 73, | 193 | "line": 77, |
194 | "column": 3 | ||
195 | } | ||
196 | }, | ||
197 | { | ||
198 | "id": "settings.account.trial", | ||
199 | "defaultMessage": "!!!Free Trial", | ||
200 | "file": "src/components/settings/account/AccountDashboard.js", | ||
201 | "start": { | ||
202 | "line": 78, | ||
203 | "column": 9 | ||
204 | }, | ||
205 | "end": { | ||
206 | "line": 81, | ||
207 | "column": 3 | ||
208 | } | ||
209 | }, | ||
210 | { | ||
211 | "id": "settings.account.yourLicense", | ||
212 | "defaultMessage": "!!!Your Franz License:", | ||
213 | "file": "src/components/settings/account/AccountDashboard.js", | ||
214 | "start": { | ||
215 | "line": 82, | ||
216 | "column": 15 | ||
217 | }, | ||
218 | "end": { | ||
219 | "line": 85, | ||
220 | "column": 3 | ||
221 | } | ||
222 | }, | ||
223 | { | ||
224 | "id": "settings.account.trialEndsIn", | ||
225 | "defaultMessage": "!!!Your free trial ends in {duration}.", | ||
226 | "file": "src/components/settings/account/AccountDashboard.js", | ||
227 | "start": { | ||
228 | "line": 86, | ||
229 | "column": 15 | ||
230 | }, | ||
231 | "end": { | ||
232 | "line": 89, | ||
233 | "column": 3 | ||
234 | } | ||
235 | }, | ||
236 | { | ||
237 | "id": "settings.account.trialUpdateBillingInfo", | ||
238 | "defaultMessage": "!!!Please update your billing info to continue using {license} after your trial period.", | ||
239 | "file": "src/components/settings/account/AccountDashboard.js", | ||
240 | "start": { | ||
241 | "line": 90, | ||
242 | "column": 33 | ||
243 | }, | ||
244 | "end": { | ||
245 | "line": 93, | ||
194 | "column": 3 | 246 | "column": 3 |
195 | } | 247 | } |
196 | } | 248 | } |
diff --git a/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json b/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json index 70a989211..7dfb3ce04 100644 --- a/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json +++ b/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Available services", | 4 | "defaultMessage": "!!!Available services", |
5 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 5 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 13, | 7 | "line": 14, |
8 | "column": 21 | 8 | "column": 21 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 16, | 11 | "line": 17, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Your services", | 17 | "defaultMessage": "!!!Your services", |
18 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 18 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 17, | 20 | "line": 18, |
21 | "column": 16 | 21 | "column": 16 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 20, | 24 | "line": 21, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Your workspaces", | 30 | "defaultMessage": "!!!Your workspaces", |
31 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 31 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 21, | 33 | "line": 22, |
34 | "column": 18 | 34 | "column": 18 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 24, | 37 | "line": 25, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Account", | 43 | "defaultMessage": "!!!Account", |
44 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 44 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 25, | 46 | "line": 26, |
47 | "column": 11 | 47 | "column": 11 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 28, | 50 | "line": 29, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Manage Team", | 56 | "defaultMessage": "!!!Manage Team", |
57 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 57 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 29, | 59 | "line": 30, |
60 | "column": 8 | 60 | "column": 8 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 32, | 63 | "line": 33, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Settings", | 69 | "defaultMessage": "!!!Settings", |
70 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 70 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 33, | 72 | "line": 34, |
73 | "column": 12 | 73 | "column": 12 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 36, | 76 | "line": 37, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Invite Friends", | 82 | "defaultMessage": "!!!Invite Friends", |
83 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 83 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 37, | 85 | "line": 38, |
86 | "column": 17 | 86 | "column": 17 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 40, | 89 | "line": 41, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Logout", | 95 | "defaultMessage": "!!!Logout", |
96 | "file": "src/components/settings/navigation/SettingsNavigation.js", | 96 | "file": "src/components/settings/navigation/SettingsNavigation.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 41, | 98 | "line": 42, |
99 | "column": 10 | 99 | "column": 10 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 44, | 102 | "line": 45, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | } | 105 | } |
diff --git a/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json b/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json index 7d9ed3283..8afaaed50 100644 --- a/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json +++ b/src/i18n/messages/src/components/settings/recipes/RecipesDashboard.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Available Services", | 4 | "defaultMessage": "!!!Available Services", |
5 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 5 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 15, | 7 | "line": 20, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 18, | 11 | "line": 23, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Search service", | 17 | "defaultMessage": "!!!Search service", |
18 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 18 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 19, | 20 | "line": 24, |
21 | "column": 17 | 21 | "column": 17 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 22, | 24 | "line": 27, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Most popular", | 30 | "defaultMessage": "!!!Most popular", |
31 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 31 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 23, | 33 | "line": 28, |
34 | "column": 22 | 34 | "column": 22 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 26, | 37 | "line": 31, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,24 +43,24 @@ | |||
43 | "defaultMessage": "!!!All services", | 43 | "defaultMessage": "!!!All services", |
44 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 44 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 27, | 46 | "line": 32, |
47 | "column": 14 | 47 | "column": 14 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 30, | 50 | "line": 35, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
54 | { | 54 | { |
55 | "id": "settings.recipes.dev", | 55 | "id": "settings.recipes.custom", |
56 | "defaultMessage": "!!!Development", | 56 | "defaultMessage": "!!!Custom Services", |
57 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 57 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 31, | 59 | "line": 36, |
60 | "column": 14 | 60 | "column": 17 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 34, | 63 | "line": 39, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Sorry, but no service matched your search term.", | 69 | "defaultMessage": "!!!Sorry, but no service matched your search term.", |
70 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 70 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 35, | 72 | "line": 40, |
73 | "column": 16 | 73 | "column": 16 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 38, | 76 | "line": 43, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Service successfully added", | 82 | "defaultMessage": "!!!Service successfully added", |
83 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 83 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 39, | 85 | "line": 44, |
86 | "column": 31 | 86 | "column": 31 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 42, | 89 | "line": 47, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,89 @@ | |||
95 | "defaultMessage": "!!!Missing a service?", | 95 | "defaultMessage": "!!!Missing a service?", |
96 | "file": "src/components/settings/recipes/RecipesDashboard.js", | 96 | "file": "src/components/settings/recipes/RecipesDashboard.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 43, | 98 | "line": 48, |
99 | "column": 18 | 99 | "column": 18 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 46, | 102 | "line": 51, |
103 | "column": 3 | ||
104 | } | ||
105 | }, | ||
106 | { | ||
107 | "id": "settings.recipes.customService.intro", | ||
108 | "defaultMessage": "!!!To add a custom service, copy the recipe folder into:", | ||
109 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
110 | "start": { | ||
111 | "line": 52, | ||
112 | "column": 21 | ||
113 | }, | ||
114 | "end": { | ||
115 | "line": 55, | ||
116 | "column": 3 | ||
117 | } | ||
118 | }, | ||
119 | { | ||
120 | "id": "settings.recipes.customService.openFolder", | ||
121 | "defaultMessage": "!!!Open directory", | ||
122 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
123 | "start": { | ||
124 | "line": 56, | ||
125 | "column": 14 | ||
126 | }, | ||
127 | "end": { | ||
128 | "line": 59, | ||
129 | "column": 3 | ||
130 | } | ||
131 | }, | ||
132 | { | ||
133 | "id": "settings.recipes.customService.openDevDocs", | ||
134 | "defaultMessage": "!!!Developer Documentation", | ||
135 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
136 | "start": { | ||
137 | "line": 60, | ||
138 | "column": 15 | ||
139 | }, | ||
140 | "end": { | ||
141 | "line": 63, | ||
142 | "column": 3 | ||
143 | } | ||
144 | }, | ||
145 | { | ||
146 | "id": "settings.recipes.customService.headline.customRecipes", | ||
147 | "defaultMessage": "!!!Custom Service Recipes", | ||
148 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
149 | "start": { | ||
150 | "line": 64, | ||
151 | "column": 25 | ||
152 | }, | ||
153 | "end": { | ||
154 | "line": 67, | ||
155 | "column": 3 | ||
156 | } | ||
157 | }, | ||
158 | { | ||
159 | "id": "settings.recipes.customService.headline.communityRecipes", | ||
160 | "defaultMessage": "!!!Community Services", | ||
161 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
162 | "start": { | ||
163 | "line": 68, | ||
164 | "column": 28 | ||
165 | }, | ||
166 | "end": { | ||
167 | "line": 71, | ||
168 | "column": 3 | ||
169 | } | ||
170 | }, | ||
171 | { | ||
172 | "id": "settings.recipes.customService.headline.devRecipes", | ||
173 | "defaultMessage": "!!!Your Development Service Recipes", | ||
174 | "file": "src/components/settings/recipes/RecipesDashboard.js", | ||
175 | "start": { | ||
176 | "line": 72, | ||
177 | "column": 22 | ||
178 | }, | ||
179 | "end": { | ||
180 | "line": 75, | ||
103 | "column": 3 | 181 | "column": 3 |
104 | } | 182 | } |
105 | } | 183 | } |
diff --git a/src/i18n/messages/src/components/settings/services/EditServiceForm.json b/src/i18n/messages/src/components/settings/services/EditServiceForm.json index 42b741b7a..e66db807d 100644 --- a/src/i18n/messages/src/components/settings/services/EditServiceForm.json +++ b/src/i18n/messages/src/components/settings/services/EditServiceForm.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Save service", | 4 | "defaultMessage": "!!!Save service", |
5 | "file": "src/components/settings/services/EditServiceForm.js", | 5 | "file": "src/components/settings/services/EditServiceForm.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 22, | 7 | "line": 24, |
8 | "column": 15 | 8 | "column": 15 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 25, | 11 | "line": 27, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Delete Service", | 17 | "defaultMessage": "!!!Delete Service", |
18 | "file": "src/components/settings/services/EditServiceForm.js", | 18 | "file": "src/components/settings/services/EditServiceForm.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 26, | 20 | "line": 28, |
21 | "column": 17 | 21 | "column": 17 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 29, | 24 | "line": 31, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Available services", | 30 | "defaultMessage": "!!!Available services", |
31 | "file": "src/components/settings/services/EditServiceForm.js", | 31 | "file": "src/components/settings/services/EditServiceForm.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 30, | 33 | "line": 32, |
34 | "column": 21 | 34 | "column": 21 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 33, | 37 | "line": 35, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Your services", | 43 | "defaultMessage": "!!!Your services", |
44 | "file": "src/components/settings/services/EditServiceForm.js", | 44 | "file": "src/components/settings/services/EditServiceForm.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 34, | 46 | "line": 36, |
47 | "column": 16 | 47 | "column": 16 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 37, | 50 | "line": 39, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Add {name}", | 56 | "defaultMessage": "!!!Add {name}", |
57 | "file": "src/components/settings/services/EditServiceForm.js", | 57 | "file": "src/components/settings/services/EditServiceForm.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 38, | 59 | "line": 40, |
60 | "column": 22 | 60 | "column": 22 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 41, | 63 | "line": 43, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Edit {name}", | 69 | "defaultMessage": "!!!Edit {name}", |
70 | "file": "src/components/settings/services/EditServiceForm.js", | 70 | "file": "src/components/settings/services/EditServiceForm.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 42, | 72 | "line": 44, |
73 | "column": 23 | 73 | "column": 23 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 45, | 76 | "line": 47, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Hosted", | 82 | "defaultMessage": "!!!Hosted", |
83 | "file": "src/components/settings/services/EditServiceForm.js", | 83 | "file": "src/components/settings/services/EditServiceForm.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 46, | 85 | "line": 48, |
86 | "column": 13 | 86 | "column": 13 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 49, | 89 | "line": 51, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Self hosted ⭐️", | 95 | "defaultMessage": "!!!Self hosted ⭐️", |
96 | "file": "src/components/settings/services/EditServiceForm.js", | 96 | "file": "src/components/settings/services/EditServiceForm.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 50, | 98 | "line": 52, |
99 | "column": 16 | 99 | "column": 16 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 53, | 102 | "line": 55, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | }, | 105 | }, |
@@ -108,11 +108,11 @@ | |||
108 | "defaultMessage": "!!!Use the hosted {name} service.", | 108 | "defaultMessage": "!!!Use the hosted {name} service.", |
109 | "file": "src/components/settings/services/EditServiceForm.js", | 109 | "file": "src/components/settings/services/EditServiceForm.js", |
110 | "start": { | 110 | "start": { |
111 | "line": 54, | 111 | "line": 56, |
112 | "column": 20 | 112 | "column": 20 |
113 | }, | 113 | }, |
114 | "end": { | 114 | "end": { |
115 | "line": 57, | 115 | "line": 59, |
116 | "column": 3 | 116 | "column": 3 |
117 | } | 117 | } |
118 | }, | 118 | }, |
@@ -121,11 +121,11 @@ | |||
121 | "defaultMessage": "!!!Could not validate custom {name} server.", | 121 | "defaultMessage": "!!!Could not validate custom {name} server.", |
122 | "file": "src/components/settings/services/EditServiceForm.js", | 122 | "file": "src/components/settings/services/EditServiceForm.js", |
123 | "start": { | 123 | "start": { |
124 | "line": 58, | 124 | "line": 60, |
125 | "column": 28 | 125 | "column": 28 |
126 | }, | 126 | }, |
127 | "end": { | 127 | "end": { |
128 | "line": 61, | 128 | "line": 63, |
129 | "column": 3 | 129 | "column": 3 |
130 | } | 130 | } |
131 | }, | 131 | }, |
@@ -134,11 +134,11 @@ | |||
134 | "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", | 134 | "defaultMessage": "!!!To add self hosted services, you need a Franz Premium Supporter Account.", |
135 | "file": "src/components/settings/services/EditServiceForm.js", | 135 | "file": "src/components/settings/services/EditServiceForm.js", |
136 | "start": { | 136 | "start": { |
137 | "line": 62, | 137 | "line": 64, |
138 | "column": 24 | 138 | "column": 24 |
139 | }, | 139 | }, |
140 | "end": { | 140 | "end": { |
141 | "line": 65, | 141 | "line": 67, |
142 | "column": 3 | 142 | "column": 3 |
143 | } | 143 | } |
144 | }, | 144 | }, |
@@ -147,11 +147,11 @@ | |||
147 | "defaultMessage": "!!!Upgrade your account", | 147 | "defaultMessage": "!!!Upgrade your account", |
148 | "file": "src/components/settings/services/EditServiceForm.js", | 148 | "file": "src/components/settings/services/EditServiceForm.js", |
149 | "start": { | 149 | "start": { |
150 | "line": 66, | 150 | "line": 68, |
151 | "column": 27 | 151 | "column": 27 |
152 | }, | 152 | }, |
153 | "end": { | 153 | "end": { |
154 | "line": 69, | 154 | "line": 71, |
155 | "column": 3 | 155 | "column": 3 |
156 | } | 156 | } |
157 | }, | 157 | }, |
@@ -160,11 +160,11 @@ | |||
160 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", | 160 | "defaultMessage": "!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...", |
161 | "file": "src/components/settings/services/EditServiceForm.js", | 161 | "file": "src/components/settings/services/EditServiceForm.js", |
162 | "start": { | 162 | "start": { |
163 | "line": 70, | 163 | "line": 72, |
164 | "column": 23 | 164 | "column": 23 |
165 | }, | 165 | }, |
166 | "end": { | 166 | "end": { |
167 | "line": 73, | 167 | "line": 75, |
168 | "column": 3 | 168 | "column": 3 |
169 | } | 169 | } |
170 | }, | 170 | }, |
@@ -173,11 +173,11 @@ | |||
173 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", | 173 | "defaultMessage": "!!!When disabled, all notification sounds and audio playback are muted", |
174 | "file": "src/components/settings/services/EditServiceForm.js", | 174 | "file": "src/components/settings/services/EditServiceForm.js", |
175 | "start": { | 175 | "start": { |
176 | "line": 74, | 176 | "line": 76, |
177 | "column": 15 | 177 | "column": 15 |
178 | }, | 178 | }, |
179 | "end": { | 179 | "end": { |
180 | "line": 77, | 180 | "line": 79, |
181 | "column": 3 | 181 | "column": 3 |
182 | } | 182 | } |
183 | }, | 183 | }, |
@@ -186,11 +186,11 @@ | |||
186 | "defaultMessage": "!!!Notifications", | 186 | "defaultMessage": "!!!Notifications", |
187 | "file": "src/components/settings/services/EditServiceForm.js", | 187 | "file": "src/components/settings/services/EditServiceForm.js", |
188 | "start": { | 188 | "start": { |
189 | "line": 78, | 189 | "line": 80, |
190 | "column": 25 | 190 | "column": 25 |
191 | }, | 191 | }, |
192 | "end": { | 192 | "end": { |
193 | "line": 81, | 193 | "line": 83, |
194 | "column": 3 | 194 | "column": 3 |
195 | } | 195 | } |
196 | }, | 196 | }, |
@@ -199,11 +199,11 @@ | |||
199 | "defaultMessage": "!!!Unread message badges", | 199 | "defaultMessage": "!!!Unread message badges", |
200 | "file": "src/components/settings/services/EditServiceForm.js", | 200 | "file": "src/components/settings/services/EditServiceForm.js", |
201 | "start": { | 201 | "start": { |
202 | "line": 82, | 202 | "line": 84, |
203 | "column": 18 | 203 | "column": 18 |
204 | }, | 204 | }, |
205 | "end": { | 205 | "end": { |
206 | "line": 85, | 206 | "line": 87, |
207 | "column": 3 | 207 | "column": 3 |
208 | } | 208 | } |
209 | }, | 209 | }, |
@@ -212,11 +212,11 @@ | |||
212 | "defaultMessage": "!!!General", | 212 | "defaultMessage": "!!!General", |
213 | "file": "src/components/settings/services/EditServiceForm.js", | 213 | "file": "src/components/settings/services/EditServiceForm.js", |
214 | "start": { | 214 | "start": { |
215 | "line": 86, | 215 | "line": 88, |
216 | "column": 19 | 216 | "column": 19 |
217 | }, | 217 | }, |
218 | "end": { | 218 | "end": { |
219 | "line": 89, | 219 | "line": 91, |
220 | "column": 3 | 220 | "column": 3 |
221 | } | 221 | } |
222 | }, | 222 | }, |
@@ -225,11 +225,11 @@ | |||
225 | "defaultMessage": "!!!Delete", | 225 | "defaultMessage": "!!!Delete", |
226 | "file": "src/components/settings/services/EditServiceForm.js", | 226 | "file": "src/components/settings/services/EditServiceForm.js", |
227 | "start": { | 227 | "start": { |
228 | "line": 90, | 228 | "line": 92, |
229 | "column": 14 | 229 | "column": 14 |
230 | }, | 230 | }, |
231 | "end": { | 231 | "end": { |
232 | "line": 93, | 232 | "line": 95, |
233 | "column": 3 | 233 | "column": 3 |
234 | } | 234 | } |
235 | }, | 235 | }, |
@@ -238,11 +238,11 @@ | |||
238 | "defaultMessage": "!!!Drop your image, or click here", | 238 | "defaultMessage": "!!!Drop your image, or click here", |
239 | "file": "src/components/settings/services/EditServiceForm.js", | 239 | "file": "src/components/settings/services/EditServiceForm.js", |
240 | "start": { | 240 | "start": { |
241 | "line": 94, | 241 | "line": 96, |
242 | "column": 14 | 242 | "column": 14 |
243 | }, | 243 | }, |
244 | "end": { | 244 | "end": { |
245 | "line": 97, | 245 | "line": 99, |
246 | "column": 3 | 246 | "column": 3 |
247 | } | 247 | } |
248 | }, | 248 | }, |
@@ -251,11 +251,11 @@ | |||
251 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", | 251 | "defaultMessage": "!!!HTTP/HTTPS Proxy Settings", |
252 | "file": "src/components/settings/services/EditServiceForm.js", | 252 | "file": "src/components/settings/services/EditServiceForm.js", |
253 | "start": { | 253 | "start": { |
254 | "line": 98, | 254 | "line": 100, |
255 | "column": 17 | 255 | "column": 17 |
256 | }, | 256 | }, |
257 | "end": { | 257 | "end": { |
258 | "line": 101, | 258 | "line": 103, |
259 | "column": 3 | 259 | "column": 3 |
260 | } | 260 | } |
261 | }, | 261 | }, |
@@ -264,11 +264,11 @@ | |||
264 | "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", | 264 | "defaultMessage": "!!!Please restart Franz after changing proxy Settings.", |
265 | "file": "src/components/settings/services/EditServiceForm.js", | 265 | "file": "src/components/settings/services/EditServiceForm.js", |
266 | "start": { | 266 | "start": { |
267 | "line": 102, | 267 | "line": 104, |
268 | "column": 20 | 268 | "column": 20 |
269 | }, | 269 | }, |
270 | "end": { | 270 | "end": { |
271 | "line": 105, | 271 | "line": 107, |
272 | "column": 3 | 272 | "column": 3 |
273 | } | 273 | } |
274 | }, | 274 | }, |
@@ -277,11 +277,11 @@ | |||
277 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", | 277 | "defaultMessage": "!!!Proxy settings will not be synchronized with the Franz servers.", |
278 | "file": "src/components/settings/services/EditServiceForm.js", | 278 | "file": "src/components/settings/services/EditServiceForm.js", |
279 | "start": { | 279 | "start": { |
280 | "line": 106, | 280 | "line": 108, |
281 | "column": 13 | 281 | "column": 13 |
282 | }, | 282 | }, |
283 | "end": { | 283 | "end": { |
284 | "line": 109, | 284 | "line": 111, |
285 | "column": 3 | 285 | "column": 3 |
286 | } | 286 | } |
287 | } | 287 | } |
diff --git a/src/i18n/messages/src/components/settings/services/ServicesDashboard.json b/src/i18n/messages/src/components/settings/services/ServicesDashboard.json index 3803c6512..fa661ea2f 100644 --- a/src/i18n/messages/src/components/settings/services/ServicesDashboard.json +++ b/src/i18n/messages/src/components/settings/services/ServicesDashboard.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Your services", | 4 | "defaultMessage": "!!!Your services", |
5 | "file": "src/components/settings/services/ServicesDashboard.js", | 5 | "file": "src/components/settings/services/ServicesDashboard.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 14, | 7 | "line": 15, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 17, | 11 | "line": 18, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Search service", | 17 | "defaultMessage": "!!!Search service", |
18 | "file": "src/components/settings/services/ServicesDashboard.js", | 18 | "file": "src/components/settings/services/ServicesDashboard.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 18, | 20 | "line": 19, |
21 | "column": 17 | 21 | "column": 17 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 21, | 24 | "line": 22, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!You haven't added any services yet.", | 30 | "defaultMessage": "!!!You haven't added any services yet.", |
31 | "file": "src/components/settings/services/ServicesDashboard.js", | 31 | "file": "src/components/settings/services/ServicesDashboard.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 22, | 33 | "line": 23, |
34 | "column": 19 | 34 | "column": 19 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 25, | 37 | "line": 26, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Sorry, but no service matched your search term.", | 43 | "defaultMessage": "!!!Sorry, but no service matched your search term.", |
44 | "file": "src/components/settings/services/ServicesDashboard.js", | 44 | "file": "src/components/settings/services/ServicesDashboard.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 26, | 46 | "line": 27, |
47 | "column": 18 | 47 | "column": 18 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 29, | 50 | "line": 30, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Discover services", | 56 | "defaultMessage": "!!!Discover services", |
57 | "file": "src/components/settings/services/ServicesDashboard.js", | 57 | "file": "src/components/settings/services/ServicesDashboard.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 30, | 59 | "line": 31, |
60 | "column": 20 | 60 | "column": 20 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 33, | 63 | "line": 34, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Could not load your services", | 69 | "defaultMessage": "!!!Could not load your services", |
70 | "file": "src/components/settings/services/ServicesDashboard.js", | 70 | "file": "src/components/settings/services/ServicesDashboard.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 34, | 72 | "line": 35, |
73 | "column": 25 | 73 | "column": 25 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 37, | 76 | "line": 38, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Try again", | 82 | "defaultMessage": "!!!Try again", |
83 | "file": "src/components/settings/services/ServicesDashboard.js", | 83 | "file": "src/components/settings/services/ServicesDashboard.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 38, | 85 | "line": 39, |
86 | "column": 21 | 86 | "column": 21 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 41, | 89 | "line": 42, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Your changes have been saved", | 95 | "defaultMessage": "!!!Your changes have been saved", |
96 | "file": "src/components/settings/services/ServicesDashboard.js", | 96 | "file": "src/components/settings/services/ServicesDashboard.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 42, | 98 | "line": 43, |
99 | "column": 15 | 99 | "column": 15 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 45, | 102 | "line": 46, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | }, | 105 | }, |
@@ -108,11 +108,11 @@ | |||
108 | "defaultMessage": "!!!Service has been deleted", | 108 | "defaultMessage": "!!!Service has been deleted", |
109 | "file": "src/components/settings/services/ServicesDashboard.js", | 109 | "file": "src/components/settings/services/ServicesDashboard.js", |
110 | "start": { | 110 | "start": { |
111 | "line": 46, | 111 | "line": 47, |
112 | "column": 15 | 112 | "column": 15 |
113 | }, | 113 | }, |
114 | "end": { | 114 | "end": { |
115 | "line": 49, | 115 | "line": 50, |
116 | "column": 3 | 116 | "column": 3 |
117 | } | 117 | } |
118 | } | 118 | } |
diff --git a/src/i18n/messages/src/components/subscription/SubscriptionForm.json b/src/i18n/messages/src/components/subscription/SubscriptionForm.json index f98eb986f..6d235254e 100644 --- a/src/i18n/messages/src/components/subscription/SubscriptionForm.json +++ b/src/i18n/messages/src/components/subscription/SubscriptionForm.json | |||
@@ -1,183 +1,53 @@ | |||
1 | [ | 1 | [ |
2 | { | 2 | { |
3 | "id": "subscription.submit.label", | 3 | "id": "subscription.cta.choosePlan", |
4 | "defaultMessage": "!!!Support the development of Franz", | 4 | "defaultMessage": "!!!Choose your plan", |
5 | "file": "src/components/subscription/SubscriptionForm.js", | 5 | "file": "src/components/subscription/SubscriptionForm.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 14, | 7 | "line": 13, |
8 | "column": 21 | 8 | "column": 21 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 17, | 11 | "line": 16, |
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "subscription.paymentSessionError", | ||
17 | "defaultMessage": "!!!Could not initialize payment form", | ||
18 | "file": "src/components/subscription/SubscriptionForm.js", | ||
19 | "start": { | ||
20 | "line": 18, | ||
21 | "column": 23 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 21, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "subscription.type.free", | ||
30 | "defaultMessage": "!!!free", | ||
31 | "file": "src/components/subscription/SubscriptionForm.js", | ||
32 | "start": { | ||
33 | "line": 22, | ||
34 | "column": 12 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 25, | ||
38 | "column": 3 | 12 | "column": 3 |
39 | } | 13 | } |
40 | }, | 14 | }, |
41 | { | 15 | { |
42 | "id": "subscription.type.month", | 16 | "id": "settings.account.headlineUpgradeAccount", |
43 | "defaultMessage": "!!!month", | 17 | "defaultMessage": "!!!Upgrade your account and get the full Franz experience", |
44 | "file": "src/components/subscription/SubscriptionForm.js", | 18 | "file": "src/components/subscription/SubscriptionForm.js", |
45 | "start": { | 19 | "start": { |
46 | "line": 26, | 20 | "line": 17, |
47 | "column": 15 | 21 | "column": 18 |
48 | }, | 22 | }, |
49 | "end": { | 23 | "end": { |
50 | "line": 29, | 24 | "line": 20, |
51 | "column": 3 | 25 | "column": 3 |
52 | } | 26 | } |
53 | }, | 27 | }, |
54 | { | 28 | { |
55 | "id": "subscription.type.year", | 29 | "id": "subscription.teaser.intro", |
56 | "defaultMessage": "!!!year", | 30 | "defaultMessage": "!!!Franz 5 comes with a wide range of new features to boost up your everyday communication - batteries included. Check out our new plans and find out which one suits you most!", |
57 | "file": "src/components/subscription/SubscriptionForm.js", | 31 | "file": "src/components/subscription/SubscriptionForm.js", |
58 | "start": { | 32 | "start": { |
59 | "line": 30, | 33 | "line": 21, |
60 | "column": 14 | 34 | "column": 14 |
61 | }, | 35 | }, |
62 | "end": { | 36 | "end": { |
63 | "line": 33, | 37 | "line": 24, |
64 | "column": 3 | 38 | "column": 3 |
65 | } | 39 | } |
66 | }, | 40 | }, |
67 | { | 41 | { |
68 | "id": "subscription.includedFeatures", | 42 | "id": "subscription.teaser.includedFeatures", |
69 | "defaultMessage": "!!!The Franz Premium Supporter Account includes", | 43 | "defaultMessage": "!!!Paid Franz Plans include:", |
70 | "file": "src/components/subscription/SubscriptionForm.js", | 44 | "file": "src/components/subscription/SubscriptionForm.js", |
71 | "start": { | 45 | "start": { |
72 | "line": 34, | 46 | "line": 25, |
73 | "column": 20 | 47 | "column": 20 |
74 | }, | 48 | }, |
75 | "end": { | 49 | "end": { |
76 | "line": 37, | 50 | "line": 28, |
77 | "column": 3 | ||
78 | } | ||
79 | }, | ||
80 | { | ||
81 | "id": "subscription.features.onpremise.mattermost", | ||
82 | "defaultMessage": "!!!Add on-premise/hosted services like Mattermost", | ||
83 | "file": "src/components/subscription/SubscriptionForm.js", | ||
84 | "start": { | ||
85 | "line": 38, | ||
86 | "column": 13 | ||
87 | }, | ||
88 | "end": { | ||
89 | "line": 41, | ||
90 | "column": 3 | ||
91 | } | ||
92 | }, | ||
93 | { | ||
94 | "id": "subscription.features.noInterruptions", | ||
95 | "defaultMessage": "!!!No app delays & nagging to upgrade license", | ||
96 | "file": "src/components/subscription/SubscriptionForm.js", | ||
97 | "start": { | ||
98 | "line": 42, | ||
99 | "column": 19 | ||
100 | }, | ||
101 | "end": { | ||
102 | "line": 45, | ||
103 | "column": 3 | ||
104 | } | ||
105 | }, | ||
106 | { | ||
107 | "id": "subscription.features.proxy", | ||
108 | "defaultMessage": "!!!Proxy support for services", | ||
109 | "file": "src/components/subscription/SubscriptionForm.js", | ||
110 | "start": { | ||
111 | "line": 46, | ||
112 | "column": 9 | ||
113 | }, | ||
114 | "end": { | ||
115 | "line": 49, | ||
116 | "column": 3 | ||
117 | } | ||
118 | }, | ||
119 | { | ||
120 | "id": "subscription.features.spellchecker", | ||
121 | "defaultMessage": "!!!Support for Spellchecker", | ||
122 | "file": "src/components/subscription/SubscriptionForm.js", | ||
123 | "start": { | ||
124 | "line": 50, | ||
125 | "column": 16 | ||
126 | }, | ||
127 | "end": { | ||
128 | "line": 53, | ||
129 | "column": 3 | ||
130 | } | ||
131 | }, | ||
132 | { | ||
133 | "id": "subscription.features.workspaces", | ||
134 | "defaultMessage": "!!!Organize your services in workspaces", | ||
135 | "file": "src/components/subscription/SubscriptionForm.js", | ||
136 | "start": { | ||
137 | "line": 54, | ||
138 | "column": 14 | ||
139 | }, | ||
140 | "end": { | ||
141 | "line": 57, | ||
142 | "column": 3 | ||
143 | } | ||
144 | }, | ||
145 | { | ||
146 | "id": "subscription.features.ads", | ||
147 | "defaultMessage": "!!!No ads, ever!", | ||
148 | "file": "src/components/subscription/SubscriptionForm.js", | ||
149 | "start": { | ||
150 | "line": 58, | ||
151 | "column": 7 | ||
152 | }, | ||
153 | "end": { | ||
154 | "line": 61, | ||
155 | "column": 3 | ||
156 | } | ||
157 | }, | ||
158 | { | ||
159 | "id": "subscription.features.comingSoon", | ||
160 | "defaultMessage": "!!!coming soon", | ||
161 | "file": "src/components/subscription/SubscriptionForm.js", | ||
162 | "start": { | ||
163 | "line": 62, | ||
164 | "column": 14 | ||
165 | }, | ||
166 | "end": { | ||
167 | "line": 65, | ||
168 | "column": 3 | ||
169 | } | ||
170 | }, | ||
171 | { | ||
172 | "id": "subscription.euTaxInfo", | ||
173 | "defaultMessage": "!!!EU residents: local sales tax may apply", | ||
174 | "file": "src/components/subscription/SubscriptionForm.js", | ||
175 | "start": { | ||
176 | "line": 66, | ||
177 | "column": 13 | ||
178 | }, | ||
179 | "end": { | ||
180 | "line": 69, | ||
181 | "column": 3 | 51 | "column": 3 |
182 | } | 52 | } |
183 | } | 53 | } |
diff --git a/src/i18n/messages/src/components/subscription/TrialForm.json b/src/i18n/messages/src/components/subscription/TrialForm.json new file mode 100644 index 000000000..8b387ba36 --- /dev/null +++ b/src/i18n/messages/src/components/subscription/TrialForm.json | |||
@@ -0,0 +1,93 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "subscription.cta.activateTrial", | ||
4 | "defaultMessage": "!!!Yes, start the free Franz Professional trial", | ||
5 | "file": "src/components/subscription/TrialForm.js", | ||
6 | "start": { | ||
7 | "line": 14, | ||
8 | "column": 21 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 17, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "subscription.cta.allOptions", | ||
17 | "defaultMessage": "!!!See all options", | ||
18 | "file": "src/components/subscription/TrialForm.js", | ||
19 | "start": { | ||
20 | "line": 18, | ||
21 | "column": 20 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 21, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "settings.account.headlineTrialUpgrade", | ||
30 | "defaultMessage": "!!!Get the free 14 day Franz Professional Trial", | ||
31 | "file": "src/components/subscription/TrialForm.js", | ||
32 | "start": { | ||
33 | "line": 22, | ||
34 | "column": 18 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 25, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "subscription.includedProFeatures", | ||
43 | "defaultMessage": "!!!The Franz Professional Plan includes:", | ||
44 | "file": "src/components/subscription/TrialForm.js", | ||
45 | "start": { | ||
46 | "line": 26, | ||
47 | "column": 20 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 29, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "pricing.trial.terms.headline", | ||
56 | "defaultMessage": "!!!No strings attached", | ||
57 | "file": "src/components/subscription/TrialForm.js", | ||
58 | "start": { | ||
59 | "line": 30, | ||
60 | "column": 29 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 33, | ||
64 | "column": 3 | ||
65 | } | ||
66 | }, | ||
67 | { | ||
68 | "id": "pricing.trial.terms.noCreditCard", | ||
69 | "defaultMessage": "!!!No credit card required", | ||
70 | "file": "src/components/subscription/TrialForm.js", | ||
71 | "start": { | ||
72 | "line": 34, | ||
73 | "column": 16 | ||
74 | }, | ||
75 | "end": { | ||
76 | "line": 37, | ||
77 | "column": 3 | ||
78 | } | ||
79 | }, | ||
80 | { | ||
81 | "id": "pricing.trial.terms.automaticTrialEnd", | ||
82 | "defaultMessage": "!!!Your free trial ends automatically after 14 days", | ||
83 | "file": "src/components/subscription/TrialForm.js", | ||
84 | "start": { | ||
85 | "line": 38, | ||
86 | "column": 21 | ||
87 | }, | ||
88 | "end": { | ||
89 | "line": 41, | ||
90 | "column": 3 | ||
91 | } | ||
92 | } | ||
93 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/ui/ActivateTrialButton/index.json b/src/i18n/messages/src/components/ui/ActivateTrialButton/index.json new file mode 100644 index 000000000..08c1a9293 --- /dev/null +++ b/src/i18n/messages/src/components/ui/ActivateTrialButton/index.json | |||
@@ -0,0 +1,54 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "feature.delayApp.upgrade.action", | ||
4 | "defaultMessage": "!!!Get a Franz Supporter License", | ||
5 | "file": "src/components/ui/ActivateTrialButton/index.js", | ||
6 | "start": { | ||
7 | "line": 13, | ||
8 | "column": 10 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 16, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "feature.delayApp.trial.action", | ||
17 | "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", | ||
18 | "file": "src/components/ui/ActivateTrialButton/index.js", | ||
19 | "start": { | ||
20 | "line": 17, | ||
21 | "column": 15 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 20, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "feature.delayApp.upgrade.actionShort", | ||
30 | "defaultMessage": "!!!Upgrade account", | ||
31 | "file": "src/components/ui/ActivateTrialButton/index.js", | ||
32 | "start": { | ||
33 | "line": 21, | ||
34 | "column": 15 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 24, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "feature.delayApp.trial.actionShort", | ||
43 | "defaultMessage": "!!!Activate the free Franz Professional trial", | ||
44 | "file": "src/components/ui/ActivateTrialButton/index.js", | ||
45 | "start": { | ||
46 | "line": 25, | ||
47 | "column": 20 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 28, | ||
51 | "column": 3 | ||
52 | } | ||
53 | } | ||
54 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/ui/FeatureList.json b/src/i18n/messages/src/components/ui/FeatureList.json new file mode 100644 index 000000000..497e299a4 --- /dev/null +++ b/src/i18n/messages/src/components/ui/FeatureList.json | |||
@@ -0,0 +1,132 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "pricing.features.unlimitedServices", | ||
4 | "defaultMessage": "!!!Add unlimited services", | ||
5 | "file": "src/components/ui/FeatureList.js", | ||
6 | "start": { | ||
7 | "line": 8, | ||
8 | "column": 21 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 11, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "pricing.features.spellchecker", | ||
17 | "defaultMessage": "!!!Spellchecker support", | ||
18 | "file": "src/components/ui/FeatureList.js", | ||
19 | "start": { | ||
20 | "line": 12, | ||
21 | "column": 16 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 15, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "pricing.features.workspaces", | ||
30 | "defaultMessage": "!!!Workspaces", | ||
31 | "file": "src/components/ui/FeatureList.js", | ||
32 | "start": { | ||
33 | "line": 16, | ||
34 | "column": 14 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 19, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "pricing.features.customWebsites", | ||
43 | "defaultMessage": "!!!Add Custom Websites", | ||
44 | "file": "src/components/ui/FeatureList.js", | ||
45 | "start": { | ||
46 | "line": 20, | ||
47 | "column": 18 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 23, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "pricing.features.onPremise", | ||
56 | "defaultMessage": "!!!On-premise & other Hosted Services", | ||
57 | "file": "src/components/ui/FeatureList.js", | ||
58 | "start": { | ||
59 | "line": 24, | ||
60 | "column": 13 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 27, | ||
64 | "column": 3 | ||
65 | } | ||
66 | }, | ||
67 | { | ||
68 | "id": "pricing.features.thirdPartyServices", | ||
69 | "defaultMessage": "!!!Install 3rd party services", | ||
70 | "file": "src/components/ui/FeatureList.js", | ||
71 | "start": { | ||
72 | "line": 28, | ||
73 | "column": 22 | ||
74 | }, | ||
75 | "end": { | ||
76 | "line": 31, | ||
77 | "column": 3 | ||
78 | } | ||
79 | }, | ||
80 | { | ||
81 | "id": "pricing.features.serviceProxies", | ||
82 | "defaultMessage": "!!!Service Proxies", | ||
83 | "file": "src/components/ui/FeatureList.js", | ||
84 | "start": { | ||
85 | "line": 32, | ||
86 | "column": 18 | ||
87 | }, | ||
88 | "end": { | ||
89 | "line": 35, | ||
90 | "column": 3 | ||
91 | } | ||
92 | }, | ||
93 | { | ||
94 | "id": "pricing.features.teamManagement", | ||
95 | "defaultMessage": "!!!Team Management", | ||
96 | "file": "src/components/ui/FeatureList.js", | ||
97 | "start": { | ||
98 | "line": 36, | ||
99 | "column": 18 | ||
100 | }, | ||
101 | "end": { | ||
102 | "line": 39, | ||
103 | "column": 3 | ||
104 | } | ||
105 | }, | ||
106 | { | ||
107 | "id": "pricing.features.appDelays", | ||
108 | "defaultMessage": "!!!No Waiting Screens", | ||
109 | "file": "src/components/ui/FeatureList.js", | ||
110 | "start": { | ||
111 | "line": 40, | ||
112 | "column": 13 | ||
113 | }, | ||
114 | "end": { | ||
115 | "line": 43, | ||
116 | "column": 3 | ||
117 | } | ||
118 | }, | ||
119 | { | ||
120 | "id": "pricing.features.adFree", | ||
121 | "defaultMessage": "!!!Forever ad-free", | ||
122 | "file": "src/components/ui/FeatureList.js", | ||
123 | "start": { | ||
124 | "line": 44, | ||
125 | "column": 10 | ||
126 | }, | ||
127 | "end": { | ||
128 | "line": 47, | ||
129 | "column": 3 | ||
130 | } | ||
131 | } | ||
132 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json b/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json index 320d3ca3e..0cde4cee5 100644 --- a/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json +++ b/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Upgrade account", | 4 | "defaultMessage": "!!!Upgrade account", |
5 | "file": "src/components/ui/PremiumFeatureContainer/index.js", | 5 | "file": "src/components/ui/PremiumFeatureContainer/index.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 15, | 7 | "line": 16, |
8 | "column": 10 | 8 | "column": 10 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 18, | 11 | "line": 19, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | } | 14 | } |
diff --git a/src/i18n/messages/src/features/delayApp/Component.json b/src/i18n/messages/src/features/delayApp/Component.json index bacd9444a..0d345a47b 100644 --- a/src/i18n/messages/src/features/delayApp/Component.json +++ b/src/i18n/messages/src/features/delayApp/Component.json | |||
@@ -4,24 +4,50 @@ | |||
4 | "defaultMessage": "!!!Please purchase license to skip waiting", | 4 | "defaultMessage": "!!!Please purchase license to skip waiting", |
5 | "file": "src/features/delayApp/Component.js", | 5 | "file": "src/features/delayApp/Component.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 15, | 7 | "line": 17, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 18, | 11 | "line": 20, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
15 | { | 15 | { |
16 | "id": "feature.delayApp.action", | 16 | "id": "feature.delayApp.trial.headline", |
17 | "defaultMessage": "!!!Get the free Franz Professional 14 day trial and skip the line", | ||
18 | "file": "src/features/delayApp/Component.js", | ||
19 | "start": { | ||
20 | "line": 21, | ||
21 | "column": 17 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 24, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "feature.delayApp.upgrade.action", | ||
17 | "defaultMessage": "!!!Get a Franz Supporter License", | 30 | "defaultMessage": "!!!Get a Franz Supporter License", |
18 | "file": "src/features/delayApp/Component.js", | 31 | "file": "src/features/delayApp/Component.js", |
19 | "start": { | 32 | "start": { |
20 | "line": 19, | 33 | "line": 25, |
21 | "column": 10 | 34 | "column": 10 |
22 | }, | 35 | }, |
23 | "end": { | 36 | "end": { |
24 | "line": 22, | 37 | "line": 28, |
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "feature.delayApp.trial.action", | ||
43 | "defaultMessage": "!!!Yes, I want the free 14 day trial of Franz Professional", | ||
44 | "file": "src/features/delayApp/Component.js", | ||
45 | "start": { | ||
46 | "line": 29, | ||
47 | "column": 15 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 32, | ||
25 | "column": 3 | 51 | "column": 3 |
26 | } | 52 | } |
27 | }, | 53 | }, |
@@ -30,11 +56,11 @@ | |||
30 | "defaultMessage": "!!!Franz will continue in {seconds} seconds.", | 56 | "defaultMessage": "!!!Franz will continue in {seconds} seconds.", |
31 | "file": "src/features/delayApp/Component.js", | 57 | "file": "src/features/delayApp/Component.js", |
32 | "start": { | 58 | "start": { |
33 | "line": 23, | 59 | "line": 33, |
34 | "column": 8 | 60 | "column": 8 |
35 | }, | 61 | }, |
36 | "end": { | 62 | "end": { |
37 | "line": 26, | 63 | "line": 36, |
38 | "column": 3 | 64 | "column": 3 |
39 | } | 65 | } |
40 | } | 66 | } |
diff --git a/src/i18n/messages/src/features/serviceLimit/components/AnnouncementScreen.json b/src/i18n/messages/src/features/serviceLimit/components/AnnouncementScreen.json new file mode 100644 index 000000000..e6e3cef99 --- /dev/null +++ b/src/i18n/messages/src/features/serviceLimit/components/AnnouncementScreen.json | |||
@@ -0,0 +1,15 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "feature.announcements.changelog.headline", | ||
4 | "defaultMessage": "!!!Changes in Franz {version}", | ||
5 | "file": "src/features/serviceLimit/components/AnnouncementScreen.js", | ||
6 | "start": { | ||
7 | "line": 20, | ||
8 | "column": 12 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 23, | ||
12 | "column": 3 | ||
13 | } | ||
14 | } | ||
15 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/features/serviceLimit/components/LimitReachedInfobox.json b/src/i18n/messages/src/features/serviceLimit/components/LimitReachedInfobox.json new file mode 100644 index 000000000..df5bc03e8 --- /dev/null +++ b/src/i18n/messages/src/features/serviceLimit/components/LimitReachedInfobox.json | |||
@@ -0,0 +1,28 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "feature.serviceLimit.limitReached", | ||
4 | "defaultMessage": "!!!You have added {amount} of {limit} services. Please upgrade your account to add more services.", | ||
5 | "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", | ||
6 | "start": { | ||
7 | "line": 11, | ||
8 | "column": 16 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 14, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "premiumFeature.button.upgradeAccount", | ||
17 | "defaultMessage": "!!!Upgrade account", | ||
18 | "file": "src/features/serviceLimit/components/LimitReachedInfobox.js", | ||
19 | "start": { | ||
20 | "line": 15, | ||
21 | "column": 10 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 18, | ||
25 | "column": 3 | ||
26 | } | ||
27 | } | ||
28 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/features/shareFranz/Component.json b/src/i18n/messages/src/features/shareFranz/Component.json index 34a43d5a0..72150f2b0 100644 --- a/src/i18n/messages/src/features/shareFranz/Component.json +++ b/src/i18n/messages/src/features/shareFranz/Component.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Franz is better together!", | 4 | "defaultMessage": "!!!Franz is better together!", |
5 | "file": "src/features/shareFranz/Component.js", | 5 | "file": "src/features/shareFranz/Component.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 15, | 7 | "line": 18, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 18, | 11 | "line": 21, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.", | 17 | "defaultMessage": "!!!Tell your friends and colleagues how awesome Franz is and help us to spread the word.", |
18 | "file": "src/features/shareFranz/Component.js", | 18 | "file": "src/features/shareFranz/Component.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 19, | 20 | "line": 22, |
21 | "column": 8 | 21 | "column": 8 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 22, | 24 | "line": 25, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Share as email", | 30 | "defaultMessage": "!!!Share as email", |
31 | "file": "src/features/shareFranz/Component.js", | 31 | "file": "src/features/shareFranz/Component.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 23, | 33 | "line": 26, |
34 | "column": 16 | 34 | "column": 16 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 26, | 37 | "line": 29, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Share on Facebook", | 43 | "defaultMessage": "!!!Share on Facebook", |
44 | "file": "src/features/shareFranz/Component.js", | 44 | "file": "src/features/shareFranz/Component.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 27, | 46 | "line": 30, |
47 | "column": 19 | 47 | "column": 19 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 30, | 50 | "line": 33, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Share on Twitter", | 56 | "defaultMessage": "!!!Share on Twitter", |
57 | "file": "src/features/shareFranz/Component.js", | 57 | "file": "src/features/shareFranz/Component.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 31, | 59 | "line": 34, |
60 | "column": 18 | 60 | "column": 18 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 34, | 63 | "line": 37, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", | 69 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com", |
70 | "file": "src/features/shareFranz/Component.js", | 70 | "file": "src/features/shareFranz/Component.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 35, | 72 | "line": 38, |
73 | "column": 18 | 73 | "column": 18 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 38, | 76 | "line": 41, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", | 82 | "defaultMessage": "!!! I've added {count} services to Franz! Get the free app for WhatsApp, Messenger, Slack, Skype and co at www.meetfranz.com /cc @FranzMessenger", |
83 | "file": "src/features/shareFranz/Component.js", | 83 | "file": "src/features/shareFranz/Component.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 39, | 85 | "line": 42, |
86 | "column": 20 | 86 | "column": 20 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 42, | 89 | "line": 45, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | } | 92 | } |
diff --git a/src/i18n/messages/src/features/todos/components/TodosWebview.json b/src/i18n/messages/src/features/todos/components/TodosWebview.json new file mode 100644 index 000000000..2387112b4 --- /dev/null +++ b/src/i18n/messages/src/features/todos/components/TodosWebview.json | |||
@@ -0,0 +1,41 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "feature.todos.premium.info", | ||
4 | "defaultMessage": "!!!The Franz Todos Preview is currently only available for Franz Premium accounts.", | ||
5 | "file": "src/features/todos/components/TodosWebview.js", | ||
6 | "start": { | ||
7 | "line": 18, | ||
8 | "column": 15 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 21, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "feature.todos.premium.upgrade", | ||
17 | "defaultMessage": "!!!Upgrade Account", | ||
18 | "file": "src/features/todos/components/TodosWebview.js", | ||
19 | "start": { | ||
20 | "line": 22, | ||
21 | "column": 14 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 25, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "feature.todos.premium.rollout", | ||
30 | "defaultMessage": "!!!Franz Todos will be available to everyone soon.", | ||
31 | "file": "src/features/todos/components/TodosWebview.js", | ||
32 | "start": { | ||
33 | "line": 26, | ||
34 | "column": 15 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 29, | ||
38 | "column": 3 | ||
39 | } | ||
40 | } | ||
41 | ] \ No newline at end of file | ||
diff --git a/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json b/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json index 9f0935620..2f340f1e9 100644 --- a/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json +++ b/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Workspaces", | 4 | "defaultMessage": "!!!Workspaces", |
5 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 5 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 16, | 7 | "line": 17, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 19, | 11 | "line": 20, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!All services", | 17 | "defaultMessage": "!!!All services", |
18 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 18 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 20, | 20 | "line": 21, |
21 | "column": 15 | 21 | "column": 15 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 23, | 24 | "line": 24, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Workspaces settings", | 30 | "defaultMessage": "!!!Workspaces settings", |
31 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 31 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 24, | 33 | "line": 25, |
34 | "column": 29 | 34 | "column": 29 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 27, | 37 | "line": 28, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Info about workspace feature", | 43 | "defaultMessage": "!!!Info about workspace feature", |
44 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 44 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 28, | 46 | "line": 29, |
47 | "column": 24 | 47 | "column": 24 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 31, | 50 | "line": 32, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Create your first workspace", | 56 | "defaultMessage": "!!!Create your first workspace", |
57 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 57 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 32, | 59 | "line": 33, |
60 | "column": 25 | 60 | "column": 25 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 35, | 63 | "line": 36, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Reactivate premium account", | 69 | "defaultMessage": "!!!Reactivate premium account", |
70 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 70 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 36, | 72 | "line": 37, |
73 | "column": 28 | 73 | "column": 28 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 39, | 76 | "line": 40, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!add new workspace", | 82 | "defaultMessage": "!!!add new workspace", |
83 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 83 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 40, | 85 | "line": 41, |
86 | "column": 24 | 86 | "column": 24 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 43, | 89 | "line": 44, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Premium feature", | 95 | "defaultMessage": "!!!Premium feature", |
96 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", | 96 | "file": "src/features/workspaces/components/WorkspaceDrawer.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 44, | 98 | "line": 45, |
99 | "column": 23 | 99 | "column": 23 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 47, | 102 | "line": 48, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | } | 105 | } |
diff --git a/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json b/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json index ef8f1bebc..7eb4fab50 100644 --- a/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json +++ b/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Your workspaces", | 4 | "defaultMessage": "!!!Your workspaces", |
5 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 5 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 17, | 7 | "line": 19, |
8 | "column": 12 | 8 | "column": 12 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 20, | 11 | "line": 22, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!You haven't added any workspaces yet.", | 17 | "defaultMessage": "!!!You haven't added any workspaces yet.", |
18 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 18 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 21, | 20 | "line": 23, |
21 | "column": 19 | 21 | "column": 19 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 24, | 24 | "line": 26, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Could not load your workspaces", | 30 | "defaultMessage": "!!!Could not load your workspaces", |
31 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 31 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 25, | 33 | "line": 27, |
34 | "column": 27 | 34 | "column": 27 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 28, | 37 | "line": 30, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | }, | 40 | }, |
@@ -43,11 +43,11 @@ | |||
43 | "defaultMessage": "!!!Try again", | 43 | "defaultMessage": "!!!Try again", |
44 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 44 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
45 | "start": { | 45 | "start": { |
46 | "line": 29, | 46 | "line": 31, |
47 | "column": 23 | 47 | "column": 23 |
48 | }, | 48 | }, |
49 | "end": { | 49 | "end": { |
50 | "line": 32, | 50 | "line": 34, |
51 | "column": 3 | 51 | "column": 3 |
52 | } | 52 | } |
53 | }, | 53 | }, |
@@ -56,11 +56,11 @@ | |||
56 | "defaultMessage": "!!!Your changes have been saved", | 56 | "defaultMessage": "!!!Your changes have been saved", |
57 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 57 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
58 | "start": { | 58 | "start": { |
59 | "line": 33, | 59 | "line": 35, |
60 | "column": 15 | 60 | "column": 15 |
61 | }, | 61 | }, |
62 | "end": { | 62 | "end": { |
63 | "line": 36, | 63 | "line": 38, |
64 | "column": 3 | 64 | "column": 3 |
65 | } | 65 | } |
66 | }, | 66 | }, |
@@ -69,11 +69,11 @@ | |||
69 | "defaultMessage": "!!!Workspace has been deleted", | 69 | "defaultMessage": "!!!Workspace has been deleted", |
70 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 70 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
71 | "start": { | 71 | "start": { |
72 | "line": 37, | 72 | "line": 39, |
73 | "column": 15 | 73 | "column": 15 |
74 | }, | 74 | }, |
75 | "end": { | 75 | "end": { |
76 | "line": 40, | 76 | "line": 42, |
77 | "column": 3 | 77 | "column": 3 |
78 | } | 78 | } |
79 | }, | 79 | }, |
@@ -82,11 +82,11 @@ | |||
82 | "defaultMessage": "!!!Info about workspace feature", | 82 | "defaultMessage": "!!!Info about workspace feature", |
83 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 83 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
84 | "start": { | 84 | "start": { |
85 | "line": 41, | 85 | "line": 43, |
86 | "column": 24 | 86 | "column": 24 |
87 | }, | 87 | }, |
88 | "end": { | 88 | "end": { |
89 | "line": 44, | 89 | "line": 46, |
90 | "column": 3 | 90 | "column": 3 |
91 | } | 91 | } |
92 | }, | 92 | }, |
@@ -95,11 +95,11 @@ | |||
95 | "defaultMessage": "!!!Less is More: Introducing Franz Workspaces", | 95 | "defaultMessage": "!!!Less is More: Introducing Franz Workspaces", |
96 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", | 96 | "file": "src/features/workspaces/components/WorkspacesDashboard.js", |
97 | "start": { | 97 | "start": { |
98 | "line": 45, | 98 | "line": 47, |
99 | "column": 28 | 99 | "column": 28 |
100 | }, | 100 | }, |
101 | "end": { | 101 | "end": { |
102 | "line": 48, | 102 | "line": 50, |
103 | "column": 3 | 103 | "column": 3 |
104 | } | 104 | } |
105 | } | 105 | } |
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..df8ee19e3 --- /dev/null +++ b/src/i18n/messages/src/helpers/plan-helpers.json | |||
@@ -0,0 +1,54 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "pricing.plan.pro", | ||
4 | "defaultMessage": "!!!Franz Professional", | ||
5 | "file": "src/helpers/plan-helpers.js", | ||
6 | "start": { | ||
7 | "line": 5, | ||
8 | "column": 15 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 8, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "pricing.plan.personal", | ||
17 | "defaultMessage": "!!!Franz Personal", | ||
18 | "file": "src/helpers/plan-helpers.js", | ||
19 | "start": { | ||
20 | "line": 9, | ||
21 | "column": 20 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 12, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "pricing.plan.free", | ||
30 | "defaultMessage": "!!!Franz Free", | ||
31 | "file": "src/helpers/plan-helpers.js", | ||
32 | "start": { | ||
33 | "line": 13, | ||
34 | "column": 16 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 16, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "pricing.plan.legacy", | ||
43 | "defaultMessage": "!!!Franz Premium", | ||
44 | "file": "src/helpers/plan-helpers.js", | ||
45 | "start": { | ||
46 | "line": 17, | ||
47 | "column": 18 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 20, | ||
51 | "column": 3 | ||
52 | } | ||
53 | } | ||
54 | ] \ 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 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "pricing.plan.pro-yearly", | ||
4 | "defaultMessage": "!!!Franz Professional Yearly", | ||
5 | "file": "src/helpers/pricing-helpers.js", | ||
6 | "start": { | ||
7 | "line": 5, | ||
8 | "column": 22 | ||
9 | }, | ||
10 | "end": { | ||
11 | "line": 8, | ||
12 | "column": 3 | ||
13 | } | ||
14 | }, | ||
15 | { | ||
16 | "id": "pricing.plan.pro-monthly", | ||
17 | "defaultMessage": "!!!Franz Professional Monthly", | ||
18 | "file": "src/helpers/pricing-helpers.js", | ||
19 | "start": { | ||
20 | "line": 9, | ||
21 | "column": 23 | ||
22 | }, | ||
23 | "end": { | ||
24 | "line": 12, | ||
25 | "column": 3 | ||
26 | } | ||
27 | }, | ||
28 | { | ||
29 | "id": "pricing.plan.personal-yearly", | ||
30 | "defaultMessage": "!!!Franz Personal Yearly", | ||
31 | "file": "src/helpers/pricing-helpers.js", | ||
32 | "start": { | ||
33 | "line": 13, | ||
34 | "column": 27 | ||
35 | }, | ||
36 | "end": { | ||
37 | "line": 16, | ||
38 | "column": 3 | ||
39 | } | ||
40 | }, | ||
41 | { | ||
42 | "id": "pricing.plan.personal-monthly", | ||
43 | "defaultMessage": "!!!Franz Personal Monthly", | ||
44 | "file": "src/helpers/pricing-helpers.js", | ||
45 | "start": { | ||
46 | "line": 17, | ||
47 | "column": 28 | ||
48 | }, | ||
49 | "end": { | ||
50 | "line": 20, | ||
51 | "column": 3 | ||
52 | } | ||
53 | }, | ||
54 | { | ||
55 | "id": "pricing.plan.free", | ||
56 | "defaultMessage": "!!!Franz Free", | ||
57 | "file": "src/helpers/pricing-helpers.js", | ||
58 | "start": { | ||
59 | "line": 21, | ||
60 | "column": 16 | ||
61 | }, | ||
62 | "end": { | ||
63 | "line": 24, | ||
64 | "column": 3 | ||
65 | } | ||
66 | }, | ||
67 | { | ||
68 | "id": "pricing.plan.legacy", | ||
69 | "defaultMessage": "!!!Franz Premium", | ||
70 | "file": "src/helpers/pricing-helpers.js", | ||
71 | "start": { | ||
72 | "line": 25, | ||
73 | "column": 18 | ||
74 | }, | ||
75 | "end": { | ||
76 | "line": 28, | ||
77 | "column": 3 | ||
78 | } | ||
79 | } | ||
80 | ] \ No newline at end of file | ||
diff --git a/src/index.js b/src/index.js index 55592c328..d9d51fd5b 100644 --- a/src/index.js +++ b/src/index.js | |||
@@ -105,35 +105,6 @@ if (!gotTheLock) { | |||
105 | } | 105 | } |
106 | }); | 106 | }); |
107 | } | 107 | } |
108 | // const isSecondInstance = app.makeSingleInstance((argv) => { | ||
109 | // if (mainWindow) { | ||
110 | // if (mainWindow.isMinimized()) mainWindow.restore(); | ||
111 | // mainWindow.focus(); | ||
112 | |||
113 | // if (process.platform === 'win32') { | ||
114 | // // Keep only command line / deep linked arguments | ||
115 | // const url = argv.slice(1); | ||
116 | |||
117 | // if (url) { | ||
118 | // handleDeepLink(mainWindow, url.toString()); | ||
119 | // } | ||
120 | // } | ||
121 | // } | ||
122 | |||
123 | // if (argv.includes('--reset-window')) { | ||
124 | // // Needs to be delayed to not interfere with mainWindow.restore(); | ||
125 | // setTimeout(() => { | ||
126 | // debug('Resetting windows via Task'); | ||
127 | // mainWindow.setPosition(DEFAULT_WINDOW_OPTIONS.x + 100, DEFAULT_WINDOW_OPTIONS.y + 100); | ||
128 | // mainWindow.setSize(DEFAULT_WINDOW_OPTIONS.width, DEFAULT_WINDOW_OPTIONS.height); | ||
129 | // }, 1); | ||
130 | // } | ||
131 | // }); | ||
132 | |||
133 | // if (isSecondInstance) { | ||
134 | // console.log('An instance of Franz is already running. Exiting...'); | ||
135 | // app.exit(); | ||
136 | // } | ||
137 | 108 | ||
138 | // Fix Unity indicator issue | 109 | // Fix Unity indicator issue |
139 | // https://github.com/electron/electron/issues/9046 | 110 | // https://github.com/electron/electron/issues/9046 |
diff --git a/src/models/Service.js b/src/models/Service.js index 88bce3360..848a84aa2 100644 --- a/src/models/Service.js +++ b/src/models/Service.js | |||
@@ -4,6 +4,11 @@ import normalizeUrl from 'normalize-url'; | |||
4 | 4 | ||
5 | const debug = require('debug')('Franz:Service'); | 5 | const debug = require('debug')('Franz:Service'); |
6 | 6 | ||
7 | export const RESTRICTION_TYPES = { | ||
8 | SERVICE_LIMIT: 0, | ||
9 | CUSTOM_URL: 1, | ||
10 | }; | ||
11 | |||
7 | export default class Service { | 12 | export default class Service { |
8 | id = ''; | 13 | id = ''; |
9 | 14 | ||
@@ -59,6 +64,12 @@ export default class Service { | |||
59 | 64 | ||
60 | @observable errorMessage = ''; | 65 | @observable errorMessage = ''; |
61 | 66 | ||
67 | @observable isUsingCustomUrl = false; | ||
68 | |||
69 | @observable isServiceAccessRestricted = false; | ||
70 | |||
71 | @observable restrictionType = null; | ||
72 | |||
62 | constructor(data, recipe) { | 73 | constructor(data, recipe) { |
63 | if (!data) { | 74 | if (!data) { |
64 | console.error('Service config not valid'); | 75 | console.error('Service config not valid'); |
@@ -111,6 +122,10 @@ export default class Service { | |||
111 | this.unreadDirectMessageCount = 0; | 122 | this.unreadDirectMessageCount = 0; |
112 | this.unreadIndirectMessageCount = 0; | 123 | this.unreadIndirectMessageCount = 0; |
113 | } | 124 | } |
125 | |||
126 | if (this.recipe.hasCustomUrl && this.customUrl) { | ||
127 | this.isUsingCustomUrl = true; | ||
128 | } | ||
114 | }); | 129 | }); |
115 | } | 130 | } |
116 | 131 | ||
diff --git a/src/models/User.js b/src/models/User.js index bec78fc16..0a2b1f62a 100644 --- a/src/models/User.js +++ b/src/models/User.js | |||
@@ -20,6 +20,10 @@ export default class User { | |||
20 | 20 | ||
21 | @observable isSubscriptionOwner = false; | 21 | @observable isSubscriptionOwner = false; |
22 | 22 | ||
23 | @observable hasSubscription = false; | ||
24 | |||
25 | @observable hadSubscription = false; | ||
26 | |||
23 | @observable isPremium = false; | 27 | @observable isPremium = false; |
24 | 28 | ||
25 | @observable beta = false; | 29 | @observable beta = false; |
@@ -32,6 +36,9 @@ export default class User { | |||
32 | 36 | ||
33 | @observable locale = false; | 37 | @observable locale = false; |
34 | 38 | ||
39 | @observable team = {}; | ||
40 | |||
41 | |||
35 | constructor(data) { | 42 | constructor(data) { |
36 | if (!data.id) { | 43 | if (!data.id) { |
37 | throw Error('User requires Id'); | 44 | throw Error('User requires Id'); |
@@ -47,8 +54,13 @@ export default class User { | |||
47 | this.beta = data.beta || this.beta; | 54 | this.beta = data.beta || this.beta; |
48 | this.donor = data.donor || this.donor; | 55 | this.donor = data.donor || this.donor; |
49 | this.isDonor = data.isDonor || this.isDonor; | 56 | this.isDonor = data.isDonor || this.isDonor; |
50 | this.isSubscriptionOwner = data.isSubscriptionOwner || this.isSubscriptionOwner; | ||
51 | this.isMiner = data.isMiner || this.isMiner; | 57 | this.isMiner = data.isMiner || this.isMiner; |
52 | this.locale = data.locale || this.locale; | 58 | this.locale = data.locale || this.locale; |
59 | |||
60 | this.isSubscriptionOwner = data.isSubscriptionOwner || this.isSubscriptionOwner; | ||
61 | this.hasSubscription = data.hasSubscription || this.hasSubscription; | ||
62 | this.hadSubscription = data.hadSubscription || this.hadSubscription; | ||
63 | |||
64 | this.team = data.team || this.team; | ||
53 | } | 65 | } |
54 | } | 66 | } |
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index 2ac306a2a..6054e6721 100644 --- a/src/stores/AppStore.js +++ b/src/stores/AppStore.js | |||
@@ -357,6 +357,8 @@ export default class AppStore extends Store { | |||
357 | this.locale = this._getDefaultLocale(); | 357 | this.locale = this._getDefaultLocale(); |
358 | } | 358 | } |
359 | 359 | ||
360 | moment.locale(this.locale); | ||
361 | |||
360 | debug(`Set locale to "${this.locale}"`); | 362 | debug(`Set locale to "${this.locale}"`); |
361 | } | 363 | } |
362 | 364 | ||
diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js index 35a050c67..cf28b6bec 100644 --- a/src/stores/FeaturesStore.js +++ b/src/stores/FeaturesStore.js | |||
@@ -16,6 +16,8 @@ import workspaces from '../features/workspaces'; | |||
16 | import shareFranz from '../features/shareFranz'; | 16 | import shareFranz from '../features/shareFranz'; |
17 | import announcements from '../features/announcements'; | 17 | import announcements from '../features/announcements'; |
18 | import settingsWS from '../features/settingsWS'; | 18 | import settingsWS from '../features/settingsWS'; |
19 | import serviceLimit from '../features/serviceLimit'; | ||
20 | import communityRecipes from '../features/communityRecipes'; | ||
19 | import todos from '../features/todos'; | 21 | import todos from '../features/todos'; |
20 | 22 | ||
21 | import { DEFAULT_FEATURES_CONFIG } from '../config'; | 23 | import { DEFAULT_FEATURES_CONFIG } from '../config'; |
@@ -76,6 +78,8 @@ export default class FeaturesStore extends Store { | |||
76 | shareFranz(this.stores, this.actions); | 78 | shareFranz(this.stores, this.actions); |
77 | announcements(this.stores, this.actions); | 79 | announcements(this.stores, this.actions); |
78 | settingsWS(this.stores, this.actions); | 80 | settingsWS(this.stores, this.actions); |
81 | serviceLimit(this.stores, this.actions); | ||
82 | communityRecipes(this.stores, this.actions); | ||
79 | todos(this.stores, this.actions); | 83 | todos(this.stores, this.actions); |
80 | } | 84 | } |
81 | } | 85 | } |
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index b13425249..2fc543192 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -13,6 +13,8 @@ import CachedRequest from './lib/CachedRequest'; | |||
13 | import { matchRoute } from '../helpers/routing-helpers'; | 13 | import { matchRoute } from '../helpers/routing-helpers'; |
14 | import { gaEvent, statsEvent } from '../lib/analytics'; | 14 | import { gaEvent, statsEvent } from '../lib/analytics'; |
15 | import { workspaceStore } from '../features/workspaces'; | 15 | import { workspaceStore } from '../features/workspaces'; |
16 | import { serviceLimitStore } from '../features/serviceLimit'; | ||
17 | import { RESTRICTION_TYPES } from '../models/Service'; | ||
16 | 18 | ||
17 | const debug = require('debug')('Franz:ServiceStore'); | 19 | const debug = require('debug')('Franz:ServiceStore'); |
18 | 20 | ||
@@ -75,6 +77,7 @@ export default class ServicesStore extends Store { | |||
75 | this._saveActiveService.bind(this), | 77 | this._saveActiveService.bind(this), |
76 | this._logoutReaction.bind(this), | 78 | this._logoutReaction.bind(this), |
77 | this._handleMuteSettings.bind(this), | 79 | this._handleMuteSettings.bind(this), |
80 | this._restrictServiceAccess.bind(this), | ||
78 | ]); | 81 | ]); |
79 | 82 | ||
80 | // Just bind this | 83 | // Just bind this |
@@ -98,7 +101,10 @@ export default class ServicesStore extends Store { | |||
98 | if (this.stores.user.isLoggedIn) { | 101 | if (this.stores.user.isLoggedIn) { |
99 | const services = this.allServicesRequest.execute().result; | 102 | const services = this.allServicesRequest.execute().result; |
100 | if (services) { | 103 | if (services) { |
101 | return observable(services.slice().slice().sort((a, b) => a.order - b.order)); | 104 | return observable(services.slice().slice().sort((a, b) => a.order - b.order).map((s, index) => { |
105 | s.index = index; | ||
106 | return s; | ||
107 | })); | ||
102 | } | 108 | } |
103 | } | 109 | } |
104 | return []; | 110 | return []; |
@@ -153,6 +159,8 @@ export default class ServicesStore extends Store { | |||
153 | 159 | ||
154 | // Actions | 160 | // Actions |
155 | @action async _createService({ recipeId, serviceData, redirect = true }) { | 161 | @action async _createService({ recipeId, serviceData, redirect = true }) { |
162 | if (serviceLimitStore.userHasReachedServiceLimit) return; | ||
163 | |||
156 | const data = this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData); | 164 | const data = this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData); |
157 | 165 | ||
158 | const response = await this.createServiceRequest.execute(recipeId, data)._promise; | 166 | const response = await this.createServiceRequest.execute(recipeId, data)._promise; |
@@ -681,6 +689,35 @@ export default class ServicesStore extends Store { | |||
681 | return serviceData; | 689 | return serviceData; |
682 | } | 690 | } |
683 | 691 | ||
692 | _restrictServiceAccess() { | ||
693 | const { features } = this.stores.features; | ||
694 | const { userHasReachedServiceLimit, serviceLimit } = this.stores.serviceLimit; | ||
695 | |||
696 | this.all.map((service, index) => { | ||
697 | if (userHasReachedServiceLimit) { | ||
698 | service.isServiceAccessRestricted = index >= serviceLimit; | ||
699 | |||
700 | if (service.isServiceAccessRestricted) { | ||
701 | service.restrictionType = RESTRICTION_TYPES.SERVICE_LIMIT; | ||
702 | |||
703 | debug('Restricting access to server due to service limit'); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | if (service.isUsingCustomUrl) { | ||
708 | service.isServiceAccessRestricted = !features.isCustomUrlIncludedInCurrentPlan; | ||
709 | |||
710 | if (service.isServiceAccessRestricted) { | ||
711 | service.restrictionType = RESTRICTION_TYPES.CUSTOM_URL; | ||
712 | |||
713 | debug('Restricting access to server due to custom url'); | ||
714 | } | ||
715 | } | ||
716 | |||
717 | return service; | ||
718 | }); | ||
719 | } | ||
720 | |||
684 | // Helper | 721 | // Helper |
685 | _initializeServiceRecipeInWebview(serviceId) { | 722 | _initializeServiceRecipeInWebview(serviceId) { |
686 | const service = this.one(serviceId); | 723 | const service = this.one(serviceId); |
diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js index 9680c5bcc..2c785111f 100644 --- a/src/stores/UIStore.js +++ b/src/stores/UIStore.js | |||
@@ -46,6 +46,7 @@ export default class UIStore extends Store { | |||
46 | // Actions | 46 | // Actions |
47 | @action _openSettings({ path = '/settings' }) { | 47 | @action _openSettings({ path = '/settings' }) { |
48 | const settingsPath = path !== '/settings' ? `/settings/${path}` : path; | 48 | const settingsPath = path !== '/settings' ? `/settings/${path}` : path; |
49 | console.log(settingsPath); | ||
49 | this.stores.router.push(settingsPath); | 50 | this.stores.router.push(settingsPath); |
50 | } | 51 | } |
51 | 52 | ||
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js index b5423af3b..7ac7d2375 100644 --- a/src/stores/UserStore.js +++ b/src/stores/UserStore.js | |||
@@ -2,12 +2,16 @@ import { observable, computed, action } from 'mobx'; | |||
2 | import moment from 'moment'; | 2 | import moment from 'moment'; |
3 | import jwt from 'jsonwebtoken'; | 3 | import jwt from 'jsonwebtoken'; |
4 | import localStorage from 'mobx-localstorage'; | 4 | import localStorage from 'mobx-localstorage'; |
5 | import ms from 'ms'; | ||
5 | 6 | ||
6 | import { isDevMode } from '../environment'; | 7 | import { isDevMode } from '../environment'; |
7 | import Store from './lib/Store'; | 8 | import Store from './lib/Store'; |
8 | import Request from './lib/Request'; | 9 | import Request from './lib/Request'; |
9 | import CachedRequest from './lib/CachedRequest'; | 10 | import CachedRequest from './lib/CachedRequest'; |
10 | import { gaEvent } from '../lib/analytics'; | 11 | import { gaEvent } from '../lib/analytics'; |
12 | import { sleep } from '../helpers/async-helpers'; | ||
13 | import { getPlan } from '../helpers/plan-helpers'; | ||
14 | import { PLANS } from '../config'; | ||
11 | 15 | ||
12 | const debug = require('debug')('Franz:UserStore'); | 16 | const debug = require('debug')('Franz:UserStore'); |
13 | 17 | ||
@@ -37,6 +41,8 @@ export default class UserStore extends Store { | |||
37 | 41 | ||
38 | @observable passwordRequest = new Request(this.api.user, 'password'); | 42 | @observable passwordRequest = new Request(this.api.user, 'password'); |
39 | 43 | ||
44 | @observable activateTrialRequest = new Request(this.api.user, 'activateTrial'); | ||
45 | |||
40 | @observable inviteRequest = new Request(this.api.user, 'invite'); | 46 | @observable inviteRequest = new Request(this.api.user, 'invite'); |
41 | 47 | ||
42 | @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo'); | 48 | @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo'); |
@@ -57,7 +63,9 @@ export default class UserStore extends Store { | |||
57 | 63 | ||
58 | @observable accountType; | 64 | @observable accountType; |
59 | 65 | ||
60 | @observable hasCompletedSignup = null; | 66 | @observable hasCompletedSignup = false; |
67 | |||
68 | @observable hasActivatedTrial = false; | ||
61 | 69 | ||
62 | @observable userData = {}; | 70 | @observable userData = {}; |
63 | 71 | ||
@@ -77,6 +85,7 @@ export default class UserStore extends Store { | |||
77 | this.actions.user.retrievePassword.listen(this._retrievePassword.bind(this)); | 85 | this.actions.user.retrievePassword.listen(this._retrievePassword.bind(this)); |
78 | this.actions.user.logout.listen(this._logout.bind(this)); | 86 | this.actions.user.logout.listen(this._logout.bind(this)); |
79 | this.actions.user.signup.listen(this._signup.bind(this)); | 87 | this.actions.user.signup.listen(this._signup.bind(this)); |
88 | this.actions.user.activateTrial.listen(this._activateTrial.bind(this)); | ||
80 | this.actions.user.invite.listen(this._invite.bind(this)); | 89 | this.actions.user.invite.listen(this._invite.bind(this)); |
81 | this.actions.user.update.listen(this._update.bind(this)); | 90 | this.actions.user.update.listen(this._update.bind(this)); |
82 | this.actions.user.resetStatus.listen(this._resetStatus.bind(this)); | 91 | this.actions.user.resetStatus.listen(this._resetStatus.bind(this)); |
@@ -87,6 +96,7 @@ export default class UserStore extends Store { | |||
87 | this.registerReactions([ | 96 | this.registerReactions([ |
88 | this._requireAuthenticatedUser, | 97 | this._requireAuthenticatedUser, |
89 | this._getUserData.bind(this), | 98 | this._getUserData.bind(this), |
99 | this._resetTrialActivationState.bind(this), | ||
90 | ]); | 100 | ]); |
91 | } | 101 | } |
92 | 102 | ||
@@ -142,10 +152,30 @@ export default class UserStore extends Store { | |||
142 | return this.getUserInfoRequest.execute().result || {}; | 152 | return this.getUserInfoRequest.execute().result || {}; |
143 | } | 153 | } |
144 | 154 | ||
155 | @computed get team() { | ||
156 | return this.data.team || null; | ||
157 | } | ||
158 | |||
145 | @computed get isPremium() { | 159 | @computed get isPremium() { |
146 | return !!this.data.isPremium; | 160 | return !!this.data.isPremium; |
147 | } | 161 | } |
148 | 162 | ||
163 | @computed get isPersonal() { | ||
164 | if (!this.team.plan) return false; | ||
165 | const plan = getPlan(this.team.plan); | ||
166 | |||
167 | return plan === PLANS.PERSONAL; | ||
168 | } | ||
169 | |||
170 | @computed get isPro() { | ||
171 | if (!this.team.plan && this.isPremium) return true; | ||
172 | |||
173 | if (!this.team.plan) return false; | ||
174 | const plan = getPlan(this.team.plan); | ||
175 | |||
176 | return plan === PLANS.PRO; | ||
177 | } | ||
178 | |||
149 | @computed get legacyServices() { | 179 | @computed get legacyServices() { |
150 | return this.getLegacyServicesRequest.execute() || {}; | 180 | return this.getLegacyServicesRequest.execute() || {}; |
151 | } | 181 | } |
@@ -199,6 +229,24 @@ export default class UserStore extends Store { | |||
199 | gaEvent('User', 'retrievePassword'); | 229 | gaEvent('User', 'retrievePassword'); |
200 | } | 230 | } |
201 | 231 | ||
232 | @action async _activateTrial({ planId }) { | ||
233 | debug('activate trial', planId); | ||
234 | |||
235 | this.activateTrialRequest.execute({ | ||
236 | plan: planId, | ||
237 | }); | ||
238 | |||
239 | await this.activateTrialRequest._promise; | ||
240 | |||
241 | this.hasActivatedTrial = true; | ||
242 | |||
243 | this.stores.features.featuresRequest.invalidate({ immediately: true }); | ||
244 | this.stores.user.getUserInfoRequest.invalidate({ immediately: true }); | ||
245 | |||
246 | |||
247 | gaEvent('User', 'activateTrial'); | ||
248 | } | ||
249 | |||
202 | @action async _invite({ invites }) { | 250 | @action async _invite({ invites }) { |
203 | const data = invites.filter(invite => invite.email !== ''); | 251 | const data = invites.filter(invite => invite.email !== ''); |
204 | 252 | ||
@@ -318,6 +366,14 @@ export default class UserStore extends Store { | |||
318 | } | 366 | } |
319 | } | 367 | } |
320 | 368 | ||
369 | async _resetTrialActivationState() { | ||
370 | if (this.hasActivatedTrial) { | ||
371 | await sleep(ms('12s')); | ||
372 | |||
373 | this.hasActivatedTrial = false; | ||
374 | } | ||
375 | } | ||
376 | |||
321 | // Helpers | 377 | // Helpers |
322 | _parseToken(authToken) { | 378 | _parseToken(authToken) { |
323 | try { | 379 | try { |
@@ -347,6 +403,15 @@ export default class UserStore extends Store { | |||
347 | } | 403 | } |
348 | } | 404 | } |
349 | 405 | ||
406 | getAuthURL(url) { | ||
407 | const parsedUrl = new URL(url); | ||
408 | const params = new URLSearchParams(parsedUrl.search.slice(1)); | ||
409 | |||
410 | params.append('authToken', this.authToken); | ||
411 | |||
412 | return `${parsedUrl.origin}${parsedUrl.pathname}?${params.toString()}`; | ||
413 | } | ||
414 | |||
350 | async _migrateUserLocale() { | 415 | async _migrateUserLocale() { |
351 | await this.getUserInfoRequest._promise; | 416 | await this.getUserInfoRequest._promise; |
352 | 417 | ||
diff --git a/src/stores/index.js b/src/stores/index.js index e9ef523f8..10dd56665 100644 --- a/src/stores/index.js +++ b/src/stores/index.js | |||
@@ -12,6 +12,8 @@ import RequestStore from './RequestStore'; | |||
12 | import GlobalErrorStore from './GlobalErrorStore'; | 12 | import GlobalErrorStore from './GlobalErrorStore'; |
13 | import { workspaceStore } from '../features/workspaces'; | 13 | import { workspaceStore } from '../features/workspaces'; |
14 | import { announcementsStore } from '../features/announcements'; | 14 | import { announcementsStore } from '../features/announcements'; |
15 | import { serviceLimitStore } from '../features/serviceLimit'; | ||
16 | import { communityRecipesStore } from '../features/communityRecipes'; | ||
15 | import { todosStore } from '../features/todos'; | 17 | import { todosStore } from '../features/todos'; |
16 | 18 | ||
17 | export default (api, actions, router) => { | 19 | export default (api, actions, router) => { |
@@ -32,6 +34,8 @@ export default (api, actions, router) => { | |||
32 | globalError: new GlobalErrorStore(stores, api, actions), | 34 | globalError: new GlobalErrorStore(stores, api, actions), |
33 | workspaces: workspaceStore, | 35 | workspaces: workspaceStore, |
34 | announcements: announcementsStore, | 36 | announcements: announcementsStore, |
37 | serviceLimit: serviceLimitStore, | ||
38 | communityRecipes: communityRecipesStore, | ||
35 | todos: todosStore, | 39 | todos: todosStore, |
36 | }); | 40 | }); |
37 | // Initialize all stores | 41 | // Initialize all stores |
diff --git a/src/styles/auth.scss b/src/styles/auth.scss index 0a075036a..154a71a36 100644 --- a/src/styles/auth.scss +++ b/src/styles/auth.scss | |||
@@ -9,7 +9,7 @@ | |||
9 | } | 9 | } |
10 | 10 | ||
11 | .auth__logo.auth__logo--sm { | 11 | .auth__logo.auth__logo--sm { |
12 | border: 4px solid $dark-theme-black; | 12 | border: none; |
13 | box-shadow: 0 0 6px rgba($dark-theme-black, .5); | 13 | box-shadow: 0 0 6px rgba($dark-theme-black, .5); |
14 | } | 14 | } |
15 | 15 | ||
diff --git a/src/styles/recipes.scss b/src/styles/recipes.scss index 84222e1fe..5bdc60a57 100644 --- a/src/styles/recipes.scss +++ b/src/styles/recipes.scss | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | .theme__dark .recipe-teaser { | 3 | .theme__dark .recipe-teaser { |
4 | background-color: $dark-theme-gray-dark; | 4 | background-color: $dark-theme-gray-dark; |
5 | color: $dark-theme-text-color; | ||
5 | 6 | ||
6 | &:hover { background-color: $dark-theme-gray; } | 7 | &:hover { background-color: $dark-theme-gray; } |
7 | } | 8 | } |
@@ -12,7 +13,7 @@ | |||
12 | display: flex; | 13 | display: flex; |
13 | flex-flow: row wrap; | 14 | flex-flow: row wrap; |
14 | height: auto; | 15 | height: auto; |
15 | min-height: 70%; | 16 | // min-height: 70%; |
16 | 17 | ||
17 | &.recipes__list--disabled { | 18 | &.recipes__list--disabled { |
18 | filter: grayscale(100%); | 19 | filter: grayscale(100%); |
diff --git a/src/styles/reset.scss b/src/styles/reset.scss index f46ede4a2..d87ce652a 100644 --- a/src/styles/reset.scss +++ b/src/styles/reset.scss | |||
@@ -51,7 +51,6 @@ button { | |||
51 | padding: 0; | 51 | padding: 0; |
52 | 52 | ||
53 | &:focus { outline: 0; } | 53 | &:focus { outline: 0; } |
54 | .theme__dark & { color: $dark-theme-gray-smoke; } | ||
55 | } | 54 | } |
56 | 55 | ||
57 | html { | 56 | html { |
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 @@ | |||
360 | .account__subscription-button { margin-left: auto; } | 360 | .account__subscription-button { margin-left: auto; } |
361 | .franz-form__button { white-space: nowrap; } | 361 | .franz-form__button { white-space: nowrap; } |
362 | div { height: auto; } | 362 | div { height: auto; } |
363 | [data-type="franz-button"] div { height: 100% } | ||
363 | 364 | ||
364 | .invoices { | 365 | .invoices { |
365 | width: 100%; | 366 | width: 100%; |
diff --git a/uidev/src/stories/button.stories.tsx b/uidev/src/stories/button.stories.tsx index f7537895c..5c1c9246d 100644 --- a/uidev/src/stories/button.stories.tsx +++ b/uidev/src/stories/button.stories.tsx | |||
@@ -1,10 +1,10 @@ | |||
1 | import { mdiInformation } from '@mdi/js'; | ||
1 | import { observable } from 'mobx'; | 2 | import { observable } from 'mobx'; |
2 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
3 | import React from 'react'; | 4 | import React from 'react'; |
4 | import injectSheet from 'react-jss'; | 5 | import injectSheet from 'react-jss'; |
5 | 6 | ||
6 | import { Button, Input } from '@meetfranz/forms'; | 7 | import { Button, Input } from '@meetfranz/forms'; |
7 | import { classes } from 'istanbul-lib-coverage'; | ||
8 | import { Classes } from 'jss'; | 8 | import { Classes } from 'jss'; |
9 | import { storiesOf } from '../stores/stories'; | 9 | import { storiesOf } from '../stores/stories'; |
10 | 10 | ||
@@ -92,7 +92,7 @@ storiesOf('Button') | |||
92 | )) | 92 | )) |
93 | .add('With icon', () => ( | 93 | .add('With icon', () => ( |
94 | <WithStoreButton store={createStore({ | 94 | <WithStoreButton store={createStore({ |
95 | icon: 'mdiInformation', | 95 | icon: mdiInformation, |
96 | })} /> | 96 | })} /> |
97 | )) | 97 | )) |
98 | .add('As link', () => ( | 98 | .add('As link', () => ( |
@@ -131,7 +131,7 @@ storiesOf('Button') | |||
131 | <div className={classes.combinedElements}> | 131 | <div className={classes.combinedElements}> |
132 | <Input showLabel={false} className={classes.input} noMargin /> | 132 | <Input showLabel={false} className={classes.input} noMargin /> |
133 | <WithStoreButton store={createStore({ | 133 | <WithStoreButton store={createStore({ |
134 | icon: 'mdiInformation', | 134 | icon: mdiInformation, |
135 | })} /> | 135 | })} /> |
136 | </div> | 136 | </div> |
137 | )), | 137 | )), |
diff --git a/uidev/src/stories/icon.stories.tsx b/uidev/src/stories/icon.stories.tsx index c8e7f8ced..f9aa1635b 100644 --- a/uidev/src/stories/icon.stories.tsx +++ b/uidev/src/stories/icon.stories.tsx | |||
@@ -1,53 +1,14 @@ | |||
1 | import { observable } from 'mobx'; | 1 | import { mdiAccountCircle } from '@mdi/js'; |
2 | import { observer } from 'mobx-react'; | ||
3 | import React from 'react'; | 2 | import React from 'react'; |
4 | import uuid from 'uuid/v4'; | ||
5 | 3 | ||
6 | import { Icon } from '@meetfranz/ui'; | 4 | import { Icon } from '@meetfranz/ui'; |
7 | import { storiesOf } from '../stores/stories'; | 5 | import { storiesOf } from '../stores/stories'; |
8 | 6 | ||
9 | // interface IStoreArgs { | ||
10 | // value?: boolean; | ||
11 | // checked?: boolean; | ||
12 | // label?: string; | ||
13 | // id?: string; | ||
14 | // name?: string; | ||
15 | // disabled?: boolean; | ||
16 | // error?: string; | ||
17 | // } | ||
18 | |||
19 | // const createStore = (args?: IStoreArgs) => { | ||
20 | // return observable(Object.assign({ | ||
21 | // id: `element-${uuid()}`, | ||
22 | // name: 'toggle', | ||
23 | // label: 'Label', | ||
24 | // value: true, | ||
25 | // checked: false, | ||
26 | // disabled: false, | ||
27 | // error: '', | ||
28 | // }, args)); | ||
29 | // }; | ||
30 | |||
31 | // const WithStoreToggle = observer(({ store }: { store: any }) => ( | ||
32 | // <> | ||
33 | // <Toggle | ||
34 | // value={store.value} | ||
35 | // checked={store.checked} | ||
36 | // label={store.label} | ||
37 | // id={store.id} | ||
38 | // name={store.name} | ||
39 | // disabled={store.disabled} | ||
40 | // error={store.error} | ||
41 | // onChange={() => store.checked = !store.checked} | ||
42 | // /> | ||
43 | // </> | ||
44 | // )); | ||
45 | |||
46 | storiesOf('Icon') | 7 | storiesOf('Icon') |
47 | .add('Basic', () => ( | 8 | .add('Basic', () => ( |
48 | <> | 9 | <> |
49 | <Icon icon="mdiAccountCircle" /> | 10 | <Icon icon={mdiAccountCircle} /> |
50 | <Icon icon="mdiAccountCircle" size={2} /> | 11 | <Icon icon={mdiAccountCircle} size={2} /> |
51 | <Icon icon="mdiAccountCircle" size={3} /> | 12 | <Icon icon={mdiAccountCircle} size={3} /> |
52 | </> | 13 | </> |
53 | )); | 14 | )); |
diff --git a/uidev/src/stories/infobox.stories.tsx b/uidev/src/stories/infobox.stories.tsx index 144855376..c3442da0d 100644 --- a/uidev/src/stories/infobox.stories.tsx +++ b/uidev/src/stories/infobox.stories.tsx | |||
@@ -1,3 +1,4 @@ | |||
1 | import { mdiEarth } from '@mdi/js'; | ||
1 | import { observable } from 'mobx'; | 2 | import { observable } from 'mobx'; |
2 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
3 | import React from 'react'; | 4 | import React from 'react'; |
@@ -44,7 +45,7 @@ storiesOf('Infobox') | |||
44 | .add('Icon + Dismissable', () => ( | 45 | .add('Icon + Dismissable', () => ( |
45 | <WithStoreInfobox | 46 | <WithStoreInfobox |
46 | store={createStore({ | 47 | store={createStore({ |
47 | icon: 'mdiEarth', | 48 | icon: mdiEarth, |
48 | dismissable: true, | 49 | dismissable: true, |
49 | })} | 50 | })} |
50 | > | 51 | > |
@@ -54,7 +55,7 @@ storiesOf('Infobox') | |||
54 | .add('With CTA', () => ( | 55 | .add('With CTA', () => ( |
55 | <WithStoreInfobox | 56 | <WithStoreInfobox |
56 | store={createStore({ | 57 | store={createStore({ |
57 | icon: 'mdiEarth', | 58 | icon: mdiEarth, |
58 | ctaLabel: 'Ok, hi!', | 59 | ctaLabel: 'Ok, hi!', |
59 | })} | 60 | })} |
60 | > | 61 | > |
@@ -64,7 +65,7 @@ storiesOf('Infobox') | |||
64 | .add('With long text', () => ( | 65 | .add('With long text', () => ( |
65 | <WithStoreInfobox | 66 | <WithStoreInfobox |
66 | store={createStore({ | 67 | store={createStore({ |
67 | icon: 'mdiEarth', | 68 | icon: mdiEarth, |
68 | ctaLabel: 'Ok, hi!', | 69 | ctaLabel: 'Ok, hi!', |
69 | })} | 70 | })} |
70 | > | 71 | > |
@@ -74,7 +75,7 @@ storiesOf('Infobox') | |||
74 | .add('Secondary', () => ( | 75 | .add('Secondary', () => ( |
75 | <WithStoreInfobox | 76 | <WithStoreInfobox |
76 | store={createStore({ | 77 | store={createStore({ |
77 | icon: 'mdiEarth', | 78 | icon: mdiEarth, |
78 | ctaLabel: 'Ok, hi!', | 79 | ctaLabel: 'Ok, hi!', |
79 | type: 'secondary', | 80 | type: 'secondary', |
80 | })} | 81 | })} |
@@ -85,7 +86,7 @@ storiesOf('Infobox') | |||
85 | .add('Success', () => ( | 86 | .add('Success', () => ( |
86 | <WithStoreInfobox | 87 | <WithStoreInfobox |
87 | store={createStore({ | 88 | store={createStore({ |
88 | icon: 'mdiEarth', | 89 | icon: mdiEarth, |
89 | ctaLabel: 'Ok, hi!', | 90 | ctaLabel: 'Ok, hi!', |
90 | type: 'success', | 91 | type: 'success', |
91 | })} | 92 | })} |
@@ -96,7 +97,7 @@ storiesOf('Infobox') | |||
96 | .add('Warning', () => ( | 97 | .add('Warning', () => ( |
97 | <WithStoreInfobox | 98 | <WithStoreInfobox |
98 | store={createStore({ | 99 | store={createStore({ |
99 | icon: 'mdiEarth', | 100 | icon: mdiEarth, |
100 | ctaLabel: 'Ok, hi!', | 101 | ctaLabel: 'Ok, hi!', |
101 | type: 'warning', | 102 | type: 'warning', |
102 | })} | 103 | })} |
@@ -107,7 +108,7 @@ storiesOf('Infobox') | |||
107 | .add('Danger', () => ( | 108 | .add('Danger', () => ( |
108 | <WithStoreInfobox | 109 | <WithStoreInfobox |
109 | store={createStore({ | 110 | store={createStore({ |
110 | icon: 'mdiEarth', | 111 | icon: mdiEarth, |
111 | ctaLabel: 'Ok, hi!', | 112 | ctaLabel: 'Ok, hi!', |
112 | type: 'danger', | 113 | type: 'danger', |
113 | })} | 114 | })} |
@@ -118,7 +119,7 @@ storiesOf('Infobox') | |||
118 | .add('Inverted', () => ( | 119 | .add('Inverted', () => ( |
119 | <WithStoreInfobox | 120 | <WithStoreInfobox |
120 | store={createStore({ | 121 | store={createStore({ |
121 | icon: 'mdiEarth', | 122 | icon: mdiEarth, |
122 | ctaLabel: 'Ok, hi!', | 123 | ctaLabel: 'Ok, hi!', |
123 | type: 'inverted', | 124 | type: 'inverted', |
124 | })} | 125 | })} |