@plusscommunities/pluss-maintenance-app 6.0.7-auth.0 → 6.0.8-beta.0
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.
- package/dist/module/actions/types.js +4 -3
- package/dist/module/actions/types.js.map +1 -1
- package/dist/module/apis/maintenanceActions.js +17 -15
- package/dist/module/apis/maintenanceActions.js.map +1 -1
- package/dist/module/components/MaintenanceList.js +5 -4
- package/dist/module/components/MaintenanceList.js.map +1 -1
- package/dist/module/components/MaintenanceListItem.js +3 -2
- package/dist/module/components/MaintenanceListItem.js.map +1 -1
- package/dist/module/components/MaintenanceWidgetItem.js +2 -1
- package/dist/module/components/MaintenanceWidgetItem.js.map +1 -1
- package/dist/module/components/WidgetSmall.js +8 -5
- package/dist/module/components/WidgetSmall.js.map +1 -1
- package/dist/module/feature.config.js +21 -36
- package/dist/module/feature.config.js.map +1 -1
- package/dist/module/index.js +15 -10
- package/dist/module/index.js.map +1 -1
- package/dist/module/reducers/JobsReducer.js +2 -1
- package/dist/module/reducers/JobsReducer.js.map +1 -1
- package/dist/module/screens/MaintenancePage.js +7 -3
- package/dist/module/screens/MaintenancePage.js.map +1 -1
- package/dist/module/screens/RequestDetail.js +106 -31
- package/dist/module/screens/RequestDetail.js.map +1 -1
- package/dist/module/screens/RequestNotes.js +2 -1
- package/dist/module/screens/RequestNotes.js.map +1 -1
- package/dist/module/screens/ServiceRequest.js +581 -86
- package/dist/module/screens/ServiceRequest.js.map +1 -1
- package/dist/module/values.config.a.js +30 -0
- package/dist/module/values.config.a.js.map +1 -0
- package/dist/module/values.config.b.js +30 -0
- package/dist/module/values.config.b.js.map +1 -0
- package/dist/module/values.config.c.js +30 -0
- package/dist/module/values.config.c.js.map +1 -0
- package/dist/module/values.config.d.js +30 -0
- package/dist/module/values.config.d.js.map +1 -0
- package/dist/module/values.config.default.js +35 -0
- package/dist/module/values.config.default.js.map +1 -0
- package/dist/module/values.config.forms.js +35 -0
- package/dist/module/values.config.forms.js.map +1 -0
- package/dist/module/values.config.js +35 -0
- package/dist/module/values.config.js.map +1 -0
- package/package.json +9 -6
- package/src/actions/types.js +5 -3
- package/src/apis/maintenanceActions.js +30 -14
- package/src/components/MaintenanceList.js +6 -4
- package/src/components/MaintenanceListItem.js +7 -2
- package/src/components/MaintenanceWidgetItem.js +2 -1
- package/src/components/WidgetSmall.js +8 -5
- package/src/feature.config.js +30 -40
- package/src/index.js +15 -8
- package/src/reducers/JobsReducer.js +2 -1
- package/src/screens/MaintenancePage.js +5 -4
- package/src/screens/RequestDetail.js +101 -33
- package/src/screens/RequestNotes.js +2 -1
- package/src/screens/ServiceRequest.js +625 -152
- package/src/values.config.a.js +30 -0
- package/src/values.config.b.js +30 -0
- package/src/values.config.c.js +30 -0
- package/src/values.config.d.js +30 -0
- package/src/values.config.default.js +35 -0
- package/src/values.config.forms.js +35 -0
- package/src/values.config.js +35 -0
@@ -12,13 +12,16 @@ import {
|
|
12
12
|
ImageBackground,
|
13
13
|
Keyboard,
|
14
14
|
} from 'react-native';
|
15
|
-
import
|
15
|
+
import DateTimePicker from 'react-native-modal-datetime-picker';
|
16
16
|
import { Icon } from 'react-native-elements';
|
17
|
+
import _ from 'lodash';
|
18
|
+
import moment from 'moment';
|
17
19
|
import { connect } from 'react-redux';
|
18
20
|
import { jobAdded } from '../actions';
|
19
21
|
import { maintenanceActions } from '../apis';
|
20
22
|
import { Services } from '../feature.config';
|
21
23
|
import { Components, Colours, Helper, Config } from '../core.config';
|
24
|
+
import { values } from '../values.config';
|
22
25
|
|
23
26
|
const PHOTO_SIZE = (Dimensions.get('window').width - 64) / 3;
|
24
27
|
|
@@ -31,6 +34,7 @@ class MaintenanceRequest extends Component {
|
|
31
34
|
fail: false,
|
32
35
|
error: null,
|
33
36
|
showError: false,
|
37
|
+
loadingTypes: values.forceCustomFields,
|
34
38
|
|
35
39
|
userName: '',
|
36
40
|
roomNumber: '',
|
@@ -55,8 +59,20 @@ class MaintenanceRequest extends Component {
|
|
55
59
|
types: [],
|
56
60
|
|
57
61
|
confirmationToShow: false,
|
62
|
+
|
63
|
+
customFields: [],
|
64
|
+
customFieldImages: {},
|
65
|
+
isDateTimePickerVisible: false,
|
66
|
+
popUpType: 'date',
|
67
|
+
dateFieldId: null,
|
68
|
+
imageFieldId: null,
|
58
69
|
};
|
59
70
|
this.checkThumb = null;
|
71
|
+
this.keyboardTypes = {
|
72
|
+
phone: 'phone-pad',
|
73
|
+
email: 'email-address',
|
74
|
+
text: 'default',
|
75
|
+
};
|
60
76
|
}
|
61
77
|
|
62
78
|
componentDidMount() {
|
@@ -74,9 +90,62 @@ class MaintenanceRequest extends Component {
|
|
74
90
|
clearInterval(this.checkThumb);
|
75
91
|
}
|
76
92
|
|
93
|
+
onChangeAnswer = (fieldId, answer) => {
|
94
|
+
const update = { customFields: _.cloneDeep(this.state.customFields) };
|
95
|
+
const field = update.customFields[fieldId];
|
96
|
+
field.answer = answer;
|
97
|
+
if (field.isTitle) update.title = field.answer;
|
98
|
+
this.setState(update);
|
99
|
+
};
|
100
|
+
|
101
|
+
onChangeToggleAnswer = (fieldId, answer) => {
|
102
|
+
const update = { customFields: _.cloneDeep(this.state.customFields) };
|
103
|
+
const field = update.customFields[fieldId];
|
104
|
+
field.answer = field.answer === answer ? undefined : answer;
|
105
|
+
if (field.isTitle) update.title = field.answer;
|
106
|
+
this.setState(update);
|
107
|
+
};
|
108
|
+
|
109
|
+
onChangeCheckboxAnswer = (fieldId, answer) => {
|
110
|
+
const update = { customFields: _.cloneDeep(this.state.customFields) };
|
111
|
+
const field = update.customFields[fieldId];
|
112
|
+
field.answer = _.xor(field.answer || [], [answer]);
|
113
|
+
if (field.isTitle) update.title = field.answer.join(', ');
|
114
|
+
this.setState(update);
|
115
|
+
};
|
116
|
+
|
117
|
+
onOpenDatePicker = (field, fieldId) => {
|
118
|
+
Keyboard.dismiss();
|
119
|
+
this.setState({ dateFieldId: fieldId, popUpType: field.type, isDateTimePickerVisible: true });
|
120
|
+
};
|
121
|
+
|
122
|
+
onClearDate = fieldId => {
|
123
|
+
const update = { customFields: _.cloneDeep(this.state.customFields) };
|
124
|
+
const field = update.customFields[fieldId];
|
125
|
+
field.answer = undefined;
|
126
|
+
if (field.isTitle) update.title = field.answer;
|
127
|
+
this.setState(update);
|
128
|
+
};
|
129
|
+
|
130
|
+
onDateSelected = date => {
|
131
|
+
const { customFields, dateFieldId, popUpType } = this.state;
|
132
|
+
const update = { customFields: _.cloneDeep(customFields), isDateTimePickerVisible: false, fieldId: null };
|
133
|
+
const field = update.customFields[dateFieldId];
|
134
|
+
const dateObj = moment(date);
|
135
|
+
if (popUpType === 'date') {
|
136
|
+
field.answer = dateObj.format('YYYY-MM-DD');
|
137
|
+
if (field.isTitle) update.title = dateObj.format('DD MMM YYYY');
|
138
|
+
} else {
|
139
|
+
field.answer = dateObj.format('HH:mm');
|
140
|
+
if (field.isTitle) update.title = dateObj.format('h:mm a');
|
141
|
+
}
|
142
|
+
this.setState(update);
|
143
|
+
};
|
144
|
+
|
77
145
|
onUploadStarted = (uploadUri, imageUri) => {
|
78
|
-
const
|
79
|
-
|
146
|
+
const { imageFieldId } = this.state;
|
147
|
+
const imagesUpdate = this.getImages(imageFieldId);
|
148
|
+
imagesUpdate.splice(imagesUpdate.length - 1, 0, {
|
80
149
|
uploading: true,
|
81
150
|
uploadProgress: '0%',
|
82
151
|
uploadUri,
|
@@ -84,24 +153,27 @@ class MaintenanceRequest extends Component {
|
|
84
153
|
allowRetry: true,
|
85
154
|
});
|
86
155
|
|
87
|
-
this.
|
156
|
+
this.setImages(imagesUpdate, imageFieldId);
|
88
157
|
};
|
89
158
|
|
90
159
|
onUploadProgress = progress => {
|
91
|
-
const
|
92
|
-
|
160
|
+
const { imageFieldId } = this.state;
|
161
|
+
const imagesUpdate = this.getImages(imageFieldId);
|
162
|
+
imagesUpdate.map(img => {
|
93
163
|
if (img.uploadUri === progress.uri) {
|
94
164
|
img.uploadProgress = progress.percentage;
|
95
165
|
img.uploading = true;
|
96
166
|
img.allowRetry = true;
|
97
167
|
}
|
98
168
|
});
|
99
|
-
|
169
|
+
|
170
|
+
this.setImages(imagesUpdate, imageFieldId);
|
100
171
|
};
|
101
172
|
|
102
173
|
onUploadSuccess = async (uri, uploadUri) => {
|
103
|
-
const
|
104
|
-
|
174
|
+
const { imageFieldId } = this.state;
|
175
|
+
const imagesUpdate = this.getImages(imageFieldId);
|
176
|
+
imagesUpdate.map(img => {
|
105
177
|
if (img.uploadUri === uploadUri && img.uploading) {
|
106
178
|
img.url = uri.replace('/general/', '/general1400/');
|
107
179
|
img.thumbNailExists = false;
|
@@ -109,12 +181,14 @@ class MaintenanceRequest extends Component {
|
|
109
181
|
img.allowRetry = true;
|
110
182
|
}
|
111
183
|
});
|
112
|
-
|
184
|
+
|
185
|
+
this.setImages(imagesUpdate, imageFieldId, () => this.waitForThumbnails());
|
113
186
|
};
|
114
187
|
|
115
188
|
onUploadFailed = uploadUri => {
|
116
|
-
const
|
117
|
-
|
189
|
+
const { imageFieldId } = this.state;
|
190
|
+
const imagesUpdate = this.getImages(imageFieldId);
|
191
|
+
imagesUpdate.map(img => {
|
118
192
|
if (img.uploadUri === uploadUri) {
|
119
193
|
img.uploading = true; // Requried for retry
|
120
194
|
img.uploadProgress = '';
|
@@ -122,12 +196,13 @@ class MaintenanceRequest extends Component {
|
|
122
196
|
}
|
123
197
|
});
|
124
198
|
|
125
|
-
this.
|
199
|
+
this.setImages(imagesUpdate, imageFieldId);
|
126
200
|
};
|
127
201
|
|
128
202
|
onLibrarySelected = uri => {
|
129
|
-
const
|
130
|
-
|
203
|
+
const { imageFieldId } = this.state;
|
204
|
+
const imagesUpdate = this.getImages(imageFieldId);
|
205
|
+
imagesUpdate.splice(imagesUpdate.length - 1, 0, {
|
131
206
|
uploading: false,
|
132
207
|
allowRetry: false,
|
133
208
|
url: Helper.get1400(uri),
|
@@ -135,7 +210,7 @@ class MaintenanceRequest extends Component {
|
|
135
210
|
thumbNailUrl: Helper.getThumb300(uri),
|
136
211
|
});
|
137
212
|
|
138
|
-
this.
|
213
|
+
this.setImages(imagesUpdate, imageFieldId);
|
139
214
|
};
|
140
215
|
|
141
216
|
onPressBack() {
|
@@ -143,7 +218,7 @@ class MaintenanceRequest extends Component {
|
|
143
218
|
}
|
144
219
|
|
145
220
|
onPressType() {
|
146
|
-
Services.navigation.navigate(
|
221
|
+
Services.navigation.navigate(values.screenJobTypePicker, {
|
147
222
|
currentType: this.state.type,
|
148
223
|
types: this.state.types,
|
149
224
|
onSelectType: this.pickType.bind(this),
|
@@ -159,52 +234,115 @@ class MaintenanceRequest extends Component {
|
|
159
234
|
}
|
160
235
|
|
161
236
|
onConfirmationReset() {
|
162
|
-
this.setState(
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
237
|
+
this.setState(
|
238
|
+
{
|
239
|
+
confirmationToShow: false,
|
240
|
+
title: '',
|
241
|
+
description: '',
|
242
|
+
times: '',
|
243
|
+
isHome: false,
|
244
|
+
uploadingImage: false,
|
245
|
+
images: [
|
246
|
+
{
|
247
|
+
add: true,
|
248
|
+
},
|
249
|
+
],
|
250
|
+
submitting: false,
|
251
|
+
success: false,
|
252
|
+
fail: false,
|
253
|
+
customFields: [],
|
254
|
+
customFieldImages: {},
|
255
|
+
isDateTimePickerVisible: false,
|
256
|
+
popUpType: 'date',
|
257
|
+
dateFieldId: null,
|
258
|
+
imageFieldId: null,
|
259
|
+
},
|
260
|
+
() => this.pickType(this.state.type),
|
261
|
+
);
|
178
262
|
}
|
179
263
|
|
264
|
+
isFieldValid = (field, fieldId) => {
|
265
|
+
const { mandatory, type, answer } = field;
|
266
|
+
if (['staticTitle', 'staticText'].includes(type)) return true;
|
267
|
+
|
268
|
+
const imagesList = type === 'image' ? this.getImageUrls(fieldId) : [];
|
269
|
+
const checkMandatory = () => {
|
270
|
+
if (!mandatory) return true;
|
271
|
+
switch (type) {
|
272
|
+
case 'yn':
|
273
|
+
return _.isBoolean(answer);
|
274
|
+
case 'image':
|
275
|
+
return imagesList.length > 0;
|
276
|
+
case 'checkbox':
|
277
|
+
return _.isArray(answer) && answer.length > 0;
|
278
|
+
default:
|
279
|
+
return !_.isNil(answer) && !_.isEmpty(answer);
|
280
|
+
}
|
281
|
+
};
|
282
|
+
const checkFormat = () => {
|
283
|
+
if (_.isNil(answer) || _.isEmpty(answer)) return true;
|
284
|
+
switch (type) {
|
285
|
+
case 'email':
|
286
|
+
return Helper.isEmail(answer);
|
287
|
+
case 'date':
|
288
|
+
return moment(answer, 'YYYY-MM-DD', true).isValid();
|
289
|
+
case 'time':
|
290
|
+
return moment(answer, 'HH:mm', true).isValid();
|
291
|
+
default:
|
292
|
+
return true;
|
293
|
+
}
|
294
|
+
};
|
295
|
+
|
296
|
+
const valid = checkMandatory() && checkFormat();
|
297
|
+
return valid;
|
298
|
+
};
|
299
|
+
|
180
300
|
getJobTypes() {
|
181
|
-
const self = this;
|
182
301
|
maintenanceActions
|
183
302
|
.getJobTypes(Helper.getSite(this.props.site))
|
184
303
|
.then(res => {
|
185
|
-
|
304
|
+
this.setState({
|
186
305
|
types: res.data,
|
187
306
|
});
|
188
|
-
|
307
|
+
console.log(res.data);
|
308
|
+
this.getDefaultJob();
|
189
309
|
})
|
190
310
|
.catch(() => {});
|
191
311
|
}
|
192
312
|
|
193
|
-
|
194
|
-
|
195
|
-
|
313
|
+
pickType(type) {
|
314
|
+
const { types } = this.state;
|
315
|
+
const selected = types.find(t => t.typeName === type) || {};
|
316
|
+
if (values.forceCustomFields && !selected.hasCustomFields) {
|
317
|
+
console.log(selected);
|
318
|
+
this.setState({
|
319
|
+
type,
|
320
|
+
customFields: [],
|
321
|
+
noType: true,
|
322
|
+
});
|
323
|
+
return;
|
196
324
|
}
|
325
|
+
this.setState({
|
326
|
+
type,
|
327
|
+
customFields: selected.hasCustomFields && selected.customFields.length > 0 ? _.cloneDeep(selected.customFields) : [],
|
328
|
+
loadingTypes: false,
|
329
|
+
});
|
197
330
|
}
|
198
331
|
|
199
|
-
|
200
|
-
|
332
|
+
getDefaultJob() {
|
333
|
+
const { types, jobId } = this.state;
|
334
|
+
if (types.length !== 0 && jobId == null) {
|
335
|
+
const defaultType = types[0];
|
336
|
+
this.pickType(defaultType.typeName);
|
337
|
+
}
|
201
338
|
}
|
202
339
|
|
203
|
-
showUploadMenu =
|
340
|
+
showUploadMenu = fieldId => {
|
204
341
|
Keyboard.dismiss();
|
205
342
|
if (this.state.uploadingImage || this.state.submitting) {
|
206
343
|
return;
|
207
344
|
}
|
345
|
+
if (fieldId) this.setState({ imageFieldId: fieldId });
|
208
346
|
this.imageUploader.showUploadMenu();
|
209
347
|
};
|
210
348
|
|
@@ -221,10 +359,13 @@ class MaintenanceRequest extends Component {
|
|
221
359
|
this.scrollContainer.scrollTo({ y: 0 });
|
222
360
|
}, 100);
|
223
361
|
|
224
|
-
const images =
|
225
|
-
|
226
|
-
|
227
|
-
|
362
|
+
const images = this.getImageUrls();
|
363
|
+
|
364
|
+
// Fix custom images field answers
|
365
|
+
const customFields = _.cloneDeep(this.state.customFields);
|
366
|
+
const updatedCustomFields = customFields.map((field, fieldId) => {
|
367
|
+
if (field.type === 'image') field.answer = this.getImageUrls(fieldId);
|
368
|
+
return field;
|
228
369
|
});
|
229
370
|
|
230
371
|
maintenanceActions
|
@@ -241,6 +382,7 @@ class MaintenanceRequest extends Component {
|
|
241
382
|
Helper.getSite(this.props.site),
|
242
383
|
this.state.isHome,
|
243
384
|
this.state.times,
|
385
|
+
updatedCustomFields,
|
244
386
|
)
|
245
387
|
.then(res => {
|
246
388
|
if (res.data.success) {
|
@@ -269,45 +411,98 @@ class MaintenanceRequest extends Component {
|
|
269
411
|
refreshRequest = async id => {
|
270
412
|
try {
|
271
413
|
const job = await maintenanceActions.getJob(Helper.getSite(this.props.site), id);
|
272
|
-
// console.log('refreshRequest', job?.data);
|
273
414
|
this.props.jobAdded(job.data);
|
274
415
|
} catch (error) {
|
275
416
|
console.log('refreshRequest error', error);
|
276
417
|
}
|
277
418
|
};
|
278
419
|
|
420
|
+
validateCustomFields = () => {
|
421
|
+
const { customFields } = this.state;
|
422
|
+
if (!customFields || customFields.length === 0) return true;
|
423
|
+
|
424
|
+
return customFields.every((field, index) => {
|
425
|
+
const isValid = this.isFieldValid(field, index);
|
426
|
+
return isValid;
|
427
|
+
});
|
428
|
+
};
|
429
|
+
|
279
430
|
submitRequest() {
|
280
|
-
|
431
|
+
const { customFields, submitting, uploadingImage, title, roomNumber, isHome, times } = this.state;
|
432
|
+
const hasCustomFields = customFields && customFields.length > 0;
|
433
|
+
|
434
|
+
if (submitting || !this.props.connected) {
|
281
435
|
if (!this.props.connected) {
|
282
436
|
this.setState({ error: { message: 'No internet connection detected' } });
|
283
437
|
}
|
284
438
|
return;
|
285
439
|
}
|
286
|
-
if (
|
287
|
-
|
288
|
-
}
|
440
|
+
if (uploadingImage) return;
|
441
|
+
|
289
442
|
this.setState({ error: null, showError: false });
|
290
|
-
if (
|
443
|
+
if (title.length === 0 || !roomNumber || roomNumber.length === 0) {
|
444
|
+
console.log('submitRequest - error', { title, roomNumber });
|
291
445
|
this.setState({ showError: true });
|
292
446
|
return;
|
293
447
|
}
|
294
|
-
if (
|
295
|
-
this.
|
296
|
-
|
448
|
+
if (hasCustomFields) {
|
449
|
+
if (!this.validateCustomFields()) {
|
450
|
+
console.log('submitRequest - custom fields error');
|
451
|
+
this.setState({ showError: true });
|
452
|
+
return;
|
453
|
+
}
|
454
|
+
} else {
|
455
|
+
if (isHome && times.length < 2) {
|
456
|
+
console.log('submitRequest - error', { isHome, times });
|
457
|
+
this.setState({ showError: true });
|
458
|
+
return;
|
459
|
+
}
|
297
460
|
}
|
298
461
|
this.submit();
|
299
462
|
}
|
300
463
|
|
464
|
+
getImages = (fieldId = null) => {
|
465
|
+
const { images, customFieldImages } = this.state;
|
466
|
+
const imagesList = _.cloneDeep(fieldId ? customFieldImages[fieldId] : images);
|
467
|
+
if (!imagesList || !Array.isArray(imagesList) || imagesList.length === 0) {
|
468
|
+
return [{ add: true }];
|
469
|
+
}
|
470
|
+
return imagesList;
|
471
|
+
};
|
472
|
+
|
473
|
+
setImages = (imagesList, fieldId = null, callback = null) => {
|
474
|
+
let update = {};
|
475
|
+
if (fieldId) {
|
476
|
+
const customFieldImages = _.cloneDeep(this.state.customFieldImages);
|
477
|
+
customFieldImages[fieldId] = imagesList;
|
478
|
+
update = { customFieldImages };
|
479
|
+
} else {
|
480
|
+
update = { images: imagesList };
|
481
|
+
}
|
482
|
+
this.setState(update, callback);
|
483
|
+
};
|
484
|
+
|
485
|
+
getImageUrls = (fieldId = null) => {
|
486
|
+
const imagesList = this.getImages(fieldId);
|
487
|
+
return _.filter(imagesList, img => {
|
488
|
+
return !img.uploading && !img.add;
|
489
|
+
}).map(img => {
|
490
|
+
return img.url;
|
491
|
+
});
|
492
|
+
};
|
493
|
+
|
301
494
|
waitForThumbnails = () => {
|
302
495
|
if (this.checkThumb) return;
|
303
496
|
|
304
497
|
this.checkThumb = setInterval(async () => {
|
305
|
-
const
|
498
|
+
const { imageFieldId } = this.state;
|
499
|
+
const imagesList = this.getImages(imageFieldId);
|
500
|
+
const imagesUpdate = [];
|
306
501
|
await Promise.all(
|
307
|
-
|
502
|
+
imagesList.map(image => {
|
308
503
|
return new Promise(async resolve => {
|
309
504
|
const newImage = { ...image };
|
310
|
-
|
505
|
+
imagesUpdate.push(newImage);
|
311
506
|
if (newImage.url && !newImage.thumbNailExists) {
|
312
507
|
newImage.uploading = false;
|
313
508
|
newImage.allowRetry = false;
|
@@ -318,20 +513,20 @@ class MaintenanceRequest extends Component {
|
|
318
513
|
});
|
319
514
|
}),
|
320
515
|
);
|
321
|
-
const thumbnailsExist =
|
516
|
+
const thumbnailsExist = imagesUpdate.every(image => !image.url || image.thumbNailExists);
|
322
517
|
if (thumbnailsExist) {
|
323
518
|
clearInterval(this.checkThumb);
|
324
519
|
this.checkThumb = null;
|
325
|
-
this.
|
520
|
+
this.setImages(imagesUpdate, imageFieldId);
|
326
521
|
}
|
327
522
|
}, 2000);
|
328
523
|
};
|
329
524
|
|
330
|
-
removeImage = index => {
|
331
|
-
const
|
332
|
-
|
525
|
+
removeImage = (index, fieldId) => {
|
526
|
+
const imagesUpdate = this.getImages(fieldId);
|
527
|
+
imagesUpdate.splice(index, 1);
|
333
528
|
|
334
|
-
this.
|
529
|
+
this.setImages(imagesUpdate, fieldId);
|
335
530
|
};
|
336
531
|
|
337
532
|
toggleFullscreenVideo = url => {
|
@@ -360,16 +555,17 @@ class MaintenanceRequest extends Component {
|
|
360
555
|
);
|
361
556
|
}
|
362
557
|
|
363
|
-
renderImage(item, index) {
|
558
|
+
renderImage(item, index, fieldId = null) {
|
364
559
|
const isVideoUrl = Helper.isVideo(item.url);
|
560
|
+
const imagesList = this.getImages(fieldId);
|
365
561
|
|
366
562
|
if (item.add) {
|
367
563
|
return (
|
368
|
-
<TouchableOpacity activeOpacity={0.8} onPress={this.showUploadMenu}>
|
564
|
+
<TouchableOpacity activeOpacity={0.8} onPress={() => this.showUploadMenu(fieldId)}>
|
369
565
|
<View
|
370
566
|
style={[
|
371
567
|
styles.imageContainer,
|
372
|
-
|
568
|
+
imagesList.length > 1 && styles.imageContainerNotEmpty,
|
373
569
|
index % 3 === 0 && { marginLeft: 0 },
|
374
570
|
index > 2 && { marginTop: 8 },
|
375
571
|
]}
|
@@ -385,7 +581,7 @@ class MaintenanceRequest extends Component {
|
|
385
581
|
<View
|
386
582
|
style={[
|
387
583
|
styles.imageContainer,
|
388
|
-
|
584
|
+
imagesList.length > 1 && styles.imageContainerNotEmpty,
|
389
585
|
index % 3 === 0 && { marginLeft: 0 },
|
390
586
|
index > 2 && { marginTop: 8 },
|
391
587
|
]}
|
@@ -404,7 +600,7 @@ class MaintenanceRequest extends Component {
|
|
404
600
|
</TouchableOpacity>
|
405
601
|
</View>
|
406
602
|
)}
|
407
|
-
<TouchableOpacity style={styles.removeImage} onPress={this.removeImage
|
603
|
+
<TouchableOpacity style={styles.removeImage} onPress={() => this.removeImage(index, fieldId)}>
|
408
604
|
<Icon name="remove" type="font-awesome" iconStyle={styles.imageControlIcon} style={styles.removeImage} />
|
409
605
|
</TouchableOpacity>
|
410
606
|
</ImageBackground>
|
@@ -421,15 +617,16 @@ class MaintenanceRequest extends Component {
|
|
421
617
|
);
|
422
618
|
}
|
423
619
|
|
424
|
-
renderImageList() {
|
620
|
+
renderImageList(fieldId = null) {
|
621
|
+
const imagesList = this.getImages(fieldId);
|
425
622
|
return (
|
426
623
|
<View style={styles.imageSection}>
|
427
|
-
<View style={[styles.imageListContainer,
|
624
|
+
<View style={[styles.imageListContainer, imagesList.length < 2 && styles.imageListContainerEmpty]}>
|
428
625
|
<FlatList
|
429
626
|
keyboardShouldPersistTaps="always"
|
430
627
|
enableEmptySections
|
431
|
-
data={
|
432
|
-
renderItem={({ item, index }) => this.renderImage(item, index)}
|
628
|
+
data={imagesList}
|
629
|
+
renderItem={({ item, index }) => this.renderImage(item, index, fieldId)}
|
433
630
|
keyExtractor={(item, index) => index}
|
434
631
|
numColumns={3}
|
435
632
|
/>
|
@@ -438,7 +635,185 @@ class MaintenanceRequest extends Component {
|
|
438
635
|
);
|
439
636
|
}
|
440
637
|
|
638
|
+
renderDateField(field, fieldId, sectionStyle) {
|
639
|
+
let displayText, placeHolder, icon, errorText;
|
640
|
+
if (field.type === 'date') {
|
641
|
+
displayText = field.answer ? moment(field.answer, 'YYYY-MM-DD').format('DD MMM YYYY') : '';
|
642
|
+
placeHolder = 'dd mmm yyyy';
|
643
|
+
icon = 'calendar';
|
644
|
+
errorText = 'Not a valid date';
|
645
|
+
} else {
|
646
|
+
displayText = field.answer ? moment(field.answer, 'HH:mm').format('h:mm a') : '';
|
647
|
+
placeHolder = '--:-- --';
|
648
|
+
icon = 'clock-o';
|
649
|
+
errorText = 'Not a valid time';
|
650
|
+
}
|
651
|
+
|
652
|
+
return (
|
653
|
+
<Components.GenericInputSection
|
654
|
+
key={fieldId}
|
655
|
+
label={field.label}
|
656
|
+
sectionStyle={sectionStyle}
|
657
|
+
isValid={() => this.isFieldValid(field, fieldId)}
|
658
|
+
required={field.mandatory}
|
659
|
+
showError={this.state.showError}
|
660
|
+
errorText={errorText}
|
661
|
+
>
|
662
|
+
<View style={styles.dateContainer}>
|
663
|
+
<TouchableOpacity style={styles.dateFieldButton} onPress={() => this.onOpenDatePicker(field, fieldId)}>
|
664
|
+
<View style={styles.dateFieldContainer}>
|
665
|
+
<Text style={styles.dateText}>{displayText || placeHolder}</Text>
|
666
|
+
<Icon type="font-awesome" name={icon} iconStyle={styles.dateIcon} />
|
667
|
+
</View>
|
668
|
+
</TouchableOpacity>
|
669
|
+
{displayText ? (
|
670
|
+
<TouchableOpacity style={styles.dateClearButton} onPress={() => this.onClearDate(fieldId)}>
|
671
|
+
<Icon type="font-awesome" name="times" iconStyle={styles.removeIcon} />
|
672
|
+
</TouchableOpacity>
|
673
|
+
) : null}
|
674
|
+
</View>
|
675
|
+
</Components.GenericInputSection>
|
676
|
+
);
|
677
|
+
}
|
678
|
+
|
679
|
+
renderField(field, fieldId) {
|
680
|
+
const sectionStyle = { marginTop: fieldId === 0 ? 24 : 0, marginBottom: 24 };
|
681
|
+
switch (field.type) {
|
682
|
+
case 'yn':
|
683
|
+
return (
|
684
|
+
<Components.GenericInputSection
|
685
|
+
key={fieldId}
|
686
|
+
label={field.label}
|
687
|
+
sectionStyle={sectionStyle}
|
688
|
+
inputType="toggle"
|
689
|
+
value={field.answer}
|
690
|
+
onChange={answer => this.onChangeToggleAnswer(fieldId, answer)}
|
691
|
+
isValid={() => this.isFieldValid(field, fieldId)}
|
692
|
+
showError={this.state.showError}
|
693
|
+
required={field.mandatory}
|
694
|
+
/>
|
695
|
+
);
|
696
|
+
case 'multichoice':
|
697
|
+
return (
|
698
|
+
<Components.GenericInputSection
|
699
|
+
key={fieldId}
|
700
|
+
label={field.label}
|
701
|
+
sectionStyle={sectionStyle}
|
702
|
+
inputType="radio"
|
703
|
+
value={field.answer}
|
704
|
+
onChange={answer => this.onChangeToggleAnswer(fieldId, answer)}
|
705
|
+
options={field.values.map(o => {
|
706
|
+
return {
|
707
|
+
Label: o,
|
708
|
+
Value: o,
|
709
|
+
};
|
710
|
+
})}
|
711
|
+
isValid={() => this.isFieldValid(field, fieldId)}
|
712
|
+
showError={this.state.showError}
|
713
|
+
required={field.mandatory}
|
714
|
+
/>
|
715
|
+
);
|
716
|
+
case 'checkbox':
|
717
|
+
return (
|
718
|
+
<Components.GenericInputSection
|
719
|
+
key={fieldId}
|
720
|
+
label={field.label}
|
721
|
+
sectionStyle={sectionStyle}
|
722
|
+
isValid={() => this.isFieldValid(field, fieldId)}
|
723
|
+
showError={this.state.showError}
|
724
|
+
required={field.mandatory}
|
725
|
+
>
|
726
|
+
{field.values.map((o, i) => {
|
727
|
+
const isActive = field.answer && _.includes(field.answer, o);
|
728
|
+
return (
|
729
|
+
<TouchableOpacity
|
730
|
+
onPress={() => this.onChangeCheckboxAnswer(fieldId, o)}
|
731
|
+
key={i}
|
732
|
+
style={styles.multiChoiceOption}
|
733
|
+
hitSlop={{ top: 8, left: 8, bottom: 8, right: 8 }}
|
734
|
+
>
|
735
|
+
{isActive ? (
|
736
|
+
<Components.TickIcon style={styles.tick} size={20} color={this.props.colourBrandingMain} />
|
737
|
+
) : (
|
738
|
+
<View style={styles.unticked} />
|
739
|
+
)}
|
740
|
+
<Text style={styles.multiChoiceText}>{o}</Text>
|
741
|
+
</TouchableOpacity>
|
742
|
+
);
|
743
|
+
})}
|
744
|
+
</Components.GenericInputSection>
|
745
|
+
);
|
746
|
+
case 'text':
|
747
|
+
case 'email':
|
748
|
+
case 'phone':
|
749
|
+
return (
|
750
|
+
<Components.GenericInputSection
|
751
|
+
key={fieldId}
|
752
|
+
label={field.label}
|
753
|
+
placeholder={field.placeHolder}
|
754
|
+
value={field.answer}
|
755
|
+
onChangeText={val => this.onChangeAnswer(fieldId, val)}
|
756
|
+
editable
|
757
|
+
squaredCorners
|
758
|
+
isValid={() => this.isFieldValid(field, fieldId)}
|
759
|
+
showError={this.state.showError}
|
760
|
+
errorText={field.type === 'email' ? 'Not a valid email' : undefined}
|
761
|
+
required={field.mandatory}
|
762
|
+
sectionStyle={sectionStyle}
|
763
|
+
autoCapitalize="sentences"
|
764
|
+
keyboardType={this.keyboardTypes[field.type]}
|
765
|
+
/>
|
766
|
+
);
|
767
|
+
case 'staticTitle':
|
768
|
+
return (
|
769
|
+
<Text key={fieldId} style={[styles.staticTitle, { color: this.props.colourBrandingMain }, sectionStyle]}>
|
770
|
+
{field.label}
|
771
|
+
</Text>
|
772
|
+
);
|
773
|
+
case 'staticText':
|
774
|
+
return (
|
775
|
+
<View key={fieldId} style={[styles.staticText, sectionStyle]}>
|
776
|
+
{Helper.toParagraphed(field.label, styles.staticText)}
|
777
|
+
</View>
|
778
|
+
);
|
779
|
+
case 'date':
|
780
|
+
case 'time':
|
781
|
+
return this.renderDateField(field, fieldId, sectionStyle);
|
782
|
+
case 'image':
|
783
|
+
return (
|
784
|
+
<Components.GenericInputSection
|
785
|
+
key={fieldId}
|
786
|
+
label={field.label}
|
787
|
+
sectionStyle={sectionStyle}
|
788
|
+
isValid={() => this.isFieldValid(field, fieldId)}
|
789
|
+
required={field.mandatory}
|
790
|
+
showError={this.state.showError}
|
791
|
+
>
|
792
|
+
{this.renderImageList(fieldId)}
|
793
|
+
</Components.GenericInputSection>
|
794
|
+
);
|
795
|
+
default:
|
796
|
+
return null;
|
797
|
+
}
|
798
|
+
}
|
799
|
+
|
800
|
+
renderCustomFields() {
|
801
|
+
const { customFields } = this.state;
|
802
|
+
if (!customFields || customFields.length === 0) return null;
|
803
|
+
|
804
|
+
return (
|
805
|
+
<Components.FormCard style={{ marginTop: 16 }}>{customFields.map((field, i) => this.renderField(field, i))}</Components.FormCard>
|
806
|
+
);
|
807
|
+
}
|
808
|
+
|
441
809
|
renderForm() {
|
810
|
+
const { customFields, loadingTypes } = this.state;
|
811
|
+
const hasCustomFields = customFields && customFields.length > 0;
|
812
|
+
|
813
|
+
if (loadingTypes) {
|
814
|
+
return <Components.Spinner />;
|
815
|
+
}
|
816
|
+
|
442
817
|
return (
|
443
818
|
<View style={{ flex: 1 }}>
|
444
819
|
<ScrollView keyboardShouldPersistTaps="always" style={{ flex: 1 }} ref={ref => (this.scrollContainer = ref)}>
|
@@ -481,7 +856,7 @@ class MaintenanceRequest extends Component {
|
|
481
856
|
}}
|
482
857
|
required
|
483
858
|
errorText="Please provide your address."
|
484
|
-
showError={this.state.showError && this.state.roomNumber
|
859
|
+
showError={this.state.showError && (!this.state.roomNumber || this.state.roomNumber.length < 2)}
|
485
860
|
/>
|
486
861
|
</Components.FormCard>
|
487
862
|
<Components.FormCard
|
@@ -499,81 +874,87 @@ class MaintenanceRequest extends Component {
|
|
499
874
|
</View>
|
500
875
|
</TouchableOpacity>
|
501
876
|
</Components.FormCard>
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
877
|
+
{hasCustomFields ? (
|
878
|
+
this.renderCustomFields()
|
879
|
+
) : (
|
880
|
+
<>
|
881
|
+
<Components.FormCard style={{ marginTop: 16 }}>
|
882
|
+
<Components.FormCardSection
|
883
|
+
label={'Title'}
|
884
|
+
placeholder={'Enter a title for your request'}
|
885
|
+
textValue={this.state.title}
|
886
|
+
onChangeText={title => this.setState({ title })}
|
887
|
+
editable={this.state.submitting === false}
|
888
|
+
hasUnderline
|
889
|
+
isValid={() => {
|
890
|
+
return this.state.title.length > 1;
|
891
|
+
}}
|
892
|
+
required
|
893
|
+
errorText="Please provide a title."
|
894
|
+
showError={this.state.showError && this.state.title.length < 2}
|
895
|
+
autoCorrect
|
896
|
+
multiline
|
897
|
+
autoGrow
|
898
|
+
/>
|
899
|
+
<Components.FormCardSection
|
900
|
+
label={'Description'}
|
901
|
+
placeholder={'Describe your request here in detail'}
|
902
|
+
textValue={this.state.description}
|
903
|
+
onChangeText={description => this.setState({ description })}
|
904
|
+
editable={this.state.submitting === false}
|
905
|
+
hasUnderline
|
906
|
+
autoCorrect
|
907
|
+
multiline
|
908
|
+
autoGrow
|
909
|
+
/>
|
910
|
+
</Components.FormCard>
|
911
|
+
<Components.FormCard style={{ marginTop: 16, paddingHorizontal: 24 }}>
|
912
|
+
<View
|
913
|
+
style={[
|
914
|
+
{
|
915
|
+
width: '100%',
|
916
|
+
paddingVertical: 16,
|
917
|
+
flexDirection: 'row',
|
918
|
+
justifyContent: 'space-between',
|
919
|
+
alignItems: 'center',
|
920
|
+
position: 'relative',
|
921
|
+
},
|
922
|
+
this.state.isHome && { borderBottomWidth: 1, borderBottomColor: Colours.LINEGREY },
|
923
|
+
]}
|
924
|
+
>
|
925
|
+
<Text style={styles.sectionTitle}>{Config.env.strings.MAINTENANCE_HOME}</Text>
|
926
|
+
<Switch
|
927
|
+
value={this.state.isHome}
|
928
|
+
disabled={this.state.submitting}
|
929
|
+
onValueChange={value => this.setState({ isHome: value })}
|
930
|
+
trackColor={{ false: '#ddd', true: this.props.colourBrandingMain }}
|
931
|
+
thumbColor={Platform.OS === 'android' ? '#fff' : null}
|
932
|
+
/>
|
933
|
+
</View>
|
934
|
+
{this.state.isHome && (
|
935
|
+
<Components.FormCardSection
|
936
|
+
label={'Available times'}
|
937
|
+
placeholder={'Describe your available times here in detail.'}
|
938
|
+
textValue={this.state.times}
|
939
|
+
onChangeText={times => this.setState({ times })}
|
940
|
+
editable={this.state.submitting === false}
|
941
|
+
hasUnderline
|
942
|
+
isValid={() => {
|
943
|
+
return this.state.times.length > 1;
|
944
|
+
}}
|
945
|
+
required
|
946
|
+
errorText="Please provide available times."
|
947
|
+
showError={this.state.showError && this.state.isHome && this.state.times.length < 2}
|
948
|
+
minHeight={40}
|
949
|
+
autoCorrect
|
950
|
+
multiline
|
951
|
+
autoGrow
|
952
|
+
/>
|
953
|
+
)}
|
954
|
+
</Components.FormCard>
|
955
|
+
{this.renderImageList()}
|
956
|
+
</>
|
957
|
+
)}
|
577
958
|
</View>
|
578
959
|
</ScrollView>
|
579
960
|
</View>
|
@@ -583,7 +964,7 @@ class MaintenanceRequest extends Component {
|
|
583
964
|
renderRegisterConfirmation() {
|
584
965
|
return (
|
585
966
|
<Components.ConfirmationPopup
|
586
|
-
confirmText={
|
967
|
+
confirmText={`${values.textEntityName} submitted`}
|
587
968
|
repeatText={'Submit another'}
|
588
969
|
visible={this.state.confirmationToShow}
|
589
970
|
onClose={this.onCloseConfirmationPopup.bind(this)}
|
@@ -606,7 +987,24 @@ class MaintenanceRequest extends Component {
|
|
606
987
|
);
|
607
988
|
}
|
608
989
|
|
990
|
+
renderNoType() {
|
991
|
+
if (!this.state.noType) {
|
992
|
+
return null;
|
993
|
+
}
|
994
|
+
return (
|
995
|
+
<Components.WarningPopup
|
996
|
+
confirmText={'No forms are available'}
|
997
|
+
infoText={'Check back later for forms.'}
|
998
|
+
visible={this.state.noType}
|
999
|
+
onClose={this.onPressBack.bind(this)}
|
1000
|
+
padHorizontal
|
1001
|
+
/>
|
1002
|
+
);
|
1003
|
+
}
|
1004
|
+
|
609
1005
|
render() {
|
1006
|
+
const { submitting, success, isDateTimePickerVisible, popUpType } = this.state;
|
1007
|
+
|
610
1008
|
return (
|
611
1009
|
<KeyboardAvoidingView behavior={Platform.OS === 'ios' && 'padding'} style={styles.viewContainer}>
|
612
1010
|
{this.renderUploadMenu()}
|
@@ -614,8 +1012,8 @@ class MaintenanceRequest extends Component {
|
|
614
1012
|
<Components.Header
|
615
1013
|
leftIcon="angle-left"
|
616
1014
|
onPressLeft={this.onPressBack.bind(this)}
|
617
|
-
text={
|
618
|
-
rightText={
|
1015
|
+
text={this.props.strings[`${values.featureKey}_textFeatureTitle`] || values.textFeatureTitle}
|
1016
|
+
rightText={submitting || success ? null : 'Done'}
|
619
1017
|
onPressRight={this.submitRequest.bind(this)}
|
620
1018
|
absoluteRight
|
621
1019
|
/>
|
@@ -623,6 +1021,14 @@ class MaintenanceRequest extends Component {
|
|
623
1021
|
</View>
|
624
1022
|
{this.renderRegisterConfirmation()}
|
625
1023
|
{this.renderVideoPlayerPopup()}
|
1024
|
+
{this.renderNoType()}
|
1025
|
+
<DateTimePicker
|
1026
|
+
isVisible={isDateTimePickerVisible}
|
1027
|
+
onConfirm={this.onDateSelected}
|
1028
|
+
onCancel={() => this.setState({ isDateTimePickerVisible: false })}
|
1029
|
+
mode={popUpType}
|
1030
|
+
headerTextIOS={`Pick a ${popUpType}`}
|
1031
|
+
/>
|
626
1032
|
</KeyboardAvoidingView>
|
627
1033
|
);
|
628
1034
|
}
|
@@ -725,6 +1131,72 @@ const styles = {
|
|
725
1131
|
alignItems: 'center',
|
726
1132
|
justifyContent: 'center',
|
727
1133
|
},
|
1134
|
+
staticTitle: {
|
1135
|
+
fontSize: 20,
|
1136
|
+
fontFamily: 'sf-semibold',
|
1137
|
+
color: Colours.TEXT_DARKEST,
|
1138
|
+
},
|
1139
|
+
staticText: {
|
1140
|
+
fontSize: 17,
|
1141
|
+
fontFamily: 'sf-regular',
|
1142
|
+
color: Colours.TEXT_DARKEST,
|
1143
|
+
lineHeight: 24,
|
1144
|
+
},
|
1145
|
+
multiChoiceOption: {
|
1146
|
+
marginTop: 16,
|
1147
|
+
flexDirection: 'row',
|
1148
|
+
alignItems: 'center',
|
1149
|
+
minHeight: 20,
|
1150
|
+
},
|
1151
|
+
multiChoiceText: {
|
1152
|
+
flex: 1,
|
1153
|
+
fontFamily: 'sf-medium',
|
1154
|
+
fontSize: 14,
|
1155
|
+
color: Colours.TEXT_DARK,
|
1156
|
+
},
|
1157
|
+
tick: {
|
1158
|
+
marginRight: 10,
|
1159
|
+
borderRadius: 4,
|
1160
|
+
},
|
1161
|
+
unticked: {
|
1162
|
+
marginRight: 10,
|
1163
|
+
width: 20,
|
1164
|
+
height: 20,
|
1165
|
+
borderColor: Colours.LINEGREY,
|
1166
|
+
borderWidth: 1,
|
1167
|
+
borderRadius: 4,
|
1168
|
+
},
|
1169
|
+
dateContainer: {
|
1170
|
+
flexDirection: 'row',
|
1171
|
+
alignItems: 'center',
|
1172
|
+
},
|
1173
|
+
dateFieldButton: {
|
1174
|
+
flex: 1,
|
1175
|
+
},
|
1176
|
+
dateFieldContainer: {
|
1177
|
+
flexDirection: 'row',
|
1178
|
+
borderRadius: 2,
|
1179
|
+
backgroundColor: '#ebeff2',
|
1180
|
+
padding: 8,
|
1181
|
+
marginTop: 8,
|
1182
|
+
},
|
1183
|
+
dateText: {
|
1184
|
+
flex: 1,
|
1185
|
+
fontFamily: 'sf-regular',
|
1186
|
+
fontSize: 16,
|
1187
|
+
color: '#65686D',
|
1188
|
+
},
|
1189
|
+
dateIcon: {
|
1190
|
+
fontSize: 18,
|
1191
|
+
color: Colours.TEXT_BLUEGREY,
|
1192
|
+
},
|
1193
|
+
dateClearButton: {
|
1194
|
+
paddingLeft: 12,
|
1195
|
+
},
|
1196
|
+
removeIcon: {
|
1197
|
+
fontSize: 26,
|
1198
|
+
color: Colours.TEXT_BLUEGREY,
|
1199
|
+
},
|
728
1200
|
};
|
729
1201
|
|
730
1202
|
const mapStateToProps = state => {
|
@@ -740,6 +1212,7 @@ const mapStateToProps = state => {
|
|
740
1212
|
unit,
|
741
1213
|
phoneNumber,
|
742
1214
|
colourBrandingMain: Colours.getMainBrandingColourFromState(state),
|
1215
|
+
strings: state.strings?.config || {},
|
743
1216
|
};
|
744
1217
|
};
|
745
1218
|
|