@plusscommunities/pluss-maintenance-app-forms 7.0.21 → 8.0.1-auth.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.
Files changed (58) hide show
  1. package/dist/module/apis/maintenanceActions.js +12 -4
  2. package/dist/module/apis/maintenanceActions.js.map +1 -1
  3. package/dist/module/components/FilterPopupMenu.js +30 -14
  4. package/dist/module/components/FilterPopupMenu.js.map +1 -1
  5. package/dist/module/components/MaintenanceList.js +199 -25
  6. package/dist/module/components/MaintenanceList.js.map +1 -1
  7. package/dist/module/components/MaintenanceListItem.js +2 -1
  8. package/dist/module/components/MaintenanceListItem.js.map +1 -1
  9. package/dist/module/components/MaintenanceWidgetItem.js +2 -1
  10. package/dist/module/components/MaintenanceWidgetItem.js.map +1 -1
  11. package/dist/module/components/PrioritySelectorPopup.js +2 -1
  12. package/dist/module/components/PrioritySelectorPopup.js.map +1 -1
  13. package/dist/module/components/StatusSelectorPopup.js +2 -1
  14. package/dist/module/components/StatusSelectorPopup.js.map +1 -1
  15. package/dist/module/components/WidgetSmall.js +5 -4
  16. package/dist/module/components/WidgetSmall.js.map +1 -1
  17. package/dist/module/core.config.js +1 -2
  18. package/dist/module/core.config.js.map +1 -1
  19. package/dist/module/screens/JobTypePicker.js +2 -1
  20. package/dist/module/screens/JobTypePicker.js.map +1 -1
  21. package/dist/module/screens/MaintenanceUserPicker.js +73 -91
  22. package/dist/module/screens/MaintenanceUserPicker.js.map +1 -1
  23. package/dist/module/screens/RequestDetail.js +76 -29
  24. package/dist/module/screens/RequestDetail.js.map +1 -1
  25. package/dist/module/screens/RequestNotes.js +11 -7
  26. package/dist/module/screens/RequestNotes.js.map +1 -1
  27. package/dist/module/screens/ServiceRequest.js +43 -42
  28. package/dist/module/screens/ServiceRequest.js.map +1 -1
  29. package/dist/module/values.config.a.js +1 -2
  30. package/dist/module/values.config.a.js.map +1 -1
  31. package/dist/module/values.config.default.js +1 -2
  32. package/dist/module/values.config.default.js.map +1 -1
  33. package/dist/module/values.config.enquiry.js +1 -2
  34. package/dist/module/values.config.enquiry.js.map +1 -1
  35. package/dist/module/values.config.feedback.js +1 -2
  36. package/dist/module/values.config.feedback.js.map +1 -1
  37. package/dist/module/values.config.food.js +1 -2
  38. package/dist/module/values.config.food.js.map +1 -1
  39. package/package.json +18 -14
  40. package/src/apis/maintenanceActions.js +17 -7
  41. package/src/components/FilterPopupMenu.js +67 -40
  42. package/src/components/MaintenanceList.js +234 -40
  43. package/src/components/MaintenanceListItem.js +2 -1
  44. package/src/components/MaintenanceWidgetItem.js +2 -1
  45. package/src/components/PrioritySelectorPopup.js +2 -1
  46. package/src/components/StatusSelectorPopup.js +2 -1
  47. package/src/components/WidgetSmall.js +12 -4
  48. package/src/core.config.js +0 -2
  49. package/src/screens/JobTypePicker.js +2 -1
  50. package/src/screens/MaintenanceUserPicker.js +77 -114
  51. package/src/screens/RequestDetail.js +88 -32
  52. package/src/screens/RequestNotes.js +17 -10
  53. package/src/screens/ServiceRequest.js +85 -44
  54. package/src/values.config.a.js +0 -1
  55. package/src/values.config.default.js +0 -1
  56. package/src/values.config.enquiry.js +0 -1
  57. package/src/values.config.feedback.js +0 -1
  58. package/src/values.config.food.js +0 -1
@@ -1,45 +1,26 @@
1
1
  import React, { Component } from "react";
2
+ import { Text } from "@plusscommunities/pluss-core-app/components";
2
3
  import _ from "lodash";
