@eohjsc/react-native-smart-city 0.2.83 → 0.2.86

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 (90) hide show
  1. package/assets/images/Device/button-lock.svg +3 -0
  2. package/assets/images/Device/button-unlock.svg +3 -0
  3. package/assets/images/Event.svg +9 -0
  4. package/assets/images/brightness.svg +12 -0
  5. package/package.json +4 -2
  6. package/src/Images/Common/SuccessfullyConnected.svg +4 -0
  7. package/src/Images/Common/eye-closed.png +0 -0
  8. package/src/Images/Common/eye-closed@2x.png +0 -0
  9. package/src/Images/Common/eye-closed@3x.png +0 -0
  10. package/src/Images/Common/eye.png +0 -0
  11. package/src/Images/Common/eye@2x.png +0 -0
  12. package/src/Images/Common/eye@3x.png +0 -0
  13. package/src/commons/ActionGroup/LightActionTemplate.js +103 -0
  14. package/src/commons/ActionGroup/LightActionTemplateStyles.js +57 -0
  15. package/src/commons/ActionGroup/OnOffSmartLock.js +48 -0
  16. package/src/commons/ActionGroup/OnOffSmartLockStyle.js +51 -0
  17. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +33 -31
  18. package/src/commons/ActionGroup/__test__/LightActionTemplate.test.js +59 -0
  19. package/src/commons/ActionGroup/index.js +6 -0
  20. package/src/commons/Automate/ItemAutomate.js +1 -1
  21. package/src/commons/Automate/ItemAutomateStyles.js +5 -1
  22. package/src/commons/CardShadow/index.js +5 -2
  23. package/src/commons/CardShadow/styles.js +2 -3
  24. package/src/commons/ConnectingProcess/DeviceItem/DeviceItem.js +16 -0
  25. package/src/commons/ConnectingProcess/DeviceItem/DeviceItemStyles.js +42 -0
  26. package/src/commons/ConnectingProcess/__test__/Connecting.test.js +27 -0
  27. package/src/commons/ConnectingProcess/__test__/DeviceItem.test.js +18 -0
  28. package/src/commons/ConnectingProcess/index.js +205 -0
  29. package/src/commons/ConnectingProcess/styles.js +69 -0
  30. package/src/commons/Device/ItemDevice.js +8 -3
  31. package/src/commons/Device/LinearChart.js +1 -0
  32. package/src/commons/Device/WaterQualitySensor/ListQualityIndicator.js +1 -1
  33. package/src/commons/Device/WaterQualitySensor/QualityIndicatorsItem.js +1 -1
  34. package/src/commons/Form/TextInputPassword.js +1 -1
  35. package/src/commons/FullLoading/index.js +35 -0
  36. package/src/commons/MediaPlayer/__test__/index.test.js +45 -0
  37. package/src/commons/SubUnit/OneTap/ItemOneTap.js +3 -0
  38. package/src/commons/SubUnit/ShortDetail.js +10 -22
  39. package/src/commons/SubUnit/__test__/ShortDetail.test.js +57 -48
  40. package/src/commons/index.js +2 -0
  41. package/src/configs/API.js +6 -2
  42. package/src/configs/Constants.js +36 -0
  43. package/src/configs/Images.js +2 -0
  44. package/src/context/actionType.ts +2 -0
  45. package/src/context/reducer.ts +10 -0
  46. package/src/hooks/Common/useBlockBackAndroid.js +3 -1
  47. package/src/navigations/AddDeviceStack.js +10 -0
  48. package/src/screens/ActivityLog/hooks/index.js +18 -4
  49. package/src/screens/ActivityLog/index.js +3 -0
  50. package/src/screens/AddCommon/SelectSubUnit.js +30 -6
  51. package/src/screens/AddCommon/SelectUnit.js +24 -2
  52. package/src/screens/AddCommon/__test__/SelectSubUnit.test.js +120 -1
  53. package/src/screens/AddCommon/__test__/SelectUnit.test.js +16 -1
  54. package/src/screens/AddNewAction/SelectAction.js +46 -28
  55. package/src/screens/AddNewAction/SelectSensorDevices.js +4 -2
  56. package/src/screens/AddNewAutoSmart/__test__/AddNewAutoSmart.test.js +3 -3
  57. package/src/screens/AddNewAutoSmart/index.js +18 -1
  58. package/src/screens/AddNewGateway/PlugAndPlay/ConnectWifiWarning.js +63 -16
  59. package/src/screens/AddNewGateway/PlugAndPlay/FirstWarning.js +4 -2
  60. package/src/screens/AddNewGateway/PlugAndPlay/GatewayWifiList.js +52 -23
  61. package/src/screens/AddNewGateway/SelectGateway.js +132 -0
  62. package/src/screens/AddNewGateway/SelectGatewayStyles.js +55 -0
  63. package/src/screens/AddNewGateway/__test__/SetupGateway.test.js +0 -52
  64. package/src/screens/AddNewOneTap/index.js +32 -17
  65. package/src/screens/Automate/index.js +2 -2
  66. package/src/screens/Device/EditDevice/index.js +5 -3
  67. package/src/screens/Device/components/SensorDisplayItem.js +3 -0
  68. package/src/screens/Device/detail.js +7 -6
  69. package/src/screens/Device/styles.js +2 -0
  70. package/src/screens/Notification/__test__/NotificationItem.test.js +27 -5
  71. package/src/screens/Notification/components/NotificationItem.js +112 -20
  72. package/src/screens/ScanChipQR/__test__/ScanChipQR.test.js +11 -7
  73. package/src/screens/ScanChipQR/hooks/index.js +78 -24
  74. package/src/screens/ScriptDetail/index.js +1 -6
  75. package/src/screens/SelectUnit/index.js +1 -0
  76. package/src/screens/SharedUnit/index.js +1 -1
  77. package/src/screens/SmartIr/__test__/SmartIr.test.js +61 -0
  78. package/src/screens/SmartIr/index.js +23 -0
  79. package/src/screens/SmartIr/styles.js +14 -0
  80. package/src/screens/Unit/AddMenu.js +4 -1
  81. package/src/screens/Unit/Detail.js +24 -2
  82. package/src/screens/Unit/ManageUnit.js +1 -1
  83. package/src/screens/Unit/ManageUnitStyles.js +0 -6
  84. package/src/screens/Unit/SmartAccount.js +5 -1
  85. package/src/screens/UnitSummary/components/PowerConsumeHistoryChart/__test__/index.test.js +32 -1
  86. package/src/screens/UnitSummary/components/PowerConsumeHistoryChart/index.js +1 -1
  87. package/src/utils/Apis/axios.js +1 -1
  88. package/src/utils/I18n/translations/en.json +18 -2
  89. package/src/utils/I18n/translations/vi.json +18 -3
  90. package/src/utils/Route/index.js +3 -0
