@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
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import renderer, { act } from 'react-test-renderer';
3
+ import DeviceItem from '../DeviceItem/DeviceItem';
4
+ import FImage from '../../FImage';
5
+ import Text from '../../Text';
6
+ describe('Test DeviceItem button', () => {
7
+ let tree;
8
+ test('create DeviceItem button', () => {
9
+ act(() => {
10
+ tree = renderer.create(<DeviceItem />);
11
+ });
12
+ const instance = tree.root;
13
+ const image = instance.findAllByType(FImage);
14
+ const text = instance.findAllByType(Text);
15
+ expect(image).toHaveLength(0);
16
+ expect(text).toHaveLength(1);
17
+ });
18
+ });
@@ -0,0 +1,205 @@
1
+ import React, { useEffect, useCallback, useState } from 'react';
2
+ import { SafeAreaView, View, TouchableOpacity } from 'react-native';
3
+ import { useTranslations } from '../../hooks/Common/useTranslations';
4
+ import Routes from '../../utils/Route';
5
+ import { useNavigation } from '@react-navigation/native';
6
+ import * as Progress from 'react-native-progress';
7
+ import ImageSuccessfully from '../../Images/Common/SuccessfullyConnected.svg';
8
+
9
+ import Text from '../Text';
10
+ import { axiosPost } from '../../utils/Apis/axios';
11
+ import { API, Colors, Constants } from '../../configs';
12
+ import styles from './styles';
13
+ import DeviceItem from './DeviceItem/DeviceItem';
14
+ import { useSCContextSelector } from '../../context';
15
+
16
+ const ConnectingProcess = ({ route }) => {
17
+ const { navigate, goBack } = useNavigation();
18
+ const t = useTranslations();
19
+
20
+ const {
21
+ scan_sensor_data,
22
+ gateway,
23
+ station,
24
+ unit,
25
+ unit_id,
26
+ unit_name,
27
+ devicePrefixName,
28
+ wifi_ssid,
29
+ wifi_pass,
30
+ chip_id,
31
+ } = route.params;
32
+ const [percent, setPercent] = useState(0);
33
+ const [isLoading, setIsLoading] = useState(true);
34
+ const [sensor, setSensor] = useState(null);
35
+ const user = useSCContextSelector((state) => state?.auth?.account?.user);
36
+ useEffect(() => {
37
+ processLoading();
38
+ }, [processLoading]);
39
+
40
+ const processLoading = useCallback(() => {
41
+ let interval;
42
+ if (isLoading) {
43
+ interval = setInterval(() => {
44
+ setPercent((prev) => {
45
+ if (prev === 1) {
46
+ clearInterval(interval);
47
+ return 1;
48
+ } else {
49
+ return prev + 0.2;
50
+ }
51
+ });
52
+ }, 180);
53
+ } else {
54
+ clearInterval(interval);
55
+ }
56
+ }, [isLoading]);
57
+
58
+ const ConnectingDevice = useCallback(async () => {
59
+ setIsLoading(true);
60
+ switch (devicePrefixName) {
61
+ case 'SENSOR':
62
+ {
63
+ const body = { imei: scan_sensor_data?.imei, chip: gateway?.id };
64
+ const { success, data } = await axiosPost(
65
+ API.SUB_UNIT.SENSOR_SCAN(station.id),
66
+ body
67
+ );
68
+ if (success) {
69
+ setSensor(data);
70
+ } else {
71
+ goBack();
72
+ }
73
+ }
74
+ break;
75
+ case 'ROBOT': {
76
+ const { success, data } = await axiosPost(API.UNIT.CHIP_SCAN(unit.id), {
77
+ imei: gateway?.imei,
78
+ qr_code: scan_sensor_data?.imei,
79
+ name: gateway?.model,
80
+ station: station?.id,
81
+ wifi_ssid: wifi_ssid,
82
+ wifi_pass: wifi_pass,
83
+ phone: user?.phone_number,
84
+ });
85
+ if (success) {
86
+ setSensor(data);
87
+ } else {
88
+ goBack();
89
+ }
90
+ break;
91
+ }
92
+ case 'LITE': {
93
+ const { success } = await axiosPost(API.UNIT.ADD_GATEWAY(unit_id), {
94
+ chip: chip_id,
95
+ imei: gateway?.imei,
96
+ chip_name: gateway?.model,
97
+ });
98
+ if (success) {
99
+ setSensor({ name: gateway?.model });
100
+ } else {
101
+ goBack();
102
+ }
103
+ break;
104
+ }
105
+ }
106
+ setIsLoading(false);
107
+ }, [
108
+ devicePrefixName,
109
+ scan_sensor_data?.imei,
110
+ gateway?.id,
111
+ gateway?.imei,
112
+ gateway?.model,
113
+ station,
114
+ goBack,
115
+ unit,
116
+ wifi_ssid,
117
+ wifi_pass,
118
+ user?.phone_number,
119
+ unit_id,
120
+ chip_id,
121
+ ]);
122
+
123
+ const Connecting = useCallback(() => {
124
+ return (
125
+ <>
126
+ <View style={styles.progressBar}>
127
+ <View style={styles.connecting}>
128
+ <Text type="H4" bold>
129
+ {t('connecting')}
130
+ </Text>
131
+ </View>
132
+ </View>
133
+ <View style={styles.percentLoad}>
134
+ <Progress.Bar
135
+ progress={percent}
136
+ animated={true}
137
+ color={Colors.Primary}
138
+ indeterminateAnimationDuration={1000}
139
+ height={7}
140
+ width={Constants.width - 80}
141
+ useNativeDriver={true}
142
+ />
143
+ <Text style={styles.textPercentLoad}>{`${parseInt(
144
+ percent * 100,
145
+ 10
146
+ )}%`}</Text>
147
+ </View>
148
+ </>
149
+ );
150
+ }, [percent, t]);
151
+
152
+ const ConnectingSuccess = useCallback(() => {
153
+ return (
154
+ <View style={styles.ConnectingSuccess}>
155
+ <ImageSuccessfully />
156
+ <Text bold style={styles.connectingText}>
157
+ {t('successfully_connected')}
158
+ </Text>
159
+ <Text size={14} style={styles.textHome}>
160
+ {`${unit?.name || unit_name} ${
161
+ station?.name !== undefined ? '- ' + station?.name : ''
162
+ }`}
163
+ </Text>
164
+ <DeviceItem icon={sensor?.icon_kit} name={sensor?.name} />
165
+ </View>
166
+ );
167
+ }, [sensor?.icon_kit, sensor?.name, station?.name, t, unit?.name, unit_name]);
168
+
169
+ const handleDone = useCallback(() => {
170
+ navigate(Routes.UnitStack, {
171
+ screen: Routes.UnitDetail,
172
+ params: {
173
+ unitId: unit?.id || unit_id,
174
+ unitData: unit,
175
+ routeName: 'DashboardStack',
176
+ stationId: station?.id,
177
+ },
178
+ });
179
+ }, [navigate, station?.id, unit, unit_id]);
180
+
181
+ useEffect(() => {
182
+ ConnectingDevice();
183
+ }, [ConnectingDevice]);
184
+
185
+ return (
186
+ <SafeAreaView style={styles.wrap}>
187
+ <View style={styles.boxText}>
188
+ <Text bold style={styles.connectingText}>
189
+ {t('connect_device')}
190
+ </Text>
191
+ {!!isLoading && <Connecting />}
192
+ {!isLoading && <ConnectingSuccess />}
193
+ </View>
194
+ {!isLoading && (
195
+ <TouchableOpacity style={styles.buttonDone} onPress={handleDone}>
196
+ <Text color={Colors.Primary} type={'H4'}>
197
+ {t('done')}
198
+ </Text>
199
+ </TouchableOpacity>
200
+ )}
201
+ </SafeAreaView>
202
+ );
203
+ };
204
+
205
+ export default ConnectingProcess;
@@ -0,0 +1,69 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import { Colors } from '../../configs';
3
+ import {
4
+ getStatusBarHeight,
5
+ getBottomSpace,
6
+ } from 'react-native-iphone-x-helper';
7
+
8
+ export default StyleSheet.create({
9
+ wrap: {
10
+ paddingTop: getStatusBarHeight(true),
11
+ backgroundColor: Colors.White,
12
+ width: '100%',
13
+ height: '100%',
14
+ justifyContent: 'space-between',
15
+ },
16
+ connectingText: {
17
+ marginLeft: 30,
18
+ marginTop: 16,
19
+ fontSize: 20,
20
+ color: Colors.Gray9,
21
+ },
22
+ animatedEllipsis: {
23
+ fontSize: 25,
24
+ color: Colors.Gray9,
25
+ marginTop: 14,
26
+ },
27
+ warningText: {
28
+ marginHorizontal: 30,
29
+ marginTop: 16,
30
+ fontSize: 14,
31
+ color: Colors.Gray8,
32
+ },
33
+ boxText: {
34
+ flex: 1,
35
+ },
36
+ progressBar: {
37
+ flexDirection: 'column',
38
+ marginTop: 180,
39
+ marginHorizontal: 30,
40
+ },
41
+ connecting: {
42
+ flexDirection: 'row',
43
+ justifyContent: 'center',
44
+ marginBottom: 10,
45
+ },
46
+ percentLoad: {
47
+ flexDirection: 'row',
48
+ justifyContent: 'center',
49
+ alignItems: 'center',
50
+ },
51
+ textPercentLoad: {
52
+ marginLeft: 10,
53
+ },
54
+ ConnectingSuccess: {
55
+ marginTop: 180,
56
+ justifyContent: 'center',
57
+ alignItems: 'center',
58
+ },
59
+ textHome: {
60
+ paddingTop: 16,
61
+ paddingBottom: 8,
62
+ },
63
+ buttonDone: {
64
+ width: '100%',
65
+ justifyContent: 'center',
66
+ alignItems: 'center',
67
+ paddingBottom: getBottomSpace() + 24,
68
+ },
69
+ });
@@ -14,7 +14,7 @@ import Text from '../../commons/Text';
14
14
  import { isDeviceConnected } from '../../iot/RemoteControl/Bluetooth';
