@eohjsc/react-native-smart-city 0.2.55 → 0.2.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/images/SonosSpeaker/buttonpause-active.svg +3 -0
- package/assets/images/SonosSpeaker/buttonpause-notactive.svg +3 -0
- package/assets/images/SonosSpeaker/picture-main-notactive.svg +5 -0
- package/assets/images/SonosSpeaker/picture-main.svg +6 -0
- package/assets/images/SonosSpeaker/picture-volume.svg +3 -0
- package/package.json +4 -22
- package/src/Images/Common/buttonLeftCurtain.png +0 -0
- package/src/Images/Common/buttonPause-center-curtain.png +0 -0
- package/src/Images/Common/buttonRightCurtain.png +0 -0
- package/src/commons/ActionGroup/CurtainButtonTemplate.js +139 -0
- package/src/commons/ActionGroup/CurtainButtonTemplateStyle.js +58 -0
- package/src/commons/ActionGroup/__test__/CurtainButtonTemplate.test.js +72 -0
- package/src/commons/ActionGroup/index.js +3 -0
- package/src/commons/AlertAction/index.js +3 -3
- package/src/commons/Auth/__test__/AccountList.test.js +33 -0
- package/src/commons/CameraDevice/index.js +2 -0
- package/src/commons/CardShadow/index.js +1 -1
- package/src/commons/CardShadow/styles.js +1 -3
- package/src/commons/DateTimeRangeChange/index.js +2 -2
- package/src/commons/Device/HistoryChart.js +9 -39
- package/src/commons/Device/HorizontalBarChart.js +1 -1
- package/src/commons/Device/LinearChart.js +0 -34
- package/src/commons/Device/PMSensor/PMSensorIndicatior.js +1 -1
- package/src/commons/Device/PMSensor/PMSensorIndicatorStyles.js +2 -1
- package/src/commons/Device/SonosSpeaker/__test__/SonosSpeaker.test.js +57 -0
- package/src/commons/Device/SonosSpeaker/index.js +88 -0
- package/src/commons/Device/SonosSpeaker/styles.js +57 -0
- package/src/commons/Form/CurrencyInput.js +169 -0
- package/src/commons/Form/__test__/CurrencyInput.test.js +65 -0
- package/src/commons/MediaPlayerDetail/Styles/MediaPlayerDetailStyles.js +4 -0
- package/src/commons/MediaPlayerDetail/index.js +195 -161
- package/src/commons/SearchLocation/index.js +0 -1
- package/src/commons/Sharing/RowMember.js +7 -2
- package/src/commons/Sharing/__test__/RowMember.test.js +42 -0
- package/src/commons/SubUnit/ShortDetail.js +12 -6
- package/src/commons/ThreeButtonHistory/__test__/ThreeButtonHistory.test.js +17 -8
- package/src/commons/ThreeButtonHistory/index.js +52 -23
- package/src/commons/UnitSummary/AirQuality/SegmentedRoundDisplay/index.js +1 -1
- package/src/configs/API.js +10 -3
- package/src/configs/Constants.js +8 -4
- package/src/configs/Images.js +3 -0
- package/src/configs/SCConfig.js +8 -0
- package/src/context/actionType.ts +5 -0
- package/src/context/mockStore.ts +3 -0
- package/src/context/reducer.ts +14 -0
- package/src/iot/RemoteControl/Bluetooth.js +14 -0
- package/src/iot/RemoteControl/index.js +0 -1
- package/src/navigations/UnitStack.js +26 -4
- package/src/screens/ActivityLog/FilterPopup.js +1 -1
- package/src/screens/ActivityLog/ItemLog.js +9 -0
- package/src/screens/ActivityLog/__test__/ItemLog.test.js +43 -0
- package/src/screens/AddCommon/SelectSubUnit.js +24 -2
- package/src/screens/AddCommon/SelectUnit.js +12 -0
- package/src/screens/AddLocationMaps/index.js +137 -44
- package/src/screens/AddLocationMaps/indexStyle.js +14 -12
- package/src/screens/AddNewAction/SelectAction.js +1 -0
- package/src/screens/Automate/MultiUnits.js +8 -8
- package/src/screens/Automate/__test__/MultiUnits.test.js +2 -2
- package/src/screens/Automate/__test__/index.test.js +2 -0
- package/src/screens/Automate/index.js +4 -2
- package/src/screens/Device/__test__/detail.test.js +0 -5
- package/src/screens/Device/components/SensorDisplayItem.js +10 -10
- package/src/screens/Device/detail.js +21 -4
- package/src/screens/Device/hooks/useDisconnectedDevice.js +31 -26
- package/src/screens/Notification/__test__/Notification.test.js +3 -3
- package/src/screens/Notification/components/NotificationItem.js +3 -6
- package/src/screens/Notification/index.js +2 -2
- package/src/screens/ScriptDetail/__test__/index.test.js +13 -0
- package/src/screens/ScriptDetail/index.js +20 -17
- package/src/screens/SelectUnit/index.js +2 -0
- package/src/screens/Sharing/MemberList.js +2 -9
- package/src/screens/SubUnit/AddSubUnit.js +79 -59
- package/src/screens/SubUnit/__test__/AddSubUnit.test.js +4 -3
- package/src/screens/TDSGuide/index.js +6 -4
- package/src/screens/Unit/ChooseLocation.js +100 -0
- package/src/screens/Unit/ChooseLocationStyles.js +29 -0
- package/src/screens/Unit/Detail.js +14 -2
- package/src/screens/Unit/ManageUnit.js +4 -5
- package/src/screens/Unit/SelectAddress.js +240 -0
- package/src/screens/Unit/SelectAddressStyles.js +48 -0
- package/src/screens/Unit/SmartAccount.js +2 -3
- package/src/screens/Unit/SmartAccountItem.js +1 -1
- package/src/screens/Unit/Summaries.js +5 -1
- package/src/screens/Unit/__test__/ChooseLocation.test.js +112 -0
- package/src/screens/Unit/__test__/SelectAddress.test.js +216 -0
- package/src/screens/Unit/components/MyUnitDevice/index.js +21 -5
- package/src/screens/Unit/hook/useStateAlertRemove.js +3 -1
- package/src/screens/UnitSummary/components/3PPowerConsumption/index.js +1 -1
- package/src/screens/UnitSummary/components/PowerConsumption/index.js +1 -1
- package/src/screens/UnitSummary/components/WaterQuality/Item/index.js +1 -3
- package/src/screens/UnitSummary/index.js +3 -2
- package/src/utils/Apis/axios.js +17 -5
- package/src/utils/I18n/translations/en.json +13 -4
- package/src/utils/I18n/translations/vi.json +16 -7
- package/src/utils/Route/index.js +2 -1
- package/src/utils/Utils.js +22 -2
- package/assets/images/AddLocationMaps/PinLocation.svg +0 -3
- package/assets/images/AddLocationMaps/Point.svg +0 -3
- package/src/screens/Unit/ManageUnit/index.js +0 -286
- package/src/screens/Unit/SelectLocation.js +0 -161
- package/src/screens/Unit/SelectLocationStyles.js +0 -114
|
@@ -63,6 +63,17 @@ describe('Test ScriptDetail', () => {
|
|
|
63
63
|
unit: { id: 2 },
|
|
64
64
|
type: AUTOMATE_TYPE.ONE_TAP,
|
|
65
65
|
havePermission: true,
|
|
66
|
+
automate: {
|
|
67
|
+
author: 'Le Minh Tam',
|
|
68
|
+
condition: '<',
|
|
69
|
+
config: 'PM2.5 (Mr.Son Office)',
|
|
70
|
+
config_id: 201,
|
|
71
|
+
config_name: 'PM2.5 (Mr.Son Office)',
|
|
72
|
+
id: 1009,
|
|
73
|
+
sensor_id: 73,
|
|
74
|
+
type: 'value_change',
|
|
75
|
+
value: 35,
|
|
76
|
+
},
|
|
66
77
|
},
|
|
67
78
|
};
|
|
68
79
|
data = {
|
|
@@ -247,6 +258,7 @@ describe('Test ScriptDetail', () => {
|
|
|
247
258
|
scriptName: route.params.name,
|
|
248
259
|
title: AUTOMATE_SELECT.SELECT_DEVICES,
|
|
249
260
|
type: AUTOMATE_TYPE.ONE_TAP,
|
|
261
|
+
automate: route.params.automate,
|
|
250
262
|
});
|
|
251
263
|
});
|
|
252
264
|
|
|
@@ -269,6 +281,7 @@ describe('Test ScriptDetail', () => {
|
|
|
269
281
|
scriptName: route.params.name,
|
|
270
282
|
title: AUTOMATE_SELECT.SELECT_DEVICES,
|
|
271
283
|
type: AUTOMATE_TYPE.ONE_TAP,
|
|
284
|
+
automate: route.params.automate,
|
|
272
285
|
});
|
|
273
286
|
});
|
|
274
287
|
|
|
@@ -6,13 +6,7 @@ import React, {
|
|
|
6
6
|
useEffect,
|
|
7
7
|
memo,
|
|
8
8
|
} from 'react';
|
|
9
|
-
import {
|
|
10
|
-
View,
|
|
11
|
-
TouchableOpacity,
|
|
12
|
-
Image,
|
|
13
|
-
BackHandler,
|
|
14
|
-
Platform,
|
|
15
|
-
} from 'react-native';
|
|
9
|
+
import { View, TouchableOpacity, Image, Platform } from 'react-native';
|
|
16
10
|
import { IconFill, IconOutline } from '@ant-design/icons-react-native';
|
|
17
11
|
import { Icon } from '@ant-design/react-native';
|
|
18
12
|
|
|
@@ -106,8 +100,23 @@ const ScriptDetail = ({ route }) => {
|
|
|
106
100
|
const deleteScript = useCallback(async () => {
|
|
107
101
|
hideAlertAction();
|
|
108
102
|
const { success } = await axiosDelete(API.AUTOMATE.SCRIPT(id));
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
if (success) {
|
|
104
|
+
if (isCreateScriptSuccess || isCreateNewAction) {
|
|
105
|
+
dispatch(popAction(5));
|
|
106
|
+
isAutomateTab && goBack();
|
|
107
|
+
} else {
|
|
108
|
+
goBack();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}, [
|
|
112
|
+
hideAlertAction,
|
|
113
|
+
id,
|
|
114
|
+
isCreateScriptSuccess,
|
|
115
|
+
isCreateNewAction,
|
|
116
|
+
dispatch,
|
|
117
|
+
isAutomateTab,
|
|
118
|
+
goBack,
|
|
119
|
+
]);
|
|
111
120
|
|
|
112
121
|
const handleRenameOrDelete = useCallback(async () => {
|
|
113
122
|
if (stateAlertAction.isDelete) {
|
|
@@ -196,12 +205,13 @@ const ScriptDetail = ({ route }) => {
|
|
|
196
205
|
type,
|
|
197
206
|
isCreateNewAction: true,
|
|
198
207
|
title: AUTOMATE_SELECT.SELECT_DEVICES,
|
|
208
|
+
automate,
|
|
199
209
|
};
|
|
200
210
|
navigate(
|
|
201
211
|
isMultiUnits ? Routes.SelectUnit : Routes.SelectSensorDevices,
|
|
202
212
|
params
|
|
203
213
|
);
|
|
204
|
-
}, [unit, scriptName, id, type, navigate, isMultiUnits]);
|
|
214
|
+
}, [unit, scriptName, id, type, navigate, isMultiUnits, automate]);
|
|
205
215
|
|
|
206
216
|
const handleScriptAction = useCallback(async () => {
|
|
207
217
|
const { success } = await axiosPost(API.AUTOMATE.ACTION_ONE_TAP(id));
|
|
@@ -344,13 +354,6 @@ const ScriptDetail = ({ route }) => {
|
|
|
344
354
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
345
355
|
}, [id, saveAt]);
|
|
346
356
|
|
|
347
|
-
useEffect(() => {
|
|
348
|
-
const backHandler = BackHandler.addEventListener(
|
|
349
|
-
'hardwareBackPress',
|
|
350
|
-
() => isCreateScriptSuccess
|
|
351
|
-
);
|
|
352
|
-
return () => backHandler.remove();
|
|
353
|
-
}, [isCreateScriptSuccess]);
|
|
354
357
|
const isHaveScriptActions = data?.length > 0;
|
|
355
358
|
|
|
356
359
|
const textCondition = useMemo(() => {
|
|
@@ -28,6 +28,7 @@ const SelectUnit = () => {
|
|
|
28
28
|
isCreateNewAction,
|
|
29
29
|
unit,
|
|
30
30
|
title,
|
|
31
|
+
automate,
|
|
31
32
|
} = params;
|
|
32
33
|
const [data, setData] = useState([]);
|
|
33
34
|
const [selectedItem, setSelectedItem] = useState(data[0]);
|
|
@@ -66,6 +67,7 @@ const SelectUnit = () => {
|
|
|
66
67
|
isCreateNewAction || !routeName ? Routes.SelectSensorDevices : routeName,
|
|
67
68
|
{
|
|
68
69
|
...params,
|
|
70
|
+
automate,
|
|
69
71
|
title,
|
|
70
72
|
selectedItem,
|
|
71
73
|
type,
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import React, { useCallback } from 'react';
|
|
2
2
|
import { IconOutline } from '@ant-design/icons-react-native';
|
|
3
3
|
import { useNavigation } from '@react-navigation/native';
|
|
4
|
-
import {
|
|
5
|
-
StyleSheet,
|
|
6
|
-
TouchableOpacity,
|
|
7
|
-
View,
|
|
8
|
-
ActivityIndicator,
|
|
9
|
-
} from 'react-native';
|
|
4
|
+
import { StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
10
5
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
11
6
|
|
|
12
7
|
import { Colors } from '../../configs';
|
|
@@ -91,9 +86,7 @@ const MemberList = ({ route }) => {
|
|
|
91
86
|
loading={isRefresh}
|
|
92
87
|
onRefresh={onRefresh}
|
|
93
88
|
>
|
|
94
|
-
{loading
|
|
95
|
-
<ActivityIndicator />
|
|
96
|
-
) : (
|
|
89
|
+
{!loading && (
|
|
97
90
|
<SharingMembers
|
|
98
91
|
dataMember={dataMembers}
|
|
99
92
|
ownerId={unit.user_id}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
useState,
|
|
3
|
+
useCallback,
|
|
4
|
+
useMemo,
|
|
5
|
+
useEffect,
|
|
6
|
+
useRef,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import {
|
|
3
9
|
View,
|
|
4
10
|
Image,
|
|
@@ -42,80 +48,94 @@ const prepareImageToUpload = async (image) => {
|
|
|
42
48
|
|
|
43
49
|
const AddSubUnit = ({ route }) => {
|
|
44
50
|
const t = useTranslations();
|
|
45
|
-
const
|
|
51
|
+
const { navigate, goBack } = useNavigation();
|
|
46
52
|
const { unit, addType, isAddUnit, location = '' } = route?.params;
|
|
47
53
|
const [roomName, setRoomName] = useState('');
|
|
48
54
|
const [wallpaper, setWallpaper] = useState('');
|
|
49
55
|
const [imageUrl, setImageUrl] = useState('');
|
|
50
56
|
const [showImagePicker, setShowImagePicker] = useState(false);
|
|
57
|
+
let awaitCreate = useRef(false);
|
|
51
58
|
|
|
52
59
|
const goDone = useCallback(async () => {
|
|
53
60
|
if (isAddUnit) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
if (!awaitCreate.current) {
|
|
62
|
+
awaitCreate.current = true;
|
|
63
|
+
const dataObj = {
|
|
64
|
+
name: roomName,
|
|
65
|
+
address: location,
|
|
66
|
+
background: wallpaper,
|
|
67
|
+
};
|
|
68
|
+
dataObj.background = await prepareImageToUpload(dataObj.background);
|
|
69
|
+
const formData = createFormData(dataObj, ['background']);
|
|
70
|
+
const { success, data } = await axiosPost(
|
|
71
|
+
API.UNIT.CREATE_UNIT(),
|
|
72
|
+
formData,
|
|
73
|
+
{
|
|
74
|
+
headers: { 'Content-Type': 'multipart/form-data' },
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
if (success) {
|
|
78
|
+
navigate(Routes.UnitStack, {
|
|
79
|
+
screen: Routes.UnitDetail,
|
|
80
|
+
params: {
|
|
81
|
+
unitId: data?.id,
|
|
82
|
+
routeName: Routes.DashboardStack,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
awaitCreate.current = false;
|
|
87
|
+
ToastBottomHelper.error(t('text_create_unit_fail'));
|
|
66
88
|
}
|
|
67
|
-
);
|
|
68
|
-
if (success) {
|
|
69
|
-
navigation.navigate(Routes.UnitStack, {
|
|
70
|
-
screen: Routes.UnitDetail,
|
|
71
|
-
params: {
|
|
72
|
-
unitId: data?.id,
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
} else {
|
|
76
|
-
ToastBottomHelper.error(t('text_create_unit_fail'));
|
|
77
89
|
}
|
|
78
90
|
} else {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
if (!awaitCreate.current) {
|
|
92
|
+
awaitCreate.current = true;
|
|
93
|
+
const dataObj = { name: roomName, background: wallpaper };
|
|
94
|
+
dataObj.background = await prepareImageToUpload(dataObj.background);
|
|
95
|
+
const formData = createFormData(dataObj, ['background']);
|
|
96
|
+
const { success, data } = await axiosPost(
|
|
97
|
+
API.SUB_UNIT.CREATE_SUB_UNIT(unit.id),
|
|
98
|
+
formData,
|
|
99
|
+
{
|
|
100
|
+
headers: { 'Content-Type': 'multipart/form-data' },
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
if (success) {
|
|
104
|
+
ToastBottomHelper.success(t('text_create_sub_unit_success'));
|
|
105
|
+
if (addType === 'AddHassiDevice') {
|
|
106
|
+
goBack();
|
|
107
|
+
return;
|
|
108
|
+
} else if (addType === 'AddNewGateway') {
|
|
109
|
+
navigate(Routes.AddCommonSelectSubUnit, {
|
|
110
|
+
...route.params,
|
|
111
|
+
});
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
navigate(Routes.UnitStack, {
|
|
115
|
+
screen: Routes.UnitDetail,
|
|
116
|
+
params: {
|
|
117
|
+
unitId: unit.id,
|
|
118
|
+
unitData: data,
|
|
119
|
+
isAddSubUnit: true,
|
|
120
|
+
},
|
|
95
121
|
});
|
|
96
|
-
|
|
122
|
+
} else {
|
|
123
|
+
awaitCreate.current = false;
|
|
124
|
+
ToastBottomHelper.error(t('text_create_sub_unit_fail'));
|
|
97
125
|
}
|
|
98
|
-
navigation.navigate(Routes.UnitStack, {
|
|
99
|
-
screen: Routes.SubUnitDetail,
|
|
100
|
-
params: {
|
|
101
|
-
unit: unit,
|
|
102
|
-
station: data,
|
|
103
|
-
},
|
|
104
|
-
});
|
|
105
|
-
} else {
|
|
106
|
-
ToastBottomHelper.error(t('text_create_sub_unit_fail'));
|
|
107
126
|
}
|
|
108
127
|
}
|
|
109
128
|
}, [
|
|
110
|
-
|
|
111
|
-
navigation,
|
|
129
|
+
isAddUnit,
|
|
112
130
|
roomName,
|
|
113
|
-
|
|
131
|
+
location,
|
|
132
|
+
wallpaper,
|
|
133
|
+
navigate,
|
|
114
134
|
t,
|
|
115
135
|
unit,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
136
|
+
addType,
|
|
137
|
+
goBack,
|
|
138
|
+
route.params,
|
|
119
139
|
]);
|
|
120
140
|
|
|
121
141
|
const onChoosePhoto = useCallback(() => {
|
|
@@ -144,8 +164,8 @@ const AddSubUnit = ({ route }) => {
|
|
|
144
164
|
}, [roomName, wallpaper, location, isAddUnit]);
|
|
145
165
|
|
|
146
166
|
const onChooseLocation = useCallback(() => {
|
|
147
|
-
|
|
148
|
-
}, [
|
|
167
|
+
navigate(Routes.AddLocationMaps);
|
|
168
|
+
}, [navigate]);
|
|
149
169
|
|
|
150
170
|
return (
|
|
151
171
|
<SafeAreaView style={styles.wrap}>
|
|
@@ -211,7 +231,7 @@ const AddSubUnit = ({ route }) => {
|
|
|
211
231
|
</View>
|
|
212
232
|
<ViewButtonBottom
|
|
213
233
|
leftTitle={t('cancel')}
|
|
214
|
-
onLeftClick={() =>
|
|
234
|
+
onLeftClick={() => goBack()}
|
|
215
235
|
rightTitle={t('done')}
|
|
216
236
|
rightDisabled={validateData}
|
|
217
237
|
onRightClick={goDone}
|
|
@@ -158,10 +158,11 @@ describe('Test AddSubUnit', () => {
|
|
|
158
158
|
});
|
|
159
159
|
expect(axios.post).toHaveBeenCalled();
|
|
160
160
|
expect(mockedNavigate).toHaveBeenCalledWith(Routes.UnitStack, {
|
|
161
|
-
screen: Routes.
|
|
161
|
+
screen: Routes.UnitDetail,
|
|
162
162
|
params: {
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
unitId: route.params.unit.id,
|
|
164
|
+
unitData: response.data,
|
|
165
|
+
isAddSubUnit: true,
|
|
165
166
|
},
|
|
166
167
|
});
|
|
167
168
|
expect(Toast.show).toHaveBeenCalledWith({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { memo } from 'react';
|
|
2
|
-
import { StyleSheet,
|
|
2
|
+
import { StyleSheet, View, ScrollView } from 'react-native';
|
|
3
3
|
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
4
4
|
import { TESTID } from '../../configs/Constants';
|
|
5
5
|
|
|
@@ -12,8 +12,8 @@ const TDSGuide = memo(() => {
|
|
|
12
12
|
useTitleHeader(t('tds_infomation'));
|
|
13
13
|
|
|
14
14
|
return (
|
|
15
|
-
<
|
|
16
|
-
<ScrollView>
|
|
15
|
+
<View style={styles.container}>
|
|
16
|
+
<ScrollView style={styles.paddingHorizontal16}>
|
|
17
17
|
<Text
|
|
18
18
|
type="H3"
|
|
19
19
|
semibold
|
|
@@ -38,7 +38,7 @@ const TDSGuide = memo(() => {
|
|
|
38
38
|
</Text>
|
|
39
39
|
</>
|
|
40
40
|
</ScrollView>
|
|
41
|
-
</
|
|
41
|
+
</View>
|
|
42
42
|
);
|
|
43
43
|
});
|
|
44
44
|
|
|
@@ -48,6 +48,8 @@ const styles = StyleSheet.create({
|
|
|
48
48
|
container: {
|
|
49
49
|
flex: 1,
|
|
50
50
|
backgroundColor: Theme.color.backgroundColor,
|
|
51
|
+
},
|
|
52
|
+
paddingHorizontal16: {
|
|
51
53
|
paddingHorizontal: 16,
|
|
52
54
|
},
|
|
53
55
|
titlePadding: {
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
2
|
+
import React, { memo, useCallback, useRef, useState } from 'react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import MapView, { PROVIDER_GOOGLE } from 'react-native-maps';
|
|
5
|
+
import { useNavigation } from '@react-navigation/native';
|
|
6
|
+
import { IconFill, IconOutline } from '@ant-design/icons-react-native';
|
|
7
|
+
|
|
8
|
+
import BottomButtonView from '../../commons/BottomButtonView';
|
|
9
|
+
import { useTranslations } from '../../hooks/Common/useTranslations';
|
|
10
|
+
|
|
11
|
+
navigator.geolocation = require('@react-native-community/geolocation');
|
|
12
|
+
|
|
13
|
+
import styles from './ChooseLocationStyles';
|
|
14
|
+
import { API, Colors } from '../../configs';
|
|
15
|
+
import { axiosGet } from '../../utils/Apis/axios';
|
|
16
|
+
import { SCConfig } from '../../configs';
|
|
17
|
+
|
|
18
|
+
const initialRegion = {
|
|
19
|
+
latitudeDelta: 0.0922,
|
|
20
|
+
longitudeDelta: 0.0421,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const DEFAULT_LATITUDE = 10.7974046; // EoH center
|
|
24
|
+
const DEFAULT_LONGITUDE = 106.7035663;
|
|
25
|
+
|
|
26
|
+
const ChooseLocation = memo(({ route }) => {
|
|
27
|
+
const t = useTranslations();
|
|
28
|
+
const { location, setAddress, setLocation } = route.params;
|
|
29
|
+
const { goBack } = useNavigation();
|
|
30
|
+
const [currentLocation, setCurrentLocation] = useState(location);
|
|
31
|
+
const mapRef = useRef(null);
|
|
32
|
+
|
|
33
|
+
const onDone = useCallback(async () => {
|
|
34
|
+
if (!currentLocation) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const { latitude, longitude } = currentLocation;
|
|
38
|
+
const { success, data } = await axiosGet(
|
|
39
|
+
API.EXTERNAL.GOOGLE_MAP.GET_LOCATION_FROM_LAT_LNG,
|
|
40
|
+
{
|
|
41
|
+
params: {
|
|
42
|
+
latlng: `${latitude},${longitude}`,
|
|
43
|
+
key: SCConfig.GOOGLE_MAP_API_KEY,
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
if (success && data.results.length > 0) {
|
|
48
|
+
const result = data.results[0];
|
|
49
|
+
setAddress(result.formatted_address);
|
|
50
|
+
setLocation({
|
|
51
|
+
description: result.formatted_address,
|
|
52
|
+
latitude: result.geometry.location.lat,
|
|
53
|
+
longitude: result.geometry.location.lng,
|
|
54
|
+
});
|
|
55
|
+
goBack();
|
|
56
|
+
}
|
|
57
|
+
}, [currentLocation, setAddress, setLocation, goBack]);
|
|
58
|
+
|
|
59
|
+
const onRegionChange = useCallback(
|
|
60
|
+
(region) => {
|
|
61
|
+
setCurrentLocation({
|
|
62
|
+
latitude: region.latitude,
|
|
63
|
+
longitude: region.longitude,
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
[setCurrentLocation]
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<View style={styles.wrap}>
|
|
71
|
+
<MapView
|
|
72
|
+
ref={mapRef}
|
|
73
|
+
provider={PROVIDER_GOOGLE}
|
|
74
|
+
style={styles.mapView}
|
|
75
|
+
initialRegion={{
|
|
76
|
+
...initialRegion,
|
|
77
|
+
latitude: location?.latitude || DEFAULT_LATITUDE,
|
|
78
|
+
longitude: location?.longitude || DEFAULT_LONGITUDE,
|
|
79
|
+
}}
|
|
80
|
+
followUserLocation={true}
|
|
81
|
+
onRegionChangeComplete={onRegionChange}
|
|
82
|
+
/>
|
|
83
|
+
<View style={styles.wrapMarker}>
|
|
84
|
+
<>
|
|
85
|
+
<IconFill name="environment" size={27} color={Colors.Blue10} />
|
|
86
|
+
<IconOutline name="close" size={14} color={Colors.Gray9} />
|
|
87
|
+
</>
|
|
88
|
+
</View>
|
|
89
|
+
<BottomButtonView
|
|
90
|
+
rowButton
|
|
91
|
+
style={styles.bottomButton}
|
|
92
|
+
mainTitle={t('done')}
|
|
93
|
+
onPressMain={onDone}
|
|
94
|
+
typeMain="primaryText"
|
|
95
|
+
/>
|
|
96
|
+
</View>
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export default ChooseLocation;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { Colors } from '../../configs';
|
|
3
|
+
|
|
4
|
+
export default StyleSheet.create({
|
|
5
|
+
wrap: {
|
|
6
|
+
flex: 1,
|
|
7
|
+
},
|
|
8
|
+
mapView: {
|
|
9
|
+
position: 'absolute',
|
|
10
|
+
top: 0,
|
|
11
|
+
left: 0,
|
|
12
|
+
right: 0,
|
|
13
|
+
bottom: 0,
|
|
14
|
+
},
|
|
15
|
+
bottomButton: {
|
|
16
|
+
backgroundColor: Colors.White,
|
|
17
|
+
},
|
|
18
|
+
wrapMarker: {
|
|
19
|
+
flex: 1,
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
position: 'absolute',
|
|
23
|
+
top: 0,
|
|
24
|
+
bottom: 0,
|
|
25
|
+
left: 0,
|
|
26
|
+
right: 0,
|
|
27
|
+
paddingBottom: 24,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -30,7 +30,7 @@ import { AUTOMATE_TYPE } from '../../configs/Constants';
|
|
|
30
30
|
|
|
31
31
|
const UnitDetail = ({ route }) => {
|
|
32
32
|
const t = useTranslations();
|
|
33
|
-
const { unitId, unitData, isOneTap } = route.params;
|
|
33
|
+
const { unitId, unitData, isOneTap, routeName, isAddSubUnit } = route.params;
|
|
34
34
|
const isFocused = useIsFocused();
|
|
35
35
|
const { stateData, setAction } = useContext(SCContext);
|
|
36
36
|
const { navigate } = useNavigation();
|
|
@@ -69,7 +69,7 @@ const UnitDetail = ({ route }) => {
|
|
|
69
69
|
(rawUnitData) => {
|
|
70
70
|
rawUnitData.stations.unshift({
|
|
71
71
|
isOneTap: true,
|
|
72
|
-
name: t('
|
|
72
|
+
name: t('smart'),
|
|
73
73
|
});
|
|
74
74
|
rawUnitData.stations.unshift({
|
|
75
75
|
isFavorites: true,
|
|
@@ -222,6 +222,12 @@ const UnitDetail = ({ route }) => {
|
|
|
222
222
|
isOneTap && setIndexStation(1);
|
|
223
223
|
}, [isOneTap]);
|
|
224
224
|
|
|
225
|
+
useEffect(() => {
|
|
226
|
+
if (listMenuItem.length && isAddSubUnit) {
|
|
227
|
+
setIndexStation(listMenuItem.length - 1);
|
|
228
|
+
}
|
|
229
|
+
}, [listMenuItem.length, isAddSubUnit]);
|
|
230
|
+
|
|
225
231
|
const onSnapToItem = useCallback(
|
|
226
232
|
(item, index) => {
|
|
227
233
|
setStation(unit.stations[index]);
|
|
@@ -274,6 +280,11 @@ const UnitDetail = ({ route }) => {
|
|
|
274
280
|
);
|
|
275
281
|
}
|
|
276
282
|
};
|
|
283
|
+
|
|
284
|
+
const onBack = useCallback(() => {
|
|
285
|
+
navigate(routeName);
|
|
286
|
+
}, [navigate, routeName]);
|
|
287
|
+
|
|
277
288
|
return (
|
|
278
289
|
<WrapParallaxScrollView
|
|
279
290
|
uriImg={unit.background}
|
|
@@ -286,6 +297,7 @@ const UnitDetail = ({ route }) => {
|
|
|
286
297
|
onAdd={setShowAdd}
|
|
287
298
|
onMore={showPopoverWithRef}
|
|
288
299
|
hideRightPlus={!isOwner}
|
|
300
|
+
onBack={routeName && onBack}
|
|
289
301
|
>
|
|
290
302
|
<View style={styles.container}>
|
|
291
303
|
<Summaries unit={unit} />
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
axiosPatch,
|
|
12
12
|
axiosDelete,
|
|
13
13
|
} from '../../utils/Apis/axios';
|
|
14
|
-
import { navigate } from '../../navigations/utils';
|
|
15
14
|
import useBoolean from '../../hooks/Common/useBoolean';
|
|
16
15
|
import useKeyboardAnimated from '../../hooks/Explore/useKeyboardAnimated';
|
|
17
16
|
|
|
@@ -103,7 +102,7 @@ const ManageUnit = ({ route }) => {
|
|
|
103
102
|
|
|
104
103
|
const goSelectLocation = useCallback(() => {
|
|
105
104
|
navigation.navigate(Routes.UnitStack, {
|
|
106
|
-
screen: Routes.
|
|
105
|
+
screen: Routes.SelectAddress,
|
|
107
106
|
params: {
|
|
108
107
|
updateLocation,
|
|
109
108
|
},
|
|
@@ -134,11 +133,11 @@ const ManageUnit = ({ route }) => {
|
|
|
134
133
|
const goRemove = useCallback(async () => {
|
|
135
134
|
const { success } = await axiosDelete(API.UNIT.MANAGE_UNIT(unit.id));
|
|
136
135
|
if (success) {
|
|
137
|
-
|
|
136
|
+
setHideRemove(true);
|
|
138
137
|
ToastBottomHelper.success(t('unit_deleted_successfully'));
|
|
139
|
-
navigate(Routes.Dashboard);
|
|
138
|
+
navigation.navigate(Routes.Dashboard);
|
|
140
139
|
}
|
|
141
|
-
}, [unit.id,
|
|
140
|
+
}, [unit.id, setHideRemove, t, navigation]);
|
|
142
141
|
|
|
143
142
|
const goToManageSubUnit = useCallback(() => {
|
|
144
143
|
navigation.navigate(Routes.UnitStack, {
|