@@ -7,7 +7,7 @@ import styles from '../styles/NotificationItemStyles';
7
7
  import Text from '../../../commons/Text';
8
8
  import { Colors, API, Images } from '../../../configs';
9
9
  import IconComponent from '../../../commons/IconComponent';
10
- import { NOTIFICATION_TYPES } from '../../../configs/Constants';
10
+ import { NOTIFICATION_TYPES, SENSOR_TYPE } from '../../../configs/Constants';
11
11
  import { useTranslations } from '../../../hooks/Common/useTranslations';
12
12
  import { axiosPost } from '../../../utils/Apis/axios';
13
13
  import Routes from '../../../utils/Route';
@@ -80,7 +80,7 @@ const NotificationItem = memo(({ item }) => {
80
80
  ),
81
81
  redirect: () =>
82
82
  navigation.navigate(Routes.SmartParkingStack, {
83
- screens: Routes.SmartParkingBookingDetails,
83
+ screen: Routes.SmartParkingBookingDetails,
84
84
  params: { id: booking_id },
85
85
  }),
86
86
  };
@@ -93,7 +93,7 @@ const NotificationItem = memo(({ item }) => {
93
93
  ),
94
94
  redirect: () =>
95
95
  navigation.navigate(Routes.SmartParkingStack, {
96
- screens: Routes.SmartParkingBookingDetails,
96
+ screen: Routes.SmartParkingBookingDetails,
97
97
  params: { id: booking_id },
98
98
  }),
99
99
  };
@@ -105,7 +105,7 @@ const NotificationItem = memo(({ item }) => {
105
105
  ),
106
106
  redirect: () =>
107
107
  navigation.navigate(Routes.SmartParkingStack, {
108
- screens: Routes.SmartParkingBookingDetails,
108
+ screen: Routes.SmartParkingBookingDetails,
109
109
  params: { id: booking_id },
110
110
  }),
111
111
  };
