aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/AppUpdateInfoBar.js2
-rw-r--r--src/components/auth/AuthLayout.js4
-rw-r--r--src/components/auth/Import.js4
-rw-r--r--src/components/auth/Login.js26
-rw-r--r--src/components/auth/Signup.js9
-rw-r--r--src/components/auth/Welcome.js15
-rw-r--r--src/components/layout/AppLayout.js22
-rw-r--r--src/components/layout/Sidebar.js86
-rw-r--r--src/components/services/content/Services.js23
-rw-r--r--src/components/settings/account/AccountDashboard.js2
-rw-r--r--src/components/settings/navigation/SettingsNavigation.js5
-rw-r--r--src/components/settings/services/EditServiceForm.js8
-rw-r--r--src/components/settings/settings/EditSettingsForm.js30
-rw-r--r--src/components/settings/team/TeamDashboard.js4
-rw-r--r--src/components/ui/AppLoader/index.js2
-rw-r--r--src/components/ui/Button.js2
-rw-r--r--src/components/ui/FullscreenLoader/styles.js1
-rw-r--r--src/components/ui/Input.js2
-rw-r--r--src/components/ui/Link.js4
-rw-r--r--src/components/ui/Loader.js2
-rw-r--r--src/components/ui/PremiumFeatureContainer/index.js6
21 files changed, 186 insertions, 73 deletions
diff --git a/src/components/AppUpdateInfoBar.js b/src/components/AppUpdateInfoBar.js
index 4fb3a8b71..4108fdf12 100644
--- a/src/components/AppUpdateInfoBar.js
+++ b/src/components/AppUpdateInfoBar.js
@@ -8,7 +8,7 @@ import InfoBar from './ui/InfoBar';
8const messages = defineMessages({ 8const messages = defineMessages({
9 updateAvailable: { 9 updateAvailable: {
10 id: 'infobar.updateAvailable', 10 id: 'infobar.updateAvailable',
11 defaultMessage: '!!!A new update for Franz is available.', 11 defaultMessage: '!!!A new update for Ferdi is available.',
12 }, 12 },
13 changelog: { 13 changelog: {
14 id: 'infobar.buttonChangelog', 14 id: 'infobar.buttonChangelog',
diff --git a/src/components/auth/AuthLayout.js b/src/components/auth/AuthLayout.js
index 75a8cfc61..641b754ed 100644
--- a/src/components/auth/AuthLayout.js
+++ b/src/components/auth/AuthLayout.js
@@ -52,7 +52,7 @@ export default @observer class AuthLayout extends Component {
52 52
53 return ( 53 return (
54 <> 54 <>
55 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />} 55 {isWindows && !isFullScreen && <TitleBar menu={window.ferdi.menu.template} icon="assets/images/logo.svg" />}
56 <div className="auth"> 56 <div className="auth">
57 {!isOnline && ( 57 {!isOnline && (
58 <InfoBar 58 <InfoBar
@@ -87,7 +87,7 @@ export default @observer class AuthLayout extends Component {
87 })} 87 })}
88 </div> 88 </div>
89 {/* </div> */} 89 {/* </div> */}
90 <Link to="https://adlk.io" className="auth__adlk" target="_blank"> 90 <Link to="https://github.com/kytwb/ferdi" className="auth__adlk" target="_blank">
91 <img src="./assets/images/adlk.svg" alt="" /> 91 <img src="./assets/images/adlk.svg" alt="" />
92 </Link> 92 </Link>
93 </div> 93 </div>
diff --git a/src/components/auth/Import.js b/src/components/auth/Import.js
index 0d5feb274..3e34c3162 100644
--- a/src/components/auth/Import.js
+++ b/src/components/auth/Import.js
@@ -12,11 +12,11 @@ import Button from '../ui/Button';
12const messages = defineMessages({ 12const messages = defineMessages({
13 headline: { 13 headline: {
14 id: 'import.headline', 14 id: 'import.headline',
15 defaultMessage: '!!!Import your Franz 4 services', 15 defaultMessage: '!!!Import your Ferdi 4 services',
16 }, 16 },
17 notSupportedHeadline: { 17 notSupportedHeadline: {
18 id: 'import.notSupportedHeadline', 18 id: 'import.notSupportedHeadline',
19 defaultMessage: '!!!Services not yet supported in Franz 5', 19 defaultMessage: '!!!Services not yet supported in Ferdi 5',
20 }, 20 },
21 submitButtonLabel: { 21 submitButtonLabel: {
22 id: 'import.submit.label', 22 id: 'import.submit.label',
diff --git a/src/components/auth/Login.js b/src/components/auth/Login.js
index 5d21f8b60..270dff30b 100644
--- a/src/components/auth/Login.js
+++ b/src/components/auth/Login.js
@@ -34,6 +34,14 @@ const messages = defineMessages({
34 id: 'login.invalidCredentials', 34 id: 'login.invalidCredentials',
35 defaultMessage: '!!!Email or password not valid', 35 defaultMessage: '!!!Email or password not valid',
36 }, 36 },
37 customServerQuestion: {
38 id: 'login.customServerQuestion',
39 defaultMessage: '!!!Using a custom Ferdi server?',
40 },
41 customServerSuggestion: {
42 id: 'login.customServerSuggestion',
43 defaultMessage: '!!!Try importing your Franz account',
44 },
37 tokenExpired: { 45 tokenExpired: {
38 id: 'login.tokenExpired', 46 id: 'login.tokenExpired',
39 defaultMessage: '!!!Your session expired, please login again.', 47 defaultMessage: '!!!Your session expired, please login again.',
@@ -137,7 +145,22 @@ export default @observer class Login extends Component {
137 showPasswordToggle 145 showPasswordToggle
138 /> 146 />
139 {error.code === 'invalid-credentials' && ( 147 {error.code === 'invalid-credentials' && (
140 <p className="error-message center">{intl.formatMessage(messages.invalidCredentials)}</p> 148 <>
149 <p className="error-message center">{intl.formatMessage(messages.invalidCredentials)}</p>
150 { window.ferdi.stores.settings.all.app.server !== 'https://api.franzinfra.com' && (
151 <p className="error-message center">
152 {intl.formatMessage(messages.customServerQuestion)}
153 {' '}
154 <Link
155 to={`${window.ferdi.stores.settings.all.app.server.replace('v1', '')}/import`}
156 target="_blank"
157 style={{ cursor: 'pointer', textDecoration: 'underline' }}
158 >
159 {intl.formatMessage(messages.customServerSuggestion)}
160 </Link>
161 </p>
162 )}
163 </>
141 )} 164 )}
142 {isSubmitting ? ( 165 {isSubmitting ? (
143 <Button 166 <Button
@@ -156,6 +179,7 @@ export default @observer class Login extends Component {
156 )} 179 )}
157 </form> 180 </form>
158 <div className="auth__links"> 181 <div className="auth__links">
182 <Link to="/settings/app">Change server</Link>
159 <Link to={signupRoute}>{intl.formatMessage(messages.signupLink)}</Link> 183 <Link to={signupRoute}>{intl.formatMessage(messages.signupLink)}</Link>
160 <Link to={passwordRoute}>{intl.formatMessage(messages.passwordLink)}</Link> 184 <Link to={passwordRoute}>{intl.formatMessage(messages.passwordLink)}</Link>
161 </div> 185 </div>
diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js
index 0499d764b..b36e71ce1 100644
--- a/src/components/auth/Signup.js
+++ b/src/components/auth/Signup.js
@@ -40,7 +40,7 @@ const messages = defineMessages({
40 }, 40 },
41 legalInfo: { 41 legalInfo: {
42 id: 'signup.legal.info', 42 id: 'signup.legal.info',
43 defaultMessage: '!!!By creating a Franz account you accept the', 43 defaultMessage: '!!!By creating a Ferdi account you accept the',
44 }, 44 },
45 terms: { 45 terms: {
46 id: 'signup.legal.terms', 46 id: 'signup.legal.terms',
@@ -117,6 +117,8 @@ export default @observer class Signup extends Component {
117 const { intl } = this.context; 117 const { intl } = this.context;
118 const { isSubmitting, loginRoute, error } = this.props; 118 const { isSubmitting, loginRoute, error } = this.props;
119 119
120 const termsBase = window.ferdi.stores.settings.all.app.server !== 'https://api.franzinfra.com' ? window.ferdi.stores.settings.all.app.server : 'https://meetfranz.com';
121
120 return ( 122 return (
121 <div className="auth__scroll-container"> 123 <div className="auth__scroll-container">
122 <div className="auth__container auth__container--signup"> 124 <div className="auth__container auth__container--signup">
@@ -163,7 +165,7 @@ export default @observer class Signup extends Component {
163 {intl.formatMessage(messages.legalInfo)} 165 {intl.formatMessage(messages.legalInfo)}
164 <br /> 166 <br />
165 <Link 167 <Link
166 to="https://meetfranz.com/terms" 168 to={`${termsBase}/terms`}
167 target="_blank" 169 target="_blank"
168 className="link" 170 className="link"
169 > 171 >
@@ -171,7 +173,7 @@ export default @observer class Signup extends Component {
171 </Link> 173 </Link>
172 &nbsp;&amp;&nbsp; 174 &nbsp;&amp;&nbsp;
173 <Link 175 <Link
174 to="https://meetfranz.com/privacy" 176 to={`${termsBase}/privacy`}
175 target="_blank" 177 target="_blank"
176 className="link" 178 className="link"
177 > 179 >
@@ -181,6 +183,7 @@ export default @observer class Signup extends Component {
181 </p> 183 </p>
182 </form> 184 </form>
183 <div className="auth__links"> 185 <div className="auth__links">
186 <Link to="/settings/app">Change server</Link>
184 <Link to={loginRoute}>{intl.formatMessage(messages.loginLink)}</Link> 187 <Link to={loginRoute}>{intl.formatMessage(messages.loginLink)}</Link>
185 </div> 188 </div>
186 </div> 189 </div>
diff --git a/src/components/auth/Welcome.js b/src/components/auth/Welcome.js
index f6d77f70f..ef917e336 100644
--- a/src/components/auth/Welcome.js
+++ b/src/components/auth/Welcome.js
@@ -41,7 +41,7 @@ export default @observer class Login extends Component {
41 <img src="./assets/images/logo.svg" className="welcome__logo" alt="" /> 41 <img src="./assets/images/logo.svg" className="welcome__logo" alt="" />
42 {/* <img src="./assets/images/welcome.png" className="welcome__services" alt="" /> */} 42 {/* <img src="./assets/images/welcome.png" className="welcome__services" alt="" /> */}
43 <div className="welcome__text"> 43 <div className="welcome__text">
44 <h1>Franz</h1> 44 <h1>Ferdi</h1>
45 </div> 45 </div>
46 </div> 46 </div>
47 <div className="welcome__buttons"> 47 <div className="welcome__buttons">
@@ -51,6 +51,19 @@ export default @observer class Login extends Component {
51 <Link to={loginRoute} className="button"> 51 <Link to={loginRoute} className="button">
52 {intl.formatMessage(messages.loginButton)} 52 {intl.formatMessage(messages.loginButton)}
53 </Link> 53 </Link>
54 <br />
55 <br />
56
57 <Link to="settings/app">
58 <span style={{
59 textAlign: 'center',
60 width: '100%',
61 cursor: 'pointer',
62 }}
63 >
64 Change server
65 </span>
66 </Link>
54 </div> 67 </div>
55 <div className="welcome__featured-services"> 68 <div className="welcome__featured-services">
56 {recipes.map(recipe => ( 69 {recipes.map(recipe => (
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index 200777ae6..ed004d07e 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -6,7 +6,6 @@ import { TitleBar } from 'electron-react-titlebar';
6import injectSheet from 'react-jss'; 6import injectSheet from 'react-jss';
7 7
8import InfoBar from '../ui/InfoBar'; 8import InfoBar from '../ui/InfoBar';
9import { Component as DelayApp } from '../../features/delayApp';
10import { Component as BasicAuth } from '../../features/basicAuth'; 9import { Component as BasicAuth } from '../../features/basicAuth';
11import { Component as ShareFranz } from '../../features/shareFranz'; 10import { Component as ShareFranz } from '../../features/shareFranz';
12import ErrorBoundary from '../util/ErrorBoundary'; 11import ErrorBoundary from '../util/ErrorBoundary';
@@ -37,6 +36,10 @@ const messages = defineMessages({
37 id: 'infobar.requiredRequestsFailed', 36 id: 'infobar.requiredRequestsFailed',
38 defaultMessage: '!!!Could not load services and user information', 37 defaultMessage: '!!!Could not load services and user information',
39 }, 38 },
39 authRequestFailed: {
40 id: 'infobar.authRequestFailed',
41 defaultMessage: '!!!There were errors while trying to perform an authenticated request. Please try logging out and back in if this error persists.',
42 },
40}); 43});
41 44
42const styles = theme => ({ 45const styles = theme => ({
@@ -63,6 +66,7 @@ class AppLayout extends Component {
63 showServicesUpdatedInfoBar: PropTypes.bool.isRequired, 66 showServicesUpdatedInfoBar: PropTypes.bool.isRequired,
64 appUpdateIsDownloaded: PropTypes.bool.isRequired, 67 appUpdateIsDownloaded: PropTypes.bool.isRequired,
65 nextAppReleaseVersion: PropTypes.string, 68 nextAppReleaseVersion: PropTypes.string,
69 authRequestFailed: PropTypes.bool.isRequired,
66 removeNewsItem: PropTypes.func.isRequired, 70 removeNewsItem: PropTypes.func.isRequired,
67 reloadServicesAfterUpdate: PropTypes.func.isRequired, 71 reloadServicesAfterUpdate: PropTypes.func.isRequired,
68 installAppUpdate: PropTypes.func.isRequired, 72 installAppUpdate: PropTypes.func.isRequired,
@@ -95,6 +99,7 @@ class AppLayout extends Component {
95 showServicesUpdatedInfoBar, 99 showServicesUpdatedInfoBar,
96 appUpdateIsDownloaded, 100 appUpdateIsDownloaded,
97 nextAppReleaseVersion, 101 nextAppReleaseVersion,
102 authRequestFailed,
98 removeNewsItem, 103 removeNewsItem,
99 reloadServicesAfterUpdate, 104 reloadServicesAfterUpdate,
100 installAppUpdate, 105 installAppUpdate,
@@ -111,7 +116,7 @@ class AppLayout extends Component {
111 return ( 116 return (
112 <ErrorBoundary> 117 <ErrorBoundary>
113 <div className="app"> 118 <div className="app">
114 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />} 119 {isWindows && !isFullScreen && <TitleBar menu={window.ferdi.menu.template} icon="assets/images/logo.svg" />}
115 <div className={`app__content ${classes.appContent}`}> 120 <div className={`app__content ${classes.appContent}`}>
116 {workspacesDrawer} 121 {workspacesDrawer}
117 {sidebar} 122 {sidebar}
@@ -151,6 +156,18 @@ class AppLayout extends Component {
151 {intl.formatMessage(messages.requiredRequestsFailed)} 156 {intl.formatMessage(messages.requiredRequestsFailed)}
152 </InfoBar> 157 </InfoBar>
153 )} 158 )}
159 {authRequestFailed && (
160 <InfoBar
161 type="danger"
162 ctaLabel="Try again"
163 ctaLoading={areRequiredRequestsLoading}
164 sticky
165 onClick={retryRequiredRequests}
166 >
167 <span className="mdi mdi-flash" />
168 {intl.formatMessage(messages.authRequestFailed)}
169 </InfoBar>
170 )}
154 {showServicesUpdatedInfoBar && ( 171 {showServicesUpdatedInfoBar && (
155 <InfoBar 172 <InfoBar
156 type="primary" 173 type="primary"
@@ -168,7 +185,6 @@ class AppLayout extends Component {
168 onInstallUpdate={installAppUpdate} 185 onInstallUpdate={installAppUpdate}
169 /> 186 />
170 )} 187 )}
171 {isDelayAppScreenVisible && (<DelayApp />)}
172 <BasicAuth /> 188 <BasicAuth />
173 <ShareFranz /> 189 <ShareFranz />
174 {services} 190 {services}
diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js
index 36c1f2e39..1bf2554b5 100644
--- a/src/components/layout/Sidebar.js
+++ b/src/components/layout/Sidebar.js
@@ -3,11 +3,11 @@ import PropTypes from 'prop-types';
3import ReactTooltip from 'react-tooltip'; 3import ReactTooltip from 'react-tooltip';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
5import { observer } from 'mobx-react'; 5import { observer } from 'mobx-react';
6import { Link } from 'react-router';
6 7
7import Tabbar from '../services/tabs/Tabbar'; 8import Tabbar from '../services/tabs/Tabbar';
8import { ctrlKey } from '../../environment'; 9import { ctrlKey } from '../../environment';
9import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../../features/workspaces'; 10import { workspaceStore } from '../../features/workspaces';
10import { gaEvent } from '../../lib/analytics';
11 11
12const messages = defineMessages({ 12const messages = defineMessages({
13 settings: { 13 settings: {
@@ -82,6 +82,7 @@ export default @observer class Sidebar extends Component {
82 const workspaceToggleMessage = ( 82 const workspaceToggleMessage = (
83 isWorkspaceDrawerOpen ? messages.closeWorkspaceDrawer : messages.openWorkspaceDrawer 83 isWorkspaceDrawerOpen ? messages.closeWorkspaceDrawer : messages.openWorkspaceDrawer
84 ); 84 );
85 const isLoggedIn = Boolean(localStorage.getItem('authToken'));
85 86
86 return ( 87 return (
87 <div className="sidebar"> 88 <div className="sidebar">
@@ -90,39 +91,54 @@ export default @observer class Sidebar extends Component {
90 enableToolTip={() => this.enableToolTip()} 91 enableToolTip={() => this.enableToolTip()}
91 disableToolTip={() => this.disableToolTip()} 92 disableToolTip={() => this.disableToolTip()}
92 /> 93 />
93 {workspaceStore.isFeatureEnabled ? ( 94 {
94 <button 95 isLoggedIn ? (
95 type="button" 96 <>
96 onClick={() => { 97 {workspaceStore.isFeatureEnabled ? (
97 toggleWorkspaceDrawer(); 98 <button
98 this.updateToolTip(); 99 type="button"
99 gaEvent(GA_CATEGORY_WORKSPACES, 'toggleDrawer', 'sidebar'); 100 onClick={() => {
100 }} 101 toggleWorkspaceDrawer();
101 className={`sidebar__button sidebar__button--workspaces ${isWorkspaceDrawerOpen ? 'is-active' : ''}`} 102 this.updateToolTip();
102 data-tip={`${intl.formatMessage(workspaceToggleMessage)} (${ctrlKey}+D)`} 103 }}
103 > 104 className={`sidebar__button sidebar__button--workspaces ${isWorkspaceDrawerOpen ? 'is-active' : ''}`}
104 <i className="mdi mdi-view-grid" /> 105 data-tip={`${intl.formatMessage(workspaceToggleMessage)} (${ctrlKey}+D)`}
105 </button> 106 >
106 ) : null} 107 <i className="mdi mdi-view-grid" />
107 <button 108 </button>
108 type="button" 109 ) : null}
109 onClick={() => { 110
110 toggleMuteApp(); 111 <button
111 this.updateToolTip(); 112 type="button"
112 }} 113 onClick={() => {
113 className={`sidebar__button sidebar__button--audio ${isAppMuted ? 'is-muted' : ''}`} 114 toggleMuteApp();
114 data-tip={`${intl.formatMessage(isAppMuted ? messages.unmute : messages.mute)} (${ctrlKey}+Shift+M)`} 115 this.updateToolTip();
115 > 116 }}
116 <i className={`mdi mdi-bell${isAppMuted ? '-off' : ''}`} /> 117 className={`sidebar__button sidebar__button--audio ${isAppMuted ? 'is-muted' : ''}`}
117 </button> 118 data-tip={`${intl.formatMessage(isAppMuted ? messages.unmute : messages.mute)} (${ctrlKey}+Shift+M)`}
118 <button 119 >
119 type="button" 120 <i className={`mdi mdi-bell${isAppMuted ? '-off' : ''}`} />
120 onClick={() => openSettings({ path: 'recipes' })} 121 </button>
121 className="sidebar__button sidebar__button--new-service" 122 <button
122 data-tip={`${intl.formatMessage(messages.addNewService)} (${ctrlKey}+N)`} 123 type="button"
123 > 124 onClick={() => openSettings({ path: 'recipes' })}
124 <i className="mdi mdi-plus-box" /> 125 className="sidebar__button sidebar__button--new-service"
125 </button> 126 data-tip={`${intl.formatMessage(messages.addNewService)} (${ctrlKey}+N)`}
127 >
128 <i className="mdi mdi-plus-box" />
129 </button>
130 </>
131 ) : (
132 <Link
133 to="/auth/welcome"
134 className="sidebar__button sidebar__button--new-service"
135 data-tip="Login"
136 >
137 <i className="mdi mdi-login-variant" />
138 </Link>
139 )
140 }
141
126 <button 142 <button
127 type="button" 143 type="button"
128 onClick={() => openSettings({ path: 'app' })} 144 onClick={() => openSettings({ path: 'app' })}
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js
index 73c27bfb6..1afbaabc4 100644
--- a/src/components/services/content/Services.js
+++ b/src/components/services/content/Services.js
@@ -13,12 +13,20 @@ import Appear from '../../ui/effects/Appear';
13const messages = defineMessages({ 13const messages = defineMessages({
14 welcome: { 14 welcome: {
15 id: 'services.welcome', 15 id: 'services.welcome',
16 defaultMessage: '!!!Welcome to Franz', 16 defaultMessage: '!!!Welcome to Ferdi',
17 }, 17 },
18 getStarted: { 18 getStarted: {
19 id: 'services.getStarted', 19 id: 'services.getStarted',
20 defaultMessage: '!!!Get started', 20 defaultMessage: '!!!Get started',
21 }, 21 },
22 login: {
23 id: 'services.login',
24 defaultMessage: '!!!Please login to use Ferdi.',
25 },
26 serverInfo: {
27 id: 'services.serverInfo',
28 defaultMessage: '!!!Optionally, you can change your Ferdi server by clicking the cog in the bottom left corner.',
29 },
22}); 30});
23 31
24 32
@@ -86,6 +94,7 @@ export default @observer @injectSheet(styles) class Services extends Component {
86 } = this.state; 94 } = this.state;
87 95
88 const { intl } = this.context; 96 const { intl } = this.context;
97 const isLoggedIn = Boolean(localStorage.getItem('authToken'));
89 98
90 return ( 99 return (
91 <div className="services"> 100 <div className="services">
@@ -104,14 +113,20 @@ export default @observer @injectSheet(styles) class Services extends Component {
104 transitionName="slideUp" 113 transitionName="slideUp"
105 > 114 >
106 <div className="services__no-service"> 115 <div className="services__no-service">
107 <img src="./assets/images/logo.svg" alt="" /> 116 <img src="./assets/images/logo.svg" alt="Logo" style={{ maxHeight: '50vh' }} />
108 <h1>{intl.formatMessage(messages.welcome)}</h1> 117 <h1>{intl.formatMessage(messages.welcome)}</h1>
118 { !isLoggedIn && (
119 <>
120 <p>{intl.formatMessage(messages.login)}</p>
121 <p>{intl.formatMessage(messages.serverInfo)}</p>
122 </>
123 ) }
109 <Appear 124 <Appear
110 timeout={300} 125 timeout={300}
111 transitionName="slideUp" 126 transitionName="slideUp"
112 > 127 >
113 <Link to="/settings/recipes" className="button"> 128 <Link to={isLoggedIn ? '/settings/services' : '/auth/welcome'} className="button">
114 {intl.formatMessage(messages.getStarted)} 129 { isLoggedIn ? intl.formatMessage(messages.getStarted) : 'Login' }
115 </Link> 130 </Link>
116 </Appear> 131 </Appear>
117 </div> 132 </div>
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js
index ac2594604..f588449f4 100644
--- a/src/components/settings/account/AccountDashboard.js
+++ b/src/components/settings/account/AccountDashboard.js
@@ -69,7 +69,7 @@ const messages = defineMessages({
69 }, 69 },
70 deleteInfo: { 70 deleteInfo: {
71 id: 'settings.account.deleteInfo', 71 id: 'settings.account.deleteInfo',
72 defaultMessage: '!!!If you don\'t need your Franz account any longer, you can delete your account and all related data here.', 72 defaultMessage: '!!!If you don\'t need your Ferdi account any longer, you can delete your account and all related data here.',
73 }, 73 },
74 deleteEmailSent: { 74 deleteEmailSent: {
75 id: 'settings.account.deleteEmailSent', 75 id: 'settings.account.deleteEmailSent',
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js
index 4696b82eb..201819526 100644
--- a/src/components/settings/navigation/SettingsNavigation.js
+++ b/src/components/settings/navigation/SettingsNavigation.js
@@ -64,6 +64,7 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp
64 const { isDarkThemeActive } = stores.ui; 64 const { isDarkThemeActive } = stores.ui;
65 const { router, user } = stores; 65 const { router, user } = stores;
66 const { intl } = this.context; 66 const { intl } = this.context;
67 const isLoggedIn = Boolean(localStorage.getItem('authToken'));
67 68
68 return ( 69 return (
69 <div className="settings-navigation"> 70 <div className="settings-navigation">
@@ -136,10 +137,10 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp
136 </Link> 137 </Link>
137 <span className="settings-navigation__expander" /> 138 <span className="settings-navigation__expander" />
138 <Link 139 <Link
139 to="/auth/logout" 140 to={isLoggedIn ? '/auth/logout' : '/auth/welcome'}
140 className="settings-navigation__link" 141 className="settings-navigation__link"
141 > 142 >
142 {intl.formatMessage(messages.logout)} 143 { isLoggedIn ? intl.formatMessage(messages.logout) : 'Login'}
143 </Link> 144 </Link>
144 </div> 145 </div>
145 ); 146 );
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js
index 5cde0db8e..5fe00cb8b 100644
--- a/src/components/settings/services/EditServiceForm.js
+++ b/src/components/settings/services/EditServiceForm.js
@@ -63,7 +63,7 @@ const messages = defineMessages({
63 }, 63 },
64 customUrlPremiumInfo: { 64 customUrlPremiumInfo: {
65 id: 'settings.service.form.customUrlPremiumInfo', 65 id: 'settings.service.form.customUrlPremiumInfo',
66 defaultMessage: '!!!To add self hosted services, you need a Franz Premium Supporter Account.', 66 defaultMessage: '!!!To add self hosted services, you need a Ferdi Premium Supporter Account.',
67 }, 67 },
68 customUrlUpgradeAccount: { 68 customUrlUpgradeAccount: {
69 id: 'settings.service.form.customUrlUpgradeAccount', 69 id: 'settings.service.form.customUrlUpgradeAccount',
@@ -103,11 +103,11 @@ const messages = defineMessages({
103 }, 103 },
104 proxyRestartInfo: { 104 proxyRestartInfo: {
105 id: 'settings.service.form.proxy.restartInfo', 105 id: 'settings.service.form.proxy.restartInfo',
106 defaultMessage: '!!!Please restart Franz after changing proxy Settings.', 106 defaultMessage: '!!!Please restart Ferdi after changing proxy Settings.',
107 }, 107 },
108 proxyInfo: { 108 proxyInfo: {
109 id: 'settings.service.form.proxy.info', 109 id: 'settings.service.form.proxy.info',
110 defaultMessage: '!!!Proxy settings will not be synchronized with the Franz servers.', 110 defaultMessage: '!!!Proxy settings will not be synchronized with the Ferdi servers.',
111 }, 111 },
112}); 112});
113 113
@@ -155,7 +155,7 @@ export default @observer class EditServiceForm extends Component {
155 const values = form.values(); 155 const values = form.values();
156 let isValid = true; 156 let isValid = true;
157 157
158 const files = form.$('customIcon').files; 158 const { files } = form.$('customIcon');
159 if (files) { 159 if (files) {
160 values.iconFile = files[0]; 160 values.iconFile = files[0];
161 } 161 }
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index ff30daed2..19333fdff 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -9,6 +9,7 @@ import Button from '../../ui/Button';
9import Toggle from '../../ui/Toggle'; 9import Toggle from '../../ui/Toggle';
10import Select from '../../ui/Select'; 10import Select from '../../ui/Select';
11import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer'; 11import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer';
12import Input from '../../ui/Input';
12 13
13import { FRANZ_TRANSLATION } from '../../../config'; 14import { FRANZ_TRANSLATION } from '../../../config';
14 15
@@ -21,6 +22,10 @@ const messages = defineMessages({
21 id: 'settings.app.headlineGeneral', 22 id: 'settings.app.headlineGeneral',
22 defaultMessage: '!!!General', 23 defaultMessage: '!!!General',
23 }, 24 },
25 serverInfo: {
26 id: 'settings.app.serverInfo',
27 defaultMessage: '!!!We advice you to logout after changing your server as your settings might not be saved otherwise.',
28 },
24 headlineLanguage: { 29 headlineLanguage: {
25 id: 'settings.app.headlineLanguage', 30 id: 'settings.app.headlineLanguage',
26 defaultMessage: '!!!Language', 31 defaultMessage: '!!!Language',
@@ -39,7 +44,7 @@ const messages = defineMessages({
39 }, 44 },
40 translationHelp: { 45 translationHelp: {
41 id: 'settings.app.translationHelp', 46 id: 'settings.app.translationHelp',
42 defaultMessage: '!!!Help us to translate Franz into your language.', 47 defaultMessage: '!!!Help us to translate Ferdi into your language.',
43 }, 48 },
44 subheadlineCache: { 49 subheadlineCache: {
45 id: 'settings.app.subheadlineCache', 50 id: 'settings.app.subheadlineCache',
@@ -47,7 +52,7 @@ const messages = defineMessages({
47 }, 52 },
48 cacheInfo: { 53 cacheInfo: {
49 id: 'settings.app.cacheInfo', 54 id: 'settings.app.cacheInfo',
50 defaultMessage: '!!!Franz cache is currently using {size} of disk space.', 55 defaultMessage: '!!!Ferdi cache is currently using {size} of disk space.',
51 }, 56 },
52 buttonClearAllCache: { 57 buttonClearAllCache: {
53 id: 'settings.app.buttonClearAllCache', 58 id: 'settings.app.buttonClearAllCache',
@@ -145,6 +150,8 @@ export default @observer class EditSettingsForm extends Component {
145 updateButtonLabelMessage = messages.buttonSearchForUpdate; 150 updateButtonLabelMessage = messages.buttonSearchForUpdate;
146 } 151 }
147 152
153 const isLoggedIn = Boolean(localStorage.getItem('authToken'));
154
148 return ( 155 return (
149 <div className="settings__main"> 156 <div className="settings__main">
150 <div className="settings__header"> 157 <div className="settings__header">
@@ -164,6 +171,15 @@ export default @observer class EditSettingsForm extends Component {
164 {process.platform === 'win32' && ( 171 {process.platform === 'win32' && (
165 <Toggle field={form.$('minimizeToSystemTray')} /> 172 <Toggle field={form.$('minimizeToSystemTray')} />
166 )} 173 )}
174 <Input
175 placeholder="Server"
176 onChange={e => this.submit(e)}
177 field={form.$('server')}
178 autoFocus
179 />
180 { isLoggedIn && (
181 <p>{ intl.formatMessage(messages.serverInfo) }</p>
182 )}
167 {isTodosEnabled && ( 183 {isTodosEnabled && (
168 <Toggle field={form.$('enableTodos')} /> 184 <Toggle field={form.$('enableTodos')} />
169 )} 185 )}
@@ -252,6 +268,16 @@ export default @observer class EditSettingsForm extends Component {
252 <span className="mdi mdi-information" /> 268 <span className="mdi mdi-information" />
253 {intl.formatMessage(messages.languageDisclaimer)} 269 {intl.formatMessage(messages.languageDisclaimer)}
254 </p> 270 </p>
271 <p className="settings__message">
272 <span className="mdi mdi-github-face" />
273 Ferdi is based on
274 {' '}
275 <a href="https://github.com/meetfranz/franz" target="_blank">Franz</a>
276 , a project published
277 under the
278 {' '}
279 <a href="https://github.com/meetfranz/franz/blob/master/LICENSE" target="_blank">Apache-2.0 License</a>
280 </p>
255 </form> 281 </form>
256 </div> 282 </div>
257 </div> 283 </div>
diff --git a/src/components/settings/team/TeamDashboard.js b/src/components/settings/team/TeamDashboard.js
index 366b0113a..2bf46b48d 100644
--- a/src/components/settings/team/TeamDashboard.js
+++ b/src/components/settings/team/TeamDashboard.js
@@ -20,7 +20,7 @@ const messages = defineMessages({
20 }, 20 },
21 contentHeadline: { 21 contentHeadline: {
22 id: 'settings.team.contentHeadline', 22 id: 'settings.team.contentHeadline',
23 defaultMessage: '!!!Franz for Teams', 23 defaultMessage: '!!!Ferdi for Teams',
24 }, 24 },
25 intro: { 25 intro: {
26 id: 'settings.team.intro', 26 id: 'settings.team.intro',
@@ -28,7 +28,7 @@ const messages = defineMessages({
28 }, 28 },
29 copy: { 29 copy: {
30 id: 'settings.team.copy', 30 id: 'settings.team.copy',
31 defaultMessage: '!!!Franz for Teams gives you the option to invite co-workers to your team by sending them email invitations and manage their subscriptions in your account’s preferences. Don’t waste time setting up subscriptions for every team member individually, forget about multiple invoices and different billing cycles - one team to rule them all!', 31 defaultMessage: '!!!Ferdi for Teams gives you the option to invite co-workers to your team by sending them email invitations and manage their subscriptions in your account’s preferences. Don’t waste time setting up subscriptions for every team member individually, forget about multiple invoices and different billing cycles - one team to rule them all!',
32 }, 32 },
33 manageButton: { 33 manageButton: {
34 id: 'settings.team.manageAction', 34 id: 'settings.team.manageAction',
diff --git a/src/components/ui/AppLoader/index.js b/src/components/ui/AppLoader/index.js
index b0c7fed7b..a9a87707b 100644
--- a/src/components/ui/AppLoader/index.js
+++ b/src/components/ui/AppLoader/index.js
@@ -49,7 +49,7 @@ export default @injectSheet(styles) @withTheme class AppLoader extends Component
49 49
50 return ( 50 return (
51 <FullscreenLoader 51 <FullscreenLoader
52 title="Franz" 52 title="Ferdi"
53 className={classes.component} 53 className={classes.component}
54 spinnerColor={theme.colorAppLoaderSpinner} 54 spinnerColor={theme.colorAppLoaderSpinner}
55 > 55 >
diff --git a/src/components/ui/Button.js b/src/components/ui/Button.js
index ffc7f7051..e2d7cea83 100644
--- a/src/components/ui/Button.js
+++ b/src/components/ui/Button.js
@@ -69,7 +69,7 @@ export default @observer class Button extends Component {
69 loaded={loaded} 69 loaded={loaded}
70 lines={10} 70 lines={10}
71 scale={0.4} 71 scale={0.4}
72 color={buttonType !== 'secondary' ? '#FFF' : '#373a3c'} 72 color={buttonType !== 'secondary' ? '#FFF' : '#7367F0'}
73 component="span" 73 component="span"
74 /> 74 />
75 {label} 75 {label}
diff --git a/src/components/ui/FullscreenLoader/styles.js b/src/components/ui/FullscreenLoader/styles.js
index 64d24e4ce..d516781a8 100644
--- a/src/components/ui/FullscreenLoader/styles.js
+++ b/src/components/ui/FullscreenLoader/styles.js
@@ -4,6 +4,7 @@ export default {
4 alignItems: 'center', 4 alignItems: 'center',
5 position: 'absolute', 5 position: 'absolute',
6 width: '100%', 6 width: '100%',
7 background: 'linear-gradient( 135deg, #CE9FFC 10%, #7367F0 100%)',
7 }, 8 },
8 component: { 9 component: {
9 width: '100%', 10 width: '100%',
diff --git a/src/components/ui/Input.js b/src/components/ui/Input.js
index 9b070c4df..4e3eb4ab8 100644
--- a/src/components/ui/Input.js
+++ b/src/components/ui/Input.js
@@ -68,7 +68,7 @@ export default @observer class Input extends Component {
68 68
69 const { passwordScore } = this.state; 69 const { passwordScore } = this.state;
70 70
71 let type = field.type; 71 let { type } = field;
72 if (type === 'password' && this.state.showPassword) { 72 if (type === 'password' && this.state.showPassword) {
73 type = 'text'; 73 type = 'text';
74 } 74 }
diff --git a/src/components/ui/Link.js b/src/components/ui/Link.js
index b88686d5e..5f729844b 100644
--- a/src/components/ui/Link.js
+++ b/src/components/ui/Link.js
@@ -25,6 +25,7 @@ export default @inject('stores') @observer class Link extends Component {
25 className, 25 className,
26 activeClassName, 26 activeClassName,
27 strictFilter, 27 strictFilter,
28 style,
28 } = this.props; 29 } = this.props;
29 const { router } = stores; 30 const { router } = stores;
30 31
@@ -44,6 +45,7 @@ export default @inject('stores') @observer class Link extends Component {
44 <a 45 <a
45 href={router.history.createHref(to)} 46 href={router.history.createHref(to)}
46 className={linkClasses} 47 className={linkClasses}
48 style={style}
47 onClick={e => this.onClick(e)} 49 onClick={e => this.onClick(e)}
48 > 50 >
49 {children} 51 {children}
@@ -65,6 +67,7 @@ Link.wrappedComponent.propTypes = {
65 activeClassName: PropTypes.string, 67 activeClassName: PropTypes.string,
66 strictFilter: PropTypes.bool, 68 strictFilter: PropTypes.bool,
67 target: PropTypes.string, 69 target: PropTypes.string,
70 style: PropTypes.object,
68}; 71};
69 72
70Link.wrappedComponent.defaultProps = { 73Link.wrappedComponent.defaultProps = {
@@ -72,4 +75,5 @@ Link.wrappedComponent.defaultProps = {
72 activeClassName: '', 75 activeClassName: '',
73 strictFilter: false, 76 strictFilter: false,
74 target: '', 77 target: '',
78 style: {},
75}; 79};
diff --git a/src/components/ui/Loader.js b/src/components/ui/Loader.js
index f73296bb6..de8769b6c 100644
--- a/src/components/ui/Loader.js
+++ b/src/components/ui/Loader.js
@@ -16,7 +16,7 @@ export default class LoaderComponent extends Component {
16 children: null, 16 children: null,
17 loaded: false, 17 loaded: false,
18 className: '', 18 className: '',
19 color: '#373a3c', 19 color: '#7367F0',
20 }; 20 };
21 21
22 render() { 22 render() {
diff --git a/src/components/ui/PremiumFeatureContainer/index.js b/src/components/ui/PremiumFeatureContainer/index.js
index 8d2746e22..c53d345a0 100644
--- a/src/components/ui/PremiumFeatureContainer/index.js
+++ b/src/components/ui/PremiumFeatureContainer/index.js
@@ -9,7 +9,6 @@ import { oneOrManyChildElements } from '../../../prop-types';
9import UserStore from '../../../stores/UserStore'; 9import UserStore from '../../../stores/UserStore';
10 10
11import styles from './styles'; 11import styles from './styles';
12import { gaEvent } from '../../../lib/analytics';
13import { FeatureStore } from '../../../features/utils/FeatureStore'; 12import { FeatureStore } from '../../../features/utils/FeatureStore';
14 13
15const messages = defineMessages({ 14const messages = defineMessages({
@@ -50,7 +49,6 @@ class PremiumFeatureContainer extends Component {
50 actions, 49 actions,
51 condition, 50 condition,
52 stores, 51 stores,
53 gaEventInfo,
54 } = this.props; 52 } = this.props;
55 53
56 const { intl } = this.context; 54 const { intl } = this.context;
@@ -75,10 +73,6 @@ class PremiumFeatureContainer extends Component {
75 type="button" 73 type="button"
76 onClick={() => { 74 onClick={() => {
77 actions.ui.openSettings({ path: 'user' }); 75 actions.ui.openSettings({ path: 'user' });
78 if (gaEventInfo) {
79 const { category, event, label } = gaEventInfo;
80 gaEvent(category, event, label);
81 }
82 }} 76 }}
83 > 77 >
84 {intl.formatMessage(messages.action)} 78 {intl.formatMessage(messages.action)}