3
4
  import {
4
5
  TouchableOpacity,
5
6
  View,
6
7
  ScrollView,
7
- Text,
8
8
  TextInput,
9
+ Keyboard,
9
10
  } from "react-native";
10
11
  import { connect } from "react-redux";
11
12
  import { Icon } from "@rneui/themed";
12
13
  import { Services } from "../feature.config";
13
- import { Components, Colours, Fonts } from "../core.config";
14
+ import { Components, Colours } from "../core.config";
14
15
 
15
16
  class MaintenanceUserPicker extends Component {
16
17
  state = {
17
18
  currentUser: null,
18
19
  searchText: "",
19
- filteredUsers: [],
20
20
  };
21
21
 
22
22
  UNSAFE_componentWillMount() {
23
- this.setState({
24
- currentUser: this.props.currentUser,
25
- filteredUsers: this.props.users || [],
26
- });
27
- }
28
-
29
- UNSAFE_componentWillReceiveProps(nextProps) {
30
- if (nextProps.users !== this.props.users) {
31
- this.setState({
32
- filteredUsers: this.getFilteredUsers(
33
- this.state.searchText,
34
- nextProps.users,
35
- ),
36
- });
37
- }
38
- if (nextProps.currentUser !== this.props.currentUser) {
39
- this.setState({
40
- currentUser: nextProps.currentUser,
41
- });
42
- }
23
+ this.setState({ currentUser: this.props.currentUser });
43
24
  }
44
25
 
45
26
  onPressBack() {
@@ -47,6 +28,7 @@ class MaintenanceUserPicker extends Component {
47
28
  }
48
29
 
49
30
  onUserPress(user) {
31
+ Keyboard.dismiss();
50
32
  this.props.onSelectUser(user);
51
33
  this.setState({ currentUser: user });
52
34
  setTimeout(() => {
@@ -55,94 +37,48 @@ class MaintenanceUserPicker extends Component {
55
37
  }
56
38
 
57
39
  onChangeSearch = (text) => {
58
- this.setState({
59
- searchText: text,
60
- filteredUsers: this.getFilteredUsers(text),
61
- });
40
+ this.setState({ searchText: text });
62
41
  };
63
42
 
64
- getFilteredUsers = (searchText, users) => {
65
- const usersList = users || this.props.users || [];
66
-
67
- if (!searchText || searchText.length === 0) {
68
- return usersList;
69
- }
70
-
71
- if (!usersList || usersList.length === 0) {
72
- return [];
73
- }
74
-
75
- return usersList.filter((user) => {
76
- const displayName = user.displayName || "";
77
- const unit = user.unit || "";
78
- const searchLower = searchText.toLowerCase();
79
-
80
- return (
81
- displayName.toLowerCase().includes(searchLower) ||
82
- unit.toLowerCase().includes(searchLower)
83
- );
43
+ getFilteredUsers = () => {
44
+ const { searchText } = this.state;
45
+ const { users } = this.props;
46
+ if (!users) return [];
47
+ if (!searchText || searchText.length === 0) return users;
48
+ const searchLower = searchText.toLowerCase();
49
+ return users.filter((user) => {
50
+ const displayName = (user.displayName || "").toLowerCase();
51
+ const unit = (user.unit || "").toLowerCase();
52
+ return displayName.includes(searchLower) || unit.includes(searchLower);
84
53
  });
85
54
  };
86
55
 
87
- renderSearch = () => {
88
- return (
89
- <View style={styles.searchContainer}>
90
- <Fonts.PlIcon name="nav-search" style={styles.searchIcon} />
91
- <TextInput
92
- placeholder="Search by name or unit"
93
- autoCorrect={false}
94
- placeholderTextColor={"rgba(60, 60, 80, .1)"}
95
- onChangeText={this.onChangeSearch}
96
- value={this.state.searchText}
97
- style={styles.searchText}
98
- underlineColorAndroid={"rgba(0,0,0,0)"}
99
- returnKeyType="search"
100
- />
101
- {this.state.searchText.length > 0 && (
102
- <TouchableOpacity
103
- onPress={() => this.onChangeSearch("")}
104
- style={styles.clearButton}
105
- >
106
- <Icon
107
- name="times-circle"
108
- type="font-awesome"
109
- iconStyle={styles.clearIcon}
110
- />
111
- </TouchableOpacity>
112
- )}
113
- </View>
114
- );
115
- };
116
-
117
56
  renderMain() {
118
57
  if (_.isEmpty(this.props.users)) {
119
58
  return (
120
- <View style={{ marginTop: 16 }}>
59
+ <View style={{ marginTop: 8 }}>
121
60
  <Components.Spinner />
122
61
  </View>
123
62
  );
124
63
  }
125
64
 
126
- return (
127
- <Components.FormCard style={{ marginTop: 16 }}>
128
- {this.renderOptions()}
129
- </Components.FormCard>
130
- );
131
- }
132
-
133
- renderOptions() {
134
- const users = this.state.filteredUsers;
135
-
136
- if (users.length === 0 && this.state.searchText.length > 0) {
65
+ const filteredUsers = this.getFilteredUsers();
66
+ if (filteredUsers.length === 0 && this.state.searchText.length > 0) {
137
67
  return (
138
68
  <View style={styles.noResultsContainer}>
139
- <Text style={styles.noResultsText}>
140
- No users found matching "{this.state.searchText}"
141
- </Text>
69
+ <Text style={styles.noResultsText}>No users found</Text>
142
70
  </View>
143
71
  );
144
72
  }
145
73
 
74
+ return (
75
+ <Components.FormCard style={{ marginTop: 8 }}>
76
+ {this.renderOptions(filteredUsers)}
77
+ </Components.FormCard>
78
+ );
79
+ }
80
+
81
+ renderOptions(users) {
146
82
  return users.map((user, index) => {
147
83
  return (
148
84
  <TouchableOpacity
@@ -180,6 +116,36 @@ class MaintenanceUserPicker extends Component {
180
116
  });
181
117
  }
182
118
 
119
+ renderSearch() {
120
+ return (
121
+ <View style={styles.searchContainer}>
122
+ <Icon name="search" type="font-awesome" iconStyle={styles.searchIcon} />
123
+ <TextInput
124
+ placeholder="Search by name or address"
125
+ autoCorrect={false}
126
+ placeholderTextColor={Colours.TEXT_MID_ALPHA50}
127
+ onChangeText={this.onChangeSearch}
128
+ value={this.state.searchText}
129
+ style={styles.searchText}
130
+ underlineColorAndroid={Colours.COLOUR_TRANSPARENT}
131
+ returnKeyType="search"
132
+ />
133
+ {this.state.searchText.length > 0 && (
134
+ <TouchableOpacity
135
+ onPress={() => this.onChangeSearch("")}
136
+ style={styles.clearButton}
137
+ >
138
+ <Icon
139
+ name="times-circle"
140
+ type="font-awesome"
141
+ iconStyle={styles.clearIcon}
142
+ />
143
+ </TouchableOpacity>
144
+ )}
145
+ </View>
146
+ );
147
+ }
148
+
183
149
  render() {
184
150
  return (
185
151
  <View style={styles.container}>
@@ -189,7 +155,13 @@ class MaintenanceUserPicker extends Component {
189
155
  text="Select user"
190
156
  />
191
157
  {this.renderSearch()}
192
- <ScrollView style={{ flex: 1 }}>{this.renderMain()}</ScrollView>
158
+ <ScrollView
159
+ style={{ flex: 1 }}
160
+ keyboardShouldPersistTaps="handled"
161
+ keyboardDismissMode="on-drag"
162
+ >
163
+ {this.renderMain()}
164
+ </ScrollView>
193
165
  </View>
194
166
  );
195
167
  }
@@ -201,17 +173,6 @@ const styles = {
201
173
  position: "relative",
202
174
  backgroundColor: "#f0f0f5",
203
175
  },
204
- row: {
205
- flexDirection: "row",
206
- alignItems: "center",
207
- minHeight: 22,
208
- },
209
- text: {
210
- flex: 1,
211
- fontFamily: "sf-regular",
212
- fontSize: 14,
213
- color: Colours.TEXT_DARK,
214
- },
215
176
  rowContainer: {
216
177
  flexDirection: "row",
217
178
  justifyContent: "space-between",
@@ -229,32 +190,34 @@ const styles = {
229
190
  searchContainer: {
230
191
  flexDirection: "row",
231
192
  alignItems: "center",
232
- paddingHorizontal: 16,
233
- paddingVertical: 12,
193
+ marginHorizontal: 15,
194
+ marginTop: 10,
195
+ marginBottom: 0,
234
196
  backgroundColor: "#fff",
235
- borderBottomWidth: 1,
236
- borderBottomColor: "#f0f0f5",
197
+ borderRadius: 8,
198
+ paddingHorizontal: 12,
199
+ paddingVertical: 8,
237
200
  },
238
201
  searchIcon: {
239
- fontSize: 20,
202
+ fontSize: 16,
240
203
  marginRight: 10,
241
- color: "rgba(90, 90, 110, .5)",
204
+ color: Colours.TEXT_MID_ALPHA50,
242
205
  },
243
206
  searchText: {
244
207
  flex: 1,
245
208
  fontSize: 16,
246
209
  fontFamily: "sf-regular",
247
210
  color: Colours.TEXT_DARK,
211
+ padding: 0,
248
212
  },
249
213
  clearButton: {
250
- padding: 8,
214
+ padding: 4,
251
215
  },
252
216
  clearIcon: {
253
- fontSize: 18,
254
- color: "rgba(90, 90, 110, .5)",
217
+ fontSize: 16,
218
+ color: Colours.TEXT_MID_ALPHA50,
255
219
  },
256
220
  noResultsContainer: {
257
- flex: 1,
258
221
  alignItems: "center",
259
222
  justifyContent: "center",
260
223
  paddingVertical: 40,
@@ -1,9 +1,9 @@
1
1
  import React, { Component } from "react";
2
+ import { Text } from "@plusscommunities/pluss-core-app/components";
2
3
  import {
3
4
  ScrollView,
4
5
  View,
5
6
  StyleSheet,
6
- Text,
7
7
  KeyboardAvoidingView,
8
8
  TouchableOpacity,
9
9
  ImageBackground,
@@ -40,6 +40,7 @@ class RequestDetail extends Component {
40
40
  showStatusPopup: false,
41
41
  showPriorityPopup: false,
42
42
  loading: false,
43
+ loadError: false,
43
44
  showFullscreenVideo: false,
44
45
  currentVideoUrl: "",
45
46
  galleryOpen: false,
@@ -54,6 +55,7 @@ class RequestDetail extends Component {
54
55
  this.scrollView = React.createRef();
55
56
  this.commentReply = React.createRef();
56
57
  this.commentSection = React.createRef();
58
+ this.imagePopup = React.createRef();
57
59
  }
58
60
 
59
61
  componentDidMount() {
@@ -66,26 +68,45 @@ class RequestDetail extends Component {
66
68
  }
67
69
 
68
70
  getJob = async () => {
69
- this.setState({ loading: true }, async () => {
71
+ this.setState({ loading: true, loadError: false }, async () => {
72
+ // Timeout fallback: if API doesn't respond in 15s, show error
73
+ const timeoutId = setTimeout(() => {
74
+ if (this.state.loading) {
75
+ this.setState({ loading: false, loadError: true });
76
+ }
77
+ }, 15000);
78
+
70
79
  try {
71
80
  const res = await maintenanceActions.getJob(
72
81
  this.props.job.site,
73
82
  this.props.job.id,
74
83
  );
75
84
  // console.log('getJob', JSON.stringify(res.data, null, 2));
76
- this.props.jobAdded(res.data);
77
- this.updateJobState(res.data);
78
- // Refresh external sync data when job is refreshed
79
- this.getExternalSync();
85
+ clearTimeout(timeoutId);
86
+ if (!this.state.loadError) {
87
+ this.props.jobAdded(res.data);
88
+ this.updateJobState(res.data);
89
+ // Refresh external sync data when job is refreshed
90
+ this.getExternalSync();
91
+ }
80
92
  } catch (error) {
93
+ clearTimeout(timeoutId);
81
94
  console.log("getJob error", error.toString());
82
- // check for 403 or 404 error
83
- if (error.response.status === 403 || error.response.status === 404) {
95
+ // Log full error details for debugging
96
+ console.log("getJob error details:", {
97
+ message: error.message,
98
+ code: error.code,
99
+ responseStatus: error.response?.status,
100
+ responseData: error.response?.data,
101
+ });
102
+ // check for 403 or 404 error (use optional chaining to prevent crash)
103
+ if (error.response?.status === 403 || error.response?.status === 404) {
84
104
  this.setState({
85
105
  forbidden: true,
86
106
  });
107
+ } else {
108
+ this.setState({ loadError: true });
87
109
  }
88
- console.log("getJob error", error);
89
110
  } finally {
90
111
  this.setState({ loading: false });
91
112
  }
@@ -157,7 +178,6 @@ class RequestDetail extends Component {
157
178
  const res = await maintenanceActions.editJob(updated, user.site);
158
179
  // console.log('markSeen updated');
159
180
  this.props.jobAdded(res.data.job);
160
- this.getJob();
161
181
  this.setState({ loading: false, seen: true });
162
182
  } catch (error) {
163
183
  console.log("markSeen error", error);
@@ -319,6 +339,14 @@ class RequestDetail extends Component {
319
339
  });
320
340
  };
321
341
 
342
+ openGallery(galleryImages, index) {
343
+ this.setState({
344
+ galleryOpen: true,
345
+ galleryImages,
346
+ });
347
+ this.imagePopup.current.scrollTo(index);
348
+ }
349
+
322
350
  hasPermission = () => {
323
351
  const { job } = this.state;
324
352
  const { permissions } = this.props.user;
@@ -339,14 +367,6 @@ class RequestDetail extends Component {
339
367
  });
340
368
  };
341
369
 
342
- openGallery(galleryImages, index) {
343
- this.setState({
344
- galleryOpen: true,
345
- galleryImages,
346
- });
347
- this.refs.imagePopup.scrollTo(index);
348
- }
349
-
350
370
  closeGallery() {
351
371
  this.setState({
352
372
  galleryOpen: false,
@@ -400,13 +420,16 @@ class RequestDetail extends Component {
400
420
  <View style={styles.jobTitleContainer}>
401
421
  {job.jobId ? (
402
422
  <Text
423
+ maxFontSizeMultiplier={1.5}
403
424
  style={[
404
425
  styles.jobIdText,
405
426
  { color: this.props.colourBrandingMain },
406
427
  ]}
407
428
  >{`${values.textEntityName} #${job.jobId}`}</Text>
408
429
  ) : null}
409
- <Text style={styles.jobTitleText}>{job.title}</Text>
430
+ <Text style={styles.jobTitleText} maxFontSizeMultiplier={1.4}>
431
+ {job.title}
432
+ </Text>
410
433
  <View style={styles.jobTypeSeenContainer}>
411
434
  <View
412
435
  style={[
@@ -453,7 +476,9 @@ class RequestDetail extends Component {
453
476
 
454
477
  {job.lastActivityUnix && (
455
478
  <View style={styles.textSectionInner}>
456
- <Text style={styles.textSectionLabel}>Last Updated On</Text>
479
+ <Text style={styles.textSectionLabel} maxFontSizeMultiplier={1.5}>
480
+ Last Updated On
481
+ </Text>
457
482
  <View style={styles.textSectionTextContainer}>
458
483
  <Text style={styles.textSectionText}>
459
484
  {moment(job.lastActivityUnix).format("ddd D MMMM, h:mm A")}
@@ -478,7 +503,9 @@ class RequestDetail extends Component {
478
503
  <View style={styles.jobInfoContainer}>
479
504
  <View style={styles.jobStatusExpectedContainer}>
480
505
  <View style={styles.jobStatusOuterContainer}>
481
- <Text style={styles.jobStatusHeading}>STATUS</Text>
506
+ <Text style={styles.jobStatusHeading} maxFontSizeMultiplier={1.5}>
507
+ STATUS
508
+ </Text>
482
509
  <TouchableOpacity
483
510
  onPress={canEdit ? this.onOpenStatusPicker : null}
484
511
  >
@@ -488,7 +515,12 @@ class RequestDetail extends Component {
488
515
  { backgroundColor: statusOption.color },
489
516
  ]}
490
517
  >
491
- <Text style={styles.jobStatusText}>{statusOption?.text}</Text>
518
+ <Text
519
+ style={styles.jobStatusText}
520
+ maxFontSizeMultiplier={1.4}
521
+ >
522
+ {statusOption?.text}
523
+ </Text>
492
524
  </View>
493
525
  </TouchableOpacity>
494
526
  </View>
@@ -656,7 +688,7 @@ class RequestDetail extends Component {
656
688
  visible={this.state.galleryOpen}
657
689
  images={this.state.galleryImages}
658
690
  onClose={this.closeGallery.bind(this)}
659
- ref="imagePopup"
691
+ ref={this.imagePopup}
660
692
  />
661
693
  );
662
694
  }
@@ -770,7 +802,7 @@ class RequestDetail extends Component {
770
802
  switch (field.type) {
771
803
  case "date":
772
804
  return (
773
- <Text style={styles.customText}>
805
+ <Text style={styles.customText} maxFontSizeMultiplier={1.5}>
774
806
  {field.answer
775
807
  ? moment(field.answer, "YYYY-MM-DD").format("DD MMM YYYY")
776
808
  : ""}
@@ -778,7 +810,7 @@ class RequestDetail extends Component {
778
810
  );
779
811
  case "time":
780
812
  return (
781
- <Text style={styles.customText}>
813
+ <Text style={styles.customText} maxFontSizeMultiplier={1.5}>
782
814
  {field.answer
783
815
  ? moment(field.answer, "HH:mm").format("h:mm a")
784
816
  : ""}
@@ -786,11 +818,13 @@ class RequestDetail extends Component {
786
818
  );
787
819
  case "yn":
788
820
  return (
789
- <Text style={styles.customText}>{field.answer ? "Yes" : "No"}</Text>
821
+ <Text style={styles.customText} maxFontSizeMultiplier={1.5}>
822
+ {field.answer ? "Yes" : "No"}
823
+ </Text>
790
824
  );
791
825
  case "checkbox":
792
826
  return (
793
- <Text style={styles.customText}>
827
+ <Text style={styles.customText} maxFontSizeMultiplier={1.5}>
794
828
  {field.answer && Array.isArray(field.answer)
795
829
  ? field.answer.join(", ")
796
830
  : ""}
@@ -809,7 +843,11 @@ class RequestDetail extends Component {
809
843
  </View>
810
844
  );
811
845
  default:
812
- return <Text style={styles.customText}>{field.answer}</Text>;
846
+ return (
847
+ <Text style={styles.customText} maxFontSizeMultiplier={1.5}>
848
+ {field.answer}
849
+ </Text>
850
+ );
813
851
  }
814
852
  };
815
853
 
@@ -823,7 +861,9 @@ class RequestDetail extends Component {
823
861
  return null;
824
862
  return (
825
863
  <View key={index}>
826
- <Text style={styles.customLabel}>{field.label}</Text>
864
+ <Text style={styles.customLabel} maxFontSizeMultiplier={1.5}>
865
+ {field.label}
866
+ </Text>
827
867
  {renderAnswer(field)}
828
868
  </View>
829
869
  );
@@ -851,14 +891,21 @@ class RequestDetail extends Component {
851
891
  <>
852
892
  {this.renderImage(job.images, job.image)}
853
893
  {!_.isEmpty(job.description) && (
854
- <Text numberOfLines={10} style={styles.jobDescriptionText}>
894
+ <Text
895
+ style={styles.jobDescriptionText}
896
+ maxFontSizeMultiplier={1.5}
897
+ >
855
898
  {job.description}
856
899
  </Text>
857
900
  )}
858
901
  </>
859
902
  ) : null}
860
- <Text style={styles.locationLabel}>Address</Text>
861
- <Text style={styles.locationText}>{job.room}</Text>
903
+ <Text style={styles.locationLabel} maxFontSizeMultiplier={1.5}>
904
+ Address
905
+ </Text>
906
+ <Text style={styles.locationText} maxFontSizeMultiplier={1.5}>
907
+ {job.room}
908
+ </Text>
862
909
  {!hasCustomFields && job.isHome ? (
863
910
  <View style={styles.detailsSection}>
864
911
  <Text style={styles.locationLabel}>Must be home</Text>
@@ -964,6 +1011,14 @@ class RequestDetail extends Component {
964
1011
  if (this.state.forbidden) {
965
1012
  return <Components.Forbidden />;
966
1013
  }
1014
+ if (this.state.loadError) {
1015
+ return (
1016
+ <Components.Forbidden
1017
+ title="Something went wrong"
1018
+ description="Failed to load this request. Please check your connection and try again."
1019
+ />
1020
+ );
1021
+ }
967
1022
  return (
968
1023
  <KeyboardAvoidingView behavior={"padding"} style={styles.container}>
969
1024
  <Components.Header
@@ -995,6 +1050,7 @@ class RequestDetail extends Component {
995
1050
  onCancel={this.onCloseDatePicker}
996
1051
  mode={this.state.popUpType}
997
1052
  headerTextIOS={`Pick a ${this.state.popUpType}`}
1053
+ date={new Date()}
998
1054
  />
999
1055
  </KeyboardAvoidingView>
1000
1056
  );
@@ -1,8 +1,8 @@
1
1
  import React, { Component } from "react";
2
+ import { Text } from "@plusscommunities/pluss-core-app/components";
2
3
  import {
3
4
  ScrollView,
4
5
  View,
5
- Text,
6
6
  TouchableOpacity,
7
7
  Modal,
8
8
  KeyboardAvoidingView,
@@ -18,7 +18,7 @@ import _ from "lodash";
18
18
  import moment from "moment";
19
19
  import { jobAdded } from "../actions";
20
20
  import { maintenanceActions } from "../apis";
21
- import { getBottomSpace } from "react-native-iphone-x-helper";
21
+ import { withSafeAreaInsets } from "react-native-safe-area-context";
22
22
  import { Services } from "../feature.config";
23
23
  import { Components, Colours, Helper } from "../core.config";
24
24
  import { values } from "../values.config";
@@ -724,9 +724,7 @@ class RequestNotes extends Component {
724
724
  style={styles.scrollContainer}
725
725
  contentContainerStyle={styles.innerContainer}
726
726
  >
727
- <Components.TextStyle type="pageHeading">
728
- Add Staff Note
729
- </Components.TextStyle>
727
+ <Components.Text type="pageHeading">Add Staff Note</Components.Text>
730
728
  <Components.GenericInputSection
731
729
  label="Content"
732
730
  placeholder="Insert your notes here..."
@@ -754,13 +752,20 @@ class RequestNotes extends Component {
754
752
  this.renderAttachment(a, i),
755
753
  )
756
754
  ) : (
757
- <Components.TextStyle type="body" style={styles.attachmentInfo}>
755
+ <Components.Text type="body" style={styles.attachmentInfo}>
758
756
  PDFs can only be attached to notes from the Community Manager.
759
- </Components.TextStyle>
757
+ </Components.Text>
760
758
  )}
761
759
  </Components.GenericInputSection>
762
760
  </ScrollView>
763
- <View style={styles.popupFooter}>{this.renderFooterContent()}</View>
761
+ <View
762
+ style={[
763
+ styles.popupFooter,
764
+ { paddingBottom: (this.props.insets?.bottom ?? 0) + 16 },
765
+ ]}
766
+ >
767
+ {this.renderFooterContent()}
768
+ </View>
764
769
  {this.renderVideoPlayerPopup()}
765
770
  </KeyboardAvoidingView>
766
771
  </Modal>
@@ -805,7 +810,7 @@ const styles = {
805
810
  },
806
811
  popupFooter: {
807
812
  paddingHorizontal: 16,
808
- paddingBottom: getBottomSpace() + 16,
813
+ paddingBottom: 16, // bottom inset added dynamically
809
814
  },
810
815
  noteContainer: {
811
816
  ...Helper.getShadowStyle(),
@@ -955,4 +960,6 @@ const mapStateToProps = (state) => {
955
960
  };
956
961
  };
957
962
 
958
- export default connect(mapStateToProps, { jobAdded })(RequestNotes);
963
+ export default connect(mapStateToProps, { jobAdded })(
964
+ withSafeAreaInsets(RequestNotes),
965
+ );