@@ -117,7 +117,7 @@ const NotificationItem = memo(({ item }) => {
117
117
  ),
118
118
  redirect: () =>
119
119
  navigation.navigate(Routes.SmartParkingStack, {
120
- screens: Routes.MyBookingList,
120
+ screen: Routes.MyBookingList,
121
121
  params: { tab: 1 },
122
122
  }),
123
123
  };
@@ -129,7 +129,7 @@ const NotificationItem = memo(({ item }) => {
129
129
  ),
130
130
  redirect: () =>
131
131
  navigation.navigate(Routes.SmartParkingStack, {
132
- screens: Routes.MyBookingList,
132
+ screen: Routes.MyBookingList,
133
133
  params: { tab: 1 },
134
134
  }),
135
135
  };
@@ -141,7 +141,7 @@ const NotificationItem = memo(({ item }) => {
141
141
  ),
142
142
  redirect: () =>
143
143
  navigation.navigate(Routes.SmartParkingStack, {
144
- screens: Routes.SmartParkingBookingDetails,
144
+ screen: Routes.SmartParkingBookingDetails,
145
145
  params: { id: booking_id },
146
146
  }),
147
147
  };
@@ -153,7 +153,7 @@ const NotificationItem = memo(({ item }) => {
153
153
  ),
154
154
  redirect: () =>
155
155
  navigation.navigate(Routes.SmartParkingStack, {
156
- screens: Routes.MyBookingList,
156
+ screen: Routes.MyBookingList,
157
157
  params: { tab: 1 },
158
158
  }),
159
159
  };
@@ -168,7 +168,7 @@ const NotificationItem = memo(({ item }) => {
168
168
  ),
169
169
  redirect: () =>
170
170
  navigation.navigate(Routes.SmartParkingStack, {
171
- screens: Routes.SmartParkingBookingDetails,
171
+ screen: Routes.SmartParkingBookingDetails,
172
172
  params: { id: violated_booking_id || booking_id },
173
173
  }),
174
174
  };
@@ -180,7 +180,7 @@ const NotificationItem = memo(({ item }) => {
180
180
  ),
181
181
  redirect: () =>
182
182
  navigation.navigate(Routes.SmartParkingStack, {
183
- screens: Routes.SmartParkingBookingDetails,
183
+ screen: Routes.SmartParkingBookingDetails,
184
184
  params: { id: booking_id },
185
185
  }),
186
186
  };
@@ -192,7 +192,7 @@ const NotificationItem = memo(({ item }) => {
192
192
  ),
193
193
  redirect: () =>
194
194
  navigation.navigate(Routes.SmartParkingStack, {
195
- screens: Routes.SmartParkingBookingDetails,
195
+ screen: Routes.SmartParkingBookingDetails,
196
196
  params: { id: booking_id },
197
197
  }),
198
198
  };
@@ -205,7 +205,7 @@ const NotificationItem = memo(({ item }) => {
205
205
  ),
206
206
  redirect: () =>
207
207
  navigation.navigate(Routes.SmartParkingStack, {
208
- screens: Routes.SmartParkingBookingDetails,
208
+ screen: Routes.SmartParkingBookingDetails,
209
209
  params: { id: new_booking_id },
210
210
  }),
211
211
  };
@@ -217,14 +217,14 @@ const NotificationItem = memo(({ item }) => {
217
217
  ),
218
218
  redirect: () =>
219
219
  navigation.navigate(Routes.SmartParkingStack, {
220
- screens: Routes.SmartParkingBookingDetails,
220
+ screen: Routes.SmartParkingBookingDetails,
221
221
  params: { id: booking_id },
222
222
  }),
223
223
  };
224
224
  case NOTIFICATION_TYPES.NOTIFY_INDICATOR:
225
225
  const { sensor_type, summary_id } = paramsJSON;
