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