diff options
author | Vijay A <avijayr@protonmail.com> | 2021-08-13 00:45:01 +0530 |
---|---|---|
committer | Vijay A <avijayr@protonmail.com> | 2021-08-13 00:45:01 +0530 |
commit | 2d27d5e66649d4f5baf127a53ee5ae524eae3a59 (patch) | |
tree | c592ea219ac8cd987fc367f57b54034c450ab2ab /src/components/settings | |
parent | Ferdi v5.6.0 (diff) | |
parent | 5.6.1-nightly.24 [skip ci] (diff) | |
download | ferdium-app-2d27d5e66649d4f5baf127a53ee5ae524eae3a59.tar.gz ferdium-app-2d27d5e66649d4f5baf127a53ee5ae524eae3a59.tar.zst ferdium-app-2d27d5e66649d4f5baf127a53ee5ae524eae3a59.zip |
chore: merge from nightly branch into release branch in prep for next beta
Diffstat (limited to 'src/components/settings')
-rw-r--r-- | src/components/settings/account/AccountDashboard.js | 159 | ||||
-rw-r--r-- | src/components/settings/navigation/SettingsNavigation.js | 16 | ||||
-rw-r--r-- | src/components/settings/recipes/RecipeItem.js | 5 | ||||
-rw-r--r-- | src/components/settings/recipes/RecipesDashboard.js | 77 | ||||
-rw-r--r-- | src/components/settings/services/EditServiceForm.js | 142 | ||||
-rw-r--r-- | src/components/settings/services/ServicesDashboard.js | 6 | ||||
-rw-r--r-- | src/components/settings/settings/EditSettingsForm.js | 91 | ||||
-rw-r--r-- | src/components/settings/supportFerdi/SupportFerdiDashboard.js | 18 | ||||
-rw-r--r-- | src/components/settings/team/TeamDashboard.js | 39 | ||||
-rw-r--r-- | src/components/settings/user/EditUserForm.js | 2 |
10 files changed, 158 insertions, 397 deletions
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js index 68d88e218..ef7748343 100644 --- a/src/components/settings/account/AccountDashboard.js +++ b/src/components/settings/account/AccountDashboard.js | |||
@@ -3,14 +3,11 @@ 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, H1, H2 } from '@meetfranz/ui'; | 6 | import { H1, H2 } from '@meetfranz/ui'; |
7 | import moment from 'moment'; | ||
8 | 7 | ||
9 | import Loader from '../../ui/Loader'; | 8 | import Loader from '../../ui/Loader'; |
10 | import Button from '../../ui/Button'; | 9 | import Button from '../../ui/Button'; |
11 | import Infobox from '../../ui/Infobox'; | 10 | import Infobox from '../../ui/Infobox'; |
12 | import SubscriptionForm from '../../../containers/subscription/SubscriptionFormScreen'; | ||
13 | import { i18nPlanName } from '../../../helpers/plan-helpers'; | ||
14 | import { LOCAL_SERVER, LIVE_FRANZ_API } from '../../../config'; | 11 | import { LOCAL_SERVER, LIVE_FRANZ_API } from '../../../config'; |
15 | 12 | ||
16 | const messages = defineMessages({ | 13 | const messages = defineMessages({ |
@@ -18,30 +15,10 @@ const messages = defineMessages({ | |||
18 | id: 'settings.account.headline', | 15 | id: 'settings.account.headline', |
19 | defaultMessage: '!!!Account', | 16 | defaultMessage: '!!!Account', |
20 | }, | 17 | }, |
21 | headlineSubscription: { | ||
22 | id: 'settings.account.headlineSubscription', | ||
23 | defaultMessage: '!!!Your Subscription', | ||
24 | }, | ||
25 | headlineDangerZone: { | 18 | headlineDangerZone: { |
26 | id: 'settings.account.headlineDangerZone', | 19 | id: 'settings.account.headlineDangerZone', |
27 | defaultMessage: '!!Danger Zone', | 20 | defaultMessage: '!!Danger Zone', |
28 | }, | 21 | }, |
29 | manageSubscriptionButtonLabel: { | ||
30 | id: 'settings.account.manageSubscription.label', | ||
31 | defaultMessage: '!!!Manage your subscription', | ||
32 | }, | ||
33 | upgradeAccountToPro: { | ||
34 | id: 'settings.account.upgradeToPro.label', | ||
35 | defaultMessage: '!!!Upgrade to Franz Professional', | ||
36 | }, | ||
37 | accountTypeBasic: { | ||
38 | id: 'settings.account.accountType.basic', | ||
39 | defaultMessage: '!!!Basic Account', | ||
40 | }, | ||
41 | accountTypePremium: { | ||
42 | id: 'settings.account.accountType.premium', | ||
43 | defaultMessage: '!!!Premium Supporter Account', | ||
44 | }, | ||
45 | accountEditButton: { | 22 | accountEditButton: { |
46 | id: 'settings.account.account.editButton', | 23 | id: 'settings.account.account.editButton', |
47 | defaultMessage: '!!!Edit Account', | 24 | defaultMessage: '!!!Edit Account', |
@@ -50,10 +27,6 @@ const messages = defineMessages({ | |||
50 | id: 'settings.account.headlineInvoices', | 27 | id: 'settings.account.headlineInvoices', |
51 | defaultMessage: '!!Invoices', | 28 | defaultMessage: '!!Invoices', |
52 | }, | 29 | }, |
53 | invoiceDownload: { | ||
54 | id: 'settings.account.invoiceDownload', | ||
55 | defaultMessage: '!!!Download', | ||
56 | }, | ||
57 | userInfoRequestFailed: { | 30 | userInfoRequestFailed: { |
58 | id: 'settings.account.userInfoRequestFailed', | 31 | id: 'settings.account.userInfoRequestFailed', |
59 | defaultMessage: '!!!Could not load user information', | 32 | defaultMessage: '!!!Could not load user information', |
@@ -76,23 +49,10 @@ const messages = defineMessages({ | |||
76 | defaultMessage: | 49 | defaultMessage: |
77 | '!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!', | 50 | '!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!', |
78 | }, | 51 | }, |
79 | trial: { | ||
80 | id: 'settings.account.trial', | ||
81 | defaultMessage: '!!!Free Trial', | ||
82 | }, | ||
83 | yourLicense: { | 52 | yourLicense: { |
84 | id: 'settings.account.yourLicense', | 53 | id: 'settings.account.yourLicense', |
85 | defaultMessage: '!!!Your Franz License:', | 54 | defaultMessage: '!!!Your Franz License:', |
86 | }, | 55 | }, |
87 | trialEndsIn: { | ||
88 | id: 'settings.account.trialEndsIn', | ||
89 | defaultMessage: '!!!Your free trial ends in {duration}.', | ||
90 | }, | ||
91 | trialUpdateBillingInformation: { | ||
92 | id: 'settings.account.trialUpdateBillingInfo', | ||
93 | defaultMessage: | ||
94 | '!!!Please update your billing info to continue using {license} after your trial period.', | ||
95 | }, | ||
96 | accountUnavailable: { | 56 | accountUnavailable: { |
97 | id: 'settings.account.accountUnavailable', | 57 | id: 'settings.account.accountUnavailable', |
98 | defaultMessage: 'Account is unavailable', | 58 | defaultMessage: 'Account is unavailable', |
@@ -107,8 +67,6 @@ const messages = defineMessages({ | |||
107 | class AccountDashboard extends Component { | 67 | class AccountDashboard extends Component { |
108 | static propTypes = { | 68 | static propTypes = { |
109 | user: MobxPropTypes.observableObject.isRequired, | 69 | user: MobxPropTypes.observableObject.isRequired, |
110 | isPremiumOverrideUser: PropTypes.bool.isRequired, | ||
111 | isProUser: PropTypes.bool.isRequired, | ||
112 | isLoading: PropTypes.bool.isRequired, | 70 | isLoading: PropTypes.bool.isRequired, |
113 | userInfoRequestFailed: PropTypes.bool.isRequired, | 71 | userInfoRequestFailed: PropTypes.bool.isRequired, |
114 | retryUserInfoRequest: PropTypes.func.isRequired, | 72 | retryUserInfoRequest: PropTypes.func.isRequired, |
@@ -116,10 +74,7 @@ class AccountDashboard extends Component { | |||
116 | isLoadingDeleteAccount: PropTypes.bool.isRequired, | 74 | isLoadingDeleteAccount: PropTypes.bool.isRequired, |
117 | isDeleteAccountSuccessful: PropTypes.bool.isRequired, | 75 | isDeleteAccountSuccessful: PropTypes.bool.isRequired, |
118 | openEditAccount: PropTypes.func.isRequired, | 76 | openEditAccount: PropTypes.func.isRequired, |
119 | openBilling: PropTypes.func.isRequired, | ||
120 | upgradeToPro: PropTypes.func.isRequired, | ||
121 | openInvoices: PropTypes.func.isRequired, | 77 | openInvoices: PropTypes.func.isRequired, |
122 | onCloseSubscriptionWindow: PropTypes.func.isRequired, | ||
123 | server: PropTypes.string.isRequired, | 78 | server: PropTypes.string.isRequired, |
124 | }; | 79 | }; |
125 | 80 | ||
@@ -130,8 +85,6 @@ class AccountDashboard extends Component { | |||
130 | render() { | 85 | render() { |
131 | const { | 86 | const { |
132 | user, | 87 | user, |
133 | isPremiumOverrideUser, | ||
134 | isProUser, | ||
135 | isLoading, | 88 | isLoading, |
136 | userInfoRequestFailed, | 89 | userInfoRequestFailed, |
137 | retryUserInfoRequest, | 90 | retryUserInfoRequest, |
@@ -139,20 +92,11 @@ class AccountDashboard extends Component { | |||
139 | isLoadingDeleteAccount, | 92 | isLoadingDeleteAccount, |
140 | isDeleteAccountSuccessful, | 93 | isDeleteAccountSuccessful, |
141 | openEditAccount, | 94 | openEditAccount, |
142 | openBilling, | ||
143 | upgradeToPro, | ||
144 | openInvoices, | 95 | openInvoices, |
145 | onCloseSubscriptionWindow, | ||
146 | server, | 96 | server, |
147 | } = this.props; | 97 | } = this.props; |
148 | const { intl } = this.context; | 98 | const { intl } = this.context; |
149 | 99 | ||
150 | let planName = ''; | ||
151 | |||
152 | if (user.team && user.team.plan) { | ||
153 | planName = i18nPlanName(user.team.plan, intl); | ||
154 | } | ||
155 | |||
156 | const isUsingWithoutAccount = server === LOCAL_SERVER; | 100 | const isUsingWithoutAccount = server === LOCAL_SERVER; |
157 | const isUsingFranzServer = server === LIVE_FRANZ_API; | 101 | const isUsingFranzServer = server === LIVE_FRANZ_API; |
158 | 102 | ||
@@ -210,98 +154,40 @@ class AccountDashboard extends Component { | |||
210 | <div className="account__info"> | 154 | <div className="account__info"> |
211 | <H1> | 155 | <H1> |
212 | <span className="username">{`${user.firstname} ${user.lastname}`}</span> | 156 | <span className="username">{`${user.firstname} ${user.lastname}`}</span> |
213 | {user.isPremium && ( | ||
214 | <> | ||
215 | {' '} | ||
216 | <ProBadge /> | ||
217 | </> | ||
218 | )} | ||
219 | </H1> | 157 | </H1> |
220 | <p> | 158 | <p> |
221 | {user.organization && `${user.organization}, `} | 159 | {user.organization && `${user.organization}, `} |
222 | {user.email} | 160 | {user.email} |
223 | </p> | 161 | </p> |
224 | {user.isPremium && ( | 162 | <div className="manage-user-links"> |
225 | <div className="manage-user-links"> | 163 | <Button |
226 | <Button | 164 | label={intl.formatMessage( |
227 | label={intl.formatMessage( | 165 | messages.accountEditButton, |
228 | messages.accountEditButton, | 166 | )} |
229 | )} | 167 | className="franz-form__button--inverted" |
230 | className="franz-form__button--inverted" | 168 | onClick={openEditAccount} |
231 | onClick={openEditAccount} | 169 | /> |
232 | /> | 170 | </div> |
233 | </div> | ||
234 | )} | ||
235 | </div> | 171 | </div> |
236 | {!user.isPremium && ( | 172 | <Button |
237 | <Button | 173 | label={intl.formatMessage( |
238 | label={intl.formatMessage( | 174 | messages.accountEditButton, |
239 | messages.accountEditButton, | 175 | )} |
240 | )} | 176 | className="franz-form__button--inverted" |
241 | className="franz-form__button--inverted" | 177 | onClick={openEditAccount} |
242 | onClick={openEditAccount} | 178 | /> |
243 | /> | ||
244 | )} | ||
245 | </div> | 179 | </div> |
246 | </div> | 180 | </div> |
247 | {user.isPremium && user.isSubscriptionOwner && isUsingFranzServer && ( | 181 | {user.isSubscriptionOwner && isUsingFranzServer && ( |
248 | <div className="account"> | 182 | <div className="account"> |
249 | <div className="account__box"> | 183 | <div className="account__box"> |
250 | <H2>{intl.formatMessage(messages.yourLicense)}</H2> | 184 | <H2>{intl.formatMessage(messages.yourLicense)}</H2> |
251 | <p> | 185 | <p> |
252 | Franz | 186 | Franz |
253 | {' '} | ||
254 | {isPremiumOverrideUser ? 'Premium' : planName} | ||
255 | {user.team.isTrial && ( | ||
256 | <> | ||
257 | {' – '} | ||
258 | {intl.formatMessage(messages.trial)} | ||
259 | </> | ||
260 | )} | ||
261 | </p> | 187 | </p> |
262 | {user.team.isTrial && ( | ||
263 | <> | ||
264 | <br /> | ||
265 | <p> | ||
266 | {intl.formatMessage(messages.trialEndsIn, { | ||
267 | duration: moment | ||
268 | .duration( | ||
269 | moment().diff(user.team.trialEnd), | ||
270 | ) | ||
271 | .humanize(), | ||
272 | })} | ||
273 | </p> | ||
274 | <p> | ||
275 | {intl.formatMessage( | ||
276 | messages.trialUpdateBillingInformation, | ||
277 | { | ||
278 | license: planName, | ||
279 | }, | ||
280 | )} | ||
281 | </p> | ||
282 | </> | ||
283 | )} | ||
284 | {!isProUser && ( | ||
285 | <div className="manage-user-links"> | ||
286 | <Button | ||
287 | label={intl.formatMessage( | ||
288 | messages.upgradeAccountToPro, | ||
289 | )} | ||
290 | className="franz-form__button--primary" | ||
291 | onClick={upgradeToPro} | ||
292 | /> | ||
293 | </div> | ||
294 | )} | ||
295 | <div className="manage-user-links"> | 188 | <div className="manage-user-links"> |
296 | <Button | 189 | <Button |
297 | label={intl.formatMessage( | 190 | label={intl.formatMessage( |
298 | messages.manageSubscriptionButtonLabel, | ||
299 | )} | ||
300 | className="franz-form__button--inverted" | ||
301 | onClick={openBilling} | ||
302 | /> | ||
303 | <Button | ||
304 | label={intl.formatMessage( | ||
305 | messages.invoicesButton, | 191 | messages.invoicesButton, |
306 | )} | 192 | )} |
307 | className="franz-form__button--inverted" | 193 | className="franz-form__button--inverted" |
@@ -311,15 +197,6 @@ class AccountDashboard extends Component { | |||
311 | </div> | 197 | </div> |
312 | </div> | 198 | </div> |
313 | )} | 199 | )} |
314 | {!user.isPremium && ( | ||
315 | <div className="account franz-form"> | ||
316 | <div className="account__box"> | ||
317 | <SubscriptionForm | ||
318 | onCloseWindow={onCloseSubscriptionWindow} | ||
319 | /> | ||
320 | </div> | ||
321 | </div> | ||
322 | )} | ||
323 | </> | 200 | </> |
324 | )} | 201 | )} |
325 | 202 | ||
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js index cebab2f12..02cae6b69 100644 --- a/src/components/settings/navigation/SettingsNavigation.js +++ b/src/components/settings/navigation/SettingsNavigation.js | |||
@@ -2,7 +2,6 @@ import React, { Component } from 'react'; | |||
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { defineMessages, intlShape } from 'react-intl'; | 3 | import { defineMessages, intlShape } from 'react-intl'; |
4 | import { inject, observer } from 'mobx-react'; | 4 | import { inject, observer } from 'mobx-react'; |
5 | import { ProBadge } from '@meetfranz/ui'; | ||
6 | import { RouterStore } from 'mobx-react-router'; | 5 | import { RouterStore } from 'mobx-react-router'; |
7 | 6 | ||
8 | import { LOCAL_SERVER, LIVE_FERDI_API, LIVE_FRANZ_API } from '../../../config'; | 7 | import { LOCAL_SERVER, LIVE_FERDI_API, LIVE_FRANZ_API } from '../../../config'; |
@@ -11,7 +10,6 @@ import { workspaceStore } from '../../../features/workspaces'; | |||
11 | import UIStore from '../../../stores/UIStore'; | 10 | import UIStore from '../../../stores/UIStore'; |
12 | import SettingsStore from '../../../stores/SettingsStore'; | 11 | import SettingsStore from '../../../stores/SettingsStore'; |
13 | import UserStore from '../../../stores/UserStore'; | 12 | import UserStore from '../../../stores/UserStore'; |
14 | import { serviceLimitStore } from '../../../features/serviceLimit'; | ||
15 | 13 | ||
16 | const messages = defineMessages({ | 14 | const messages = defineMessages({ |
17 | availableServices: { | 15 | availableServices: { |
@@ -98,8 +96,6 @@ export default @inject('stores', 'actions') @observer class SettingsNavigation e | |||
98 | 96 | ||
99 | render() { | 97 | render() { |
100 | const { serviceCount, workspaceCount, stores } = this.props; | 98 | const { serviceCount, workspaceCount, stores } = this.props; |
101 | const { isDarkThemeActive } = stores.ui; | ||
102 | const { router, user } = stores; | ||
103 | const { intl } = this.context; | 99 | const { intl } = this.context; |
104 | const isLoggedIn = Boolean(localStorage.getItem('authToken')); | 100 | const isLoggedIn = Boolean(localStorage.getItem('authToken')); |
105 | const isUsingWithoutAccount = stores.settings.app.server === LOCAL_SERVER; | 101 | const isUsingWithoutAccount = stores.settings.app.server === LOCAL_SERVER; |
@@ -124,9 +120,6 @@ export default @inject('stores', 'actions') @observer class SettingsNavigation e | |||
124 | {' '} | 120 | {' '} |
125 | <span className="badge"> | 121 | <span className="badge"> |
126 | {serviceCount} | 122 | {serviceCount} |
127 | {serviceLimitStore.serviceLimit !== 0 && ( | ||
128 | `/${serviceLimitStore.serviceLimit}` | ||
129 | )} | ||
130 | </span> | 123 | </span> |
131 | </Link> | 124 | </Link> |
132 | {workspaceStore.isFeatureEnabled ? ( | 125 | {workspaceStore.isFeatureEnabled ? ( |
@@ -138,11 +131,7 @@ export default @inject('stores', 'actions') @observer class SettingsNavigation e | |||
138 | > | 131 | > |
139 | {intl.formatMessage(messages.yourWorkspaces)} | 132 | {intl.formatMessage(messages.yourWorkspaces)} |
140 | {' '} | 133 | {' '} |
141 | {workspaceStore.isPremiumUpgradeRequired ? ( | 134 | <span className="badge">{workspaceCount}</span> |
142 | <ProBadge inverted={!isDarkThemeActive && workspaceStore.isSettingsRouteActive} /> | ||
143 | ) : ( | ||
144 | <span className="badge">{workspaceCount}</span> | ||
145 | )} | ||
146 | </Link> | 135 | </Link> |
147 | ) : null} | 136 | ) : null} |
148 | {!isUsingWithoutAccount && ( | 137 | {!isUsingWithoutAccount && ( |
@@ -163,9 +152,6 @@ export default @inject('stores', 'actions') @observer class SettingsNavigation e | |||
163 | disabled={!isLoggedIn} | 152 | disabled={!isLoggedIn} |
164 | > | 153 | > |
165 | {intl.formatMessage(messages.team)} | 154 | {intl.formatMessage(messages.team)} |
166 | {!user.data.isPremium && ( | ||
167 | <ProBadge inverted={!isDarkThemeActive && router.location.pathname === '/settings/team'} /> | ||
168 | )} | ||
169 | </Link> | 155 | </Link> |
170 | )} | 156 | )} |
171 | <Link | 157 | <Link |
diff --git a/src/components/settings/recipes/RecipeItem.js b/src/components/settings/recipes/RecipeItem.js index 12e3775f6..55f415bd5 100644 --- a/src/components/settings/recipes/RecipeItem.js +++ b/src/components/settings/recipes/RecipeItem.js | |||
@@ -28,6 +28,11 @@ export default @observer class RecipeItem extends Component { | |||
28 | alt="" | 28 | alt="" |
29 | /> | 29 | /> |
30 | <span className="recipe-teaser__label">{recipe.name}</span> | 30 | <span className="recipe-teaser__label">{recipe.name}</span> |
31 | {recipe.aliases && recipe.aliases.length > 0 && ( | ||
32 | <span className="recipe-teaser__alias_label"> | ||
33 | {`Aliases: ${recipe.aliases.join(', ')}`} | ||
34 | </span> | ||
35 | )} | ||
31 | </button> | 36 | </button> |
32 | ); | 37 | ); |
33 | } | 38 | } |
diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js index b4e2fc05c..44ff2d0d7 100644 --- a/src/components/settings/recipes/RecipesDashboard.js +++ b/src/components/settings/recipes/RecipesDashboard.js | |||
@@ -6,15 +6,13 @@ import { Link } from 'react-router'; | |||
6 | 6 | ||
7 | import { Button, Input } from '@meetfranz/forms'; | 7 | import { Button, Input } from '@meetfranz/forms'; |
8 | import injectSheet from 'react-jss'; | 8 | import injectSheet from 'react-jss'; |
9 | import { H3, H2, ProBadge } from '@meetfranz/ui'; | 9 | import { H3, H2 } from '@meetfranz/ui'; |
10 | import SearchInput from '../../ui/SearchInput'; | 10 | import SearchInput from '../../ui/SearchInput'; |
11 | import Infobox from '../../ui/Infobox'; | 11 | import Infobox from '../../ui/Infobox'; |
12 | import RecipeItem from './RecipeItem'; | 12 | import RecipeItem from './RecipeItem'; |
13 | import Loader from '../../ui/Loader'; | 13 | import Loader from '../../ui/Loader'; |
14 | import Appear from '../../ui/effects/Appear'; | 14 | import Appear from '../../ui/effects/Appear'; |
15 | 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'; | ||
18 | import RecipePreview from '../../../models/RecipePreview'; | 16 | import RecipePreview from '../../../models/RecipePreview'; |
19 | 17 | ||
20 | const messages = defineMessages({ | 18 | const messages = defineMessages({ |
@@ -26,10 +24,6 @@ const messages = defineMessages({ | |||
26 | id: 'settings.searchService', | 24 | id: 'settings.searchService', |
27 | defaultMessage: '!!!Search service', | 25 | defaultMessage: '!!!Search service', |
28 | }, | 26 | }, |
29 | mostPopularRecipes: { | ||
30 | id: 'settings.recipes.mostPopular', | ||
31 | defaultMessage: '!!!Most popular', | ||
32 | }, | ||
33 | allRecipes: { | 27 | allRecipes: { |
34 | id: 'settings.recipes.all', | 28 | id: 'settings.recipes.all', |
35 | defaultMessage: '!!!All services', | 29 | defaultMessage: '!!!All services', |
@@ -109,7 +103,6 @@ export default @injectSheet(styles) @observer class RecipesDashboard extends Com | |||
109 | recipes: MobxPropTypes.arrayOrObservableArray.isRequired, | 103 | recipes: MobxPropTypes.arrayOrObservableArray.isRequired, |
110 | customWebsiteRecipe: PropTypes.instanceOf(RecipePreview).isRequired, | 104 | customWebsiteRecipe: PropTypes.instanceOf(RecipePreview).isRequired, |
111 | isLoading: PropTypes.bool.isRequired, | 105 | isLoading: PropTypes.bool.isRequired, |
112 | hasLoadedRecipes: PropTypes.bool.isRequired, | ||
113 | showAddServiceInterface: PropTypes.func.isRequired, | 106 | showAddServiceInterface: PropTypes.func.isRequired, |
114 | searchRecipes: PropTypes.func.isRequired, | 107 | searchRecipes: PropTypes.func.isRequired, |
115 | resetSearch: PropTypes.func.isRequired, | 108 | resetSearch: PropTypes.func.isRequired, |
@@ -120,7 +113,6 @@ export default @injectSheet(styles) @observer class RecipesDashboard extends Com | |||
120 | openRecipeDirectory: PropTypes.func.isRequired, | 113 | openRecipeDirectory: PropTypes.func.isRequired, |
121 | openDevDocs: PropTypes.func.isRequired, | 114 | openDevDocs: PropTypes.func.isRequired, |
122 | classes: PropTypes.object.isRequired, | 115 | classes: PropTypes.object.isRequired, |
123 | isCommunityRecipesIncludedInCurrentPlan: PropTypes.bool.isRequired, | ||
124 | }; | 116 | }; |
125 | 117 | ||
126 | static defaultProps = { | 118 | static defaultProps = { |
@@ -137,7 +129,6 @@ export default @injectSheet(styles) @observer class RecipesDashboard extends Com | |||
137 | recipes, | 129 | recipes, |
138 | customWebsiteRecipe, | 130 | customWebsiteRecipe, |
139 | isLoading, | 131 | isLoading, |
140 | hasLoadedRecipes, | ||
141 | showAddServiceInterface, | 132 | showAddServiceInterface, |
142 | searchRecipes, | 133 | searchRecipes, |
143 | resetSearch, | 134 | resetSearch, |
@@ -148,11 +139,9 @@ export default @injectSheet(styles) @observer class RecipesDashboard extends Com | |||
148 | openRecipeDirectory, | 139 | openRecipeDirectory, |
149 | openDevDocs, | 140 | openDevDocs, |
150 | classes, | 141 | classes, |
151 | isCommunityRecipesIncludedInCurrentPlan, | ||
152 | } = this.props; | 142 | } = this.props; |
153 | const { intl } = this.context; | 143 | const { intl } = this.context; |
154 | 144 | ||
155 | |||
156 | const communityRecipes = recipes.filter(r => !r.isDevRecipe); | 145 | const communityRecipes = recipes.filter(r => !r.isDevRecipe); |
157 | const devRecipes = recipes.filter(r => r.isDevRecipe); | 146 | const devRecipes = recipes.filter(r => r.isDevRecipe); |
158 | 147 | ||
@@ -163,7 +152,6 @@ export default @injectSheet(styles) @observer class RecipesDashboard extends Com | |||
163 | <div className="settings__header"> | 152 | <div className="settings__header"> |
164 | <h1>{intl.formatMessage(messages.headline)}</h1> | 153 | <h1>{intl.formatMessage(messages.headline)}</h1> |
165 | </div> | 154 | </div> |
166 | <LimitReachedInfobox /> | ||
167 | <div className="settings__body recipes"> | 155 | <div className="settings__body recipes"> |
168 | {serviceStatus.length > 0 && serviceStatus.includes('created') && ( | 156 | {serviceStatus.length > 0 && serviceStatus.includes('created') && ( |
169 | <Appear> | 157 | <Appear> |
@@ -190,14 +178,6 @@ export default @injectSheet(styles) @observer class RecipesDashboard extends Com | |||
190 | activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} | 178 | activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} |
191 | onClick={() => resetSearch()} | 179 | onClick={() => resetSearch()} |
192 | > | 180 | > |
193 | {intl.formatMessage(messages.mostPopularRecipes)} | ||
194 | </Link> | ||
195 | <Link | ||
196 | to="/settings/recipes/all" | ||
197 | className="badge" | ||
198 | activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`} | ||
199 | onClick={() => resetSearch()} | ||
200 | > | ||
201 | {intl.formatMessage(messages.allRecipes)} | 181 | {intl.formatMessage(messages.allRecipes)} |
202 | </Link> | 182 | </Link> |
203 | <Link | 183 | <Link |
@@ -208,7 +188,7 @@ export default @injectSheet(styles) @observer class RecipesDashboard extends Com | |||
208 | > | 188 | > |
209 | {intl.formatMessage(messages.customRecipes)} | 189 | {intl.formatMessage(messages.customRecipes)} |
210 | </Link> | 190 | </Link> |
211 | <a href={FRANZ_SERVICE_REQUEST} target="_blank" className="link recipes__service-request"> | 191 | <a href={FRANZ_SERVICE_REQUEST} target="_blank" className="link recipes__service-request" rel="noreferrer"> |
212 | {intl.formatMessage(messages.missingService)} | 192 | {intl.formatMessage(messages.missingService)} |
213 | {' '} | 193 | {' '} |
214 | <i className="mdi mdi-open-in-new" /> | 194 | <i className="mdi mdi-open-in-new" /> |
@@ -223,9 +203,6 @@ export default @injectSheet(styles) @observer class RecipesDashboard extends Com | |||
223 | <> | 203 | <> |
224 | <H2> | 204 | <H2> |
225 | {intl.formatMessage(messages.headlineCustomRecipes)} | 205 | {intl.formatMessage(messages.headlineCustomRecipes)} |
226 | {!isCommunityRecipesIncludedInCurrentPlan && ( | ||
227 | <ProBadge className={classes.proBadge} /> | ||
228 | )} | ||
229 | </H2> | 206 | </H2> |
230 | <div className={classes.devRecipeIntroContainer}> | 207 | <div className={classes.devRecipeIntroContainer}> |
231 | <p> | 208 | <p> |
@@ -251,37 +228,33 @@ export default @injectSheet(styles) @observer class RecipesDashboard extends Com | |||
251 | </div> | 228 | </div> |
252 | </> | 229 | </> |
253 | )} | 230 | )} |
254 | <PremiumFeatureContainer | 231 | {recipeFilter === 'dev' && communityRecipes.length > 0 && ( |
255 | condition={(recipeFilter === 'dev' && communityRecipes.length > 0) && !isCommunityRecipesIncludedInCurrentPlan} | 232 | <H3>{intl.formatMessage(messages.headlineCommunityRecipes)}</H3> |
256 | > | 233 | )} |
257 | {recipeFilter === 'dev' && communityRecipes.length > 0 && ( | 234 | <div className="recipes__list"> |
258 | <H3>{intl.formatMessage(messages.headlineCommunityRecipes)}</H3> | 235 | {recipes.length === 0 && recipeFilter !== 'dev' && ( |
259 | )} | 236 | <div className="align-middle settings__empty-state"> |
260 | <div className="recipes__list"> | 237 | <span className="emoji"> |
261 | {hasLoadedRecipes && recipes.length === 0 && recipeFilter !== 'dev' && ( | 238 | <img src="./assets/images/emoji/dontknow.png" alt="" /> |
262 | <div className="align-middle settings__empty-state"> | 239 | </span> |
263 | <span className="emoji"> | ||
264 | <img src="./assets/images/emoji/dontknow.png" alt="" /> | ||
265 | </span> | ||
266 | 240 | ||
267 | <p className="settings__empty-state-text">{intl.formatMessage(messages.nothingFound)}</p> | 241 | <p className="settings__empty-state-text">{intl.formatMessage(messages.nothingFound)}</p> |
268 | 242 | ||
269 | <RecipeItem | ||
270 | key={customWebsiteRecipe.id} | ||
271 | recipe={customWebsiteRecipe} | ||
272 | onClick={() => isLoggedIn && showAddServiceInterface({ recipeId: customWebsiteRecipe.id })} | ||
273 | /> | ||
274 | </div> | ||
275 | )} | ||
276 | {communityRecipes.map(recipe => ( | ||
277 | <RecipeItem | 243 | <RecipeItem |
278 | key={recipe.id} | 244 | key={customWebsiteRecipe.id} |
279 | recipe={recipe} | 245 | recipe={customWebsiteRecipe} |
280 | onClick={() => isLoggedIn && showAddServiceInterface({ recipeId: recipe.id })} | 246 | onClick={() => isLoggedIn && showAddServiceInterface({ recipeId: customWebsiteRecipe.id })} |
281 | /> | 247 | /> |
282 | ))} | 248 | </div> |
283 | </div> | 249 | )} |
284 | </PremiumFeatureContainer> | 250 | {communityRecipes.map(recipe => ( |
251 | <RecipeItem | ||
252 | key={recipe.id} | ||
253 | recipe={recipe} | ||
254 | onClick={() => isLoggedIn && showAddServiceInterface({ recipeId: recipe.id })} | ||
255 | /> | ||
256 | ))} | ||
257 | </div> | ||
285 | {recipeFilter === 'dev' && devRecipes.length > 0 && ( | 258 | {recipeFilter === 'dev' && devRecipes.length > 0 && ( |
286 | <div className={classes.devRecipeList}> | 259 | <div className={classes.devRecipeList}> |
287 | <H3>{intl.formatMessage(messages.headlineDevRecipes)}</H3> | 260 | <H3>{intl.formatMessage(messages.headlineDevRecipes)}</H3> |
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js index 513c75eed..c41cdd56a 100644 --- a/src/components/settings/services/EditServiceForm.js +++ b/src/components/settings/services/EditServiceForm.js | |||
@@ -1,4 +1,4 @@ | |||
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 } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import { Link } from 'react-router'; | 4 | import { Link } from 'react-router'; |
@@ -6,7 +6,6 @@ import { defineMessages, intlShape } from 'react-intl'; | |||
6 | import normalizeUrl from 'normalize-url'; | 6 | import normalizeUrl from 'normalize-url'; |
7 | 7 | ||
8 | import Form from '../../../lib/Form'; | 8 | import Form from '../../../lib/Form'; |
9 | import User from '../../../models/User'; | ||
10 | import Recipe from '../../../models/Recipe'; | 9 | import Recipe from '../../../models/Recipe'; |
11 | import Service from '../../../models/Service'; | 10 | import Service from '../../../models/Service'; |
12 | import Tabs, { TabItem } from '../../ui/Tabs'; | 11 | import Tabs, { TabItem } from '../../ui/Tabs'; |
@@ -17,9 +16,6 @@ import Button from '../../ui/Button'; | |||
17 | import ImageUpload from '../../ui/ImageUpload'; | 16 | import ImageUpload from '../../ui/ImageUpload'; |
18 | import Select from '../../ui/Select'; | 17 | import Select from '../../ui/Select'; |
19 | 18 | ||
20 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; | ||
21 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; | ||
22 | import { serviceLimitStore } from '../../../features/serviceLimit'; | ||
23 | import { isMac } from '../../../environment'; | 19 | import { isMac } from '../../../environment'; |
24 | import globalMessages from '../../../i18n/globalMessages'; | 20 | import globalMessages from '../../../i18n/globalMessages'; |
25 | 21 | ||
@@ -80,14 +76,6 @@ const messages = defineMessages({ | |||
80 | id: 'settings.service.form.customUrlValidationError', | 76 | id: 'settings.service.form.customUrlValidationError', |
81 | defaultMessage: '!!!Could not validate custom {name} server.', | 77 | defaultMessage: '!!!Could not validate custom {name} server.', |
82 | }, | 78 | }, |
83 | customUrlPremiumInfo: { | ||
84 | id: 'settings.service.form.customUrlPremiumInfo', | ||
85 | defaultMessage: '!!!To add self hosted services, you need a Ferdi Premium Supporter Account.', | ||
86 | }, | ||
87 | customUrlUpgradeAccount: { | ||
88 | id: 'settings.service.form.customUrlUpgradeAccount', | ||
89 | defaultMessage: '!!!Upgrade your account', | ||
90 | }, | ||
91 | indirectMessageInfo: { | 79 | indirectMessageInfo: { |
92 | id: 'settings.service.form.indirectMessageInfo', | 80 | id: 'settings.service.form.indirectMessageInfo', |
93 | defaultMessage: '!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...', | 81 | defaultMessage: '!!!You will be notified about all new messages in a channel, not just @username, @channel, @here, ...', |
@@ -149,7 +137,6 @@ export default @observer class EditServiceForm extends Component { | |||
149 | 137 | ||
150 | return null; | 138 | return null; |
151 | }, | 139 | }, |
152 | user: PropTypes.instanceOf(User).isRequired, | ||
153 | action: PropTypes.string.isRequired, | 140 | action: PropTypes.string.isRequired, |
154 | form: PropTypes.instanceOf(Form).isRequired, | 141 | form: PropTypes.instanceOf(Form).isRequired, |
155 | onSubmit: PropTypes.func.isRequired, | 142 | onSubmit: PropTypes.func.isRequired, |
@@ -158,9 +145,6 @@ export default @observer class EditServiceForm extends Component { | |||
158 | isSaving: PropTypes.bool.isRequired, | 145 | isSaving: PropTypes.bool.isRequired, |
159 | isDeleting: PropTypes.bool.isRequired, | 146 | isDeleting: PropTypes.bool.isRequired, |
160 | isProxyFeatureEnabled: PropTypes.bool.isRequired, | 147 | isProxyFeatureEnabled: PropTypes.bool.isRequired, |
161 | isServiceProxyIncludedInCurrentPlan: PropTypes.bool.isRequired, | ||
162 | isSpellcheckerIncludedInCurrentPlan: PropTypes.bool.isRequired, | ||
163 | isHibernationFeatureActive: PropTypes.bool.isRequired, | ||
164 | }; | 148 | }; |
165 | 149 | ||
166 | static defaultProps = { | 150 | static defaultProps = { |
@@ -217,16 +201,12 @@ export default @observer class EditServiceForm extends Component { | |||
217 | recipe, | 201 | recipe, |
218 | service, | 202 | service, |
219 | action, | 203 | action, |
220 | user, | ||
221 | form, | 204 | form, |
222 | isSaving, | 205 | isSaving, |
223 | isDeleting, | 206 | isDeleting, |
224 | onDelete, | 207 | onDelete, |
225 | openRecipeFile, | 208 | openRecipeFile, |
226 | isProxyFeatureEnabled, | 209 | isProxyFeatureEnabled, |
227 | isServiceProxyIncludedInCurrentPlan, | ||
228 | isSpellcheckerIncludedInCurrentPlan, | ||
229 | isHibernationFeatureActive, | ||
230 | } = this.props; | 210 | } = this.props; |
231 | const { intl } = this.context; | 211 | const { intl } = this.context; |
232 | 212 | ||
@@ -285,9 +265,8 @@ export default @observer class EditServiceForm extends Component { | |||
285 | )} | 265 | )} |
286 | </span> | 266 | </span> |
287 | </div> | 267 | </div> |
288 | <LimitReachedInfobox /> | ||
289 | <div className="settings__body"> | 268 | <div className="settings__body"> |
290 | <form onSubmit={e => this.submit(e)} id="form"> | 269 | <form onSubmit={(e) => this.submit(e)} id="form"> |
291 | <div className="service-name"> | 270 | <div className="service-name"> |
292 | <Input field={form.$('name')} focus /> | 271 | <Input field={form.$('name')} focus /> |
293 | </div> | 272 | </div> |
@@ -311,24 +290,11 @@ export default @observer class EditServiceForm extends Component { | |||
311 | )} | 290 | )} |
312 | {recipe.hasCustomUrl && ( | 291 | {recipe.hasCustomUrl && ( |
313 | <TabItem title={intl.formatMessage(messages.tabOnPremise)}> | 292 | <TabItem title={intl.formatMessage(messages.tabOnPremise)}> |
314 | {user.isPremium || recipe.author.find(a => a.email === user.email) ? ( | 293 | <Input field={form.$('customUrl')} /> |
315 | <> | 294 | {form.error === 'url-validation-error' && ( |
316 | <Input field={form.$('customUrl')} /> | 295 | <p className="franz-form__error"> |
317 | {form.error === 'url-validation-error' && ( | 296 | {intl.formatMessage(messages.customUrlValidationError, { name: recipe.name })} |
318 | <p className="franz-form__error"> | 297 | </p> |
319 | {intl.formatMessage(messages.customUrlValidationError, { name: recipe.name })} | ||
320 | </p> | ||
321 | )} | ||
322 | </> | ||
323 | ) : ( | ||
324 | <div className="center premium-info"> | ||
325 | <p>{intl.formatMessage(messages.customUrlPremiumInfo)}</p> | ||
326 | <p> | ||
327 | <Link to="/settings/user" className="button"> | ||
328 | {intl.formatMessage(messages.customUrlUpgradeAccount)} | ||
329 | </Link> | ||
330 | </p> | ||
331 | </div> | ||
332 | )} | 298 | )} |
333 | </TabItem> | 299 | </TabItem> |
334 | )} | 300 | )} |
@@ -373,14 +339,10 @@ export default @observer class EditServiceForm extends Component { | |||
373 | <div className="settings__settings-group"> | 339 | <div className="settings__settings-group"> |
374 | <h3>{intl.formatMessage(messages.headlineGeneral)}</h3> | 340 | <h3>{intl.formatMessage(messages.headlineGeneral)}</h3> |
375 | <Toggle field={form.$('isEnabled')} /> | 341 | <Toggle field={form.$('isEnabled')} /> |
376 | {isHibernationFeatureActive && ( | 342 | <Toggle field={form.$('isHibernationEnabled')} /> |
377 | <> | 343 | <p className="settings__help indented__help"> |
378 | <Toggle field={form.$('isHibernationEnabled')} /> | 344 | {intl.formatMessage(messages.isHibernationEnabledInfo)} |
379 | <p className="settings__help indented__help"> | 345 | </p> |
380 | {intl.formatMessage(messages.isHibernationEnabledInfo)} | ||
381 | </p> | ||
382 | </> | ||
383 | )} | ||
384 | <Toggle field={form.$('isDarkModeEnabled')} /> | 346 | <Toggle field={form.$('isDarkModeEnabled')} /> |
385 | {form.$('isDarkModeEnabled').value | 347 | {form.$('isDarkModeEnabled').value |
386 | && ( | 348 | && ( |
@@ -403,56 +365,46 @@ export default @observer class EditServiceForm extends Component { | |||
403 | </div> | 365 | </div> |
404 | 366 | ||
405 | {!isMac && ( | 367 | {!isMac && ( |
406 | <PremiumFeatureContainer | 368 | <div className="settings__settings-group"> |
407 | condition={!isSpellcheckerIncludedInCurrentPlan} | 369 | <Select field={form.$('spellcheckerLanguage')} /> |
408 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} | 370 | </div> |
409 | > | ||
410 | <div className="settings__settings-group"> | ||
411 | <Select field={form.$('spellcheckerLanguage')} /> | ||
412 | </div> | ||
413 | </PremiumFeatureContainer> | ||
414 | )} | 371 | )} |
415 | 372 | ||
416 | {isProxyFeatureEnabled && ( | 373 | {isProxyFeatureEnabled && ( |
417 | <PremiumFeatureContainer | 374 | <div className="settings__settings-group"> |
418 | condition={!isServiceProxyIncludedInCurrentPlan} | 375 | <h3> |
419 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'proxy' }} | 376 | {intl.formatMessage(messages.headlineProxy)} |
420 | > | 377 | <span className="badge badge--success">beta</span> |
421 | <div className="settings__settings-group"> | 378 | </h3> |
422 | <h3> | 379 | <Toggle field={form.$('proxy.isEnabled')} /> |
423 | {intl.formatMessage(messages.headlineProxy)} | 380 | {form.$('proxy.isEnabled').value && ( |
424 | <span className="badge badge--success">beta</span> | 381 | <> |
425 | </h3> | 382 | <div className="grid"> |
426 | <Toggle field={form.$('proxy.isEnabled')} /> | 383 | <div className="grid__row"> |
427 | {form.$('proxy.isEnabled').value && ( | 384 | <Input field={form.$('proxy.host')} className="proxyHost" /> |
428 | <> | 385 | <Input field={form.$('proxy.port')} /> |
429 | <div className="grid"> | ||
430 | <div className="grid__row"> | ||
431 | <Input field={form.$('proxy.host')} className="proxyHost" /> | ||
432 | <Input field={form.$('proxy.port')} /> | ||
433 | </div> | ||
434 | </div> | 386 | </div> |
435 | <div className="grid"> | 387 | </div> |
436 | <div className="grid__row"> | 388 | <div className="grid"> |
437 | <Input field={form.$('proxy.user')} /> | 389 | <div className="grid__row"> |
438 | <Input | 390 | <Input field={form.$('proxy.user')} /> |
439 | field={form.$('proxy.password')} | 391 | <Input |
440 | showPasswordToggle | 392 | field={form.$('proxy.password')} |
441 | /> | 393 | showPasswordToggle |
442 | </div> | 394 | /> |
443 | </div> | 395 | </div> |
444 | <p> | 396 | </div> |
445 | <span className="mdi mdi-information" /> | 397 | <p> |
446 | {intl.formatMessage(messages.proxyRestartInfo)} | 398 | <span className="mdi mdi-information" /> |
447 | </p> | 399 | {intl.formatMessage(messages.proxyRestartInfo)} |
448 | <p> | 400 | </p> |
449 | <span className="mdi mdi-information" /> | 401 | <p> |
450 | {intl.formatMessage(messages.proxyInfo)} | 402 | <span className="mdi mdi-information" /> |
451 | </p> | 403 | {intl.formatMessage(messages.proxyInfo)} |
452 | </> | 404 | </p> |
453 | )} | 405 | </> |
454 | </div> | 406 | )} |
455 | </PremiumFeatureContainer> | 407 | </div> |
456 | )} | 408 | )} |
457 | 409 | ||
458 | <div className="user-agent"> | 410 | <div className="user-agent"> |
@@ -512,7 +464,7 @@ export default @observer class EditServiceForm extends Component { | |||
512 | type="submit" | 464 | type="submit" |
513 | label={intl.formatMessage(messages.saveService)} | 465 | label={intl.formatMessage(messages.saveService)} |
514 | htmlForm="form" | 466 | htmlForm="form" |
515 | disabled={action !== 'edit' && ((form.isPristine && requiresUserInput) || serviceLimitStore.userHasReachedServiceLimit)} | 467 | disabled={action !== 'edit' && (form.isPristine && requiresUserInput)} |
516 | /> | 468 | /> |
517 | )} | 469 | )} |
518 | </div> | 470 | </div> |
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js index a0f05fd20..11d3eaa79 100644 --- a/src/components/settings/services/ServicesDashboard.js +++ b/src/components/settings/services/ServicesDashboard.js | |||
@@ -10,7 +10,6 @@ import Loader from '../../ui/Loader'; | |||
10 | import FAB from '../../ui/FAB'; | 10 | import FAB from '../../ui/FAB'; |
11 | import ServiceItem from './ServiceItem'; | 11 | import ServiceItem from './ServiceItem'; |
12 | import Appear from '../../ui/effects/Appear'; | 12 | import Appear from '../../ui/effects/Appear'; |
13 | import LimitReachedInfobox from '../../../features/serviceLimit/components/LimitReachedInfobox'; | ||
14 | 13 | ||
15 | const messages = defineMessages({ | 14 | const messages = defineMessages({ |
16 | headline: { | 15 | headline: { |
@@ -93,12 +92,11 @@ export default @observer class ServicesDashboard extends Component { | |||
93 | <div className="settings__header"> | 92 | <div className="settings__header"> |
94 | <h1>{intl.formatMessage(messages.headline)}</h1> | 93 | <h1>{intl.formatMessage(messages.headline)}</h1> |
95 | </div> | 94 | </div> |
96 | <LimitReachedInfobox /> | ||
97 | <div className="settings__body"> | 95 | <div className="settings__body"> |
98 | {(services.length !== 0 || searchNeedle) && !isLoading && ( | 96 | {(services.length !== 0 || searchNeedle) && !isLoading && ( |
99 | <SearchInput | 97 | <SearchInput |
100 | placeholder={intl.formatMessage(messages.searchService)} | 98 | placeholder={intl.formatMessage(messages.searchService)} |
101 | onChange={needle => filterServices({ needle })} | 99 | onChange={(needle) => filterServices({ needle })} |
102 | onReset={() => resetFilter()} | 100 | onReset={() => resetFilter()} |
103 | autoFocus | 101 | autoFocus |
104 | /> | 102 | /> |
@@ -165,7 +163,7 @@ export default @observer class ServicesDashboard extends Component { | |||
165 | ) : ( | 163 | ) : ( |
166 | <table className="service-table"> | 164 | <table className="service-table"> |
167 | <tbody> | 165 | <tbody> |
168 | {services.map(service => ( | 166 | {services.map((service) => ( |
169 | <ServiceItem | 167 | <ServiceItem |
170 | key={service.id} | 168 | key={service.id} |
171 | service={service} | 169 | service={service} |
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index 52b26d65b..87a4ada27 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js | |||
@@ -1,5 +1,5 @@ | |||
1 | import { app, systemPreferences } from '@electron/remote'; | 1 | import { app, systemPreferences } from '@electron/remote'; |
2 | import React, { Component, Fragment } from 'react'; | 2 | import React, { Component } from 'react'; |
3 | import PropTypes from 'prop-types'; | 3 | import PropTypes from 'prop-types'; |
4 | import { observer } from 'mobx-react'; | 4 | import { observer } from 'mobx-react'; |
5 | import prettyBytes from 'pretty-bytes'; | 5 | import prettyBytes from 'pretty-bytes'; |
@@ -10,14 +10,13 @@ import Button from '../../ui/Button'; | |||
10 | import Toggle from '../../ui/Toggle'; | 10 | import Toggle from '../../ui/Toggle'; |
11 | import ToggleRaw from '../../ui/ToggleRaw'; | 11 | import ToggleRaw from '../../ui/ToggleRaw'; |
12 | import Select from '../../ui/Select'; | 12 | import Select from '../../ui/Select'; |
13 | import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; | ||
14 | import Input from '../../ui/Input'; | 13 | import Input from '../../ui/Input'; |
15 | 14 | ||
16 | import { | 15 | import { |
17 | FRANZ_TRANSLATION, | 16 | FRANZ_TRANSLATION, |
18 | GITHUB_FRANZ_URL, | 17 | GITHUB_FRANZ_URL, |
19 | } from '../../../config'; | 18 | } from '../../../config'; |
20 | import { DEFAULT_APP_SETTINGS, isMac, isWindows } from '../../../environment'; | 19 | import { DEFAULT_APP_SETTINGS, isMac, isWindows, lockFerdiShortcutKey } from '../../../environment'; |
21 | import globalMessages from '../../../i18n/globalMessages'; | 20 | import globalMessages from '../../../i18n/globalMessages'; |
22 | 21 | ||
23 | const messages = defineMessages({ | 22 | const messages = defineMessages({ |
@@ -31,7 +30,7 @@ const messages = defineMessages({ | |||
31 | }, | 30 | }, |
32 | sentryInfo: { | 31 | sentryInfo: { |
33 | id: 'settings.app.sentryInfo', | 32 | id: 'settings.app.sentryInfo', |
34 | defaultMessage: '!!!Sending telemetry data allows us to find errors in Ferdi - we will not send any personal information like your message data! Changing this option requires you to restart Ferdi.', | 33 | defaultMessage: '!!!Sending telemetry data allows us to find errors in Ferdi - we will not send any personal information like your message data!', |
35 | }, | 34 | }, |
36 | hibernateInfo: { | 35 | hibernateInfo: { |
37 | id: 'settings.app.hibernateInfo', | 36 | id: 'settings.app.hibernateInfo', |
@@ -55,7 +54,7 @@ const messages = defineMessages({ | |||
55 | }, | 54 | }, |
56 | lockInfo: { | 55 | lockInfo: { |
57 | id: 'settings.app.lockInfo', | 56 | id: 'settings.app.lockInfo', |
58 | defaultMessage: '!!!Password Lock allows you to keep your messages protected.\nUsing Password Lock, you will be prompted to enter your password everytime you start Ferdi or lock Ferdi yourself using the lock symbol in the bottom left corner or the shortcut CMD/CTRL+Shift+L.', | 57 | defaultMessage: '!!!Password Lock allows you to keep your messages protected.\nUsing Password Lock, you will be prompted to enter your password everytime you start Ferdi or lock Ferdi yourself using the lock symbol in the bottom left corner or the shortcut {lockShortcut}.', |
59 | }, | 58 | }, |
60 | scheduledDNDTimeInfo: { | 59 | scheduledDNDTimeInfo: { |
61 | id: 'settings.app.scheduledDNDTimeInfo', | 60 | id: 'settings.app.scheduledDNDTimeInfo', |
@@ -168,12 +167,10 @@ export default @observer class EditSettingsForm extends Component { | |||
168 | isClearingAllCache: PropTypes.bool.isRequired, | 167 | isClearingAllCache: PropTypes.bool.isRequired, |
169 | onClearAllCache: PropTypes.func.isRequired, | 168 | onClearAllCache: PropTypes.func.isRequired, |
170 | getCacheSize: PropTypes.func.isRequired, | 169 | getCacheSize: PropTypes.func.isRequired, |
171 | isSpellcheckerIncludedInCurrentPlan: PropTypes.bool.isRequired, | ||
172 | isTodosEnabled: PropTypes.bool.isRequired, | 170 | isTodosEnabled: PropTypes.bool.isRequired, |
173 | isTodosActivated: PropTypes.bool.isRequired, | 171 | isTodosActivated: PropTypes.bool.isRequired, |
174 | isWorkspaceEnabled: PropTypes.bool.isRequired, | 172 | isWorkspaceEnabled: PropTypes.bool.isRequired, |
175 | automaticUpdates: PropTypes.bool.isRequired, | 173 | automaticUpdates: PropTypes.bool.isRequired, |
176 | hibernationEnabled: PropTypes.bool.isRequired, | ||
177 | isDarkmodeEnabled: PropTypes.bool.isRequired, | 174 | isDarkmodeEnabled: PropTypes.bool.isRequired, |
178 | isAdaptableDarkModeEnabled: PropTypes.bool.isRequired, | 175 | isAdaptableDarkModeEnabled: PropTypes.bool.isRequired, |
179 | isNightlyEnabled: PropTypes.bool.isRequired, | 176 | isNightlyEnabled: PropTypes.bool.isRequired, |
@@ -224,11 +221,9 @@ export default @observer class EditSettingsForm extends Component { | |||
224 | isClearingAllCache, | 221 | isClearingAllCache, |
225 | onClearAllCache, | 222 | onClearAllCache, |
226 | getCacheSize, | 223 | getCacheSize, |
227 | isSpellcheckerIncludedInCurrentPlan, | ||
228 | isTodosEnabled, | 224 | isTodosEnabled, |
229 | isWorkspaceEnabled, | 225 | isWorkspaceEnabled, |
230 | automaticUpdates, | 226 | automaticUpdates, |
231 | hibernationEnabled, | ||
232 | isDarkmodeEnabled, | 227 | isDarkmodeEnabled, |
233 | isTodosActivated, | 228 | isTodosActivated, |
234 | isNightlyEnabled, | 229 | isNightlyEnabled, |
@@ -271,8 +266,8 @@ export default @observer class EditSettingsForm extends Component { | |||
271 | </div> | 266 | </div> |
272 | <div className="settings__body"> | 267 | <div className="settings__body"> |
273 | <form | 268 | <form |
274 | onSubmit={e => this.submit(e)} | 269 | onSubmit={(e) => this.submit(e)} |
275 | onChange={e => this.submit(e)} | 270 | onChange={(e) => this.submit(e)} |
276 | id="form" | 271 | id="form" |
277 | > | 272 | > |
278 | {/* Titles */} | 273 | {/* Titles */} |
@@ -339,13 +334,8 @@ export default @observer class EditSettingsForm extends Component { | |||
339 | 334 | ||
340 | <Hr /> | 335 | <Hr /> |
341 | 336 | ||
342 | <Toggle field={form.$('hibernate')} /> | 337 | <Select field={form.$('hibernationStrategy')} /> |
343 | {hibernationEnabled && ( | 338 | <Toggle field={form.$('hibernateOnStartup')} /> |
344 | <> | ||
345 | <Select field={form.$('hibernationStrategy')} /> | ||
346 | <Toggle field={form.$('hibernateOnStartup')} /> | ||
347 | </> | ||
348 | )} | ||
349 | <p | 339 | <p |
350 | className="settings__message" | 340 | className="settings__message" |
351 | style={{ | 341 | style={{ |
@@ -357,14 +347,17 @@ export default @observer class EditSettingsForm extends Component { | |||
357 | </span> | 347 | </span> |
358 | </p> | 348 | </p> |
359 | 349 | ||
350 | <Select field={form.$('wakeUpStrategy')} /> | ||
351 | |||
360 | <Hr /> | 352 | <Hr /> |
361 | 353 | ||
362 | {isWorkspaceEnabled && ( | 354 | {isWorkspaceEnabled && ( |
363 | <Toggle field={form.$('keepAllWorkspacesLoaded')} /> | 355 | <> |
356 | <Toggle field={form.$('keepAllWorkspacesLoaded')} /> | ||
357 | <Hr /> | ||
358 | </> | ||
364 | )} | 359 | )} |
365 | 360 | ||
366 | <Hr /> | ||
367 | |||
368 | {isTodosEnabled && !hasAddedTodosAsService && ( | 361 | {isTodosEnabled && !hasAddedTodosAsService && ( |
369 | <> | 362 | <> |
370 | <Toggle field={form.$('enableTodos')} /> | 363 | <Toggle field={form.$('enableTodos')} /> |
@@ -375,7 +368,7 @@ export default @observer class EditSettingsForm extends Component { | |||
375 | <div> | 368 | <div> |
376 | <Input | 369 | <Input |
377 | placeholder="Todo Server" | 370 | placeholder="Todo Server" |
378 | onChange={e => this.submit(e)} | 371 | onChange={(e) => this.submit(e)} |
379 | field={form.$('customTodoServer')} | 372 | field={form.$('customTodoServer')} |
380 | /> | 373 | /> |
381 | <p | 374 | <p |
@@ -409,7 +402,7 @@ export default @observer class EditSettingsForm extends Component { | |||
409 | > | 402 | > |
410 | <Input | 403 | <Input |
411 | placeholder="17:00" | 404 | placeholder="17:00" |
412 | onChange={e => this.submit(e)} | 405 | onChange={(e) => this.submit(e)} |
413 | field={form.$('scheduledDNDStart')} | 406 | field={form.$('scheduledDNDStart')} |
414 | type="time" | 407 | type="time" |
415 | /> | 408 | /> |
@@ -421,7 +414,7 @@ export default @observer class EditSettingsForm extends Component { | |||
421 | > | 414 | > |
422 | <Input | 415 | <Input |
423 | placeholder="09:00" | 416 | placeholder="09:00" |
424 | onChange={e => this.submit(e)} | 417 | onChange={(e) => this.submit(e)} |
425 | field={form.$('scheduledDNDEnd')} | 418 | field={form.$('scheduledDNDEnd')} |
426 | type="time" | 419 | type="time" |
427 | /> | 420 | /> |
@@ -488,7 +481,7 @@ export default @observer class EditSettingsForm extends Component { | |||
488 | 481 | ||
489 | <Input | 482 | <Input |
490 | placeholder="Accent Color" | 483 | placeholder="Accent Color" |
491 | onChange={e => this.submit(e)} | 484 | onChange={(e) => this.submit(e)} |
492 | field={form.$('accentColor')} | 485 | field={form.$('accentColor')} |
493 | /> | 486 | /> |
494 | <p> | 487 | <p> |
@@ -509,8 +502,12 @@ export default @observer class EditSettingsForm extends Component { | |||
509 | <Hr /> | 502 | <Hr /> |
510 | 503 | ||
511 | <Select field={form.$('searchEngine')} /> | 504 | <Select field={form.$('searchEngine')} /> |
505 | |||
506 | <Hr /> | ||
507 | |||
512 | <Toggle field={form.$('sentry')} /> | 508 | <Toggle field={form.$('sentry')} /> |
513 | <p>{intl.formatMessage(messages.sentryInfo)}</p> | 509 | <p className="settings__help">{intl.formatMessage(messages.sentryInfo)}</p> |
510 | <p className="settings__help">{intl.formatMessage(messages.appRestartRequired)}</p> | ||
514 | 511 | ||
515 | <Hr /> | 512 | <Hr /> |
516 | 513 | ||
@@ -523,7 +520,7 @@ export default @observer class EditSettingsForm extends Component { | |||
523 | 520 | ||
524 | <Input | 521 | <Input |
525 | placeholder={intl.formatMessage(messages.lockedPassword)} | 522 | placeholder={intl.formatMessage(messages.lockedPassword)} |
526 | onChange={e => this.submit(e)} | 523 | onChange={(e) => this.submit(e)} |
527 | field={form.$('lockedPassword')} | 524 | field={form.$('lockedPassword')} |
528 | type="password" | 525 | type="password" |
529 | scorePassword | 526 | scorePassword |
@@ -535,7 +532,7 @@ export default @observer class EditSettingsForm extends Component { | |||
535 | 532 | ||
536 | <Input | 533 | <Input |
537 | placeholder="Lock after inactivity" | 534 | placeholder="Lock after inactivity" |
538 | onChange={e => this.submit(e)} | 535 | onChange={(e) => this.submit(e)} |
539 | field={form.$('inactivityLock')} | 536 | field={form.$('inactivityLock')} |
540 | autoFocus | 537 | autoFocus |
541 | /> | 538 | /> |
@@ -551,7 +548,7 @@ export default @observer class EditSettingsForm extends Component { | |||
551 | }} | 548 | }} |
552 | > | 549 | > |
553 | <span> | 550 | <span> |
554 | { intl.formatMessage(messages.lockInfo) } | 551 | { intl.formatMessage(messages.lockInfo, { lockShortcut: `${lockFerdiShortcutKey(false)}` }) } |
555 | </span> | 552 | </span> |
556 | </p> | 553 | </p> |
557 | </div> | 554 | </div> |
@@ -564,26 +561,24 @@ export default @observer class EditSettingsForm extends Component { | |||
564 | 561 | ||
565 | <Hr /> | 562 | <Hr /> |
566 | 563 | ||
567 | <PremiumFeatureContainer | 564 | <Toggle |
568 | condition={!isSpellcheckerIncludedInCurrentPlan} | 565 | field={form.$('enableSpellchecking')} |
569 | gaEventInfo={{ category: 'User', event: 'upgrade', label: 'spellchecker' }} | 566 | /> |
570 | > | 567 | {!isMac && form.$('enableSpellchecking').value && ( |
571 | <> | 568 | <Select field={form.$('spellcheckerLanguage')} /> |
572 | <Toggle | 569 | )} |
573 | field={form.$('enableSpellchecking')} | 570 | {isMac && form.$('enableSpellchecking').value && ( |
574 | /> | 571 | <p className="settings__help">{intl.formatMessage(messages.spellCheckerLanguageInfo)}</p> |
575 | {!isMac && form.$('enableSpellchecking').value && ( | 572 | )} |
576 | <Select field={form.$('spellcheckerLanguage')} /> | 573 | <p className="settings__help">{intl.formatMessage(messages.appRestartRequired)}</p> |
577 | )} | 574 | |
578 | {isMac && form.$('enableSpellchecking').value && ( | 575 | <Hr /> |
579 | <p>{intl.formatMessage(messages.spellCheckerLanguageInfo)}</p> | 576 | |
580 | )} | ||
581 | </> | ||
582 | </PremiumFeatureContainer> | ||
583 | <a | 577 | <a |
584 | href={FRANZ_TRANSLATION} | 578 | href={FRANZ_TRANSLATION} |
585 | target="_blank" | 579 | target="_blank" |
586 | className="link" | 580 | className="link" |
581 | rel="noreferrer" | ||
587 | > | 582 | > |
588 | {intl.formatMessage(messages.translationHelp)} | 583 | {intl.formatMessage(messages.translationHelp)} |
589 | {' '} | 584 | {' '} |
@@ -602,7 +597,7 @@ export default @observer class EditSettingsForm extends Component { | |||
602 | 597 | ||
603 | <Input | 598 | <Input |
604 | placeholder="User Agent" | 599 | placeholder="User Agent" |
605 | onChange={e => this.submit(e)} | 600 | onChange={(e) => this.submit(e)} |
606 | field={form.$('userAgentPref')} | 601 | field={form.$('userAgentPref')} |
607 | /> | 602 | /> |
608 | <p className="settings__help">{intl.formatMessage(globalMessages.userAgentHelp)}</p> | 603 | <p className="settings__help">{intl.formatMessage(globalMessages.userAgentHelp)}</p> |
@@ -688,12 +683,12 @@ export default @observer class EditSettingsForm extends Component { | |||
688 | 683 | ||
689 | Ferdi is based on | 684 | Ferdi is based on |
690 | {' '} | 685 | {' '} |
691 | <a href={`${GITHUB_FRANZ_URL}/franz`} target="_blank">Franz</a> | 686 | <a href={`${GITHUB_FRANZ_URL}/franz`} target="_blank" rel="noreferrer">Franz</a> |
692 | 687 | ||
693 | , a project published | 688 | , a project published |
694 | under the | 689 | under the |
695 | {' '} | 690 | {' '} |
696 | <a href={`${GITHUB_FRANZ_URL}/franz/blob/master/LICENSE`} target="_blank">Apache-2.0 License</a> | 691 | <a href={`${GITHUB_FRANZ_URL}/franz/blob/master/LICENSE`} target="_blank" rel="noreferrer">Apache-2.0 License</a> |
697 | </span> | 692 | </span> |
698 | <br /> | 693 | <br /> |
699 | <span className="mdi mdi-information" /> | 694 | <span className="mdi mdi-information" /> |
diff --git a/src/components/settings/supportFerdi/SupportFerdiDashboard.js b/src/components/settings/supportFerdi/SupportFerdiDashboard.js index 36c126565..b84e06739 100644 --- a/src/components/settings/supportFerdi/SupportFerdiDashboard.js +++ b/src/components/settings/supportFerdi/SupportFerdiDashboard.js | |||
@@ -94,10 +94,10 @@ class SupportFerdiDashboard extends Component { | |||
94 | <h1>{intl.formatMessage(messages.title)}</h1> | 94 | <h1>{intl.formatMessage(messages.title)}</h1> |
95 | <div> | 95 | <div> |
96 | <p className="settings__support-badges"> | 96 | <p className="settings__support-badges"> |
97 | <a href="https://github.com/getferdi/ferdi" target="_blank"><img alt="GitHub Stars" src="https://img.shields.io/github/stars/getferdi/ferdi?style=social" /></a> | 97 | <a href="https://github.com/getferdi/ferdi" target="_blank" rel="noreferrer"><img alt="GitHub Stars" src="https://img.shields.io/github/stars/getferdi/ferdi?style=social" /></a> |
98 | <a href="https://twitter.com/getferdi/" target="_blank"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/getferdi?label=Follow&style=social" /></a> | 98 | <a href="https://twitter.com/getferdi/" target="_blank" rel="noreferrer"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/getferdi?label=Follow&style=social" /></a> |
99 | <a href="https://opencollective.com/getferdi#section-contributors" target="_blank"><img alt="Open Collective backers" src="https://img.shields.io/opencollective/backers/getferdi?logo=open-collective" /></a> | 99 | <a href="https://opencollective.com/getferdi#section-contributors" target="_blank" rel="noreferrer"><img alt="Open Collective backers" src="https://img.shields.io/opencollective/backers/getferdi?logo=open-collective" /></a> |
100 | <a href="https://opencollective.com/getferdi#section-contributors" target="_blank"><img alt="Open Collective sponsors" src="https://img.shields.io/opencollective/sponsors/getferdi?logo=open-collective" /></a> | 100 | <a href="https://opencollective.com/getferdi#section-contributors" target="_blank" rel="noreferrer"><img alt="Open Collective sponsors" src="https://img.shields.io/opencollective/sponsors/getferdi?logo=open-collective" /></a> |
101 | </p> | 101 | </p> |
102 | <FormattedHTMLMessage {...messages.aboutIntro} /> | 102 | <FormattedHTMLMessage {...messages.aboutIntro} /> |
103 | <br /> | 103 | <br /> |
@@ -109,7 +109,7 @@ class SupportFerdiDashboard extends Component { | |||
109 | </p> | 109 | </p> |
110 | <p> | 110 | <p> |
111 | {intl.formatMessage(messages.textListContributors)} | 111 | {intl.formatMessage(messages.textListContributors)} |
112 | <a href="https://github.com/getferdi/ferdi#contributors-" target="_blank" className="link"> | 112 | <a href="https://github.com/getferdi/ferdi#contributors-" target="_blank" className="link" rel="noreferrer"> |
113 | {' '} | 113 | {' '} |
114 | {intl.formatMessage(messages.textListContributorsHere)} | 114 | {intl.formatMessage(messages.textListContributorsHere)} |
115 | <i className="mdi mdi-open-in-new" /> | 115 | <i className="mdi mdi-open-in-new" /> |
@@ -122,7 +122,7 @@ class SupportFerdiDashboard extends Component { | |||
122 | </p> | 122 | </p> |
123 | <p> | 123 | <p> |
124 | {intl.formatMessage(messages.textSupportWelcome)} | 124 | {intl.formatMessage(messages.textSupportWelcome)} |
125 | <a href="https://help.getferdi.com/general/support" target="_blank" className="link"> | 125 | <a href="https://help.getferdi.com/general/support" target="_blank" className="link" rel="noreferrer"> |
126 | {' '} | 126 | {' '} |
127 | {intl.formatMessage(messages.textSupportWelcomeHere)} | 127 | {intl.formatMessage(messages.textSupportWelcomeHere)} |
128 | <i className="mdi mdi-open-in-new" /> | 128 | <i className="mdi mdi-open-in-new" /> |
@@ -130,7 +130,7 @@ class SupportFerdiDashboard extends Component { | |||
130 | </p> | 130 | </p> |
131 | <p> | 131 | <p> |
132 | {intl.formatMessage(messages.textExpenses)} | 132 | {intl.formatMessage(messages.textExpenses)} |
133 | <a href="https://opencollective.com/getferdi#section-budget" target="_blank" className="link"> | 133 | <a href="https://opencollective.com/getferdi#section-budget" target="_blank" className="link" rel="noreferrer"> |
134 | {' '} | 134 | {' '} |
135 | {intl.formatMessage(messages.textOpenCollective)} | 135 | {intl.formatMessage(messages.textOpenCollective)} |
136 | <i className="mdi mdi-open-in-new" /> | 136 | <i className="mdi mdi-open-in-new" /> |
@@ -138,14 +138,14 @@ class SupportFerdiDashboard extends Component { | |||
138 | </p> | 138 | </p> |
139 | <p> | 139 | <p> |
140 | {intl.formatMessage(messages.textDonation)} | 140 | {intl.formatMessage(messages.textDonation)} |
141 | <a href="https://opencollective.com/getferdi#section-contribute" target="_blank" className="link"> | 141 | <a href="https://opencollective.com/getferdi#section-contribute" target="_blank" className="link" rel="noreferrer"> |
142 | {' '} | 142 | {' '} |
143 | {intl.formatMessage(messages.textOpenCollective)} | 143 | {intl.formatMessage(messages.textOpenCollective)} |
144 | <i className="mdi mdi-open-in-new" /> | 144 | <i className="mdi mdi-open-in-new" /> |
145 | </a> | 145 | </a> |
146 | {' '} | 146 | {' '} |
147 | {intl.formatMessage(messages.textDonationAnd)} | 147 | {intl.formatMessage(messages.textDonationAnd)} |
148 | <a href="https://github.com/sponsors/getferdi" target="_blank" className="link"> | 148 | <a href="https://github.com/sponsors/getferdi" target="_blank" className="link" rel="noreferrer"> |
149 | {' '} | 149 | {' '} |
150 | {intl.formatMessage(messages.textGitHubSponsors)} | 150 | {intl.formatMessage(messages.textGitHubSponsors)} |
151 | <i className="mdi mdi-open-in-new" /> | 151 | <i className="mdi mdi-open-in-new" /> |
diff --git a/src/components/settings/team/TeamDashboard.js b/src/components/settings/team/TeamDashboard.js index 602d6e490..437225058 100644 --- a/src/components/settings/team/TeamDashboard.js +++ b/src/components/settings/team/TeamDashboard.js | |||
@@ -6,12 +6,9 @@ import ReactTooltip from 'react-tooltip'; | |||
6 | import injectSheet from 'react-jss'; | 6 | import injectSheet from 'react-jss'; |
7 | import classnames from 'classnames'; | 7 | import classnames from 'classnames'; |
8 | 8 | ||
9 | import { Badge } from '@meetfranz/ui'; | ||
10 | import Loader from '../../ui/Loader'; | 9 | import Loader from '../../ui/Loader'; |
11 | import Button from '../../ui/Button'; | 10 | import Button from '../../ui/Button'; |
12 | import Infobox from '../../ui/Infobox'; | 11 | import Infobox from '../../ui/Infobox'; |
13 | import globalMessages from '../../../i18n/globalMessages'; | ||
14 | import UpgradeButton from '../../ui/UpgradeButton'; | ||
15 | import { LIVE_FRANZ_API } from '../../../config'; | 12 | import { LIVE_FRANZ_API } from '../../../config'; |
16 | 13 | ||
17 | const messages = defineMessages({ | 14 | const messages = defineMessages({ |
@@ -35,10 +32,6 @@ const messages = defineMessages({ | |||
35 | id: 'settings.team.manageAction', | 32 | id: 'settings.team.manageAction', |
36 | defaultMessage: '!!!Manage your Team on meetfranz.com', | 33 | defaultMessage: '!!!Manage your Team on meetfranz.com', |
37 | }, | 34 | }, |
38 | upgradeButton: { | ||
39 | id: 'settings.team.upgradeAction', | ||
40 | defaultMessage: '!!!Upgrade your Account', | ||
41 | }, | ||
42 | teamsUnavailable: { | 35 | teamsUnavailable: { |
43 | id: 'settings.team.teamsUnavailable', | 36 | id: 'settings.team.teamsUnavailable', |
44 | defaultMessage: '!!!Teams are unavailable', | 37 | defaultMessage: '!!!Teams are unavailable', |
@@ -88,10 +81,6 @@ const styles = { | |||
88 | headlineWithSpacing: { | 81 | headlineWithSpacing: { |
89 | marginBottom: 'inherit', | 82 | marginBottom: 'inherit', |
90 | }, | 83 | }, |
91 | proRequired: { | ||
92 | margin: [10, 0, 40], | ||
93 | height: 'auto', | ||
94 | }, | ||
95 | buttonContainer: { | 84 | buttonContainer: { |
96 | display: 'flex', | 85 | display: 'flex', |
97 | height: 'auto', | 86 | height: 'auto', |
@@ -105,7 +94,6 @@ export default @injectSheet(styles) @observer class TeamDashboard extends Compon | |||
105 | retryUserInfoRequest: PropTypes.func.isRequired, | 94 | retryUserInfoRequest: PropTypes.func.isRequired, |
106 | openTeamManagement: PropTypes.func.isRequired, | 95 | openTeamManagement: PropTypes.func.isRequired, |
107 | classes: PropTypes.object.isRequired, | 96 | classes: PropTypes.object.isRequired, |
108 | isProUser: PropTypes.bool.isRequired, | ||
109 | server: PropTypes.string.isRequired, | 97 | server: PropTypes.string.isRequired, |
110 | }; | 98 | }; |
111 | 99 | ||
@@ -119,7 +107,6 @@ export default @injectSheet(styles) @observer class TeamDashboard extends Compon | |||
119 | userInfoRequestFailed, | 107 | userInfoRequestFailed, |
120 | retryUserInfoRequest, | 108 | retryUserInfoRequest, |
121 | openTeamManagement, | 109 | openTeamManagement, |
122 | isProUser, | ||
123 | classes, | 110 | classes, |
124 | server, | 111 | server, |
125 | } = this.props; | 112 | } = this.props; |
@@ -157,37 +144,25 @@ export default @injectSheet(styles) @observer class TeamDashboard extends Compon | |||
157 | <> | 144 | <> |
158 | <h1 className={classnames({ | 145 | <h1 className={classnames({ |
159 | [classes.headline]: true, | 146 | [classes.headline]: true, |
160 | [classes.headlineWithSpacing]: isProUser, | 147 | [classes.headlineWithSpacing]: true, |
161 | })} | 148 | })} |
162 | > | 149 | > |
163 | {intl.formatMessage(messages.contentHeadline)} | 150 | {intl.formatMessage(messages.contentHeadline)} |
164 | 151 | ||
165 | </h1> | 152 | </h1> |
166 | {!isProUser && ( | ||
167 | <Badge className={classes.proRequired}>{intl.formatMessage(globalMessages.proRequired)}</Badge> | ||
168 | )} | ||
169 | <div className={classes.container}> | 153 | <div className={classes.container}> |
170 | <div className={classes.content}> | 154 | <div className={classes.content}> |
171 | <p>{intl.formatMessage(messages.intro)}</p> | 155 | <p>{intl.formatMessage(messages.intro)}</p> |
172 | <p>{intl.formatMessage(messages.copy)}</p> | 156 | <p>{intl.formatMessage(messages.copy)}</p> |
173 | </div> | 157 | </div> |
174 | <img className={classes.image} src="https://cdn.franzinfra.com/announcements/assets/teams.png" alt="Franz for Teams" /> | 158 | <img className={classes.image} src="https://cdn.franzinfra.com/announcements/assets/teams.png" alt="Ferdi for Teams" /> |
175 | </div> | 159 | </div> |
176 | <div className={classes.buttonContainer}> | 160 | <div className={classes.buttonContainer}> |
177 | {!isProUser ? ( | 161 | <Button |
178 | <UpgradeButton | 162 | label={intl.formatMessage(messages.manageButton)} |
179 | className={classes.cta} | 163 | onClick={openTeamManagement} |
180 | gaEventInfo={{ category: 'Todos', event: 'upgrade' }} | 164 | className={classes.cta} |
181 | requiresPro | 165 | /> |
182 | short | ||
183 | /> | ||
184 | ) : ( | ||
185 | <Button | ||
186 | label={intl.formatMessage(messages.manageButton)} | ||
187 | onClick={openTeamManagement} | ||
188 | className={classes.cta} | ||
189 | /> | ||
190 | )} | ||
191 | </div> | 166 | </div> |
192 | </> | 167 | </> |
193 | </> | 168 | </> |
diff --git a/src/components/settings/user/EditUserForm.js b/src/components/settings/user/EditUserForm.js index a1a353e57..db78acb69 100644 --- a/src/components/settings/user/EditUserForm.js +++ b/src/components/settings/user/EditUserForm.js | |||
@@ -84,7 +84,7 @@ export default @observer class EditUserForm extends Component { | |||
84 | </span> | 84 | </span> |
85 | </div> | 85 | </div> |
86 | <div className="settings__body"> | 86 | <div className="settings__body"> |
87 | <form onSubmit={e => this.submit(e)} id="form"> | 87 | <form onSubmit={(e) => this.submit(e)} id="form"> |
88 | {status.length > 0 && status.includes('data-updated') && ( | 88 | {status.length > 0 && status.includes('data-updated') && ( |
89 | <Infobox | 89 | <Infobox |
90 | type="success" | 90 | type="success" |