@eohjsc/react-native-smart-city 0.2.46 → 0.2.50

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 (76) hide show
  1. package/README.md +9 -0
  2. package/index.js +6 -0
  3. package/package.json +22 -3
  4. package/src/commons/ActionTemplate/index.js +40 -25
  5. package/src/commons/Automate/ItemAutomate.js +2 -2
  6. package/src/commons/Dashboard/MyPinnedSharedUnit/index.js +82 -0
  7. package/src/commons/Dashboard/MyPinnedSharedUnit/styles.js +78 -0
  8. package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +60 -0
  9. package/src/commons/Dashboard/MyUnit/index.js +111 -0
  10. package/src/commons/Dashboard/MyUnit/styles.js +61 -0
  11. package/src/commons/Device/ConnectedViewHeader.js +4 -1
  12. package/src/commons/Form/TextInput.js +1 -1
  13. package/src/commons/MediaPlayer/index.js +6 -1
  14. package/src/commons/OneTapTemplate/OptionsDropdownActionTemplate.js +3 -3
  15. package/src/{screens/Unit/components → commons}/SearchLocation/RowLocation.js +2 -2
  16. package/src/{screens/Unit/components → commons}/SearchLocation/RowLocationStyles.js +1 -1
  17. package/src/{screens/Unit/components → commons}/SearchLocation/SearchBarLocationStyles.js +1 -1
  18. package/src/{screens/Unit/components → commons}/SearchLocation/__test__/RowLocation.test.js +2 -2
  19. package/src/{screens/Unit/components → commons}/SearchLocation/index.js +2 -2
  20. package/src/commons/Unit/SharedUnit.js +2 -2
  21. package/src/configs/API.js +11 -4
  22. package/src/configs/Constants.js +12 -6
  23. package/src/iot/RemoteControl/Bluetooth.js +10 -1
  24. package/src/iot/RemoteControl/Internet.js +0 -2
  25. package/src/navigations/AddDeviceStack.js +5 -0
  26. package/src/navigations/AddUnitStack.js +2 -0
  27. package/src/navigations/UnitStack.js +8 -0
  28. package/src/screens/ActivityLog/FilterPopup.js +24 -17
  29. package/src/screens/ActivityLog/ItemLog.js +26 -22
  30. package/src/screens/ActivityLog/__test__/FilterPopup.test.js +1 -0
  31. package/src/screens/ActivityLog/__test__/ItemLog.test.js +0 -20
  32. package/src/screens/ActivityLog/__test__/index.test.js +3 -0
  33. package/src/screens/ActivityLog/hooks/__test__/index.test.js +8 -0
  34. package/src/screens/ActivityLog/hooks/index.js +5 -9
  35. package/src/screens/ActivityLog/index.js +4 -4
  36. package/src/screens/ActivityLog/styles/filterPopupStyles.js +3 -0
  37. package/src/screens/AddCommon/SelectSubUnit.js +10 -1
  38. package/src/screens/AddCommon/SelectUnit.js +11 -0
  39. package/src/screens/AddLocationMaps/index.js +124 -74
  40. package/src/screens/AddLocationMaps/indexStyle.js +58 -0
  41. package/src/screens/AddNewAction/SelectAction.js +8 -1
  42. package/src/screens/AddNewAction/__test__/SelectAction.test.js +6 -4
  43. package/src/screens/AddNewDevice/ConnectingDevices.js +3 -0
  44. package/src/screens/AddNewGateway/ConnectingGatewayStyles.js +10 -1
  45. package/src/screens/AddNewOneTap/index.js +8 -6
  46. package/src/screens/Automate/MultiUnits.js +11 -1
  47. package/src/screens/Automate/__test__/MultiUnits.test.js +2 -0
  48. package/src/screens/Device/__test__/detail.test.js +14 -0
  49. package/src/screens/Device/components/DetailHistoryChart.js +63 -0
  50. package/src/screens/Device/components/EmergencyCountdown.js +29 -0
  51. package/src/screens/Device/components/SensorConnectStatusViewHeader.js +57 -0
  52. package/src/screens/Device/components/SensorDisplayItem.js +127 -0
  53. package/src/screens/Device/detail.js +81 -294
  54. package/src/screens/Device/hooks/useDisconnectedDevice.js +63 -0
  55. package/src/screens/Device/styles.js +0 -10
  56. package/src/screens/GuestInfo/components/RecurringDetail.js +2 -2
  57. package/src/screens/ScriptDetail/__test__/index.test.js +12 -3
  58. package/src/screens/ScriptDetail/hooks/index.js +4 -0
  59. package/src/screens/ScriptDetail/index.js +18 -9
  60. package/src/screens/SetSchedule/__test__/SelectWeekday.test.js +2 -2
  61. package/src/screens/SetSchedule/components/SelectWeekday.js +13 -7
  62. package/src/screens/SubUnit/AddSubUnit.js +113 -29
  63. package/src/screens/SubUnit/AddSubUnitStyles.js +10 -0
  64. package/src/screens/SubUnit/__test__/AddSubUnit.test.js +1 -0
  65. package/src/screens/SyncLGDevice/AddLGDevice.js +1 -1
  66. package/src/screens/Unit/MoreMenu.js +6 -1
  67. package/src/screens/Unit/SelectLocation.js +2 -3
  68. package/src/screens/Unit/SmartAccount.js +141 -0
  69. package/src/screens/Unit/SmartAccountItem.js +51 -0
  70. package/src/screens/Unit/SmartAccountStyles.js +46 -0
  71. package/src/screens/Unit/__test__/SmartAccount.test.js +58 -0
  72. package/src/screens/Unit/hook/useStateAlertRemove.js +36 -0
  73. package/src/utils/I18n/translations/en.json +18 -2
  74. package/src/utils/I18n/translations/vi.json +19 -3
  75. package/src/utils/Route/index.js +3 -0
  76. package/src/utils/Validation.js +3 -1