15
15
 
16
16
  import { Colors, Constants } from '../../configs';
17
- import { TESTID } from '../../configs/Constants';
17
+ import { TESTID, DEVICE_TYPE } from '../../configs/Constants';
18
18
  import FImage from '../../commons/FImage';
19
19
 
20
20
  const marginItem = 12;
@@ -61,11 +61,16 @@ const ItemDevice = memo(
61
61
  status === undefined
62
62
  ? isNetworkConnected && sensor.is_connected
63
63
  : isNetworkConnected && status.is_connected;
64
- const isBLEConnected = isDeviceConnected(
64
+ const isConnectedViaBLE = isDeviceConnected(
65
65
  sensor?.remote_control_options?.bluetooth?.address
66
66
  );
67
+ const isConnectedViaGGHome =
68
+ !!sensor &&
69
+ sensor?.is_other_device &&
70
+ !sensor?.device_type !== DEVICE_TYPE.LG_THINQ &&
71
+ isGGHomeConnected;
67
72
  const isConnected =
68
- isConnectedViaInternet || isGGHomeConnected || isBLEConnected;
73
+ isConnectedViaInternet || isConnectedViaGGHome || isConnectedViaBLE;
69
74
  const borderColor = isConnected ? Colors.Gray4 : Colors.Red6;
70
75
  const textConnected = isConnected ? t('connected') : t('disconnected');
71
76
 
@@ -55,6 +55,7 @@ const chartOptions = {
55
55
  },
56
56
  },
57
57
  minRange: 3600 * 24 * 1000,
58
+ tickInterval: 24 * 3600 * 1000,
58
59
  },