226
226
  switch (sensor_type) {
227
- case 'air_quality':
227
+ case SENSOR_TYPE.AIR_QUALITY:
228
228
  return {
229
229
  content: customColorText(
230
230
  t('text_notification_content_air_quality_high'),
@@ -240,7 +240,7 @@ const NotificationItem = memo(({ item }) => {
240
240
  }),
241
241
  iconContent: <Image source={Images.logo} style={styles.logo} />,
242
242
  };
243
- case 'turbidity':
243
+ case SENSOR_TYPE.TURBIDITY:
244
244
  return {
245
245
  content: customColorText(
246
246
  t('text_notification_content_turbility_high'),
@@ -256,7 +256,7 @@ const NotificationItem = memo(({ item }) => {
256
256
  }),
257
257
  iconContent: <Image source={Images.logo} style={styles.logo} />,
258
258
  };
259
- case 'ph':
259
+ case SENSOR_TYPE.PH:
260
260
  return {
261
261
  content: customColorText(
262
262
  t('text_notification_content_pH_index_high'),
@@ -272,7 +272,7 @@ const NotificationItem = memo(({ item }) => {
272
272
  }),
273
273
  iconContent: <Image source={Images.logo} style={styles.logo} />,
274
274
  };
275
- case 'clo':
275
+ case SENSOR_TYPE.CLO:
276
276
  return {
277
277
  content: customColorText(
278
278
  t('text_notification_content_clo_high'),
@@ -288,7 +288,7 @@ const NotificationItem = memo(({ item }) => {
288
288
  }),
289
289
  iconContent: <Image source={Images.logo} style={styles.logo} />,
290
290
  };
291
- case 'uv':
291
+ case SENSOR_TYPE.UV:
292
292
  return {
293
293
  content: customColorText(
294
294
  t('text_notification_content_uv_index_high'),
@@ -304,7 +304,7 @@ const NotificationItem = memo(({ item }) => {
304
304
  }),
305
305
  iconContent: <Image source={Images.logo} style={styles.logo} />,
306
306
  };
307
- case 'smoke':
307
+ case SENSOR_TYPE.SMOKE:
308
308
  return {
309
309
  content: customColorText(
310
310
  t('text_notification_content_smoke'),
@@ -320,7 +320,7 @@ const NotificationItem = memo(({ item }) => {
320
320
  }),
321
321
  iconContent: <Image source={Images.logo} style={styles.logo} />,
322
322
  };
323
- case 'fire':
323
+ case SENSOR_TYPE.FIRE:
324
324
  return {
325
325
  content: customColorText(
326
326
  t('text_notification_content_fire'),
@@ -336,6 +336,22 @@ const NotificationItem = memo(({ item }) => {
336
336
  }),
337
337
  iconContent: <Image source={Images.logo} style={styles.logo} />,
338
338
  };
339
+ case SENSOR_TYPE.SOS:
340
+ return {
341
+ content: customColorText(
342
+ t('text_notification_content_active_sos'),
343
+ arrParams
344
+ ),
345
+ redirect: () =>
346
+ navigation.navigate(Routes.UnitStack, {
347
+ screen: Routes.DeviceDetail,
348
+ params: {
349
+ unitId,
350
+ sensorId,
351
+ },
352
+ }),
353
+ iconContent: <Image source={Images.logo} style={styles.logo} />,
354
+ };
339
355
  default:
340
356
  return {
341
357
  content: customColorText(
@@ -398,6 +414,82 @@ const NotificationItem = memo(({ item }) => {
398
414
  <IconComponent icon={'home'} style={styles.backgroundSummer} />
399
415
  ),
400
416
  };
417
+ case NOTIFICATION_TYPES.NOTIFY_DEVICE_DISCONNECT:
418
+ return {
419
+ content: customColorText(
420
+ t('text_notification_content_divice_disconnect'),
421
+ arrParams
422
+ ),
423
+ redirect: () => {
424
+ navigation.navigate(Routes.UnitStack, {
425
+ screen: Routes.DeviceDetail,
426
+ params: {
427
+ unitId,
428
+ sensorId,
429
+ },
430
+ });
431
+ },
432
+ };
433
+ case NOTIFICATION_TYPES.NOTIFY_UPDATE_ADDRESS:
434
+ return {
435
+ content: customColorText(
436
+ t('text_notification_content_update_address'),
437
+ arrParams
438
+ ),
439
+ redirect: () => {
440
+ navigation.navigate(Routes.UnitStack, {
441
+ screen: Routes.UnitDetail,
442
+ params: {
443
+ unitId,
444
+ },
445
+ });
446
+ },
447
+ iconContent: (
448
+ <IconComponent icon={'home'} style={styles.backgroundSummer} />
449
+ ),
450
+ };
451
+ case NOTIFICATION_TYPES.NOTIFY_RENAME_SUB_UNIT:
452
+ const stationId = paramsJSON?.sub_unit_id;
453
+ return {
454
+ content: customColorText(
455
+ t('text_notification_content_rename_sub_unit'),
456
+ arrParams
457
+ ),
458
+ redirect: () => {
459
+ navigation.navigate(Routes.UnitStack, {
460
+ screen: Routes.UnitDetail,
461
+ params: {
462
+ unitId,
463
+ stationId,
464
+ },
465
+ });
466
+ },
467
+ iconContent: (
468
+ <IconComponent icon={'home'} style={styles.backgroundSummer} />
469
+ ),
470
+ };
471
+ case NOTIFICATION_TYPES.NOTIFY_REMOVE_SUB_UNIT:
472
+ return {
473
+ content: customColorText(
474
+ t('text_notification_content_remove_sub_unit'),
475
+ arrParams
476
+ ),
477
+ redirect: () => null,
478
+ iconContent: (
479
+ <IconComponent icon={'home'} style={styles.backgroundSummer} />
480
+ ),
481
+ };
482
+ case NOTIFICATION_TYPES.NOTIFY_REMOVE_DEVICE:
483
+ return {
484
+ content: customColorText(
485
+ t('text_notification_content_remove_device'),
486
+ arrParams
487
+ ),
488
+ redirect: () => null,
489
+ iconContent: (
490
+ <IconComponent icon={'home'} style={styles.backgroundSummer} />
491
+ ),
492
+ };
401
493
  default:
402
494
  return {
403
495
  content: customColorText(t('this_notification_will_be_updated_soon')),
@@ -43,6 +43,7 @@ describe('test ScanChipQR', () => {
43
43
  station_id: 1,
44
44
  phoneNumber: '0909123456',
45
45
  chipName: 'Chip name',
46
+ isNewFlow: true,
46
47
  },
47
48
  };
48
49
  });
@@ -62,7 +63,7 @@ describe('test ScanChipQR', () => {
62
63
  expect(qrScan[0].props.loading).toEqual(false);
63
64
  });
64
65
 
65
- test('onScan success', async () => {
66
+ test('onScan addDeviceNewFlow success', async () => {
66
67
  const new_chip = {
67
68
  id: 1,
68
69
  name: 'ABC',
@@ -76,7 +77,7 @@ describe('test ScanChipQR', () => {
76
77
  });
77
78
 
78
79
  let tree;
79
- const body = { id: 1, imei: 'IMEI_X', name: 'New Chip' };
80
+ const body = { id: 1, imei: 'SENSOR-X341241', name: 'New Chip' };
80
81
  await act(async () => {
81
82
  tree = await create(wrapComponent(route));
82
83
  });
@@ -87,10 +88,14 @@ describe('test ScanChipQR', () => {
87
88
  qrScan.props.onScan(JSON.stringify(body));
88
89
  });
89
90
  expect(qrScan.props.loading).toEqual(true);
90
- expect(axios.post).toHaveBeenCalled();
91
- expect(mockedNavigate).toHaveBeenCalledWith(Routes.ConnectingGateway, {
92
- new_chip,
93
- ...route.params,
91
+ expect(mockedNavigate).toHaveBeenCalledWith(Routes.AddDeviceStack, {
92
+ params: {
93
+ scan_sensor_data: { id: 1, imei: 'SENSOR-X341241', name: 'New Chip' },
94
+ addType: 'AddDeviceNewFlow',
95
+ devicePrefixName: 'SENSOR',
96
+ unit_id: undefined,
97
+ },
98
+ screen: 'AddGatewaySelectGateway',
94
99
  });
95
100
  });
96
101
 
@@ -118,7 +123,6 @@ describe('test ScanChipQR', () => {
118
123
  qrScan.props.onScan(JSON.stringify(body));
119
124
  });
120
125
  expect(qrScan.props.loading).toEqual(true);
121
- expect(axios.post).toHaveBeenCalled();
122
126
  expect(mockedGoBack).toHaveBeenCalled();
123
127
  });
124
128
  });
@@ -5,8 +5,17 @@ import { axiosPost } from '../../../utils/Apis/axios';
5
5
  import Routes from '../../../utils/Route';
6
6
 
7
7
  const useChipScan = (route) => {
8
- const { unit_id, station, phoneNumber, chipName, wifiName, wifiPass, imei } =
9
- route.params;
8
+ const {
9
+ unit_id,
10
+ unit_name,
11
+ imei,
12
+ isNewFlow,
13
+ phoneNumber,
14
+ chipName,
15
+ wifiName,
16
+ wifiPass,
17
+ station,
18
+ } = route.params;
10
19
  const navigation = useNavigation();
11
20
  const [loading, setLoading] = useState(false);
12
21
 
@@ -14,44 +23,89 @@ const useChipScan = (route) => {
14
23
  async (data) => {
15
24
  setLoading(true);
16
25
  const body = JSON.parse(data);
17
- const { success, data: new_chip } = await axiosPost(
18
- API.UNIT.CHIP_SCAN(unit_id),
19
- {
20
- imei: imei || body.imei,
21
- qr_code: body.imei,
22
- phone: phoneNumber,
23
- name: chipName,
24
- station: station,
25
- wifi_ssid: wifiName,
26
- wifi_pass: wifiPass,
26
+ if (isNewFlow) {
27
+ const devicePrefixName = body?.imei.split('-')[0];
28
+ switch (devicePrefixName) {
29
+ case 'SENSOR':
30
+ navigation.navigate(Routes.AddDeviceStack, {
31
+ screen: Routes.AddGatewaySelectGateway,
32
+ params: {
33
+ scan_sensor_data: { ...body },
34
+ addType: 'AddDeviceNewFlow',
35
+ unit_id: unit_id,
36
+ devicePrefixName,
37
+ },
38
+ });
39
+ break;
40
+ case 'ROBOT':
41
+ case 'LITE':
42
+ {
43
+ const { success, data: new_chip } = await axiosPost(
44
+ API.UNIT.CHIP_SCAN_GET_WIFI_INFO(),
45
+ {
46
+ imei: imei || body.imei,
47
+ qr_code: body.imei,
48
+ }
49
+ );
50
+ if (success) {
51
+ if (new_chip.is_wifi) {
52
+ navigation.navigate(Routes.ConnectWifiWarning, {
53
+ wifi_ssid: new_chip.wifi_ssid,
54
+ wifi_pass: new_chip.wifi_pass,
55
+ chip_id: new_chip.id,
56
+ unit_id: unit_id,
57
+ unit_name: unit_name,
58
+ devicePrefixName,
59
+ body,
60
+ });
61
+ } else {
62
+ navigation.navigate(Routes.ConnectingGateway, {
63
+ new_chip,
64
+ ...route.params,
65
+ });
66
+ }
67
+ } else {
68
+ navigation.goBack();
69
+ }
70
+ }
71
+ break;
72
+ default:
73
+ navigation.goBack();
74
+ break;
27
75
  }
28
- );
29
- if (success) {
30
- if (new_chip.is_wifi) {
31
- navigation.navigate(Routes.ConnectWifiWarning, {
32
- wifi_ssid: new_chip.wifi_ssid,
33
- wifi_pass: new_chip.wifi_pass,
34
- chip_id: new_chip.id,
35
- unit_id: unit_id,
36
- });
37
- } else {
76
+ } else {
77
+ const { success, data: new_chip } = await axiosPost(
78
+ API.UNIT.CHIP_SCAN(unit_id),
79
+ {
80
+ imei: imei,
81
+ qr_code: body.imei,
82
+ phone: phoneNumber,
83
+ name: chipName,
84
+ station: station,
85
+ wifi_ssid: wifiName,
86
+ wifi_pass: wifiPass,
87
+ }
88
+ );
89
+ if (success) {
38
90
  navigation.navigate(Routes.ConnectingGateway, {
39
91
  new_chip,
40
92
  ...route.params,
41
93
  });
94
+ } else {
95
+ navigation.goBack();
42
96
  }
43
- } else {
44
- navigation.goBack();
45
97
  }
46
98
  },
47
99
  [
48
100
  chipName,
49
101
  imei,
102
+ isNewFlow,
50
103
  navigation,
51
104
  phoneNumber,
52
105
  route.params,
53
106
  station,
54
107
  unit_id,
108
+ unit_name,
55
109
  wifiName,
56
110
  wifiPass,
57
111
  ]
@@ -236,12 +236,7 @@ const ScriptDetail = ({ route }) => {
236
236
  }, [name, automate]);
237
237
 
238
238
  const onGoBack = useCallback(() => {
239
- if (isCreateScriptSuccess || isCreateNewAction) {
240
- dispatch(popAction(5));
241
- isAutomateTab && goBack();
242
- } else {
243
- goBack();
244
- }
239
+ goBack();
245
240
  // eslint-disable-next-line react-hooks/exhaustive-deps
246
241
  }, [isCreateScriptSuccess]);
247
242
 
@@ -93,6 +93,7 @@ const SelectUnit = () => {
93
93
  const isSelectedItem = selectedItem?.id === id;
94
94
  return (
95
95
  <TouchableOpacity
96
+ key={id}
96
97
  onPress={onPressItem(item)}
97
98
  style={styles.wrapItem}
98
99
  testID={TESTID.ITEM_UNIT}
@@ -128,7 +128,7 @@ const Shared = () => {
128
128
  renderItem={({ item, index }) => {
129
129
  return (
130
130
  <SharedUnit
131
- key={`${item.id}-${item.is_star}-${item.is_pin}`}
131
+ key={`${item.id}-${item?.is_star}-${item?.is_pin}`}
132
132
  navigation={navigation}
133
133
  item={item}
134
134
  index={index}
@@ -0,0 +1,61 @@
1
+ import React from 'react';
2
+ import { TouchableOpacity } from 'react-native';
3
+ import renderer, { act } from 'react-test-renderer';
4
+ import SmartIr from '../index';
5
+ import { SCProvider } from '../../../context';
6
+ import { mockSCStore } from '../../../context/mockStore';
7
+
8
+ const wrapComponent = (item) => (
9
+ <SCProvider initState={mockSCStore({})}>
10
+ <SmartIr item={item} />
11
+ </SCProvider>
12
+ );
13
+ const mockNavigate = jest.fn();
14
+ jest.mock('@react-navigation/native', () => {
15
+ return {
16
+ ...jest.requireActual('@react-navigation/native'),
17
+ useNavigation: () => ({
18
+ navigate: mockNavigate,
19
+ }),
20
+ };
21
+ });
22
+ describe('Test SmartIr', () => {
23
+ let tree;
24
+ beforeEach(() => {
25
+ mockNavigate.mockClear();
26
+ });
27
+ test('render SmartIr', () => {
28
+ const item = {
29
+ configuration: { devices: [] },
30
+ id: 11,
31
+ order: 1,
32
+ template: 'smart_ir',
33
+ type: 'smart_ir',
34
+ };
35
+ act(() => {
36
+ tree = renderer.create(wrapComponent(item));
37
+ });
38
+ const instance = tree.root;
39
+ const itemAddNew = instance.findAllByType(TouchableOpacity);
40
+ expect(itemAddNew).toHaveLength(2);
41
+ });
42
+
43
+ test('render SmartIr on AddNew', () => {
44
+ const item = {
45
+ configuration: { devices: [] },
46
+ id: 11,
47
+ order: 1,
48
+ template: 'smart_ir',
49
+ type: 'smart_ir',
50
+ };
51
+ act(() => {
52
+ tree = renderer.create(wrapComponent(item));
53
+ });
54
+ const instance = tree.root;
55
+ const itemAddNew = instance.findAllByType(TouchableOpacity);
56
+ expect(itemAddNew).toHaveLength(2);
57
+ act(() => {
58
+ itemAddNew[0].props.onPress();
59
+ });
60
+ });
61
+ });
@@ -0,0 +1,23 @@
1
+ import React, { memo, useCallback } from 'react';
2
+ import { View, Alert } from 'react-native';
3
+ import { useTranslations } from '../../hooks/Common/useTranslations';
4
+ import ItemAddNew from '../../commons/Device/ItemAddNew';
5
+ import styles from './styles';
6
+
7
+ const SmartIr = memo(({ item }) => {
8
+ const t = useTranslations();
9
+ const AddRemoteControl = useCallback(() => {
10
+ Alert.alert(t('feature_under_development'));
11
+ }, [t]);
12
+ return (
13
+ <View style={styles.container}>
14
+ <ItemAddNew
15
+ title={t('add_remote_control')}
16
+ wrapStyle={styles.itemAddNew}
17
+ onAddNew={AddRemoteControl}
18
+ />
19
+ </View>
20
+ );
21
+ });
22
+
23
+ export default SmartIr;
@@ -0,0 +1,14 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ export default StyleSheet.create({
4
+ container: {
5
+ flex: 1,
6
+ paddingHorizontal: 16,
7
+ },
8
+ itemAddNew: {
9
+ flex: 1,
10
+ width: '100%',
11
+ justifyContent: 'center',
12
+ alignItems: 'center',
13
+ },
14
+ });
@@ -56,7 +56,10 @@ const AddMenu = memo(({ unit, afterItemClick, showAdd, setHideAdd }) => {
56
56
  route: Routes.AddGatewayStack,
57
57
  text: t('gateway') + ' Wifi',
58
58
  image: <AddDeviceIcon width={43} height={43} />,
59
- data: { screen: Routes.FirstWarning, params: { unit_id: unit.id } },
59
+ data: {
60
+ screen: Routes.FirstWarning,
61
+ params: { unit_id: unit?.id, unit_name: unit?.name },
62
+ },
60
63
  },
61
64
  {
62
65
  id: 6,
@@ -11,7 +11,12 @@ import Summaries from './Summaries';
11
11
 
12
12
  import Text from '../../commons/Text';
13
13
  import { API } from '../../configs';
14
- import { useBoolean, useIsOwnerOfUnit, usePopover } from '../../hooks/Common';
14
+ import {
15
+ useBlockBackAndroid,
16
+ useBoolean,
17
+ useIsOwnerOfUnit,
18
+ usePopover,
19
+ } from '../../hooks/Common';
15
20
  import { scanBluetoothDevices } from '../../iot/RemoteControl/Bluetooth';
16
21
  import { googleHomeConnect } from '../../iot/RemoteControl/GoogleHome';
17
22
  import { axiosPost, fetchWithCache } from '../../utils/Apis/axios';
@@ -41,6 +46,7 @@ const UnitDetail = ({ route }) => {
41
46
  unitData,
42
47
  isOneTap,
43
48
  routeName,
49
+ stationId,
44
50
  isAddSubUnit,
45
51
  isSuccessfullyConnected,
46
52
  } = route.params;
@@ -48,6 +54,13 @@ const UnitDetail = ({ route }) => {
48
54
  const isFocused = useIsFocused();
49
55
  const { stateData, setAction } = useContext(SCContext);
50
56
  const { navigate } = useNavigation();
57
+ const RouterHardware = useCallback(
58
+ (routeHardware) => () => {
59
+ navigate(routeHardware);
60
+ },
61
+ [navigate]
62
+ );
63
+ useBlockBackAndroid(RouterHardware(Routes.Dashboard));
51
64
  const user = useSCContextSelector((state) => state?.auth?.account?.user);
52
65
  const isLavidaSource = useSCContextSelector(
53
66
  (state) => state.app.isLavidaSource
@@ -146,7 +159,7 @@ const UnitDetail = ({ route }) => {
146
159
  ]);
147
160
  setFavorites((prevData) => ({
148
161
  ...prevData,
149
- automates: data.filter((item) => item.script.is_star),
162
+ automates: data.filter((item) => item?.script?.is_star),
150
163
  }));
151
164
  }
152
165
  }
@@ -268,6 +281,15 @@ const UnitDetail = ({ route }) => {
268
281
  }
269
282
  }, [listMenuItem.length, isAddSubUnit]);
270
283
 
284
+ useEffect(() => {
285
+ if (listMenuItem.length && stationId) {
286
+ const getStationCurrent = listMenuItem.filter(
287
+ (item) => item?.station.id === stationId
288
+ );
289
+ setIndexStation(getStationCurrent[0]?.index);
290
+ }
291
+ }, [listMenuItem, listMenuItem.length, stationId]);
292
+
271
293
  const onSnapToItem = useCallback(
272
294
  (item, index) => {
273
295
  setStation(unit.stations[index]);
@@ -36,7 +36,7 @@ const ButtonWrapper = ({
36
36
  <TouchableOpacity
37
37
  onPress={onPress}
38
38
  testID={testId}
39
- style={!icon ? styles.buttonWrapper : styles.buttonWrapperAvatar}
39
+ style={styles.buttonWrapper}
40
40
  >
41
41
  <View style={styles.buttonInfo}>
42
42
  {!icon ? (