@@ -1,14 +1,20 @@
1
- import React, { memo, useState, useEffect, useCallback } from 'react';
2
- import { View, StyleSheet } from 'react-native';
3
- import MapView, { Marker, Circle, PROVIDER_GOOGLE } from 'react-native-maps';
4
- import { getStatusBarHeight } from 'react-native-iphone-x-helper';
1
+ import React, { memo, useState, useCallback, useRef } from 'react';
2
+ import { View, ScrollView } from 'react-native';
3
+ import MapView, { Marker, PROVIDER_GOOGLE } from 'react-native-maps';
5
4
  import { useNavigation } from '@react-navigation/native';
6
5
  import { useTranslations } from '../../hooks/Common/useTranslations';
7
6
 
8
7
  import { Colors } from '../../configs';
9
8
  import Text from '../../commons/Text';
10
9
  import { ViewButtonBottom } from '../../commons';
11
- import PinLocation from '../../../assets/images/AddLocationMaps/PinLocation.svg';
10
+ import SearchBarLocation from '../../commons/SearchLocation';
11
+ import RowLocation from '../../commons/SearchLocation/RowLocation';
12
+ import Point from '../../../assets/images/AddLocationMaps/Point.svg';
13
+ import { axiosGet } from '../../utils/Apis/axios';
14
+ import { API } from '../../configs';
15
+ import { SCConfig } from '../../configs';
16
+ import styles from './indexStyle';
17
+ import Routes from '../../utils/Route';
12
18
 
13
19
  export const initialRadius = 250;