59
60
  plotOptions: {
60
61
  series: {
@@ -37,7 +37,7 @@ export default ListQualityIndicator;
37
37
  const styles = StyleSheet.create({
38
38
  standard: {
39
39
  flexDirection: 'row',
40
- marginTop: 16,
40
+ marginVertical: 16,
41
41
  },
42
42
  flatlistContent: {
43
43
  paddingHorizontal: 16,
@@ -68,7 +68,7 @@ const styles = StyleSheet.create({
68
68
  borderWidth: 1,
69
69
  borderColor: Colors.Gray4,
70
70
  marginRight: 8,
71
- width: (width / 375) * 120,
71
+ width: ((width - 32) / 375) * 120,
72
72
  },
73
73
  rowFlex: {
74
74
  flexDirection: 'row',
@@ -111,7 +111,7 @@ const styles = StyleSheet.create({
111
111
  icons: {
112
112
  position: 'absolute',
113
113
  right: 0,
114
- top: 7,
114
+ top: -5,
115
115
  bottom: 0,
116
116
  width: 40,
117
117
  justifyContent: 'center',
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import { View, ActivityIndicator, StyleSheet } from 'react-native';
3
+
4
+ import { colorOpacity } from '../../utils/Converter/color';
5
+ import { Colors } from '../../configs';
6
+
7
+ const FullLoading = ({ wrapStyle, color = Colors.Primary, size = 'small' }) => (
8
+ <View style={[styles.wrap, wrapStyle]}>
9
+ <View style={styles.background}>
10
+ <ActivityIndicator color={color} size={size} />
11
+ </View>
12
+ </View>
13
+ );
14
+
15
+ const styles = StyleSheet.create({
16
+ wrap: {
17
+ position: 'absolute',
18
+ backgroundColor: colorOpacity(Colors.Black, 0.1),
19
+ alignItems: 'center',
20
+ justifyContent: 'center',
21
+ top: 0,
22
+ left: 0,
23
+ bottom: 0,
24
+ right: 0,
25
+ zIndex: 10,
26
+ },
27
+ background: {
28
+ backgroundColor: colorOpacity(Colors.White, 0.8),
29
+ borderRadius: 5,
30
+ paddingHorizontal: 32,
31
+ paddingVertical: 24,
32
+ },
33
+ });
34
+
35
+ export default FullLoading;
@@ -0,0 +1,45 @@
1
+ import React from 'react';
2
+ import { act, create } from 'react-test-renderer';
3
+ import { SCProvider } from '../../../context';
4
+ import { mockSCStore } from '../../../context/mockStore';
5
+ import { TouchableOpacity } from 'react-native';
6
+ import MediaPlay from '../index';
7
+
8
+ jest.mock('react', () => {
9
+ return {
10
+ ...jest.requireActual('react'),
11
+ memo: (x) => x,
12
+ };
13
+ });
14
+
15
+ const wrapComponent = (props) => (
16
+ <SCProvider initState={mockSCStore({})}>
17
+ <MediaPlay {...props} />
18
+ </SCProvider>
19
+ );
20
+
21
+ describe('Test MediaPlayer', () => {
22
+ let tree, props;
23
+
24
+ beforeAll(() => {
25
+ jest.useFakeTimers();
26
+ props = {
27
+ uri: 'uri',
28
+ previewUri: 'previewUri',
29
+ thumbnail: 'thumbnail',
30
+ background: 'background',
31
+ };
32
+ });
33
+
34
+ it('Test render', async () => {
35
+ await act(async () => {
36
+ tree = await create(wrapComponent(props));
37
+ });
38
+ const instance = tree.root;
39
+ const pauseButton = instance.findByType(TouchableOpacity);
40
+ await act(async () => {
41
+ await pauseButton.props.onPress();
42
+ });
43
+ jest.runAllTimers();
44
+ });
45
+ });
@@ -7,6 +7,7 @@ import { API, Colors } from '../../../configs';
7
7
  import OneTap from '../../../../assets/images/OneTap.svg';
8
8
  import ValueChange from '../../../../assets/images/ValueChange.svg';
9
9
  import Schedule from '../../../../assets/images/Schedule.svg';
10
+ import Event from '../../../../assets/images/Event.svg';
10
11
  import CheckCircle from '../../../../assets/images/CheckCircle.svg';
11
12
  import FImage from '../../FImage';
12
13
  import { timeDifference } from '../../../utils/Converter/time';
@@ -92,6 +93,8 @@ const ItemOneTap = memo(
92
93
  return <OneTap />;
93
94
  } else if (type === AUTOMATE_TYPE.VALUE_CHANGE) {
94
95
  return <ValueChange />;
96
+ } else if (type === AUTOMATE_TYPE.EVENT) {
97
+ return <Event />;
95
98
  } else {
96
99
  return <Schedule />;
97
100
  }
@@ -4,7 +4,7 @@ import { useNavigation, useIsFocused } from '@react-navigation/native';
4
4
  import { useTranslations } from '../../hooks/Common/useTranslations';
5
5
 
6
6
  import { Images, Device, API } from '../../configs';
7
- import { SubUnitName, TESTID } from '../../configs/Constants';
7
+ import { TESTID } from '../../configs/Constants';
8
8
  import { Section } from '../Section';
9
9
  import Text from '../Text';
10
10
  import ItemDevice from '../Device/ItemDevice';
@@ -104,28 +104,16 @@ const ShortDetailSubUnit = ({
104
104
  };
105
105
 
106
106
  const handleOnAddNew = () => {
107
- if (!station.isFavorites) {
108
- navigate(Routes.AddDeviceStack, {
109
- screen: Routes.ScanSensorQR,
110
- params: {
111
- station_id: station.id,
112
- unit_id: unit.id,
113
- unit_name: unit.name,
114
- },
115
- });
116
- } else {
117
- alert(t('feature_under_development'));
118
- }
107
+ navigate(Routes.AddDeviceStack, {
108
+ screen: Routes.ScanSensorQR,
109
+ params: {
110
+ station_id: station?.id,
111
+ unit_id: unit.id,
112
+ unit_name: unit.name,
113
+ },
114
+ });
119
115
  };
120
116
 
121
- const itemAddNewTitle = t(
122
- station?.isFavorites
123
- ? 'add_to_favorites'
124
- : station?.name === SubUnitName.smart
125
- ? 'add_script'
126
- : 'add_new'
127
- );
128
-
129
117
  return (
130
118
  <Section style={styles.noShadow}>
131
119
  {renderCamera()}
@@ -156,7 +144,7 @@ const ShortDetailSubUnit = ({
156
144
  status={sensorsStatus.find((s) => s.id === sensor.id)}
157
145
  />
158
146
  ))}
159
- <ItemAddNew title={itemAddNewTitle} onAddNew={handleOnAddNew} />
147
+ <ItemAddNew title={t('add_new_device')} onAddNew={handleOnAddNew} />
160
148
  </View>
161
149
  </Section>
162
150
  );