diff options
author | 2022-11-16 23:30:39 +0530 | |
---|---|---|
committer | 2022-11-16 18:00:39 +0000 | |
commit | eb7b2481f631cec5953265eef4ebc3f2fa7e496a (patch) | |
tree | 419d4413f90ece77c0a2204b40948f1a158793d5 /src/components/auth/SetupAssistant.tsx | |
parent | 6.2.1-nightly.44 [skip ci] (diff) | |
download | ferdium-app-eb7b2481f631cec5953265eef4ebc3f2fa7e496a.tar.gz ferdium-app-eb7b2481f631cec5953265eef4ebc3f2fa7e496a.tar.zst ferdium-app-eb7b2481f631cec5953265eef4ebc3f2fa7e496a.zip |
Transform JSX components to TSX (#755)
* color picker types
* Import
* SetupAssistant
* Services & appear
* ServiceWebView
* SettingsLayout
* ImportantScreen
* WorkspaceDrawer
* SetupAssistant
* chore: update vscode settings
* chore: removed stale Import screen component & its tree
Diffstat (limited to 'src/components/auth/SetupAssistant.tsx')
-rw-r--r-- | src/components/auth/SetupAssistant.tsx | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/src/components/auth/SetupAssistant.tsx b/src/components/auth/SetupAssistant.tsx new file mode 100644 index 000000000..c5fb79919 --- /dev/null +++ b/src/components/auth/SetupAssistant.tsx | |||
@@ -0,0 +1,337 @@ | |||
1 | import { Component } from 'react'; | ||
2 | import { observer } from 'mobx-react'; | ||
3 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; | ||
4 | import withStyles, { WithStylesProps } from 'react-jss'; | ||
5 | import classnames from 'classnames'; | ||
6 | import Input from '../ui/input/index'; | ||
7 | import Button from '../ui/button'; | ||
8 | import Badge from '../ui/badge'; | ||
9 | import Modal from '../ui/Modal'; | ||
10 | import Infobox from '../ui/Infobox'; | ||
11 | import Appear from '../ui/effects/Appear'; | ||
12 | import globalMessages from '../../i18n/globalMessages'; | ||
13 | import { CDN_URL } from '../../config'; | ||
14 | import { H1, H2 } from '../ui/headline'; | ||
15 | |||
16 | const SLACK_ID = 'slack'; | ||
17 | |||
18 | const messages = defineMessages({ | ||
19 | headline: { | ||
20 | id: 'setupAssistant.headline', | ||
21 | defaultMessage: "Let's get started", | ||
22 | }, | ||
23 | subHeadline: { | ||
24 | id: 'setupAssistant.subheadline', | ||
25 | defaultMessage: | ||
26 | 'Choose from our most used services and get back on top of your messaging now.', | ||
27 | }, | ||
28 | submitButtonLabel: { | ||
29 | id: 'setupAssistant.submit.label', | ||
30 | defaultMessage: "Let's go", | ||
31 | }, | ||
32 | skipButtonLabel: { | ||
33 | id: 'setupAssistant.skip.label', | ||
34 | defaultMessage: 'Skip', | ||
35 | }, | ||
36 | inviteSuccessInfo: { | ||
37 | id: 'invite.successInfo', | ||
38 | defaultMessage: 'Invitations sent successfully', | ||
39 | }, | ||
40 | }); | ||
41 | |||
42 | const transition = | ||
43 | window && window.matchMedia('(prefers-reduced-motion: no-preference)') | ||
44 | ? 'all 0.25s' | ||
45 | : 'none'; | ||
46 | |||
47 | const styles = theme => ({ | ||
48 | root: { | ||
49 | width: '500px !important', | ||
50 | textAlign: 'center', | ||
51 | padding: 20, | ||
52 | |||
53 | '& h1': {}, | ||
54 | }, | ||
55 | servicesGrid: { | ||
56 | display: 'flex', | ||
57 | flexWrap: 'wrap', | ||
58 | justifyContent: 'space-between', | ||
59 | }, | ||
60 | serviceContainer: { | ||
61 | background: theme.colorBackground, | ||
62 | position: 'relative', | ||
63 | width: '32%', | ||
64 | display: 'flex', | ||
65 | alignItems: 'center', | ||
66 | flexDirection: 'column', | ||
67 | justifyContent: 'center', | ||
68 | padding: 20, | ||
69 | borderRadius: theme.borderRadius, | ||
70 | marginBottom: 10, | ||
71 | opacity: 0.5, | ||
72 | transition, | ||
73 | border: [3, 'solid', 'transparent'], | ||
74 | |||
75 | '& h2': { | ||
76 | margin: [10, 0, 0], | ||
77 | color: theme.colorText, | ||
78 | }, | ||
79 | |||
80 | '&:hover': { | ||
81 | border: [3, 'solid', theme.brandPrimary], | ||
82 | '& $serviceIcon': {}, | ||
83 | }, | ||
84 | }, | ||
85 | selected: { | ||
86 | border: [3, 'solid', theme.brandPrimary], | ||
87 | background: `${theme.brandPrimary}47`, | ||
88 | opacity: 1, | ||
89 | }, | ||
90 | serviceIcon: { | ||
91 | width: 50, | ||
92 | transition, | ||
93 | }, | ||
94 | |||
95 | slackModalContent: { | ||
96 | textAlign: 'center', | ||
97 | |||
98 | '& img': { | ||
99 | width: 50, | ||
100 | marginBottom: 20, | ||
101 | }, | ||
102 | }, | ||
103 | modalActionContainer: { | ||
104 | display: 'flex', | ||
105 | flexDirection: 'column', | ||
106 | justifyContent: 'center', | ||
107 | alignItems: 'center', | ||
108 | }, | ||
109 | ctaCancel: { | ||
110 | background: 'none !important', | ||
111 | }, | ||
112 | slackBadge: { | ||
113 | position: 'absolute', | ||
114 | bottom: 4, | ||
115 | height: 'auto', | ||
116 | padding: '0px 4px', | ||
117 | borderRadius: theme.borderRadiusSmall, | ||
118 | margin: 0, | ||
119 | display: 'flex', | ||
120 | overflow: 'hidden', | ||
121 | }, | ||
122 | clearSlackWorkspace: { | ||
123 | background: theme.inputPrefixColor, | ||
124 | marginLeft: 5, | ||
125 | height: '100%', | ||
126 | color: theme.colorText, | ||
127 | display: 'inline-flex', | ||
128 | justifyContent: 'center', | ||
129 | alignItems: 'center', | ||
130 | marginRight: -4, | ||
131 | padding: [0, 5], | ||
132 | }, | ||
133 | }); | ||
134 | |||
135 | interface IProps extends WithStylesProps<typeof styles>, WrappedComponentProps { | ||
136 | onSubmit: (...args: any[]) => void; | ||
137 | isInviteSuccessful?: boolean; | ||
138 | services: any; // TODO - [TS DEBT] check legacy services type | ||
139 | isSettingUpServices: boolean; | ||
140 | } | ||
141 | |||
142 | interface IState { | ||
143 | services: any[]; | ||
144 | isSlackModalOpen: boolean; | ||
145 | slackWorkspace: string; | ||
146 | showSuccessInfo: boolean; | ||
147 | } | ||
148 | |||
149 | @observer | ||
150 | class SetupAssistant extends Component<IProps, IState> { | ||
151 | constructor(props: IProps) { | ||
152 | super(props); | ||
153 | |||
154 | this.state = { | ||
155 | services: [], | ||
156 | isSlackModalOpen: false, | ||
157 | showSuccessInfo: false, | ||
158 | slackWorkspace: '', | ||
159 | }; | ||
160 | } | ||
161 | |||
162 | slackWorkspaceHandler(): void { | ||
163 | const { slackWorkspace = '', services } = this.state; | ||
164 | const sanitizedWorkspace = slackWorkspace | ||
165 | .trim() | ||
166 | .replace(/^https?:\/\//, ''); | ||
167 | |||
168 | if (sanitizedWorkspace) { | ||
169 | const index = services.findIndex(s => s.id === SLACK_ID); | ||
170 | if (index === -1) { | ||
171 | const newServices = services; | ||
172 | newServices.push({ id: SLACK_ID, team: sanitizedWorkspace }); | ||
173 | this.setState({ services: newServices }); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | this.setState({ | ||
178 | isSlackModalOpen: false, | ||
179 | slackWorkspace: sanitizedWorkspace, | ||
180 | }); | ||
181 | } | ||
182 | |||
183 | render() { | ||
184 | const { | ||
185 | classes, | ||
186 | isInviteSuccessful = false, | ||
187 | onSubmit, | ||
188 | services, | ||
189 | isSettingUpServices, | ||
190 | intl, | ||
191 | } = this.props; | ||
192 | const { | ||
193 | isSlackModalOpen, | ||
194 | slackWorkspace, | ||
195 | services: addedServices, | ||
196 | } = this.state; | ||
197 | |||
198 | return ( | ||
199 | <div className={`auth__container ${classes.root}`}> | ||
200 | {this.state.showSuccessInfo && isInviteSuccessful && ( | ||
201 | <Appear> | ||
202 | <Infobox | ||
203 | type="success" | ||
204 | icon="checkbox-marked-circle-outline" | ||
205 | dismissible | ||
206 | > | ||
207 | {intl.formatMessage(messages.inviteSuccessInfo)} | ||
208 | </Infobox> | ||
209 | </Appear> | ||
210 | )} | ||
211 | |||
212 | <img src="./assets/images/logo.svg" className="auth__logo" alt="" /> | ||
213 | <H1>{intl.formatMessage(messages.headline)}</H1> | ||
214 | <H2>{intl.formatMessage(messages.subHeadline)}</H2> | ||
215 | <div className={classnames('grid', classes.servicesGrid)}> | ||
216 | {Object.keys(services).map(id => { | ||
217 | const service = services[id]; | ||
218 | return ( | ||
219 | <button | ||
220 | className={classnames({ | ||
221 | [classes.serviceContainer]: true, | ||
222 | [classes.selected]: | ||
223 | this.state.services.findIndex(s => s.id === id) !== -1, | ||
224 | })} | ||
225 | key={id} | ||
226 | onClick={() => { | ||
227 | const index = this.state.services.findIndex(s => s.id === id); | ||
228 | if (index === -1) { | ||
229 | if (id === SLACK_ID) { | ||
230 | this.setState({ isSlackModalOpen: true }); | ||
231 | } else { | ||
232 | addedServices.push({ id }); | ||
233 | } | ||
234 | } else { | ||
235 | addedServices.splice(index, 1); | ||
236 | if (id === SLACK_ID) { | ||
237 | this.setState({ | ||
238 | slackWorkspace: '', | ||
239 | }); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | this.setState({ services: addedServices }); | ||
244 | }} | ||
245 | type="button" | ||
246 | > | ||
247 | <img | ||
248 | src={`${CDN_URL}/recipes/dist/${id}/src/icon.svg`} | ||
249 | className={classes.serviceIcon} | ||
250 | alt="" | ||
251 | /> | ||
252 | <H2>{service.name}</H2> | ||
253 | {id === SLACK_ID && slackWorkspace && ( | ||
254 | <Badge type="secondary" className={classes.slackBadge}> | ||
255 | {slackWorkspace} | ||
256 | <button | ||
257 | type="button" | ||
258 | className={classes.clearSlackWorkspace} | ||
259 | onClick={() => { | ||
260 | this.setState({ | ||
261 | slackWorkspace: '', | ||
262 | }); | ||
263 | }} | ||
264 | > | ||
265 | x | ||
266 | </button> | ||
267 | </Badge> | ||
268 | )} | ||
269 | </button> | ||
270 | ); | ||
271 | })} | ||
272 | </div> | ||
273 | <Modal | ||
274 | isOpen={isSlackModalOpen} | ||
275 | // isBlocking={false} | ||
276 | close={() => this.setState({ isSlackModalOpen: false })} | ||
277 | > | ||
278 | <div className={classes.slackModalContent}> | ||
279 | <img src={`${CDN_URL}/recipes/dist/slack/src/icon.svg`} alt="" /> | ||
280 | <H1>Create your first Slack workspace</H1> | ||
281 | <form | ||
282 | onSubmit={e => { | ||
283 | e.preventDefault(); | ||
284 | this.slackWorkspaceHandler(); | ||
285 | }} | ||
286 | > | ||
287 | <Input | ||
288 | suffix=".slack.com" | ||
289 | placeholder="workspace-url" | ||
290 | onChange={e => | ||
291 | this.setState({ slackWorkspace: e.target.value }) | ||
292 | } | ||
293 | value={slackWorkspace} | ||
294 | /> | ||
295 | <div className={classes.modalActionContainer}> | ||
296 | <Button | ||
297 | type="submit" | ||
298 | label={intl.formatMessage(globalMessages.save)} | ||
299 | /> | ||
300 | <Button | ||
301 | type="button" | ||
302 | buttonType="secondary" | ||
303 | label={intl.formatMessage(globalMessages.cancel)} | ||
304 | className={classes.ctaCancel} | ||
305 | onClick={e => { | ||
306 | e.preventDefault(); | ||
307 | this.setState({ slackWorkspace: '' }); | ||
308 | }} | ||
309 | /> | ||
310 | </div> | ||
311 | </form> | ||
312 | </div> | ||
313 | </Modal> | ||
314 | <Button | ||
315 | type="button" | ||
316 | className="auth__button" | ||
317 | // disabled={!atLeastOneEmailAddress} | ||
318 | label={intl.formatMessage(messages.submitButtonLabel)} | ||
319 | onClick={() => onSubmit(this.state.services)} | ||
320 | busy={isSettingUpServices} | ||
321 | disabled={isSettingUpServices || addedServices.length === 0} | ||
322 | /> | ||
323 | <Button | ||
324 | type="button" | ||
325 | className="auth__button auth__button--skip" | ||
326 | label={intl.formatMessage(messages.skipButtonLabel)} | ||
327 | onClick={() => onSubmit([])} | ||
328 | buttonType="secondary" | ||
329 | /> | ||
330 | </div> | ||
331 | ); | ||
332 | } | ||
333 | } | ||
334 | |||
335 | export default injectIntl( | ||
336 | withStyles(styles, { injectTheme: true })(SetupAssistant), | ||
337 | ); | ||