14
20
  const initialRegion = {
@@ -16,21 +22,99 @@ const initialRegion = {
16
22
  longitudeDelta: 0.009221,
17
23
  };
18
24
 
25
+ const DEFAULT_LATITUDE = 10.7974046; // EoH center
26
+ const DEFAULT_LONGITUDE = 106.7035663;
27
+
19
28
  const AddLocationMaps = memo(() => {
20
29
  const t = useTranslations();
21
- const { goBack } = useNavigation();
22
- const [color, setColor] = useState(Colors.Black);
23
- useEffect(() => {
24
- setColor(Colors.DaybreakBlue);
25
- }, [setColor]);
30
+ const { goBack, navigate } = useNavigation();
31
+ const [input, setInput] = useState('');
32
+ const [searchData, setSearchData] = useState([]);
33
+ const [searchedLocation, setSearchedLocation] = useState(null);
26
34
 
27
- const selectedCoordinates = { latitude: 10.7993573, longitude: 106.7050793 };
35
+ const mapRef = useRef(null);
28
36
 
29
- const onDone = useCallback(() => {}, []);
37
+ const onDone = useCallback(() => {
38
+ navigate(Routes.AddSubUnit, {
39
+ location: input,
40
+ isAddUnit: true,
41
+ });
42
+ }, [input, navigate]);
30
43
  const onBack = useCallback(() => {
31
44
  goBack();
32
45
  }, [goBack]);
33
46
 
47
+ const onTextInput = useCallback(async (input) => {
48
+ setInput(input);
49
+ if (!input) {
50
+ setSearchData([]);
51
+ setSearchedLocation(null);
52
+ return;
53
+ }
54
+ try {
55
+ const config = {
56
+ params: {
57
+ input: input,
58
+ key: SCConfig.GOOGLE_MAP_API_KEY,
59
+ sessiontoken: 123456324,
60
+ strictBounds: false,
61
+ types: ['establishment'],
62
+ },
63
+ };
64
+
65
+ const { success, data } = await axiosGet(
66
+ API.EXTERNAL.GOOGLE_MAP.AUTO_COMPLETE,
67
+ config
68
+ );
69
+ if (success) {
70
+ setSearchData(data.predictions);
71
+ }
72
+ } catch (error) {}
73
+ }, []);
74
+
75
+ const animateToRegion = useCallback((lat, lng) => {
76
+ if (!mapRef || !mapRef.current) {
77
+ return;
78
+ }
79
+
80
+ mapRef.current.animateToRegion(
81
+ {
82
+ latitude: lat,
83
+ longitude: lng,
84
+ ...initialRegion,
85
+ },
86
+ 600
87
+ );
88
+ }, []);
89
+
90
+ const onPressRowLocation = useCallback(
91
+ async (item) => {
92
+ setInput(item.description);
93
+ setSearchData([]);
94
+ const body = {
95
+ params: {
96
+ place_id: item.place_id,
97
+ key: SCConfig.GOOGLE_MAP_API_KEY,
98
+ },
99
+ };
100
+
101
+ const { success, data } = await axiosGet(
102
+ API.EXTERNAL.GOOGLE_MAP.GET_LAT_LNG_BY_PLACE_ID,
103
+ body
104
+ );
105
+ if (success) {
106
+ const { location } = data.result.geometry;
107
+ animateToRegion(location.lat, location.lng);
108
+ setSearchedLocation({
109
+ description: item.description,
110
+ latitude: location.lat,
111
+ longitude: location.lng,
112
+ });
113
+ }
114
+ },
115
+ [animateToRegion]
116
+ );
117
+
34
118
  return (
35
119
  <View style={styles.container}>
36
120
  <Text color={Colors.Gray9} size={24} semibold style={styles.textHeader}>
@@ -40,35 +124,39 @@ const AddLocationMaps = memo(() => {
40
124
  <Text color={Colors.Gray8} size={12} style={styles.textExplain}>
41
125
  {t('text_explain_add_geolocation')}
42
126
  </Text>
43
- <Text color={Colors.Black} size={16} style={styles.textAddress}>
44
- 298/3 Điện Biên Phủ, phường 17, quận Bình Thạnh, Thành phố Hồ Chí
45
- Minh, Việt Nam
46
- </Text>
127
+ <View style={styles.searchLocation}>
128
+ <SearchBarLocation input={input} onTextInput={onTextInput} />
129
+ <ScrollView style={styles.searchData}>
130
+ {searchData.map((item) => (
131
+ <RowLocation item={item} onPress={onPressRowLocation} />
132
+ ))}
133
+ </ScrollView>
134
+ </View>
47
135
  <View style={styles.mapContainer}>
48
136
  <MapView
137
+ ref={mapRef}
49
138
  provider={PROVIDER_GOOGLE}
50
- region={{
51
- ...selectedCoordinates,
139
+ style={styles.mapView}
140
+ initialRegion={{
52
141
  ...initialRegion,
142
+ latitude: DEFAULT_LATITUDE,
143
+ longitude: DEFAULT_LONGITUDE,
53
144
  }}
54
- style={styles.mapView}
145
+ followUserLocation={true}
55
146
  >
56
- <Marker
57
- coordinate={selectedCoordinates}
58
- anchor={{ x: 0.5, y: 0.5 }}
59
- calloutOffset={{ x: 1, y: 1 }}
60
- tracksViewChanges={false}
61
- >
62
- <PinLocation />
63
- </Marker>
64
- <Circle
65
- center={selectedCoordinates}
66
- radius={initialRadius}
67
- strokeColor={Colors.Blue6}
68
- fillColor={color}
69
- zIndex={2}
70
- strokeWidth={1}
71
- />
147
+ {searchedLocation && (
148
+ <Marker
149
+ coordinate={{
150
+ latitude: searchedLocation.latitude,
151
+ longitude: searchedLocation.longitude,
152
+ }}
153
+ tracksViewChanges={false}
154
+ >
155
+ <View style={styles.pointCircle}>
156
+ <Point />
157
+ </View>
158
+ </Marker>
159
+ )}
72
160
  </MapView>
73
161
  </View>
74
162
  </View>
@@ -77,48 +165,10 @@ const AddLocationMaps = memo(() => {
77
165
  onLeftClick={onBack}
78
166
  rightTitle={t('done')}
79
167
  onRightClick={onDone}
168
+ rightDisabled={!input}
80
169
  />
81
170
  </View>
82
171
  );
83
172
  });
84
173
 
85
174
  export default AddLocationMaps;
86
-
87
- const styles = StyleSheet.create({
88
- container: {
89
- flex: 1,
90
- backgroundColor: Colors.Gray2,
91
- paddingTop: getStatusBarHeight() + 16,
92
- },
93
- textHeader: {
94
- marginHorizontal: 16,
95
- },
96
- content: {
97
- marginTop: 16,
98
- paddingTop: 16,
99
- borderTopLeftRadius: 20,
100
- borderTopRightRadius: 20,
101
- backgroundColor: Colors.White,
102
- borderWidth: 1,
103
- borderColor: Colors.Gray4,
104
- flex: 1,
105
- },
106
- textExplain: {
107
- lineHeight: 20,
108
- marginHorizontal: 16,
109
- },
110
- textAddress: {
111
- lineHeight: 24,
112
- margin: 16,
113
- },
114
- mapContainer: {
115
- flex: 1,
116
- },
117
- mapView: {
118
- position: 'absolute',
119
- top: 0,
120
- left: 0,
121
- right: 0,
122
- bottom: 0,
123
- },
124
- });
@@ -0,0 +1,58 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { getStatusBarHeight } from 'react-native-iphone-x-helper';
3
+
4
+ import { Colors } from '../../configs';
5
+
6
+ export default StyleSheet.create({
7
+ container: {
8
+ flex: 1,
9
+ backgroundColor: Colors.Gray2,
10
+ paddingTop: getStatusBarHeight() + 16,
11
+ },
12
+ textHeader: {
13
+ marginHorizontal: 16,
14
+ },
15
+ content: {
16
+ marginTop: 16,
17
+ paddingTop: 16,
18
+ borderTopLeftRadius: 20,
19
+ borderTopRightRadius: 20,
20
+ backgroundColor: Colors.White,
21
+ borderWidth: 1,
22
+ borderColor: Colors.Gray4,
23
+ flex: 1,
24
+ },
25
+ textExplain: {
26
+ lineHeight: 20,
27
+ marginHorizontal: 16,
28
+ },
29
+ mapContainer: {
30
+ flex: 1,
31
+ },
32
+ mapView: {
33
+ position: 'absolute',
34
+ top: 0,
35
+ left: 0,
36
+ right: 0,
37
+ bottom: 0,
38
+ },
39
+ pointCircle: {
40
+ flex: 1,
41
+ alignItems: 'center',
42
+ justifyContent: 'center',
43
+ width: 109,
44
+ height: 109,
45
+ borderRadius: 50,
46
+ backgroundColor: Colors.BlueTransparent5,
47
+ borderWidth: 1,
48
+ borderColor: Colors.Blue10,
49
+ },
50
+ searchLocation: {
51
+ paddingVertical: 8,
52
+ },
53
+ searchData: {
54
+ paddingHorizontal: 26,
55
+ width: '100%',
56
+ maxHeight: 100,
57
+ },
58
+ });
@@ -100,7 +100,14 @@ const SelectAction = memo(({ route }) => {
100
100
  setIsLoading(false);
101
101
  clearTimeout(to);
102
102
  }, 1000);
103
- }, [automate, device.id, isSelectSensor, t]);
103
+ }, [
104
+ automate.condition,
105
+ automate.config_id,
106
+ automate.value,
107
+ device.id,
108
+ isSelectSensor,
109
+ t,
110
+ ]);
104
111
 
105
112
  const checkConditionToContinue = useCallback(() => {
106
113
  const itemTemp = sensorData?.find((i) => i.id === checkedItem?.id);
@@ -63,7 +63,7 @@ describe('Test SelectAction', () => {
63
63
  return response;
64
64
  });
65
65
  await act(async () => {
66
- tree = renderer.create(wrapComponent(route));
66
+ tree = await renderer.create(wrapComponent(route));
67
67
  });
68
68
  const instance = tree.root;
69
69
 
@@ -83,7 +83,7 @@ describe('Test SelectAction', () => {
83
83
  return response;
84
84
  });
85
85
  await act(async () => {
86
- tree = renderer.create(wrapComponent(route));
86
+ tree = await renderer.create(wrapComponent(route));
87
87
  });
88
88
  const instance = tree.root;
89
89
 
@@ -99,6 +99,7 @@ describe('Test SelectAction', () => {
99
99
  visibilityTime: 1000,
100
100
  });
101
101
  });
102
+
102
103
  test('test fetchData', async () => {
103
104
  const response = {
104
105
  status: 200,
@@ -113,7 +114,7 @@ describe('Test SelectAction', () => {
113
114
  return response;
114
115
  });
115
116
  await act(async () => {
116
- tree = renderer.create(wrapComponent(route));
117
+ tree = await renderer.create(wrapComponent(route));
117
118
  });
118
119
  expect(axios.get).toHaveBeenCalled();
119
120
  });
@@ -219,6 +220,7 @@ describe('Test SelectAction', () => {
219
220
  expect(optionsDropdownActionTemplate).toBeDefined();
220
221
  expect(statesGridActionTemplate).toBeDefined();
221
222
  });
223
+
222
224
  test('test onPress handleOnSelectAction', async () => {
223
225
  const response = {
224
226
  status: 200,
@@ -247,7 +249,7 @@ describe('Test SelectAction', () => {
247
249
  return response;
248
250
  });
249
251
  await act(async () => {
250
- tree = renderer.create(wrapComponent(route));
252
+ tree = await renderer.create(wrapComponent(route));
251
253
  });
252
254
  const instance = tree.root;
253
255
  const actionTemplate = instance.findByType(ActionTemplate);
@@ -1,5 +1,7 @@
1
1
  import React, { memo, useEffect } from 'react';
2
2
  import { View, StyleSheet } from 'react-native';
3
+ import { getStatusBarHeight } from 'react-native-iphone-x-helper';
4
+
3
5
  import { API, Colors } from '../../configs';
4
6
  import { axiosGet } from '../../utils/Apis/axios';
5
7
  import Text from '../../commons/Text';
@@ -44,6 +46,7 @@ const styles = StyleSheet.create({
44
46
  wrap: {
45
47
  flex: 1,
46
48
  backgroundColor: Colors.Gray2,
49
+ paddingTop: getStatusBarHeight(true),
47
50
  },
48
51
  txtHeader: {
49
52
  marginTop: 16,
@@ -1,10 +1,19 @@
1
- import { StyleSheet } from 'react-native';
1
+ import { StyleSheet, StatusBar, Platform } from 'react-native';
2
2
  import { Colors } from '../../configs';
3
3
  import { colorOpacity } from '../../utils/Converter/color';
4
+ import { getStatusBarHeight } from 'react-native-iphone-x-helper';
4
5
 
5
6
  export default StyleSheet.create({
6
7
  wrap: {
7
8
  flex: 1,
9
+ ...Platform.select({
10
+ android: {
11
+ paddingTop: StatusBar.currentHeight,
12
+ },
13
+ ios: {
14
+ paddingTop: getStatusBarHeight(),
15
+ },
16
+ }),
8
17
  },
9
18
  txtHeader: {
10
19
  marginTop: 16,
@@ -13,7 +13,7 @@ import { useTranslations } from '../../hooks/Common/useTranslations';
13
13
  import { axiosPost, axiosPut } from '../../utils/Apis/axios';
14
14
  import Routes from '../../utils/Route';
15
15
  import { popAction } from '../../navigations/utils';
16
- import { ToastBottomHelper } from '../../utils/Utils';
16
+ import { AUTOMATE_TYPE } from '../../configs/Constants';
17
17
 
18
18
  const AddNewOneTap = memo(({ route }) => {
19
19
  const {
@@ -52,8 +52,6 @@ const AddNewOneTap = memo(({ route }) => {
52
52
  isAutomateTab: automateId ? false : isAutomateTab,
53
53
  isMultiUnits,
54
54
  });
55
- } else {
56
- ToastBottomHelper.error(t('error_please_try_later'));
57
55
  }
58
56
  }, [
59
57
  isMultiUnits,
@@ -65,7 +63,6 @@ const AddNewOneTap = memo(({ route }) => {
65
63
  automate,
66
64
  navigate,
67
65
  isAutomateTab,
68
- t,
69
66
  ]);
70
67
 
71
68
  const onChangeName = useCallback((text) => {
@@ -92,6 +89,11 @@ const AddNewOneTap = memo(({ route }) => {
92
89
  // eslint-disable-next-line react-hooks/exhaustive-deps
93
90
  }, [isAutomateTab]);
94
91
 
92
+ const textForNewTap =
93
+ type === AUTOMATE_TYPE.ONE_TAP
94
+ ? t('name_your_button')
95
+ : t('name_your_script');
96
+
95
97
  return (
96
98
  <SafeAreaView
97
99
  style={
@@ -109,10 +111,10 @@ const AddNewOneTap = memo(({ route }) => {
109
111
  color={Colors.Gray9}
110
112
  style={styles.textHeader}
111
113
  >
112
- {t('name_your_button')}
114
+ {textForNewTap}
113
115
  </Text>
114
116
  <_TextInput
115
- placeholder={t('name_your_button')}
117
+ placeholder={textForNewTap}
116
118
  wrapStyle={styles.noMarginTop}
117
119
  onChange={onChangeName}
118
120
  textInputStyle={styles.textInput}
@@ -114,9 +114,19 @@ const MultiUnits = () => {
114
114
  : item?.type !== AUTOMATE_TYPE.ONE_TAP
115
115
  );
116
116
 
117
+ const listFavorite = listItems.filter(
118
+ (item) => item.script?.is_star === true
119
+ );
120
+
121
+ const listNotFavorite = listItems.filter(
122
+ (item) => item.script?.is_star === false
123
+ );
124
+
125
+ const newListItems = listFavorite.concat(listNotFavorite);
126
+
117
127
  return (
118
128
  <View style={styles.wrapItem}>
119
- {listItems.map((item, index) => (
129
+ {newListItems.map((item, index) => (
120
130
  <ItemOneTap
121
131
  isOwner={idUser === item?.user}
122
132
  automate={item}
@@ -70,6 +70,7 @@ describe('Test MultiUnits', () => {
70
70
  id: 1,
71
71
  name: 'Tap to up down up down coc coc coc coc coc',
72
72
  icon: null,
73
+ is_star: true,
73
74
  icon_kit:
74
75
  'https://eoh-gateway-backend.eoh.io/_Category_Sensors_Type_Garage_door_StyleC_olorful.png',
75
76
  },
@@ -86,6 +87,7 @@ describe('Test MultiUnits', () => {
86
87
  id: 300,
87
88
  name: 'p14',
88
89
  icon: null,
90
+ is_star: true,
89
91
  icon_kit: null,
90
92
  },
91
93
  },
@@ -43,6 +43,16 @@ jest.mock('react-redux', () => {
43
43
  };
44
44
  });
45
45
 
46
+ jest.mock('@react-native-community/netinfo', () => {
47
+ return {
48
+ useNetInfo: () => {
49
+ return {
50
+ isConnected: true,
51
+ };
52
+ },
53
+ };
54
+ });
55
+
46
56
  jest.mock('react', () => ({
47
57
  ...jest.requireActual('react'),
48
58
  useLayoutEffect: jest.fn(),
@@ -807,6 +817,10 @@ describe('test DeviceDetail', () => {
807
817
  expect(mockedNavigate).toHaveBeenCalledWith(Routes.ActivityLog, {
808
818
  id: route.params.sensor.id,
809
819
  type: 'action',
820
+ filterEnabled: {
821
+ date: false,
822
+ user: false,
823
+ },
810
824
  });
811
825
  });
812
826
  });
@@ -0,0 +1,63 @@
1
+ import moment from 'moment';
2
+ import React, { useEffect, useState } from 'react';
3
+ import { StyleSheet } from 'react-native';
4
+ import HistoryChart from '../../../commons/Device/HistoryChart';
5
+ import { API } from '../../../configs';
6
+ import { axiosGet } from '../../../utils/Apis/axios';
7
+
8
+ export const DetailHistoryChart = ({ item, sensor }) => {
9
+ const [chartData, setChartData] = useState(item.configuration.configs);
10
+ const [startDate, setStartDate] = useState(
11
+ moment().subtract(1, 'days').valueOf()
12
+ );
13
+ const [endDate, setEndDate] = useState(moment().valueOf());
14
+ useEffect(() => {
15
+ const fetchData = async () => {
16
+ let params = new URLSearchParams();
17
+ item.configuration.configs.map((config) => {
18
+ params.append('config', config.id);
19
+ });
20
+ params.append('date_from', startDate / 1000);
21
+ params.append('date_to', endDate / 1000);
22
+ const { success, data } = await axiosGet(
23
+ API.SENSOR.DISPLAY_HISTORY(sensor.id),
24
+ { params }
25
+ );
26
+ if (success) {
27
+ for (let i = 0; i < data.length; i++) {
28
+ for (let j = 0; j < data[i].data.length; j++) {
29
+ data[i].data[j].x = moment(data[i].data[j].x).toDate();
30
+ }
31
+ }
32
+
33
+ const formatData = item.configuration.configs.map((config) => {
34
+ const dataChart = data.find((k) => k.config === config.id) || {
35
+ data: [],
36
+ };
37
+ return { ...config, data: dataChart.data };
38
+ });
39
+ setChartData(formatData);
40
+ }
41
+ };
42
+ fetchData();
43
+ }, [startDate, endDate, item, sensor]);
44
+ if (!chartData.length) {
45
+ return false;
46
+ }
47
+
48
+ return (
49
+ <HistoryChart
50
+ configuration={item.configuration}
51
+ datas={chartData}
52
+ style={styles.chartStyle}
53
+ setStartDate={setStartDate}
54
+ setEndDate={setEndDate}
55
+ />
56
+ );
57
+ };
58
+
59
+ const styles = StyleSheet.create({
60
+ chartStyle: {
61
+ paddingHorizontal: 16,
62
+ },
63
+ });
@@ -0,0 +1,29 @@
1
+ import React, { memo } from 'react';
2
+ import { StyleSheet, View } from 'react-native';
3
+ import Text from '../../../commons/Text';
4
+ import { Colors } from '../../../configs';
5
+ import { useTranslations } from '../../../hooks/Common/useTranslations';
6
+
7
+ export const EmergencyCountdown = memo(({ countUpStr }) => {
8
+ const t = useTranslations();
9
+ return (
10
+ <View style={styles.countDown}>
11
+ <Text type="Label" center style={styles.messageCountDown}>
12
+ {t('time_since_the_emergency_button_was_pressed')}
13
+ </Text>
14
+ <Text type="H3" center semibold color={Colors.Red6}>
15
+ {countUpStr}
16
+ </Text>
17
+ </View>
18
+ );
19
+ });
20
+
21
+ const styles = StyleSheet.create({
22
+ countDown: {
23
+ marginBottom: 16,
24
+ marginTop: 8,
25
+ },
26
+ messageCountDown: {
27
+ marginBottom: 8,
28
+ },
29
+ });
@@ -0,0 +1,57 @@
1
+ import React from 'react';
2
+ import { ConnectedViewHeader, DisconnectedView } from '../../../commons/Device';
3
+ import { DEVICE_TYPE } from '../../../configs/Constants';
4
+
5
+ export const SensorConnectStatusViewHeader = (props) => {
6
+ if (!!props.sensor && !props.sensor.is_other_device) {
7
+ if (props.connected) {
8
+ return (
9
+ <>
10
+ <ConnectedViewHeader
11
+ lastUpdated={props.lastUpdated}
12
+ isDisplayTime={props.isDisplayTime}
13
+ showWindDirection={props.showWindDirection}
14
+ />
15
+ {props.children}
16
+ </>
17
+ );
18
+ } else if (props.connectedBlt) {
19
+ return (
20
+ <>
21
+ <ConnectedViewHeader
22
+ lastUpdated={props.lastUpdated}
23
+ type={'Bluetooth'}
24
+ isDisplayTime={props.isDisplayTime}
25
+ showWindDirection={props.showWindDirection}
26
+ />
27
+ {props.children}
28
+ </>
29
+ );
30
+ } else {
31
+ return <DisconnectedView sensor={props.sensor} />;
32
+ }
33
+ } else {
34
+ if (props.sensor.device_type === DEVICE_TYPE.LG_THINQ) {
35
+ return (
36
+ <>
37
+ <ConnectedViewHeader lastUpdated={props.lastUpdated} />
38
+ {props.children}
39
+ </>
40
+ );
41
+ } else {
42
+ if (props.isGGHomeConnected) {
43
+ return (
44
+ <>
45
+ <ConnectedViewHeader
46
+ lastUpdated={props.lastUpdated}
47
+ type={'GoogleHome'}
48
+ />
49
+ {props.children}
50
+ </>
51
+ );
52
+ } else {
53
+ return <DisconnectedView sensor={props.sensor} type={'GoogleHome'} />;
54
+ }
55
+ }
56
+ }
57
+ };