@aarhus-university/au-lib-react-components 10.19.0 → 10.19.2

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,307 +0,0 @@
1
- /* eslint-env browser */
2
- /* eslint-disable max-len */
3
- /* eslint-disable jsx-a11y/label-has-associated-control */
4
- /* eslint-disable jsx-a11y/label-has-for */
5
- import React, { useState, useEffect } from 'react';
6
- import PropTypes from 'prop-types';
7
- import { Link } from 'react-router-dom';
8
- import AUSubmitButtonContainerComponent from '../form/AUSubmitButtonContainerComponent';
9
- import { useProfileForm } from './AUProfileHooks';
10
- import {
11
- setCaretPosition,
12
- scrollTo,
13
- } from '../../lib/helpers';
14
- import { profileLabels } from '../../lib/i18n';
15
- import { renderValidation, validateForm, emailRegex } from '../../lib/validation';
16
-
17
- const AUProfileMailComponent = ({
18
- lang,
19
- routeProps: { history },
20
- path,
21
- studentMailAddress,
22
- studentChosenMailAddress: pStudentChosenMailAddress,
23
- privateMailAddress: pPrivateMailAddress,
24
- workMailAddress: pWorkMailAddress,
25
- workMailDomain,
26
- isStudentAdGroupMember,
27
- onSave,
28
- onSaveAction,
29
- saving,
30
- saved,
31
- dismissMessages,
32
- clear,
33
- }) => {
34
- const [workMail, setWorkMail] = useState(!pWorkMailAddress ? '' : pWorkMailAddress);
35
- const [workMailPrefix, setWorkMailPrefix] = useState(workMail.includes('@') && !workMail.includes('@uni.au.dk') ? workMail.split('@')[0] : '');
36
- const workMailPostfix = `@${workMailDomain}`; // `@${workMail.includes('@') ? workMail.split('@')[1] : ''}`;
37
- const [workMailValidationMessages, setWorkMailValidationMessages] = useState([]);
38
- const [isWorkMailValid, setIsWorkMailValid] = useState(!!pWorkMailAddress && !workMail.includes('@uni.au.dk') || pWorkMailAddress == null);
39
-
40
- const [studentChosenMail, setStudentChosenMail] = useState(pStudentChosenMailAddress);
41
- let initialStudentChosenMailPrefix = '';
42
- if (studentChosenMail.includes('@')) {
43
- [initialStudentChosenMailPrefix] = studentChosenMail.split('@');
44
- } else if (studentMailAddress && studentMailAddress.includes('@')) {
45
- [initialStudentChosenMailPrefix] = studentMailAddress.split('@');
46
- }
47
- const [studentChosenMailPrefix, setStudentChosenMailPrefix] = useState(initialStudentChosenMailPrefix);
48
- const studentChosenMailPostfix = '@post.au.dk';
49
- const [studentChosenMailValidationMessages, setStudentChosenMailValidationMessages] = useState([]);
50
- const [isStudentChosenMailValid, setIsStudentChosenMailValid] = useState(!!pStudentChosenMailAddress || !isStudentAdGroupMember);
51
-
52
- const [privateMail, setPrivateMail] = useState(pPrivateMailAddress);
53
- const [privateMailValidationMessages, setPrivateMailValidationMessages] = useState([]);
54
- const [isPrivateMailValid, setIsPrivateMailValid] = useState(!!pPrivateMailAddress);
55
-
56
- const [onCancel] = useProfileForm(saved, history, lang, clear);
57
-
58
- useEffect(() => {
59
- scrollTo();
60
- dismissMessages();
61
- if (pWorkMailAddress) {
62
- setCaretPosition(document.getElementById('mail-work'), pWorkMailAddress.indexOf('@'));
63
- document.getElementById('mail-work').focus();
64
- } else if (pStudentChosenMailAddress) {
65
- setCaretPosition(document.getElementById('mail-student'), pStudentChosenMailAddress.indexOf('@'));
66
- document.getElementById('mail-student').focus();
67
- } else if (pPrivateMailAddress) {
68
- setCaretPosition(document.getElementById('mail-private'), pPrivateMailAddress.indexOf('@'));
69
- document.getElementById('mail-private').focus();
70
- }
71
- }, []);
72
-
73
- const validationRules = [{
74
- message: profileLabels[lang].validMail,
75
- rule: (fieldValue) => fieldValue.trim().match(emailRegex),
76
- }];
77
-
78
- const validationRulesPrivateMail = [{
79
- message: profileLabels[lang].validMailPrivate,
80
- rule: (fieldValue) => fieldValue.trim().match(emailRegex) && !fieldValue.trim().endsWith(workMailPostfix),
81
- }];
82
-
83
- const validateWorkMail = (value, alert = true) => {
84
- const [valid, messages] = validateForm(lang, value, validationRules);
85
- setWorkMail(value);
86
- setWorkMailValidationMessages(alert ? messages : []);
87
- setIsWorkMailValid(valid);
88
- };
89
-
90
- const validateStudentChosenMail = (value, alert = true) => {
91
- const [valid, messages] = validateForm(lang, value, validationRules);
92
- setStudentChosenMail(value); // Her skal vi lige gøre noget, hvis man har slettet sin selvvalgte og den nulstiller til 20XXXXXXX@post.au.dk
93
- setStudentChosenMailValidationMessages(alert ? messages : []);
94
- setIsStudentChosenMailValid(valid);
95
- };
96
-
97
- const validatePrivateMail = (value, alert = true) => {
98
- const [valid, messages] = validateForm(lang, value, validationRulesPrivateMail);
99
- setPrivateMail(value);
100
- setPrivateMailValidationMessages(alert ? messages : []);
101
- setIsPrivateMailValid(valid);
102
- };
103
-
104
- const submit = (e) => {
105
- e.preventDefault();
106
- validateWorkMail(workMailPrefix + workMailPostfix, !isWorkMailValid);
107
- validateStudentChosenMail(studentChosenMail, !isStudentChosenMailValid);
108
- let valid = true; // Vi tillader tom privatmailadresse
109
- if (privateMail !== '') {
110
- validatePrivateMail(privateMail, !isPrivateMailValid);
111
- valid = isPrivateMailValid;
112
- }
113
- if (isStudentAdGroupMember) {
114
- valid = valid && isStudentChosenMailValid;
115
- }
116
- if (pWorkMailAddress) {
117
- valid = valid && isWorkMailValid;
118
- }
119
- if (valid) {
120
- onSave({
121
- workMailName: workMailPrefix,
122
- studentChosenMailAddress: studentChosenMail === studentMailAddress ? '' : studentChosenMail,
123
- privateMailAddress: privateMail,
124
- }, onSaveAction);
125
- }
126
- };
127
-
128
- let workMailValidationClassName = '';
129
- if (!isWorkMailValid && workMailValidationMessages.length) {
130
- workMailValidationClassName = ' form-info--error';
131
- } else if (isWorkMailValid) {
132
- workMailValidationClassName = ' form-info--confirmed';
133
- }
134
-
135
- let studentChosenMailValidationClassName = '';
136
- if (!isStudentChosenMailValid && studentChosenMailValidationMessages.length) {
137
- studentChosenMailValidationClassName = ' form-info--error';
138
- } else if (isStudentChosenMailValid) {
139
- studentChosenMailValidationClassName = ' form-info--confirmed';
140
- }
141
-
142
- let privateMailValidationClassName = '';
143
- if (!isPrivateMailValid && privateMailValidationMessages.length) {
144
- privateMailValidationClassName = ' form-info--error';
145
- } else if (isPrivateMailValid) {
146
- privateMailValidationClassName = ' form-info--confirmed';
147
- }
148
-
149
- return [
150
- <div key="header" className="list-navigator">
151
- <h1 className="list-navigator__header">{profileLabels[lang].headerMail}</h1>
152
- <Link className="list-navigator__list-name" to={path}>{profileLabels[lang].headerContainer}</Link>
153
- </div>,
154
- <form key="form" className="form" noValidate="novalidate">
155
- {
156
- pWorkMailAddress && (
157
- <div className={`form__field${workMailValidationClassName}`}>
158
- <label key="label" htmlFor="mail-work">
159
- {profileLabels[lang].workMail}
160
- <span className="screenreader-only">{profileLabels[lang].workMailScreenreader.replace('###MAIL###', workMail)}</span>
161
- <div className="form-info__hint">
162
- {profileLabels[lang].workMailHint}
163
- </div>
164
- {renderValidation(workMailValidationMessages)}
165
- </label>
166
- <div className="form__field__shadow-input">
167
- <input
168
- type="text"
169
- id="mail-work"
170
- value={workMailPrefix}
171
- onChange={(e) => {
172
- const trimmed = e.target.value.trim();
173
- setWorkMailPrefix(trimmed);
174
- validateWorkMail(trimmed + workMailPostfix, workMailValidationMessages.length);
175
- }}
176
- onKeyUp={(e) => {
177
- if (e.key === 'Enter') {
178
- const trimmed = e.target.value.trim();
179
- setWorkMailPrefix(trimmed);
180
- validateWorkMail(trimmed + workMailPostfix);
181
- }
182
- }}
183
- disabled={saving}
184
- />
185
- <div className="form__field__shadow-input__content" aria-hidden="true">
186
- <span className="form__field__shadow-input__input">{workMailPrefix}</span>
187
- <span className="form__field__shadow-input__postfix">{workMailPostfix}</span>
188
- </div>
189
- </div>
190
- </div>
191
- )
192
- }
193
- {
194
- isStudentAdGroupMember && (
195
- <div className={`form__field${studentChosenMailValidationClassName}`}>
196
- <label key="label" htmlFor="mail-student">
197
- {profileLabels[lang].studentMail}
198
- <span className="screenreader-only">{profileLabels[lang].studentMailScreenreader.replace('###MAIL###', studentChosenMail)}</span>
199
- {renderValidation(studentChosenMailValidationMessages)}
200
- </label>
201
- <div className="form__field__shadow-input">
202
- <input
203
- type="text"
204
- id="mail-student"
205
- value={studentChosenMailPrefix}
206
- onChange={(e) => {
207
- const trimmed = e.target.value.trim();
208
- setStudentChosenMailPrefix(trimmed);
209
- validateStudentChosenMail(trimmed + studentChosenMailPostfix, studentChosenMailValidationMessages.length);
210
- }}
211
- onKeyUp={(e) => {
212
- if (e.key === 'Enter') {
213
- const trimmed = e.target.value.trim();
214
- setStudentChosenMailPrefix(trimmed);
215
- validateStudentChosenMail(trimmed + studentChosenMailPostfix);
216
- }
217
- }}
218
- disabled={saving}
219
- />
220
- <div className="form__field__shadow-input__content" aria-hidden="true">
221
- <span className="form__field__shadow-input__input">{studentChosenMailPrefix}</span>
222
- <span className="form__field__shadow-input__postfix">{studentChosenMailPostfix}</span>
223
- </div>
224
- </div>
225
- </div>
226
- )
227
- }
228
- <div className={`form__field${privateMailValidationClassName}`}>
229
- <label key="label" htmlFor="mail-private">
230
- {profileLabels[lang].privateMail}
231
- <div className="form-info__hint">
232
- {profileLabels[lang].privateMailHint}
233
- </div>
234
- {renderValidation(privateMailValidationMessages)}
235
- </label>
236
- <input
237
- type="text"
238
- id="mail-private"
239
- value={privateMail || ''}
240
- onChange={(e) => {
241
- validatePrivateMail(e.target.value.trim(), privateMailValidationMessages.length);
242
- }}
243
- onKeyUp={(e) => {
244
- if (e.key === 'Enter') {
245
- validatePrivateMail(e.target.value.trim());
246
- }
247
- }}
248
- disabled={saving}
249
- />
250
- </div>
251
- <AUSubmitButtonContainerComponent
252
- lang={lang}
253
- disabled={saving}
254
- onSubmit={submit}
255
- onCancel={onCancel}
256
- />
257
- </form>,
258
- ];
259
- };
260
-
261
- AUProfileMailComponent.defaultProps = {
262
- onSaveAction: (data, callback) => {
263
- const putData = async () => {
264
- let url = `${window.profileApiUri}/UpdateMailAddresses`;
265
- if (typeof window.API_AUID !== 'undefined') {
266
- url = `${url}?auid=${window.API_AUID}`;
267
- }
268
- const response = await fetch(url, {
269
- method: 'PUT',
270
- credentials: 'include',
271
- headers: {
272
- 'Content-Type': 'application/json',
273
- },
274
- body: JSON.stringify(data),
275
- });
276
- const json = await response.json();
277
- callback(response.ok, response.status, json);
278
-
279
- // clear context cache
280
- // Mail is a litte slow...
281
- // window.auAuth.setUserContext(window.API_AUID || 0, 'profile-clear-cache', true, () => { }, () => { }, true, window.authenticated);
282
- };
283
-
284
- putData();
285
- },
286
- };
287
-
288
- AUProfileMailComponent.propTypes = {
289
- lang: PropTypes.string.isRequired,
290
- routeProps: PropTypes.shape({}).isRequired,
291
- path: PropTypes.string.isRequired,
292
- studentMailAddress: PropTypes.string.isRequired,
293
- studentChosenMailAddress: PropTypes.string.isRequired,
294
- workMailAddress: PropTypes.string.isRequired,
295
- workMailDomain: PropTypes.string.isRequired,
296
- privateMailAddress: PropTypes.string.isRequired,
297
- isStudentAdGroupMember: PropTypes.bool.isRequired,
298
- onSave: PropTypes.func.isRequired,
299
- onSaveAction: PropTypes.func,
300
- saving: PropTypes.bool.isRequired,
301
- saved: PropTypes.bool.isRequired,
302
- dismissMessages: PropTypes.func.isRequired,
303
- clear: PropTypes.func.isRequired,
304
- };
305
-
306
- AUProfileMailComponent.displayName = 'AUProfileMailComponent';
307
- export default AUProfileMailComponent;
@@ -1,164 +0,0 @@
1
- /* eslint-env browser */
2
- /* eslint-disable jsx-a11y/label-has-associated-control */
3
- /* eslint-disable jsx-a11y/label-has-for */
4
- /* eslint-disable max-len */
5
- import React, { useEffect, useState } from 'react';
6
- import PropTypes from 'prop-types';
7
- import { Link } from 'react-router-dom';
8
- import AUSubmitButtonContainerComponent from '../form/AUSubmitButtonContainerComponent';
9
- import AUMobilePrefixComponent from '../form/AUMobilePrefixComponent';
10
- import { useProfileForm, useMobilePrefix } from './AUProfileHooks';
11
- import {
12
- splitPhoneNumber,
13
- scrollTo,
14
- } from '../../lib/helpers';
15
- import { profileLabels } from '../../lib/i18n';
16
- import { renderValidation, validateForm } from '../../lib/validation';
17
-
18
- const AUProfileMobileComponent = ({
19
- lang,
20
- routeProps: { history },
21
- path,
22
- countryCodes,
23
- privateMobileNumber,
24
- onSave,
25
- onSaveAction,
26
- saving,
27
- saved,
28
- dismissMessages,
29
- clear,
30
- }) => {
31
- const validationRules = [{
32
- message: profileLabels[lang].validMobile,
33
- rule: (fieldValue) => fieldValue.trim().match(/^\+[1-9][0-9]{5,14}$/),
34
- }];
35
-
36
- const [onCancel] = useProfileForm(saved, history, lang, clear);
37
- const [prefix, mobile, setPrefix, setMobile] = useMobilePrefix(splitPhoneNumber, countryCodes, privateMobileNumber);
38
- const [mobileValidationMessages, setMobileValidationMessages] = useState([]);
39
- const [isMobileValid, setIsMobileValid] = useState(!!privateMobileNumber);
40
-
41
- const validate = (value, alert = true) => {
42
- const [valid, messages] = validateForm(lang, prefix + value, validationRules);
43
- setMobile(value);
44
- setMobileValidationMessages(alert ? messages : []);
45
- setIsMobileValid(valid);
46
- };
47
-
48
- const submit = (e) => {
49
- e.preventDefault();
50
- validate(mobile, !isMobileValid);
51
- if (isMobileValid) {
52
- onSave({
53
- privatePhoneNumber: '',
54
- privateMobileNumber: prefix + mobile,
55
- }, onSaveAction);
56
- }
57
- };
58
-
59
- let mobileValidationClassName = '';
60
- if (!isMobileValid && mobileValidationMessages.length) {
61
- mobileValidationClassName = ' form-info--error';
62
- } else if (isMobileValid) {
63
- mobileValidationClassName = ' form-info--confirmed';
64
- }
65
-
66
- useEffect(() => {
67
- dismissMessages();
68
- scrollTo();
69
- document.getElementById('contact-phone').focus();
70
- }, []);
71
-
72
- return [
73
- <div key="header" className="list-navigator">
74
- <h1 className="list-navigator__header">{profileLabels[lang].headerMobile}</h1>
75
- <Link className="list-navigator__list-name" to={path}>{profileLabels[lang].headerContainer}</Link>
76
- </div>,
77
- <form key="form" className="form" noValidate="novalidate">
78
- <div className="form__field">
79
- <label htmlFor="contact-country-code">{profileLabels[lang].countryCode}</label>
80
- <select
81
- id="contact-country-code"
82
- value={prefix}
83
- onChange={(e) => {
84
- setPrefix(e.target.value);
85
- }}
86
- >
87
- <AUMobilePrefixComponent countryCodes={countryCodes} important />
88
- <optgroup label="Alle lande">
89
- <AUMobilePrefixComponent countryCodes={countryCodes} />
90
- </optgroup>
91
- </select>
92
- </div>
93
- <div className={`form__field${mobileValidationClassName}`}>
94
- <label htmlFor="contact-phone">
95
- {profileLabels[lang].number}
96
- {renderValidation(mobileValidationMessages)}
97
- </label>
98
- <input
99
- type="tel"
100
- id="contact-phone"
101
- value={mobile}
102
- onChange={(e) => {
103
- validate(e.target.value.trim(), mobileValidationMessages.length);
104
- }}
105
- onKeyUp={(e) => {
106
- if (e.key === 'Enter') {
107
- validate(e.target.value.trim());
108
- }
109
- }}
110
- disabled={saving}
111
- />
112
- </div>
113
- <AUSubmitButtonContainerComponent
114
- lang={lang}
115
- disabled={saving}
116
- onSubmit={submit}
117
- onCancel={onCancel}
118
- />
119
- </form>,
120
- ];
121
- };
122
-
123
- AUProfileMobileComponent.defaultProps = {
124
- onSaveAction: (data, callback) => {
125
- const putData = async () => {
126
- let url = `${window.profileApiUri}/UpdatePrivatePhoneNumbers`;
127
- if (typeof window.API_AUID !== 'undefined') {
128
- url = `${url}?auid=${window.API_AUID}`;
129
- }
130
- const response = await fetch(url, {
131
- method: 'PUT',
132
- credentials: 'include',
133
- headers: {
134
- 'Content-Type': 'application/json',
135
- },
136
- body: JSON.stringify(data),
137
- });
138
- const json = await response.json();
139
- callback(response.ok, response.status, json);
140
-
141
- // clear context cache
142
- window.auAuth.setUserContext(window.API_AUID || 0, 'profile-clear-cache', true, () => {}, () => {}, true, window.authenticated);
143
- };
144
-
145
- putData();
146
- },
147
- };
148
-
149
- AUProfileMobileComponent.propTypes = {
150
- lang: PropTypes.string.isRequired,
151
- routeProps: PropTypes.shape({}).isRequired,
152
- path: PropTypes.string.isRequired,
153
- countryCodes: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
154
- privateMobileNumber: PropTypes.string.isRequired,
155
- onSave: PropTypes.func.isRequired,
156
- onSaveAction: PropTypes.func,
157
- saving: PropTypes.bool.isRequired,
158
- saved: PropTypes.bool.isRequired,
159
- dismissMessages: PropTypes.func.isRequired,
160
- clear: PropTypes.func.isRequired,
161
- };
162
-
163
- AUProfileMobileComponent.displayName = 'AUProfileMobileComponent';
164
- export default AUProfileMobileComponent;