@openeventkit/event-site 2.0.125-beta.2 → 2.0.125

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,369 +0,0 @@
1
- import React, { useState, useRef, useEffect } from 'react'
2
- import AvatarEditor from 'react-avatar-editor'
3
- import AjaxLoader from "openstack-uicore-foundation/lib/components/ajaxloader";
4
- import { create_UUID } from '../utils/uuidGenerator'
5
- import Link from "./Link";
6
-
7
- import styles from '../styles/profile.module.scss'
8
-
9
-
10
- const ProfilePopupComponent = ({ userProfile, idpLoading, closePopup, showProfile, changePicture, changeProfile, fromFullProfile }) => {
11
-
12
- const editorRef = useRef(null);
13
- const modalHeaderRef = useRef(null)
14
- const modalRef = useRef(null)
15
- const fileInput = useRef(null)
16
-
17
- const [firstName, setFirstName] = useState("");
18
- const [lastName, setLastName] = useState("");
19
- const [company, setCompany] = useState("");
20
- const [bio, setBio] = useState('');
21
- const [jobTitle, setJobTitle] = useState('');
22
- const [github, setGithub] = useState('');
23
- const [irc, setIRC] = useState('');
24
- const [linkedin, setLinkedin] = useState('');
25
- const [twitter, setTwitter] = useState('');
26
-
27
- const [image, setImage] = useState(null);
28
- const [newImage, setNewImage] = useState(false);
29
- const [position, setPosition] = useState({ x: 0.5, y: 0.5 });
30
- const [scale, setScale] = useState(1);
31
- const [rotate, setRotate] = useState(0);
32
- const width = 200;
33
- const height = 200;
34
-
35
- useEffect(() => {
36
- setFirstName(userProfile.given_name || '');
37
- setLastName(userProfile.family_name || '');
38
- setCompany(userProfile.company || '');
39
- setBio(userProfile.bio || '');
40
- setJobTitle(userProfile.job_title || '');
41
- setImage(userProfile.picture || '');
42
- setGithub(userProfile.github_user || '');
43
- setIRC(userProfile.irc || '');
44
- setLinkedin(userProfile.linked_in_profile || '');
45
- setTwitter(userProfile.twitter_name || '');
46
-
47
- return () => {
48
- setFirstName('');
49
- setLastName('');
50
- setCompany('');
51
- setBio('');
52
- setJobTitle('');
53
- setGithub('');
54
- setIRC('');
55
- setLinkedin('');
56
- setTwitter('');
57
- };
58
- }, [
59
- userProfile.given_name,
60
- userProfile.family_name,
61
- userProfile.company,
62
- userProfile.picture,
63
- userProfile.bio,
64
- userProfile.job_title,
65
- userProfile.github,
66
- userProfile.irc,
67
- userProfile.linkedin,
68
- userProfile.twitter_name
69
- ]);
70
-
71
- useEffect(() => {
72
- if (modalHeaderRef) {
73
- window.setTimeout(function () {
74
- modalHeaderRef.current.focus();
75
- }, 0);
76
- }
77
- }, [modalHeaderRef])
78
-
79
- useEffect(() => {
80
- window.addEventListener('keydown', handleUserKeyPress);
81
-
82
- return () => {
83
- window.removeEventListener('keydown', handleUserKeyPress);
84
- };
85
- }, []);
86
-
87
- const handleUserKeyPress = (e) => {
88
- const focusable = modalRef.current.querySelectorAll('button, input, a, textarea, select, [tabindex]:not([tabindex="-1"])');
89
- const firstFocusable = focusable[0];
90
- const lastFocusable = focusable[focusable.length - 1];
91
- const KEYCODE_TAB = 9;
92
- const KEYCODE_ESC = 27;
93
- const isTabPressed = (e.key === 'Tab' || e.keyCode === KEYCODE_TAB);
94
- const isEscapePressed = (e.key === 'Escape' || e.keyCode === KEYCODE_ESC);
95
-
96
- if (isEscapePressed) {
97
- closePopup();
98
- }
99
-
100
- if (!isTabPressed) {
101
- return;
102
- }
103
-
104
- if ( e.shiftKey ) /* shift + tab */ {
105
- if (document.activeElement === firstFocusable) {
106
- lastFocusable.focus();
107
- e.preventDefault();
108
- }
109
- } else /* tab */ {
110
- if (document.activeElement === lastFocusable) {
111
- firstFocusable.focus();
112
- e.preventDefault();
113
- }
114
- }
115
- }
116
-
117
-
118
- const handleNewImage = (e) => {
119
- setImage(e.target.files[0]);
120
- setNewImage(true);
121
- };
122
-
123
- const urltoFile = (url, filename, mimeType) => {
124
- mimeType = mimeType || (url.match(/^data:([^;]+);/) || '')[1];
125
- filename = filename || create_UUID();
126
- return (fetch(url)
127
- .then(function (res) { return res.arrayBuffer(); })
128
- .then(function (buf) { return new File([buf], filename, { type: mimeType }); })
129
- );
130
- };
131
-
132
- const handleScale = (e) => {
133
- const scale = parseFloat(e.target.value);
134
- setScale(scale);
135
- setNewImage(true);
136
- };
137
-
138
- const handlePositionChange = (position) => {
139
- setPosition(position);
140
- setNewImage(true);
141
- };
142
-
143
- const rotateLeft = (e) => {
144
- e.preventDefault();
145
- setRotate(rotate - 90);
146
- setNewImage(true);
147
- };
148
-
149
- const rotateRight = (e) => {
150
- e.preventDefault();
151
- setRotate(rotate + 90);
152
- setNewImage(true);
153
- };
154
-
155
- const onClickSave = () => {
156
- if (editorRef.current && newImage) {
157
- const canvas = editorRef.current?.getImage()?.toDataURL();
158
- if(canvas) {
159
- urltoFile(canvas, image.name)
160
- .then(file => changePicture(file));
161
- }
162
- }
163
- if (userProfile.given_name !== firstName ||
164
- userProfile.family_name !== lastName ||
165
- userProfile.company !== company ||
166
- userProfile.bio !== bio ||
167
- userProfile.job_title !== jobTitle ||
168
- userProfile.github_user !== github ||
169
- userProfile.irc !== irc ||
170
- userProfile.linked_in_profile !== linkedin ||
171
- userProfile.twitter_name != twitter) {
172
- const newProfile = {
173
- first_name: firstName,
174
- last_name: lastName,
175
- company: company,
176
- bio: bio,
177
- job_title: jobTitle,
178
- github_user: github,
179
- irc: irc,
180
- linked_in_profile: linkedin,
181
- twitter_name: twitter,
182
- };
183
- changeProfile(newProfile);
184
- }
185
- };
186
-
187
- return (
188
- <div className={`${styles.modal} ${showProfile ? styles.isActive : ''}`} ref={modalRef}>
189
- <div className={`${styles.modalCard} ${styles.profilePopup}`}>
190
- <AjaxLoader relative={true} color={'#ffffff'} show={idpLoading} size={120} />
191
- <header className={`${styles.modalCardHead}`}>
192
- <h2 className={`${styles.modalCardTitle}`} tabIndex='-1' ref={modalHeaderRef}>Edit profile</h2>
193
- <button className="link" onClick={() => closePopup()}>
194
- <i className={`${styles.closeIcon} fa fa-times icon`} />
195
- </button>
196
- </header>
197
- <section className={`${styles.modalCardBody}`}>
198
- <div className={styles.modalCardPicture}>
199
- <div className={styles.title}>Profile picture</div>
200
- <div className={styles.picture}>
201
- <AvatarEditor
202
- ref={editorRef}
203
- image={image}
204
- width={width}
205
- height={height}
206
- border={50}
207
- color={[0, 0, 0, 0.8]} // RGBA
208
- position={position}
209
- onPositionChange={handlePositionChange}
210
- scale={scale}
211
- borderRadius={5}
212
- rotate={parseFloat(rotate)}
213
- />
214
- <div className={styles.imageUpload} tabIndex="0" onKeyPress={() => {fileInput.current.click()}}>
215
- <label htmlFor="file-input" >
216
- <i className={`${styles.pictureIcon} fa fa-2x fa-camera icon is-large`} />
217
- </label>
218
- <input ref={fileInput} name="newImage" id="file-input" type="file" accept=".jpg,.jpeg,.png" onChange={handleNewImage} />
219
- </div>
220
- <div>
221
- <div className={`columns ${styles.inputRow}`}>
222
- <span id="zoomLabel" className='column is-one-quarter'>Zoom:</span>
223
- <div className='column is-two-thirds'>
224
- <input
225
- name="scale"
226
- type="range"
227
- aria-labelledby='zoomLabel'
228
- max="2"
229
- onChange={(e) => handleScale(e)}
230
- step="0.01"
231
- defaultValue="1"
232
- />
233
- </div>
234
- </div>
235
- <div className={`columns ${styles.inputRow}`}>
236
- <div className='column is-one-quarter'>Rotate:</div>
237
- <div className='column is-two-thirds'>
238
- <button className={`button is-large ${styles.button}`} onClick={rotateLeft}>
239
- <i className={`fa fa-undo icon is-large`} />Left
240
- </button>
241
- <button className={`button is-large ${styles.button}`} onClick={rotateRight}>
242
- <i className={`fa fa-undo icon is-large`} />Right
243
- </button>
244
- </div>
245
- </div>
246
- </div>
247
-
248
- </div>
249
- </div>
250
- {!fromFullProfile &&
251
- <div className={styles.modalCardForm}>
252
- <div className={styles.title}>Profile Info</div>
253
- <div className={styles.form}>
254
- <div className={`columns is-mobile ${styles.inputRow}`}>
255
- <div className='column is-one-quarter'>First Name</div>
256
- <div className='column is-two-thirds'>
257
- <input
258
- className={`${styles.input} ${styles.isMedium}`}
259
- type="text"
260
- placeholder="First Name"
261
- onChange={e => setFirstName(e.target.value)}
262
- value={firstName} />
263
- </div>
264
- </div>
265
- <div className={`columns is-mobile ${styles.inputRow}`}>
266
- <div className='column is-one-quarter'>Last Name</div>
267
- <div className='column is-two-thirds'>
268
- <input
269
- className={`${styles.input} ${styles.isMedium}`}
270
- type="text"
271
- placeholder="Last Name"
272
- onChange={e => setLastName(e.target.value)}
273
- value={lastName} />
274
- </div>
275
- </div>
276
- <div className={`columns is-mobile ${styles.inputRow}`}>
277
- <div className='column is-one-quarter'>Company</div>
278
- <div className='column is-two-thirds'>
279
- <input
280
- className={`${styles.input} ${styles.isMedium}`}
281
- type="text"
282
- placeholder="Company"
283
- onChange={e => setCompany(e.target.value)}
284
- value={company}
285
- />
286
- </div>
287
- </div>
288
- <div className={`columns is-mobile ${styles.inputRow}`}>
289
- <div className='column is-one-quarter'>Bio</div>
290
- <div className='column is-two-thirds'>
291
- <textarea
292
- className={`textarea ${styles.textarea}`}
293
- placeholder=''
294
- rows="6"
295
- onChange={e => setBio(e.target.value)}
296
- value={bio}
297
- >
298
- </textarea>
299
- </div>
300
- </div>
301
- <div className={`columns is-mobile ${styles.inputRow}`}>
302
- <div className='column is-one-quarter'>Job Title</div>
303
- <div className='column is-two-thirds'>
304
- <input
305
- className={`${styles.input} ${styles.isMedium}`}
306
- type="text"
307
- placeholder="Job Title"
308
- onChange={e => setJobTitle(e.target.value)}
309
- value={jobTitle} />
310
- </div>
311
- </div>
312
- <div className={`columns is-mobile ${styles.inputRow}`}>
313
- <div className='column is-one-quarter'>Github</div>
314
- <div className='column is-two-thirds'>
315
- <input
316
- className={`${styles.input} ${styles.isMedium}`}
317
- type="text"
318
- placeholder="Github"
319
- onChange={e => setGithub(e.target.value)}
320
- value={github} />
321
- </div>
322
- </div>
323
- <div className={`columns is-mobile ${styles.inputRow}`}>
324
- <div className='column is-one-quarter'>IRC</div>
325
- <div className='column is-two-thirds'>
326
- <input
327
- className={`${styles.input} ${styles.isMedium}`}
328
- type="text"
329
- placeholder="IRC"
330
- onChange={e => setIRC(e.target.value)}
331
- value={irc} />
332
- </div>
333
- </div>
334
- <div className={`columns is-mobile ${styles.inputRow}`}>
335
- <div className='column is-one-quarter'>LinkedIn</div>
336
- <div className='column is-two-thirds'>
337
- <input
338
- className={`${styles.input} ${styles.isMedium}`}
339
- type="text"
340
- placeholder="LinkedIn"
341
- onChange={e => setLinkedin(e.target.value)}
342
- value={linkedin} />
343
- </div>
344
- </div>
345
- <div className={`columns is-mobile ${styles.inputRow}`}>
346
- <div className='column is-one-quarter'>X</div>
347
- <div className='column is-two-thirds'>
348
- <input
349
- className={`${styles.input} ${styles.isMedium}`}
350
- type="text"
351
- placeholder="Twitter/X"
352
- onChange={e => setTwitter(e.target.value)}
353
- value={twitter} />
354
- </div>
355
- </div>
356
- </div>
357
- </div>
358
- }
359
- </section>
360
- <footer className={`${styles.modalCardFoot}`}>
361
- <button onClick={() => closePopup()} className="button is-large">Discard</button>
362
- <button onClick={() => onClickSave()} className="button is-large">Update</button>
363
- </footer>
364
- </div>
365
- </div>
366
- )
367
- };
368
-
369
- export default ProfilePopupComponent