@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
|
@@ -1,16 +1,32 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { Image, StyleSheet, View } from 'react-native';
|
|
1
|
+
import React, { useState, useCallback } from 'react';
|
|
2
|
+
import { Image, StyleSheet, View, TouchableOpacity } from 'react-native';
|
|
3
|
+
import { useNavigation } from '@react-navigation/native';
|
|
4
|
+
|
|
3
5
|
import ItemQuickAction from '../../../../commons/Action/ItemQuickAction';
|
|
4
6
|
import Text from '../../../../commons/Text';
|
|
7
|
+
import Routes from '../../../../utils/Route';
|
|
5
8
|
|
|
6
9
|
import { Colors, Images } from '../../../../configs';
|
|
7
10
|
|
|
8
|
-
const MyUnitDevice = ({ sensor }) => {
|
|
11
|
+
const MyUnitDevice = ({ sensor, unit }) => {
|
|
9
12
|
const [status, setStatus] = useState(sensor.status);
|
|
13
|
+
const { navigate } = useNavigation();
|
|
14
|
+
|
|
15
|
+
const goToSensorDisplay = useCallback(() => {
|
|
16
|
+
navigate(Routes.UnitStack, {
|
|
17
|
+
screen: Routes.DeviceDetail,
|
|
18
|
+
params: {
|
|
19
|
+
unit,
|
|
20
|
+
sensor,
|
|
21
|
+
title: sensor?.name,
|
|
22
|
+
station: sensor?.station,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}, [navigate, sensor, unit]);
|
|
10
26
|
|
|
11
27
|
return (
|
|
12
28
|
<View style={styles.item}>
|
|
13
|
-
<
|
|
29
|
+
<TouchableOpacity style={styles.rowCenter} onPress={goToSensorDisplay}>
|
|
14
30
|
<Image style={styles.image} source={Images.mainDoor} />
|
|
15
31
|
<View style={styles.marginTop3}>
|
|
16
32
|
<Text semibold style={styles.nameDevice}>
|
|
@@ -23,7 +39,7 @@ const MyUnitDevice = ({ sensor }) => {
|
|
|
23
39
|
</Text>
|
|
24
40
|
</View>
|
|
25
41
|
</View>
|
|
26
|
-
</
|
|
42
|
+
</TouchableOpacity>
|
|
27
43
|
<ItemQuickAction
|
|
28
44
|
sensor={sensor}
|
|
29
45
|
wrapperStyle={styles.iconCircle}
|
|
@@ -22,7 +22,9 @@ export const useStateAlertRemove = () => {
|
|
|
22
22
|
setStateAlertRemove((state) => ({
|
|
23
23
|
...state,
|
|
24
24
|
visible: true,
|
|
25
|
-
message: `${t('are_you_sure_want_to_delete', {
|
|
25
|
+
message: `${t('are_you_sure_want_to_delete', {
|
|
26
|
+
text: brand === 'google_home' ? 'Điện Quang' : brand,
|
|
27
|
+
})}`,
|
|
26
28
|
}));
|
|
27
29
|
},
|
|
28
30
|
[t]
|
|
@@ -239,7 +239,7 @@ const ThreePhasePowerConsumption = memo(({ unit, summary, summaryDetail }) => {
|
|
|
239
239
|
</Section>
|
|
240
240
|
|
|
241
241
|
<Section type={'border'}>
|
|
242
|
-
<Text semibold style={styles.textIndoor}
|
|
242
|
+
<Text type="H3" semibold style={styles.textIndoor}>
|
|
243
243
|
{t('text_total_power_consumption')}
|
|
244
244
|
</Text>
|
|
245
245
|
|
|
@@ -145,7 +145,7 @@ const PowerConsumption = memo(({ summaryDetail }) => {
|
|
|
145
145
|
</Section>
|
|
146
146
|
|
|
147
147
|
<Section type={'border'}>
|
|
148
|
-
<Text semibold style={styles.textIndoor}
|
|
148
|
+
<Text type="H3" semibold style={styles.textIndoor}>
|
|
149
149
|
{t('text_total_power_consumption')}
|
|
150
150
|
</Text>
|
|
151
151
|
|
|
@@ -35,9 +35,7 @@ const Item = memo((props) => {
|
|
|
35
35
|
<Text size={24} color={color || Colors.Gray9} style={styles.textValue}>
|
|
36
36
|
{value}
|
|
37
37
|
</Text>
|
|
38
|
-
<Text
|
|
39
|
-
{des}
|
|
40
|
-
</Text>
|
|
38
|
+
<Text color={Colors.Gray8}>{des}</Text>
|
|
41
39
|
<View style={styles.boxSvg}>
|
|
42
40
|
<Text>{svgMain}</Text>
|
|
43
41
|
</View>
|
|
@@ -68,7 +68,9 @@ const UnitSummary = memo(({ route }) => {
|
|
|
68
68
|
|
|
69
69
|
const fetchSummaryDetail = useCallback(async () => {
|
|
70
70
|
const { success, data } = await axiosGet(
|
|
71
|
-
API.UNIT.UNIT_SUMMARY_DETAIL(unit.id, summary.id)
|
|
71
|
+
API.UNIT.UNIT_SUMMARY_DETAIL(unit.id, summary.id),
|
|
72
|
+
{},
|
|
73
|
+
true
|
|
72
74
|
);
|
|
73
75
|
setLoading(false);
|
|
74
76
|
if (success) {
|
|
@@ -136,7 +138,6 @@ const styles = StyleSheet.create({
|
|
|
136
138
|
container: {
|
|
137
139
|
flex: 1,
|
|
138
140
|
backgroundColor: Colors.Gray2,
|
|
139
|
-
paddingBottom: 60,
|
|
140
141
|
},
|
|
141
142
|
textHeader: {
|
|
142
143
|
color: Colors.Gray9,
|
package/src/utils/Apis/axios.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import { deleteData, getData, storeData } from '../Storage';
|
|
3
3
|
import { ToastBottomHelper } from '../Utils';
|
|
4
|
+
import NetInfo from '@react-native-community/netinfo';
|
|
4
5
|
|
|
5
6
|
export const replaceParams = (apiURL, params) => {
|
|
6
7
|
let _result = apiURL;
|
|
@@ -12,7 +13,7 @@ export const replaceParams = (apiURL, params) => {
|
|
|
12
13
|
return _result;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
|
-
const parseErrorResponse = (error) => {
|
|
16
|
+
const parseErrorResponse = async (error) => {
|
|
16
17
|
let message;
|
|
17
18
|
let data = {};
|
|
18
19
|
if (
|
|
@@ -31,7 +32,18 @@ const parseErrorResponse = (error) => {
|
|
|
31
32
|
message = error.message;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
typeof message === 'string'
|
|
35
|
+
if (typeof message === 'string') {
|
|
36
|
+
let hideError = false;
|
|
37
|
+
if (message === 'Network Error') {
|
|
38
|
+
const netState = await NetInfo.fetch();
|
|
39
|
+
if (!netState.isConnected) {
|
|
40
|
+
hideError = true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!hideError) {
|
|
44
|
+
ToastBottomHelper.error(message);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
35
47
|
|
|
36
48
|
return {
|
|
37
49
|
success: false,
|
|
@@ -77,12 +89,12 @@ export async function axiosGet(URL, config = {}, cache = false) {
|
|
|
77
89
|
if (cache) {
|
|
78
90
|
// only network error or server error
|
|
79
91
|
if (!error.response || error.response.status >= 500) {
|
|
80
|
-
return (await axiosCache(URL)) || parseErrorResponse(error);
|
|
92
|
+
return (await axiosCache(URL)) || (await parseErrorResponse(error));
|
|
81
93
|
} else {
|
|
82
94
|
await deleteData(cacheKey);
|
|
83
95
|
}
|
|
84
96
|
}
|
|
85
|
-
return parseErrorResponse(error);
|
|
97
|
+
return await parseErrorResponse(error);
|
|
86
98
|
}
|
|
87
99
|
const { data } = response;
|
|
88
100
|
if (response.status === 200) {
|
|
@@ -106,7 +118,7 @@ async function axiosCall(method, ...args) {
|
|
|
106
118
|
try {
|
|
107
119
|
response = await axios[method](...args);
|
|
108
120
|
} catch (error) {
|
|
109
|
-
return parseErrorResponse(error);
|
|
121
|
+
return await parseErrorResponse(error);
|
|
110
122
|
}
|
|
111
123
|
|
|
112
124
|
const { data } = response;
|
|
@@ -186,7 +186,8 @@
|
|
|
186
186
|
"explanation": "Do everything with just one button",
|
|
187
187
|
"value_change": "Value change",
|
|
188
188
|
"schedule": "Schedule",
|
|
189
|
-
"
|
|
189
|
+
"setup_the_conditions": "Setup the conditions",
|
|
190
|
+
"setup_the_schedule": "Setup the Schedule",
|
|
190
191
|
"des_launch_one_tap": "Quick button create at the dashboard",
|
|
191
192
|
"active_list": "Actions List",
|
|
192
193
|
"text_very_good_level": "Very good",
|
|
@@ -300,6 +301,9 @@
|
|
|
300
301
|
"text_next": "Next",
|
|
301
302
|
"text_done": "Done",
|
|
302
303
|
"locations_near_me": "Locations near me",
|
|
304
|
+
"your_location": "Your location",
|
|
305
|
+
"choose_on_map": "Choose on map",
|
|
306
|
+
"plan_and_zoom_to_adjust": "Plan and zoom to adjust",
|
|
303
307
|
"manage_sub_unit": "Manage sub-unit",
|
|
304
308
|
"remove_sub_unit": "Remove sub-unit",
|
|
305
309
|
"text_ble_is_powered_on": "Bluetooth is powered on",
|
|
@@ -662,7 +666,6 @@
|
|
|
662
666
|
"text_notification_content_pay_fine_successfully": "Your violation **%{booking}** has been paid successfully.",
|
|
663
667
|
"text_notification_content_pay_fine_and_extend_successfully": "Your violation **%{booking_id_old}** has been paid successfully. The new parking session **%{booking_id_new}** is now extended until **%{leave_time}**.",
|
|
664
668
|
"text_notification_content_stop_violation_free_parking_zone": "Free parking zone. You have an unpaid violation. Please complete your fine.",
|
|
665
|
-
"text_notification_content_update_reminder": "You have an Update Health Value schedule need to complete.",
|
|
666
669
|
"this_spot_does_not_exsit": "This spot does not exist",
|
|
667
670
|
"please_scan_again_or_contact_the_parking_manager": "Please scan again or contact the parking manager",
|
|
668
671
|
"this_spot_does_not_support_to_scan": "This spot does not support to scan",
|
|
@@ -825,7 +828,8 @@
|
|
|
825
828
|
"quick_button_create_at_dashboard": "Quick button create at dashboard",
|
|
826
829
|
"every_day_at": "Every day at {time}",
|
|
827
830
|
"you_do_not_have_the_device_or_have_share_control_device": "You do not have the device or you haven’t been shared the control for the device.",
|
|
828
|
-
"
|
|
831
|
+
"your_internet_is_disconnected": "Your internet is disconnected",
|
|
832
|
+
"change_to_control_via_bluetooth_connection": "change to control {name} via Bluetooth connection",
|
|
829
833
|
"your_connection_to_the_server_was_disconnected_please_open_the_bluetooth_to_continue": "Your connection to the server was disconnected, Please open the Bluetooth to continue",
|
|
830
834
|
"error_please_try_later": "Error! Please try later",
|
|
831
835
|
"mon": "Mon",
|
|
@@ -839,5 +843,10 @@
|
|
|
839
843
|
"connected_via_internet": "Connected via Internet",
|
|
840
844
|
"name_your_unit": "Name your unit",
|
|
841
845
|
"script_updated_by": "Script updated by",
|
|
842
|
-
"qr_scan_guidelines": "The QR code will be detected automatically when it’s positioned within the guide lines."
|
|
846
|
+
"qr_scan_guidelines": "The QR code will be detected automatically when it’s positioned within the guide lines.",
|
|
847
|
+
"now_playing": "Now Playing",
|
|
848
|
+
"pause": "Pause",
|
|
849
|
+
"volume": "Volume",
|
|
850
|
+
"this_notification_will_be_updated_soon": "This notification will be updated soon",
|
|
851
|
+
"tap_to_add_new_schedule": "Tap + to add new schedule"
|
|
843
852
|
}
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
"launch_one_tap": "Khởi chạy một lần chạm",
|
|
44
44
|
"explanation": "Làm mọi thứ chỉ với một nút",
|
|
45
45
|
"value_change": "Thay đổi giá trị",
|
|
46
|
-
"
|
|
46
|
+
"setup_the_conditions": "Cài đặt điều kiện",
|
|
47
|
+
"setup_the_schedule": "Cài đặt thời gian ",
|
|
47
48
|
"schedule": "Lịch trình",
|
|
48
49
|
"des_launch_one_tap": "Tạo nút nhanh trên trang tổng quan",
|
|
49
50
|
"active_list": "Danh sách hành động",
|
|
@@ -335,13 +336,16 @@
|
|
|
335
336
|
"text_next": "Tiếp theo",
|
|
336
337
|
"text_done": "Hoàn tất",
|
|
337
338
|
"locations_near_me": "Địa điểm gần tôi",
|
|
339
|
+
"your_location": "Vị trí của bạn",
|
|
340
|
+
"choose_on_map": "Chọn trên bản đồ",
|
|
341
|
+
"plan_and_zoom_to_adjust": "Di chuyển và phóng to để điều chỉnh",
|
|
338
342
|
"manage_sub_unit": "Quản lý khu vực",
|
|
339
343
|
"remove_sub_unit": "Xóa khu vực",
|
|
340
344
|
"text_ble_is_powered_on": "Bluetooth đã được mở",
|
|
341
345
|
"current_wind_speed": "Tốc độ gió hiện tại",
|
|
342
346
|
"history": "Lịch sử",
|
|
343
347
|
"wind_speed": "Tốc độ gió",
|
|
344
|
-
"from": "
|
|
348
|
+
"from": "Từ",
|
|
345
349
|
"to": "đến",
|
|
346
350
|
"condition": "Điều kiện",
|
|
347
351
|
"shared_unit": "Khu vực được chia sẻ",
|
|
@@ -670,7 +674,6 @@
|
|
|
670
674
|
"text_notification_content_pay_fine_successfully": "Đỗ xe vi phạm **%{booking}** của bạn đã được thanh toán.",
|
|
671
675
|
"text_notification_content_pay_fine_and_extend_successfully": "Đỗ xe vi phạm **%{oldbooking}** của bạn đã được thanh toán thành công. Phiên đỗ xe mới **%{newbooking}** sẽ kết thúc vào lúc **%{time}**.",
|
|
672
676
|
"text_notification_content_stop_violation_free_parking_zone": "Thời gian đậu xe miễn phí. Bạn có một vi phạm chưa được thanh toán. Vui lòng hoàn thành tiền phạt của bạn.",
|
|
673
|
-
"text_notification_content_update_reminder": "Bạn có một nhắc nhở cập nhật chỉ số sức khỏe cần hoàn thành.",
|
|
674
677
|
"this_spot_does_not_exsit": "Vị trí đỗ này không tồn tại",
|
|
675
678
|
"please_scan_again_or_contact_the_parking_manager": "Vui lòng quét lại hoặc liên hệ với người quản lý bãi đậu xe",
|
|
676
679
|
"this_spot_does_not_support_to_scan": "Vị trí đỗ này không hỗ trợ quét",
|
|
@@ -805,8 +808,8 @@
|
|
|
805
808
|
"activated_by": "Đã kích hoạt bởi",
|
|
806
809
|
"delete": "Xóa",
|
|
807
810
|
"apply": "Xác nhận",
|
|
808
|
-
"by_date": "
|
|
809
|
-
"by_user": "
|
|
811
|
+
"by_date": "Theo Ngày",
|
|
812
|
+
"by_user": "Bởi Người Dùng",
|
|
810
813
|
"options": "Tùy chọn",
|
|
811
814
|
"mode": "Chế độ",
|
|
812
815
|
"text_on": "Bật",
|
|
@@ -826,7 +829,8 @@
|
|
|
826
829
|
"quick_button_create_at_dashboard": "Tạo nút nhanh trên bảng điều khiển",
|
|
827
830
|
"every_day_at": "Mỗi ngày vào lúc {time}",
|
|
828
831
|
"you_do_not_have_the_device_or_have_share_control_device": "Bạn không có thiết bị nào hoặc chưa được cấp quyền để điều khiển thiết bị.",
|
|
829
|
-
"
|
|
832
|
+
"your_internet_is_disconnected": "Internet của bạn bị ngắt kết nối",
|
|
833
|
+
"change_to_control_via_bluetooth_connection": "thay đổi sang điều khiển {name} qua kết nối Bluetooth",
|
|
830
834
|
"your_connection_to_the_server_was_disconnected_please_open_the_bluetooth_to_continue": "Kết nối của bạn với máy chủ đã bị ngắt, vui lòng mở Bluetooth để tiếp tục",
|
|
831
835
|
"error_please_try_later": "Lỗi! Vui lòng thử lại sau",
|
|
832
836
|
"mon": "T2",
|
|
@@ -840,5 +844,10 @@
|
|
|
840
844
|
"connected_via_internet": "Đã kết nối điều khiển thông qua Internet",
|
|
841
845
|
"name_your_unit": "Đặt tên cho khu vực của bạn",
|
|
842
846
|
"script_updated_by": "Kịch bản được cập nhật bởi",
|
|
843
|
-
"qr_scan_guidelines": "Mã QR sẽ được phát hiện tự động khi nó được định vị trong các dòng hướng dẫn."
|
|
847
|
+
"qr_scan_guidelines": "Mã QR sẽ được phát hiện tự động khi nó được định vị trong các dòng hướng dẫn.",
|
|
848
|
+
"now_playing": "Đang chạy",
|
|
849
|
+
"pause": "Tạm dừng",
|
|
850
|
+
"volume": "Âm lượng",
|
|
851
|
+
"this_notification_will_be_updated_soon": "Thông báo này sẽ sớm được cập nhật",
|
|
852
|
+
"tap_to_add_new_schedule": "Nhấn + để thêm lịch trình mới"
|
|
844
853
|
}
|
package/src/utils/Route/index.js
CHANGED
|
@@ -41,7 +41,8 @@ const Routes = {
|
|
|
41
41
|
ConnectingDevices: 'ConnectingDevices',
|
|
42
42
|
ConnectingGateway: 'ConnectingGateway',
|
|
43
43
|
ManageUnit: 'ManageUnit',
|
|
44
|
-
|
|
44
|
+
SelectAddress: 'SelectAddress',
|
|
45
|
+
ChooseLocation: 'ChooseLocation',
|
|
45
46
|
ManageSubUnit: 'ManageSubUnit',
|
|
46
47
|
Dashboard: 'Dashboard',
|
|
47
48
|
Shared: 'Shared',
|
package/src/utils/Utils.js
CHANGED
|
@@ -26,6 +26,11 @@ export const isObjectEmpty = (obj) => {
|
|
|
26
26
|
return Object.keys(obj).length === 0;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
export const shortEmailName = (email) => {
|
|
30
|
+
const regex = '([^@]+)';
|
|
31
|
+
return email?.match(regex)[0];
|
|
32
|
+
};
|
|
33
|
+
|
|
29
34
|
export const formatNumberCompact = (number) => {
|
|
30
35
|
return new Intl.NumberFormat('en-US', {
|
|
31
36
|
notation: 'compact',
|
|
@@ -66,7 +71,7 @@ export const openMapDirection = (item) => () => {
|
|
|
66
71
|
};
|
|
67
72
|
|
|
68
73
|
export const ToastBottomHelper = {
|
|
69
|
-
success: (msg) => {
|
|
74
|
+
success: (msg, line2) => {
|
|
70
75
|
if (!Toast._ref) {
|
|
71
76
|
return;
|
|
72
77
|
}
|
|
@@ -75,10 +80,11 @@ export const ToastBottomHelper = {
|
|
|
75
80
|
type: 'success',
|
|
76
81
|
position: 'bottom',
|
|
77
82
|
text1: msg,
|
|
83
|
+
text2: line2,
|
|
78
84
|
visibilityTime: 1000,
|
|
79
85
|
});
|
|
80
86
|
},
|
|
81
|
-
error: (msg) => {
|
|
87
|
+
error: (msg, line2) => {
|
|
82
88
|
if (!Toast._ref) {
|
|
83
89
|
return;
|
|
84
90
|
}
|
|
@@ -87,6 +93,20 @@ export const ToastBottomHelper = {
|
|
|
87
93
|
type: 'error',
|
|
88
94
|
position: 'bottom',
|
|
89
95
|
text1: msg,
|
|
96
|
+
text2: line2,
|
|
97
|
+
visibilityTime: 1000,
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
info: (msg, line2) => {
|
|
101
|
+
if (!Toast._ref) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
Toast.show({
|
|
106
|
+
type: 'info',
|
|
107
|
+
position: 'bottom',
|
|
108
|
+
text1: msg,
|
|
109
|
+
text2: line2,
|
|
90
110
|
visibilityTime: 1000,
|
|
91
111
|
});
|
|
92
112
|
},
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<path d="M16 10.2188C15.0656 10.2188 14.1875 10.5812 13.525 11.2437C13.1994 11.5684 12.9413 11.9542 12.7654 12.3789C12.5895 12.8037 12.4993 13.259 12.5 13.7188C12.5 14.6531 12.8656 15.5312 13.525 16.1938C13.8496 16.5193 14.2354 16.7775 14.6602 16.9534C15.0849 17.1293 15.5403 17.2195 16 17.2188C16.9344 17.2188 17.8125 16.8531 18.475 16.1938C19.1375 15.5312 19.5 14.6531 19.5 13.7188C19.5 12.7844 19.1375 11.9062 18.475 11.2437C17.8125 10.5812 16.9344 10.2188 16 10.2188ZM26.7062 9.03438C26.1179 7.67775 25.2697 6.44944 24.2094 5.41875C23.1456 4.37875 21.8915 3.55331 20.5156 2.9875C19.0844 2.39375 17.5656 2.09375 16 2.09375C14.4344 2.09375 12.9156 2.39375 11.4844 2.98438C10.1 3.55625 8.85938 4.375 7.79063 5.41563C6.73101 6.44689 5.88286 7.67506 5.29375 9.03125C4.68437 10.4375 4.375 11.9312 4.375 13.4688C4.375 15.675 4.90313 17.8719 5.94063 19.9906C6.775 21.6938 7.94063 23.3531 9.40938 24.9312C11.9188 27.625 14.55 29.2719 15.2969 29.7125C15.5089 29.8377 15.7507 29.9036 15.9969 29.9031C16.2406 29.9031 16.4812 29.8406 16.6969 29.7125C17.4437 29.2719 20.075 27.625 22.5844 24.9312C24.0531 23.3562 25.2188 21.6938 26.0531 19.9906C27.0969 17.875 27.625 15.6812 27.625 13.4719C27.625 11.9344 27.3156 10.4406 26.7062 9.03438ZM16 19.2188C12.9625 19.2188 10.5 16.7563 10.5 13.7188C10.5 10.6812 12.9625 8.21875 16 8.21875C19.0375 8.21875 21.5 10.6812 21.5 13.7188C21.5 16.7563 19.0375 19.2188 16 19.2188Z" fill="#1890FF"/>
|
|
3
|
-
</svg>
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<path d="M16 10.2188C15.0656 10.2188 14.1875 10.5812 13.525 11.2437C13.1994 11.5684 12.9413 11.9542 12.7654 12.3789C12.5895 12.8037 12.4993 13.259 12.5 13.7188C12.5 14.6531 12.8656 15.5312 13.525 16.1938C13.8496 16.5193 14.2354 16.7775 14.6602 16.9534C15.0849 17.1293 15.5403 17.2195 16 17.2188C16.9344 17.2188 17.8125 16.8531 18.475 16.1938C19.1375 15.5312 19.5 14.6531 19.5 13.7188C19.5 12.7844 19.1375 11.9062 18.475 11.2437C17.8125 10.5812 16.9344 10.2188 16 10.2188ZM26.7062 9.03438C26.1179 7.67775 25.2697 6.44944 24.2094 5.41875C23.1456 4.37875 21.8915 3.55331 20.5156 2.9875C19.0844 2.39375 17.5656 2.09375 16 2.09375C14.4344 2.09375 12.9156 2.39375 11.4844 2.98438C10.1 3.55625 8.85938 4.375 7.79063 5.41563C6.73101 6.44689 5.88286 7.67506 5.29375 9.03125C4.68437 10.4375 4.375 11.9312 4.375 13.4688C4.375 15.675 4.90313 17.8719 5.94063 19.9906C6.775 21.6938 7.94063 23.3531 9.40938 24.9312C11.9188 27.625 14.55 29.2719 15.2969 29.7125C15.5089 29.8377 15.7507 29.9036 15.9969 29.9031C16.2406 29.9031 16.4812 29.8406 16.6969 29.7125C17.4437 29.2719 20.075 27.625 22.5844 24.9312C24.0531 23.3562 25.2188 21.6938 26.0531 19.9906C27.0969 17.875 27.625 15.6812 27.625 13.4719C27.625 11.9344 27.3156 10.4406 26.7062 9.03438ZM16 19.2188C12.9625 19.2188 10.5 16.7563 10.5 13.7188C10.5 10.6812 12.9625 8.21875 16 8.21875C19.0375 8.21875 21.5 10.6812 21.5 13.7188C21.5 16.7563 19.0375 19.2188 16 19.2188Z" fill="#1890FF"/>
|
|
3
|
-
</svg>
|
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
import React, { useState, useCallback, useEffect } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
View,
|
|
4
|
-
StyleSheet,
|
|
5
|
-
TouchableOpacity,
|
|
6
|
-
Image,
|
|
7
|
-
Platform,
|
|
8
|
-
} from 'react-native';
|
|
9
|
-
import Animated from 'react-native-reanimated';
|
|
10
|
-
import { useTranslations } from '../../../hooks/Common/useTranslations';
|
|
11
|
-
|
|
12
|
-
import { Colors, API, Device } from '../../../configs';
|
|
13
|
-
import Routes from '../../../utils/Route';
|
|
14
|
-
import { ToastBottomHelper } from '../../../utils/Utils';
|
|
15
|
-
import {
|
|
16
|
-
createFormData,
|
|
17
|
-
axiosPatch,
|
|
18
|
-
axiosDelete,
|
|
19
|
-
} from '../../../utils/Apis/axios';
|
|
20
|
-
import { navigate } from '../../../navigations/utils';
|
|
21
|
-
import useBoolean from '../../../hooks/Common/useBoolean';
|
|
22
|
-
import useKeyboardAnimated from '../../../hooks/Explore/useKeyboardAnimated';
|
|
23
|
-
|
|
24
|
-
import {
|
|
25
|
-
AlertAction,
|
|
26
|
-
Section,
|
|
27
|
-
ViewButtonBottom,
|
|
28
|
-
ImagePicker,
|
|
29
|
-
} from '../../../commons';
|
|
30
|
-
|
|
31
|
-
import Text from '../../../commons/Text';
|
|
32
|
-
import _TextInput from '../../../commons/Form/TextInput';
|
|
33
|
-
import WrapHeaderScrollable from '../../../commons/Sharing/WrapHeaderScrollable';
|
|
34
|
-
import { getBottomSpace } from 'react-native-iphone-x-helper';
|
|
35
|
-
import { useIsOwnerOfUnit } from '../../../hooks/Common';
|
|
36
|
-
import { TESTID } from '../../../configs/Constants';
|
|
37
|
-
import { ModalCustom } from '../../../commons/Modal';
|
|
38
|
-
|
|
39
|
-
const ManageUnit = ({ route }) => {
|
|
40
|
-
const t = useTranslations();
|
|
41
|
-
const { unit } = route.params;
|
|
42
|
-
const { isOwner } = useIsOwnerOfUnit(unit.user_id);
|
|
43
|
-
const [showEdit, setshowEdit, setHideEdit] = useBoolean();
|
|
44
|
-
const [unitName, setUnitName] = useState(unit.name);
|
|
45
|
-
const [imageUrl, setImageUrl] = useState('');
|
|
46
|
-
const [showImagePicker, setShowImagePicker] = useState(false);
|
|
47
|
-
|
|
48
|
-
const updateUnit = useCallback(
|
|
49
|
-
async (headers) => {
|
|
50
|
-
const formData = createFormData(imageUrl, ['background']);
|
|
51
|
-
|
|
52
|
-
const { success } = await axiosPatch(
|
|
53
|
-
API.UNIT.MANAGE_UNIT(unit.id),
|
|
54
|
-
formData,
|
|
55
|
-
headers
|
|
56
|
-
);
|
|
57
|
-
if (success) {
|
|
58
|
-
ToastBottomHelper.success(t('unit_updated_successfully'));
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
[imageUrl, unit.id, t]
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
const goRename = useCallback(async () => {
|
|
65
|
-
await updateUnit({ name: unitName }, {});
|
|
66
|
-
setHideEdit(true);
|
|
67
|
-
}, [unitName, setHideEdit, updateUnit]);
|
|
68
|
-
|
|
69
|
-
const handleChoosePhoto = useCallback(() => {
|
|
70
|
-
setShowImagePicker(true);
|
|
71
|
-
}, [setShowImagePicker]);
|
|
72
|
-
|
|
73
|
-
useEffect(() => {
|
|
74
|
-
if (imageUrl) {
|
|
75
|
-
updateUnit({
|
|
76
|
-
headers: { 'Content-Type': 'multipart/form-data' },
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}, [imageUrl, updateUnit]);
|
|
80
|
-
|
|
81
|
-
const [showRemove, setshowRemove, setHideRemove] = useBoolean();
|
|
82
|
-
const goRemove = useCallback(async () => {
|
|
83
|
-
const { success } = await axiosDelete(API.UNIT.MANAGE_UNIT(unit.id));
|
|
84
|
-
if (success) {
|
|
85
|
-
setHideEdit(true);
|
|
86
|
-
ToastBottomHelper.success(t('unit_deleted_successfully'));
|
|
87
|
-
navigate(Routes.Dashboard);
|
|
88
|
-
}
|
|
89
|
-
}, [unit.id, setHideEdit, t]);
|
|
90
|
-
|
|
91
|
-
const [transY] = useKeyboardAnimated(-16);
|
|
92
|
-
const animatedStyle = Platform.select({
|
|
93
|
-
ios: {
|
|
94
|
-
marginBottom: transY,
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
const options = {
|
|
99
|
-
mediaType: 'photo',
|
|
100
|
-
maxWidth: 1024,
|
|
101
|
-
quality: 0.8,
|
|
102
|
-
includeBase64: Device.isIOS,
|
|
103
|
-
saveToPhotos: true,
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
return (
|
|
107
|
-
<>
|
|
108
|
-
<WrapHeaderScrollable title={t('manage_unit')}>
|
|
109
|
-
<View style={styles.wraper}>
|
|
110
|
-
{isOwner && (
|
|
111
|
-
<Section type={'border'}>
|
|
112
|
-
<TouchableOpacity
|
|
113
|
-
onPress={setshowEdit}
|
|
114
|
-
testID={TESTID.TOUCH_UNIT_IN_MANAGE_UNIT}
|
|
115
|
-
>
|
|
116
|
-
<Text style={[styles.textWraper, styles.unitName]}>
|
|
117
|
-
{unit.name}
|
|
118
|
-
</Text>
|
|
119
|
-
</TouchableOpacity>
|
|
120
|
-
|
|
121
|
-
<TouchableOpacity style={[styles.textWraper]}>
|
|
122
|
-
<Text style={styles.unitName}>{t('geolocation')}</Text>
|
|
123
|
-
<Text style={styles.unitGeolocation}>{unit.address}</Text>
|
|
124
|
-
</TouchableOpacity>
|
|
125
|
-
<TouchableOpacity
|
|
126
|
-
style={[styles.backgroundContainer]}
|
|
127
|
-
onPress={handleChoosePhoto}
|
|
128
|
-
>
|
|
129
|
-
<Text style={[styles.unitName, styles.textBackground]}>
|
|
130
|
-
{t('background')}
|
|
131
|
-
</Text>
|
|
132
|
-
<Image
|
|
133
|
-
style={styles.image}
|
|
134
|
-
source={{ uri: unit.background }}
|
|
135
|
-
resizeMode="cover"
|
|
136
|
-
/>
|
|
137
|
-
</TouchableOpacity>
|
|
138
|
-
|
|
139
|
-
<ImagePicker
|
|
140
|
-
showImagePicker={showImagePicker}
|
|
141
|
-
setShowImagePicker={setShowImagePicker}
|
|
142
|
-
setImageUrl={setImageUrl}
|
|
143
|
-
optionsCapture={options}
|
|
144
|
-
/>
|
|
145
|
-
</Section>
|
|
146
|
-
)}
|
|
147
|
-
</View>
|
|
148
|
-
</WrapHeaderScrollable>
|
|
149
|
-
<TouchableOpacity style={styles.removeButton} onPress={setshowRemove}>
|
|
150
|
-
<Text type={'H4'} semibold color={Colors.Gray6}>
|
|
151
|
-
{t('remove_unit')}
|
|
152
|
-
</Text>
|
|
153
|
-
</TouchableOpacity>
|
|
154
|
-
<ModalCustom
|
|
155
|
-
isVisible={showEdit}
|
|
156
|
-
onBackButtonPress={setHideEdit}
|
|
157
|
-
onBackdropPress={setHideEdit}
|
|
158
|
-
style={styles.modalContainer}
|
|
159
|
-
>
|
|
160
|
-
<Animated.View style={[styles.popoverStyle, animatedStyle]}>
|
|
161
|
-
<View style={styles.modalWrapper}>
|
|
162
|
-
<View style={styles.modalHeader}>
|
|
163
|
-
<Text semibold style={styles.modalHeaderText}>
|
|
164
|
-
{t('rename_unit')}
|
|
165
|
-
</Text>
|
|
166
|
-
</View>
|
|
167
|
-
<_TextInput
|
|
168
|
-
defaultValue={unitName}
|
|
169
|
-
onChange={(value) => setUnitName(value)}
|
|
170
|
-
textInputStyle={styles.textInputStyle}
|
|
171
|
-
wrapStyle={styles.textInputWrapStyle}
|
|
172
|
-
selectionColor={Colors.Primary}
|
|
173
|
-
/>
|
|
174
|
-
|
|
175
|
-
<ViewButtonBottom
|
|
176
|
-
leftTitle={t('cancel')}
|
|
177
|
-
onLeftClick={setHideEdit}
|
|
178
|
-
rightTitle={t('rename')}
|
|
179
|
-
onRightClick={goRename}
|
|
180
|
-
/>
|
|
181
|
-
</View>
|
|
182
|
-
</Animated.View>
|
|
183
|
-
</ModalCustom>
|
|
184
|
-
<AlertAction
|
|
185
|
-
visible={showRemove}
|
|
186
|
-
hideModal={setHideRemove}
|
|
187
|
-
title={t('remove_unit_name', { name: unitName })}
|
|
188
|
-
message={t('remove_note')}
|
|
189
|
-
leftButtonTitle={t('cancel')}
|
|
190
|
-
leftButtonClick={setHideRemove}
|
|
191
|
-
rightButtonTitle={t('remove')}
|
|
192
|
-
rightButtonClick={goRemove}
|
|
193
|
-
/>
|
|
194
|
-
</>
|
|
195
|
-
);
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
const styles = StyleSheet.create({
|
|
199
|
-
wraper: {
|
|
200
|
-
flex: 1,
|
|
201
|
-
},
|
|
202
|
-
textWraper: {
|
|
203
|
-
paddingTop: 16,
|
|
204
|
-
paddingBottom: 16,
|
|
205
|
-
borderBottomWidth: 0.5,
|
|
206
|
-
},
|
|
207
|
-
unitName: {
|
|
208
|
-
fontStyle: 'normal',
|
|
209
|
-
fontWeight: 'normal',
|
|
210
|
-
fontSize: 16,
|
|
211
|
-
lineHeight: 24,
|
|
212
|
-
color: Colors.Gray9,
|
|
213
|
-
},
|
|
214
|
-
unitGeolocation: {
|
|
215
|
-
fontSize: 14,
|
|
216
|
-
lineHeight: 22,
|
|
217
|
-
color: Colors.Primary,
|
|
218
|
-
},
|
|
219
|
-
removeButton: {
|
|
220
|
-
position: 'absolute',
|
|
221
|
-
bottom: 0,
|
|
222
|
-
borderWidth: 0,
|
|
223
|
-
alignSelf: 'center',
|
|
224
|
-
paddingBottom: 16 + getBottomSpace(),
|
|
225
|
-
},
|
|
226
|
-
backgroundContainer: {
|
|
227
|
-
alignItems: 'center',
|
|
228
|
-
flexDirection: 'row',
|
|
229
|
-
borderBottomWidth: 0.5,
|
|
230
|
-
},
|
|
231
|
-
image: {
|
|
232
|
-
width: 40,
|
|
233
|
-
height: 40,
|
|
234
|
-
borderRadius: 40 / 2,
|
|
235
|
-
},
|
|
236
|
-
textBackground: {
|
|
237
|
-
flex: 1,
|
|
238
|
-
paddingTop: 16,
|
|
239
|
-
paddingBottom: 16,
|
|
240
|
-
},
|
|
241
|
-
modalContainer: {
|
|
242
|
-
flex: 1,
|
|
243
|
-
margin: 0,
|
|
244
|
-
},
|
|
245
|
-
popoverStyle: {
|
|
246
|
-
width: '100%',
|
|
247
|
-
backgroundColor: Colors.White,
|
|
248
|
-
bottom: 0,
|
|
249
|
-
left: 0,
|
|
250
|
-
position: 'absolute',
|
|
251
|
-
borderRadius: 10,
|
|
252
|
-
},
|
|
253
|
-
modalWrapper: {
|
|
254
|
-
flex: 1,
|
|
255
|
-
flexDirection: 'column',
|
|
256
|
-
backgroundColor: Colors.White,
|
|
257
|
-
borderRadius: 10,
|
|
258
|
-
},
|
|
259
|
-
modalHeader: {
|
|
260
|
-
padding: 16,
|
|
261
|
-
backgroundColor: Colors.White,
|
|
262
|
-
borderBottomWidth: 1,
|
|
263
|
-
borderTopLeftRadius: 20,
|
|
264
|
-
borderTopRightRadius: 20,
|
|
265
|
-
borderColor: Colors.Gray4,
|
|
266
|
-
},
|
|
267
|
-
modalHeaderText: {
|
|
268
|
-
fontSize: 16,
|
|
269
|
-
lineHeight: 24,
|
|
270
|
-
color: Colors.Gray9,
|
|
271
|
-
},
|
|
272
|
-
textInputStyle: {
|
|
273
|
-
borderWidth: 0,
|
|
274
|
-
borderBottomWidth: 1,
|
|
275
|
-
borderBottomColor: Colors.Primary,
|
|
276
|
-
fontSize: 16,
|
|
277
|
-
marginLeft: 16,
|
|
278
|
-
marginRight: 16,
|
|
279
|
-
paddingHorizontal: 0,
|
|
280
|
-
},
|
|
281
|
-
textInputWrapStyle: {
|
|
282
|
-
marginTop: 0,
|
|
283
|
-
},
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
export default ManageUnit;
|