@eohjsc/react-native-smart-city 0.3.26 → 0.3.29

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 (108) hide show
  1. package/index.js +2 -0
  2. package/package.json +1 -1
  3. package/src/Images/Common/device_icon.png +0 -0
  4. package/src/Images/DevMode/gateway.png +0 -0
  5. package/src/Images/DevMode/gateway@2x.png +0 -0
  6. package/src/Images/DevMode/gateway@3x.png +0 -0
  7. package/src/Images/DevMode/menu.png +0 -0
  8. package/src/Images/DevMode/menu@2x.png +0 -0
  9. package/src/Images/DevMode/menu@3x.png +0 -0
  10. package/src/Images/DevMode/search.png +0 -0
  11. package/src/Images/DevMode/search@2x.png +0 -0
  12. package/src/Images/DevMode/search@3x.png +0 -0
  13. package/src/Images/DevMode/smart.png +0 -0
  14. package/src/Images/DevMode/smart@2x.png +0 -0
  15. package/src/Images/DevMode/smart@3x.png +0 -0
  16. package/src/Images/DevMode/template.png +0 -0
  17. package/src/Images/DevMode/template@2x.png +0 -0
  18. package/src/Images/DevMode/template@3x.png +0 -0
  19. package/src/commons/ActionGroup/CurtainButtonTemplate.js +1 -2
  20. package/src/commons/ActionGroup/OnOffTemplate/OnOffButtonTemplate.js +2 -0
  21. package/src/commons/ActionTemplate/CurtainAction.js +60 -0
  22. package/src/commons/ActionTemplate/CurtainActionStyles.js +11 -0
  23. package/src/commons/ActionTemplate/OnOffSmartLockAction.js +44 -0
  24. package/src/commons/ActionTemplate/OnOffSmartLockActionStyles.js +11 -0
  25. package/src/commons/ActionTemplate/index.js +18 -0
  26. package/src/commons/CameraDevice/index.js +1 -2
  27. package/src/commons/ConnectingProcess/DeviceItem/DeviceItem.js +20 -12
  28. package/src/commons/ConnectingProcess/DeviceItem/DeviceItemStyles.js +2 -0
  29. package/src/commons/ConnectingProcess/__test__/DeviceItem.test.js +1 -1
  30. package/src/commons/ConnectingProcess/index.js +11 -0
  31. package/src/commons/Dashboard/MyUnit/__test__/MyUnit.test.js +55 -5
  32. package/src/commons/Dashboard/MyUnit/index.js +59 -12
  33. package/src/commons/DevMode/Label.js +10 -0
  34. package/src/commons/DevMode/Search.js +20 -0
  35. package/src/commons/DevMode/Styles/LabelStyles.js +8 -0
  36. package/src/commons/DevMode/Styles/SearchStyles.js +21 -0
  37. package/src/commons/DevMode/index.js +3 -0
  38. package/src/commons/Device/ItemDevice.js +1 -0
  39. package/src/commons/Form/TextInput.js +4 -0
  40. package/src/commons/HeaderAni/index.js +1 -0
  41. package/src/commons/MediaPlayerDetail/index.js +0 -20
  42. package/src/commons/MenuActionMore/index.js +12 -4
  43. package/src/commons/Modal/index.js +1 -2
  44. package/src/commons/NavBar/index.js +12 -1
  45. package/src/commons/Popover/index.js +26 -0
  46. package/src/commons/SubUnit/ShortDetail.js +1 -0
  47. package/src/commons/SummaryItem/index.js +2 -1
  48. package/src/commons/Tabbar/Styles/indexStyles.js +51 -0
  49. package/src/commons/Tabbar/index.js +110 -0
  50. package/src/commons/Unit/HeaderUnit/index.js +2 -0
  51. package/src/commons/Unit/SharedUnit.js +1 -0
  52. package/src/commons/WrapParallaxScrollView/index.js +16 -2
  53. package/src/configs/Colors.js +4 -0
  54. package/src/configs/Constants.js +5 -0
  55. package/src/configs/Images.js +6 -0
  56. package/src/context/actionType.ts +2 -0
  57. package/src/context/reducer.ts +10 -0
  58. package/src/hooks/Common/useGGHomeDeviceConnected.js +9 -2
  59. package/src/hooks/Common/usePopover.js +0 -8
  60. package/src/hooks/IoT/useGGHomeConnection.js +0 -1
  61. package/src/navigations/GatewayStack.js +23 -0
  62. package/src/navigations/Main.js +144 -0
  63. package/src/navigations/SmartStack.js +23 -0
  64. package/src/navigations/TemplateStack.js +23 -0
  65. package/src/navigations/UnitStack.js +10 -2
  66. package/src/screens/AddNewAction/SelectAction.js +6 -1
  67. package/src/screens/AllCamera/__test__/index.test.js +1 -8
  68. package/src/screens/AllCamera/index.js +0 -13
  69. package/src/screens/Device/hooks/__test__/useEmergencyButton.test.js +37 -0
  70. package/src/screens/Drawer/Drawer.test.js +24 -0
  71. package/src/screens/Drawer/index.js +198 -0
  72. package/src/screens/Gateway/__test__/index.test.js +16 -0
  73. package/src/screens/Gateway/index.js +8 -0
  74. package/src/screens/Notification/__test__/NotificationItem.test.js +79 -85
  75. package/src/screens/Notification/components/NotificationItem.js +37 -220
  76. package/src/screens/ScriptDetail/__test__/index.test.js +39 -3
  77. package/src/screens/ScriptDetail/index.js +7 -10
  78. package/src/screens/Smart/__test__/index.test.js +16 -0
  79. package/src/screens/Smart/index.js +8 -0
  80. package/src/screens/SubUnit/AddSubUnit.js +1 -1
  81. package/src/screens/SubUnit/EditSubUnit.js +4 -1
  82. package/src/screens/Template/Styles/indexStyles.js +51 -0
  83. package/src/screens/Template/__test__/index.test.js +16 -0
  84. package/src/screens/Template/index.js +84 -0
  85. package/src/screens/Unit/Detail.js +10 -27
  86. package/src/screens/Unit/MoreMenu.js +16 -1
  87. package/src/screens/Unit/SmartAccount.js +7 -6
  88. package/src/screens/Unit/Station/__test__/index.test.js +41 -0
  89. package/src/screens/Unit/Station/index.js +0 -1
  90. package/src/screens/Unit/Summaries.js +14 -2
  91. package/src/screens/Unit/__test__/Detail.test.js +1 -5
  92. package/src/screens/Unit/components/Header/index.js +1 -1
  93. package/src/screens/Unit/components/MyUnitDevice/index.js +29 -12
  94. package/src/screens/Unit/components/__test__/Header.test.js +1 -1
  95. package/src/screens/Unit/components/__test__/MyUnitDevice.test.js +2 -2
  96. package/src/screens/Unit/hook/useUnitConnectRemoteDevices.js +6 -5
  97. package/src/utils/Converter/__test__/timer.test.js +99 -0
  98. package/src/utils/Functions/Search.js +17 -0
  99. package/src/utils/Functions/ShortEmail.js +4 -0
  100. package/src/utils/Functions/__test__/Search.test.js +6 -0
  101. package/src/utils/Functions/__test__/ShortEmail.test.js +6 -0
  102. package/src/utils/I18n/translations/en.json +32 -42
  103. package/src/utils/I18n/translations/vi.json +32 -44
  104. package/src/utils/Route/index.js +6 -0
  105. package/src/commons/Modal/ModalFullVideo.js +0 -48
  106. package/src/commons/Modal/Styles/ModalFullVideoStyles.js +0 -26
  107. package/src/screens/Unit/components/MyUnit/index.js +0 -136
  108. package/src/screens/Unit/components/__test__/MyUnit.test.js +0 -35
@@ -1,15 +1,17 @@
1
1
  import React, { useState, useCallback } from 'react';
2
2
  import { StyleSheet, View, TouchableOpacity } from 'react-native';
3
3
  import { useNavigation } from '@react-navigation/native';
4
+ import { useGGHomeDeviceConnected } from '../../../../hooks/Common';
4
5
 
5
6
  import ItemQuickAction from '../../../../commons/Action/ItemQuickAction';
6
7
  import Text from '../../../../commons/Text';
7
8
  import Routes from '../../../../utils/Route';
8
9
  import { Colors } from '../../../../configs';
9
10
  import FImage from '../../../../commons/FImage';
11
+ import { DEVICE_TYPE } from '../../../../configs/Constants';
10
12
 
11
- const MyUnitDevice = ({ sensor, unit }) => {
12
- const [status, setStatus] = useState(sensor.status);
13
+ const MyUnitDevice = ({ device, unit }) => {
14
+ const [status, setStatus] = useState(device.status);
13
15
  const { navigate } = useNavigation();
14
16
 
15
17
  const goToSensorDisplay = useCallback(() => {
@@ -17,34 +19,49 @@ const MyUnitDevice = ({ sensor, unit }) => {
17
19
  screen: Routes.DeviceDetail,
18
20
  params: {
19
21
  unitData: unit,
20
- sensorData: sensor,
22
+ sensorData: device,
21
23
  },
22
24
  });
23
- }, [navigate, sensor, unit]);
25
+ }, [navigate, device, unit]);
26
+
27
+ const { isConnecting: isGGHomeConnecting } = useGGHomeDeviceConnected(device);
28
+
29
+ const canRenderQuickAction = (() => {
30
+ if (
31
+ !!device &&
32
+ !device?.is_managed_by_backend &&
33
+ device?.device_type === DEVICE_TYPE.GOOGLE_HOME
34
+ ) {
35
+ return !isGGHomeConnecting;
36
+ }
37
+ return true;
38
+ })();
24
39
 
25
40
  return (
26
41
  <View style={styles.item}>
27
42
  <TouchableOpacity style={styles.flex1} onPress={goToSensorDisplay}>
28
43
  <View style={styles.rowCenter}>
29
- <FImage style={styles.image} source={{ uri: sensor?.icon_kit }} />
44
+ <FImage style={styles.image} source={{ uri: device?.icon_kit }} />
30
45
  <View style={styles.marginTop3}>
31
46
  <Text numberOfLines={1} semibold style={styles.nameDevice}>
32
- {sensor.name}
47
+ {device.name}
33
48
  </Text>
34
49
  <View style={styles.roomDevice}>
35
50
  <Text numberOfLines={1} style={styles.roomDevicePart}>
36
- {sensor.station_name}
51
+ {device.station_name}
37
52
  {status ? ` - ${status}` : ''}
38
53
  </Text>
39
54
  </View>
40
55
  </View>
41
56
  </View>
42
57
  </TouchableOpacity>
43
- <ItemQuickAction
44
- sensor={sensor}
45
- wrapperStyle={styles.iconCircle}
46
- setStatus={setStatus}
47
- />
58
+ {canRenderQuickAction && (
59
+ <ItemQuickAction
60
+ sensor={device}
61
+ wrapperStyle={styles.iconCircle}
62
+ setStatus={setStatus}
63
+ />
64
+ )}
48
65
  </View>
49
66
  );
50
67
  };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import renderer, { act } from 'react-test-renderer';
3
3
  import Modal from 'react-native-modal';
4
- import Popover from 'react-native-popover-view';
4
+ import Popover from '../../../../commons/Popover';
5
5
 
6
6
  import { SCProvider } from '../../../../context';
7
7
  import { mockSCStore } from '../../../../context/mockStore';
@@ -26,7 +26,7 @@ describe('Test MyUnitDevice', () => {
26
26
 
27
27
  beforeEach(() => {
28
28
  props = {
29
- sensor: {
29
+ device: {
30
30
  status: 'Ok',
31
31
  name: 'Test',
32
32
  station_name: '',
@@ -54,7 +54,7 @@ describe('Test MyUnitDevice', () => {
54
54
  });
55
55
 
56
56
  it('Test render without status', async () => {
57
- props.sensor.status = undefined;
57
+ props.device.status = undefined;
58
58
  await act(() => {
59
59
  tree = create(wrapComponent(props));
60
60
  });
@@ -5,7 +5,9 @@ import { useGGHomeConnection } from '../../../hooks/IoT';
5
5
  import { useSCContextSelector } from '../../../context';
6
6
 
7
7
  export const useUnitConnectRemoteDevices = (unit) => {
8
- const { isNetworkConnected } = useSCContextSelector((state) => state.app);
8
+ const isNetworkConnected = useSCContextSelector(
9
+ (state) => state.app.isNetworkConnected
10
+ );
9
11
 
10
12
  const { connectGoogleHome } = useGGHomeConnection();
11
13
 
@@ -21,15 +23,14 @@ export const useUnitConnectRemoteDevices = (unit) => {
21
23
  }, []);
22
24
 
23
25
  useEffect(() => {
24
- if (unit.remote_control_options && unit.remote_control_options.bluetooth) {
26
+ if (unit?.remote_control_options?.bluetooth) {
25
27
  scanBluetoothDevices(unit.remote_control_options.bluetooth);
26
28
  }
27
29
  }, [unit]);
28
30
 
29
31
  useEffect(() => {
30
32
  if (
31
- unit.remote_control_options &&
32
- unit.remote_control_options.googlehome?.length &&
33
+ unit?.remote_control_options?.googlehome?.length &&
33
34
  isNetworkConnected
34
35
  ) {
35
36
  (async () => {
@@ -40,7 +41,7 @@ export const useUnitConnectRemoteDevices = (unit) => {
40
41
  }, [unit, isNetworkConnected]);
41
42
 
42
43
  useEffect(() => {
43
- if (unit.remote_control_options && unit.remote_control_options.lg_thinq) {
44
+ if (unit?.remote_control_options?.lg_thinq) {
44
45
  (async () => {
45
46
  await handleLgThinqConnect(unit.remote_control_options.lg_thinq);
46
47
  })();
@@ -0,0 +1,99 @@
1
+ import { getDateData, getTitleFromTime, timeDifference } from '../time';
2
+
3
+ describe('Test timer', () => {
4
+ let result;
5
+ it('Test timeDifference when elapsed < msPerMinute and symbol=false', async () => {
6
+ result = await timeDifference(
7
+ new Date('2022-08-01T03:24:01'),
8
+ new Date('2022-08-01T03:24:00')
9
+ );
10
+ expect(result).toBe('1 seconds ago');
11
+ });
12
+
13
+ it('Test timeDifference when elapsed < msPerMinute and symbol=true', async () => {
14
+ result = await timeDifference(
15
+ new Date('2022-08-01T03:24:01'),
16
+ new Date('2022-08-01T03:24:00'),
17
+ true
18
+ );
19
+ expect(result).toBe('1 secs ago');
20
+ });
21
+
22
+ it('Test timeDifference when elapsed < msPerHour and symbol=false', async () => {
23
+ result = await timeDifference(
24
+ new Date('2022-08-01T03:24:01'),
25
+ new Date('2022-08-01T03:00:00')
26
+ );
27
+ expect(result).toBe('24 minutes ago');
28
+ });
29
+
30
+ it('Test timeDifference when elapsed < msPerHour and symbol=true', async () => {
31
+ result = await timeDifference(
32
+ new Date('2022-08-01T03:24:01'),
33
+ new Date('2022-08-01T03:00:00'),
34
+ true
35
+ );
36
+ expect(result).toBe('24 mins ago');
37
+ });
38
+
39
+ it('Test timeDifference when elapsed < msPerDay and symbol=false', async () => {
40
+ result = await timeDifference(
41
+ new Date('2022-08-01T03:24:01'),
42
+ new Date('2022-08-01T02:00:00')
43
+ );
44
+ expect(result).toBe('1 hours ago');
45
+ });
46
+
47
+ it('Test timeDifference when elapsed < msPerMonthe', async () => {
48
+ result = await timeDifference(
49
+ new Date('2022-08-01T03:24:01'),
50
+ new Date('2022-07-31T02:00:00')
51
+ );
52
+ expect(result).toBe('1 days ago');
53
+ });
54
+
55
+ it('Test timeDifference when elapsed < msPerYear', async () => {
56
+ result = await timeDifference(
57
+ new Date('2022-08-01T03:24:01'),
58
+ new Date('2022-05-31T02:00:00')
59
+ );
60
+ expect(result).toBe('2 months ago');
61
+ });
62
+
63
+ it('Test timeDifference when elapsed > msPerYear', async () => {
64
+ result = await timeDifference(
65
+ new Date('2022-08-01T03:24:01'),
66
+ new Date('2021-05-31T02:00:00')
67
+ );
68
+ expect(result).toBe('1 years ago');
69
+ });
70
+
71
+ it('Test getTitleFromTime when time = current', async () => {
72
+ result = await getTitleFromTime(new Date(), new Date());
73
+ expect(result).toBe('Today');
74
+ });
75
+
76
+ it('Test getTitleFromTime when time > current', async () => {
77
+ result = await getTitleFromTime(
78
+ new Date('2022-05-31T02:00:00'),
79
+ new Date('2022-05-30T02:00:00')
80
+ );
81
+ expect(result).toBe('31/05/2022');
82
+ });
83
+
84
+ it('Test getTitleFromTime when time < current', async () => {
85
+ result = await getTitleFromTime(
86
+ new Date('2022-05-29T02:00:00'),
87
+ new Date('2022-05-30T02:00:00')
88
+ );
89
+ expect(result).toBe('Yesterday');
90
+ });
91
+
92
+ it('Test getDateData', async () => {
93
+ result = await getDateData(
94
+ new Date('2022-05-30T02:00:00'),
95
+ new Date('2022-06-30T02:00:00')
96
+ );
97
+ expect(result).toEqual([[], 0]);
98
+ });
99
+ });
@@ -0,0 +1,17 @@
1
+ export const formatVietnamese = (str) => {
2
+ str = str.toLowerCase();
3
+ str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, 'a');
4
+ str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, 'e');
5
+ str = str.replace(/ì|í|ị|ỉ|ĩ/g, 'i');
6
+ str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, 'o');
7
+ str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, 'u');
8
+ str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, 'y');
9
+ str = str.replace(/đ/g, 'd');
10
+ return str;
11
+ };
12
+
13
+ export const convertToSlug = (text) => {
14
+ text = text.substring(0, Math.max(80, text.length));
15
+ text = formatVietnamese(text);
16
+ return text.toLowerCase().replace(/[^\w ]+/g, '');
17
+ };
@@ -0,0 +1,4 @@
1
+ export const shortEmailName = (email) => {
2
+ const regex = '([^@]+)';
3
+ return email?.match(regex)[0] || '';
4
+ };
@@ -0,0 +1,6 @@
1
+ const { convertToSlug } = require('../Search');
2
+
3
+ it('Test Search function', () => {
4
+ const data = convertToSlug('Bệnh viện');
5
+ expect(data).toEqual('benh vien');
6
+ });
@@ -0,0 +1,6 @@
1
+ import { shortEmailName } from '../ShortEmail';
2
+
3
+ it('Test shortEmailName function', () => {
4
+ const data = shortEmailName('emailExample@gmail.com');
5
+ expect(data).toEqual('emailExample');
6
+ });
@@ -666,47 +666,27 @@
666
666
  "is": "is",
667
667
  "is_below": "is below",
668
668
  "is_above": "is above",
669
- "text_notification_title_remind_to_make_payment": "Complete payment for your booking",
670
- "text_notification_title_expire_parking_session": "Parking session expires soon",
671
- "text_notification_title_remind_to_scan_qr_code": "Scan QR Code to activate your booking",
672
- "text_notification_title_user_cancel": "Booking cancellation has been accepted",
673
- "text_notification_title_system_cancel_no_payment": "Your booking is cancelled",
674
- "text_notification_title_booking_successfully": "Booking successfully",
675
- "text_notification_title_parking_completed": "Parking completed",
676
- "text_notification_content_remind_to_make_payment": "Your booking **%{booking}** is not completed. Please make payment before **%{time}** to reserve your booking.",
677
- "text_notification_content_expire_parking_session": "Your parking **%{booking}** will expire soon. Please leave before **%{time}** or extend your booking hours.",
678
- "text_notification_content_remind_to_scan_qr_code": "Your booking **%{booking}** is not yet activated. Please remember to scan the QR code when you arrive at your booked parking spot to activate it.",
679
- "text_notification_content_user_cancel": "Request to cancel your booking has been accepted. Booking **%{booking}** was cancelled successfully.",
680
- "text_notification_content_system_cancel_no_payment": "Your booking **%{booking}** is automatically cancelled by the system because no payment has been made on time.",
681
- "text_notification_content_booking_successfully": "Your booking **%{booking}** was confirmed.",
682
- "text_notification_content_parking_completed": "Your booking **%{booking}** is completed. Thank you for using our service.",
683
- "text_notification_content_invite_member": "**%{unit_owner_name}** invited you to join **%{unit_name}**.",
684
- "text_notification_content_not_move_car_after_parking_session_expire": "Your car (booking **%{booking}**) was locked for violating our parking regulations. Please pay a fine to unlock and move your car.",
685
- "text_notification_content_move_car_without_pay_violation": "You have an unpaid violation. Please complete your fine.",
686
- "text_notification_content_pay_fine_successfully": "Your violation **%{booking}** has been paid successfully.",
687
- "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}**.",
688
- "text_notification_content_stop_violation_free_parking_zone": "Free parking zone. You have an unpaid violation. Please complete your fine.",
689
- "text_notification_content_air_quality_high": "The Air Quality index at **%{unit_name}** is **%{status}**. Wear a mask and reduce outdoor exercise.",
690
- "text_notification_content_uv_index_high": "The UV index at **%{unit_name}** is **%{status}**. Reduce time in the sun and protect your skin, eyes.",
691
- "text_notification_content_pH_index_high": "The pH index at **%{unit_name}** is **%{status}**. Water is not safe to drink.",
692
- "text_notification_content_clo_high": "The Chlorine residual at **%{unit_name}** is **%{status}**. Water is not safe to drink.",
693
- "text_notification_content_turbility_high": "The Turbility at **%{unit_name}** is **%{status}**. Water is not safe to drink.",
694
- "text_notification_content_smoke": "Smoke appears in **%{unit_name}**. Please check your home and call the rescue team if there is a fire.",
695
- "text_notification_content_fire": "There is a fire at **%{unit_name}**, Please move out of the house immediately and call the rescue team.",
696
- "text_notification_content_active_sos": "SOS button is activating at **%{unit_name}**, Please check it NOW.",
697
- "text_notification_content_replace_water_filter": "Filter **%{number_coil}** of **%{device_name}** in **%{unit_name}**: **%{sub_unit_name}** has less than 10h remaining. Check and replace now.",
698
- "text_notification_content_remove_unit_to_owner": "Unit **%{unit_name}** has been removed successfully.",
699
- "text_notification_content_remove_unit_to_member": "Unit **%{unit_name}** has been removed by **%{unit_owner_name}**. You cannot access to this unit anymore.",
700
- "text_notification_content_remove_member": "You were removed from **%{unit_name}** by **%{unit_owner_name}**. You cannot access to this unit anymore.",
701
- "text_notification_content_member_leave_unit": "**%{member_name}** has left **%{unit_name}**.",
702
- "text_notification_content_rename_unit": "Unit **%{old_unit_name}** has been renamed to **%{new_unit_name}** by **%{owner_name}**.",
703
- "text_notification_content_divice_disconnect": "**%{device_name}** at **%{unit_name}**: **%{sub_unit_name}** has been disconnected. Please check and reconnect.",
704
- "text_notification_content_rename_sub_unit": "Sub-unit **%{old_sub_unit_name}**: **%{unit_name}** has been renamed to **%{new_sub_unit_name}** by **%{unti_owner_name}**.",
705
- "text_notification_content_remove_sub_unit": "Sub-unit **%{sub_unit_name}** has been removed from **%{unit_name}** by **%{unit_owner_name}**.",
706
- "text_notification_content_remove_device": "Device **%{device_name}** has been removed from **%{unit_name}** by **%{unit_owner_name}**.",
707
- "text_notification_content_update_address": "New address of **%{unit_name}** has been updated by **%{unit_owner_name}** to **%{unit_address}**.",
708
- "text_notification_content_emergency": "The Emergency button has been activated at **%{unit_name}**: **%{sub_unit_name}**. Please check now!",
709
- "text_notification_content_emergency_resolve": "Emergency situation activated at **%{unit_name}**: **%{sub_unit_name}** has resolved.",
669
+ "text_notification_content_air_quality_high": "The Air Quality index at **unit_name** is **status**. Wear a mask and reduce outdoor exercise.",
670
+ "text_notification_content_uv_index_high": "The UV index at **unit_name** is **status**. Reduce time in the sun and protect your skin, eyes.",
671
+ "text_notification_content_pH_index_high": "The pH index at **unit_name** is **status**. Water is not safe to drink.",
672
+ "text_notification_content_clo_high": "The Chlorine residual at **unit_name** is **status**. Water is not safe to drink.",
673
+ "text_notification_content_turbility_high": "The Turbility at **unit_name** is **status**. Water is not safe to drink.",
674
+ "text_notification_content_smoke": "Smoke appears in **unit_name**. Please check your home and call the rescue team if there is a fire.",
675
+ "text_notification_content_fire": "There is a fire at **unit_name**, Please move out of the house immediately and call the rescue team.",
676
+ "text_notification_content_active_sos": "SOS button is activating at **unit_name**, Please check it NOW.",
677
+ "text_notification_content_replace_water_filter": "Filter **config_name** of **device_name** in **station_name** has less than 10h remaining. Check and replace now.",
678
+ "text_notification_content_remove_unit_to_owner": "Unit **unit_name** has been removed successfully.",
679
+ "text_notification_content_remove_unit_to_member": "Unit **unit_name** has been removed by **unit_owner_name**. You cannot access to this unit anymore.",
680
+ "text_notification_content_remove_member": "You were removed from **unit_name** by **unit_owner_name**. You cannot access to this unit anymore.",
681
+ "text_notification_content_member_leave_unit": "**member_name** has left **unit_name**.",
682
+ "text_notification_content_rename_unit": "Unit **old_unit_name** has been renamed to **new_unit_name** by **owner_name**.",
683
+ "text_notification_content_divice_disconnect": "**device_name** at **unit_name**: **sub_unit_name** has been disconnected. Please check and reconnect.",
684
+ "text_notification_content_rename_sub_unit": "Sub-unit **old_sub_unit_name**: **unit_name** has been renamed to **new_sub_unit_name** by **unti_owner_name**.",
685
+ "text_notification_content_remove_sub_unit": "Sub-unit **sub_unit_name** has been removed from **unit_name** by **unit_owner_name**.",
686
+ "text_notification_content_remove_device": "Device **device_name** has been removed from **unit_name** by **unit_owner_name**.",
687
+ "text_notification_content_update_address": "New address of **unit_name** has been updated by **unit_owner_name** to **unit_address**.",
688
+ "text_notification_content_emergency": "The Emergency button has been activated at **unit_name**: **sub_unit_name**. Please check now!",
689
+ "text_notification_content_emergency_resolve": "Emergency situation activated at **unit_name**: **sub_unit_name** has resolved.",
710
690
  "this_spot_does_not_exsit": "This spot does not exist",
711
691
  "please_scan_again_or_contact_the_parking_manager": "Please scan again or contact the parking manager",
712
692
  "this_spot_does_not_support_to_scan": "This spot does not support to scan",
@@ -1002,5 +982,15 @@
1002
982
  "not_activated": "Not activated",
1003
983
  "open": "Open",
1004
984
  "close": "Close",
1005
- "create_contact_success": "Create contact success!"
985
+ "create_contact_success": "Create contact success!",
986
+ "templates": "Templates",
987
+ "template": "Template",
988
+ "gateways": "Gateways",
989
+ "help": "Help",
990
+ "about_us": "About us",
991
+ "exit_dev_mode": "Exit developer mode",
992
+ "developer_mode": "Developer Mode",
993
+ "what_are_you_looking_for": "What are you looking for?",
994
+ "no_template_yet": "No Template yet",
995
+ "add_your_template": "Add your template at web app"
1006
996
  }
@@ -681,49 +681,27 @@
681
681
  "select_unit_members": "Chọn từ danh sách thành viên của địa điểm",
682
682
  "select_contacts": "Chọn liên hệ",
683
683
  "no_contact": "Không có liên hệ nào",
684
- "text_notification_title_remind_to_make_payment": "Hoàn tất thanh toán đặt chỗ trước",
685
- "text_notification_title_expire_parking_session": "Phiên đỗ xe sẽ sớm kết thúc",
686
- "text_notification_title_remind_to_scan_qr_code": "Quét QR để kích hoạt đặt chỗ",
687
- "text_notification_title_user_cancel": "Chấp nhận yêu cầu huỷ đặt chỗ",
688
- "text_notification_title_system_cancel_no_payment": "Đặt chỗ trước của bạn đã bị huỷ",
689
- "text_notification_title_system_cancel_emergency_situation": "Đặt chỗ bị huỷ do tình huống khẩn cấp",
690
- "text_notification_title_booking_successfully": "Xác nhận đặt chỗ thành công",
691
- "text_notification_title_parking_completed": "Hoàn tất đỗ xe",
692
- "text_notification_content_remind_to_make_payment": "Đặt chỗ **%{booking}** chưa hoàn tất. Vui lòng thực hiện thanh toán trước **%{time}** để giữ đặt trước của bạn.",
693
- "text_notification_content_expire_parking_session": "Phiên đỗ xe **%{booking}** sẽ sớm kết thúc. Vui lòng di chuyển xe trước **%{time}** hoặc thêm giờ đỗ xe.",
694
- "text_notification_content_remind_to_scan_qr_code": "Đặt chỗ **%{booking}** chưa được kích hoạt. Vui lòng quét QR tại vị trí đỗ xe được cung cấp để kích hoạt đặt chỗ trước của bạn.",
695
- "text_notification_content_user_cancel": "Yêu cầu huỷ đặt chỗ trước của bạn đã được chấp nhận. Đặt chỗ **%{booking}** đã được huỷ thành công.",
696
- "text_notification_content_system_cancel_no_payment": "Đặt chỗ **%{booking}** đã tự động huỷ bởi hệ thống do quá hạn thanh toán.",
697
- "text_notification_content_system_cancel_emergency_situation_%{spot}": "Chúng tôi rất tiếc vì đặt chỗ %{spot} đã bị huỷ vì một tình huống khẩn cấp. Bạn sẽ nhận được phiếu giảm giá cho lần đỗ xe tiếp theo. ",
698
- "text_notification_content_booking_successfully": "Đặt chỗ **%{booking}** đã được xác nhận.",
699
- "text_notification_content_parking_completed": "Đặt chỗ **%{booking}** đã hoàn tất. Cảm ơn đã sử dụng dịch vụ của chúng tôi.",
700
- "text_notification_content_invite_member": "**%{unit_owner_name}** mời bạn đến địa điểm **%{unit_name}**.",
701
- "text_notification_content_not_move_car_after_parking_session_expire": "Xe của bạn (booking **%{booking}**) đã bị khóa do vi phạm quy định về giờ đỗ xe của chúng tôi. Vui lòng nộp phạt để mở khóa và di chuyển xe của bạn.",
702
- "text_notification_content_move_car_without_pay_violation": "Bạn 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.",
703
- "text_notification_content_pay_fine_successfully": "Đỗ xe vi phạm **%{booking}** của bạn đã được thanh toán.",
704
- "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}**.",
705
- "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.",
706
- "text_notification_content_air_quality_high": "Chỉ số AQI tại **%{unit_name}** đang ở mức **%{status}**. Đeo khẩu trang và giảm các hoạt động ngoài trời để bảo vệ sức khoẻ của bạn.",
707
- "text_notification_content_uv_index_high": "Chỉ số UV tại **%{unit_name}** đang ở mức **%{status}**. Giảm thời gian ngoài trời và bảo vệ da, mắt khỏi ánh nắng mặt trời.",
708
- "text_notification_content_pH_index_high": "Độ pH của nước tại **%{unit_name}** đang ở mức **%{status}**. Nước không đảm bảo an toàn để uống.",
709
- "text_notification_content_clo_high": "Độ clo của nước tại **%{unit_name}** đang ở mức **%{status}**. Nước không đảm bảo an toàn để uống.",
710
- "text_notification_content_turbility_high": "Độ đục của nước tại **%{unit_name}** đang ở mức **%{status}**. Nước không đảm bảo an toàn để uống.",
711
- "text_notification_content_smoke": "Xuất hiện khói tại **%{unit_name}**. Vui lòng kiểm tra nhà của bạn và gọi cho đội cứu hộ nếu xảy ra hỏa hoạn.",
712
- "text_notification_content_fire": "Có đám cháy tại **%{unit_name}**, Vui lòng di chuyển ra khỏi nhà ngay lập tức và gọi cho đội cứu hộ.",
713
- "text_notification_content_active_sos": "Nút SOS đang kích hoạt tại **%{unit_name}**. Vui lòng kiểm tra nó NGAY BÂY GIỜ.",
714
- "text_notification_content_replace_water_filter": "Lõi lọc **%{number_coil}** của **%{device_name}** thuộc **%{unit_name}**: **%{sub_unit_name}** còn ít hơn 10 giờ lọc. Vui lòng kiểm tra và thay lõi lọc mới.",
715
- "text_notification_content_remove_unit_to_owner": "Địa điểm **%{unit_name}** vừa được xoá thành công.",
716
- "text_notification_content_remove_unit_to_member": "Địa điểm **%{unit_name}** vừa được xoá bởi **%{unit_owner_name}**. Bạn không thể truy cập vào địa điểm này được nữa.",
717
- "text_notification_content_remove_member": "Bạn vừa được xoá khỏi **%{unit_name}** bởi **%{unit_owner_name}**. Bạn không thể truy cập vào địa điểm này được nữa.",
718
- "text_notification_content_member_leave_unit": "**%{member_name}** vừa rời khỏi **%{unit_name}**.",
719
- "text_notification_content_rename_unit": "Địa điểm **%{old_unit_name}** vừa được đổi tên thành **%{new_unit_name}** bởi **%{owner_name}**.",
720
- "text_notification_content_divice_disconnect": "**%{device_name}** tại **%{unit_name}**: **%{sub_unit_name}** vừa bị mất kết nối. Vui lòng kiểm tra và kết nối lại.",
721
- "text_notification_content_rename_sub_unit": "Khu vực **%{old_sub_unit_name}**: **%{unit_name}** vừa được đổi tên thành **%{new_sub_unit_name}** bởi **%{unti_owner_name}**.",
722
- "text_notification_content_remove_sub_unit": "Khu vực **%{sub_unit_name}** vừa được xoá khỏi **%{unit_name}** bởi **%{unit_owner_name}**.",
723
- "text_notification_content_remove_device": "Thiết bị **%{device_name}** vừa được xoá khỏi **%{unit_name}** bởi **%{unit_owner_name}**.",
724
- "text_notification_content_update_address": "Địa chỉ mới của **%{unit_name}** vừa được cập nhật bởi **%{unit_owner_name}** thành **%{unit_address}**.",
725
- "text_notification_content_emergency": "Một tình huống khẩn cấp vừa được kích hoạt tại **%{unit_name}**: **%{sub_unit_name}**. Vui lòng kiểm tra ngay!",
726
- "text_notification_content_emergency_resolve": "Tình huống khẩn cấp được kích hoạt tại **%{unit_name}**: **%{sub_unit_name}** đã được giải quyết.",
684
+ "text_notification_content_air_quality_high": "Chỉ số AQI tại **unit_name** đang ở mức **status**. Đeo khẩu trang và giảm các hoạt động ngoài trời để bảo vệ sức khoẻ của bạn.",
685
+ "text_notification_content_uv_index_high": "Chỉ số UV tại **unit_name** đang ở mức **status**. Giảm thời gian ngoài trời và bảo vệ da, mắt khỏi ánh nắng mặt trời.",
686
+ "text_notification_content_pH_index_high": "Độ pH của nước tại **unit_name** đang ở mức **status**. Nước không đảm bảo an toàn để uống.",
687
+ "text_notification_content_clo_high": "Độ clo của nước tại **unit_name** đang ở mức **status**. Nước không đảm bảo an toàn để uống.",
688
+ "text_notification_content_turbility_high": "Độ đục của nước tại **unit_name** đang ở mức **status**. Nước không đảm bảo an toàn để uống.",
689
+ "text_notification_content_smoke": "Xuất hiện khói tại **unit_name**. Vui lòng kiểm tra nhà của bạn và gọi cho đội cứu hộ nếu xảy ra hỏa hoạn.",
690
+ "text_notification_content_fire": " đám cháy tại **unit_name**, Vui lòng di chuyển ra khỏi nhà ngay lập tức và gọi cho đội cứu hộ.",
691
+ "text_notification_content_active_sos": "Nút SOS đang kích hoạt tại **unit_name**. Vui lòng kiểm tra nó NGAY BÂY GIỜ.",
692
+ "text_notification_content_replace_water_filter": "Lõi lọc **config_name** của **device_name** thuộc **unit_name**: **station_name** còn ít hơn 10 giờ lọc. Vui lòng kiểm tra thay lõi lọc mới.",
693
+ "text_notification_content_remove_unit_to_owner": "Địa điểm **unit_name** vừa được xoá thành công.",
694
+ "text_notification_content_remove_unit_to_member": "Địa điểm **unit_name** vừa được xoá bởi **unit_owner_name**. Bạn không thể truy cập vào địa điểm này được nữa.",
695
+ "text_notification_content_remove_member": "Bạn vừa được xoá khỏi **unit_name** bởi **unit_owner_name**. Bạn không thể truy cập vào địa điểm này được nữa.",
696
+ "text_notification_content_member_leave_unit": "**member_name** vừa rời khỏi **unit_name**.",
697
+ "text_notification_content_rename_unit": "Địa điểm **old_unit_name** vừa được đổi tên thành **new_unit_name** bởi **owner_name**.",
698
+ "text_notification_content_divice_disconnect": "**device_name** tại **unit_name**: **sub_unit_name** vừa bị mất kết nối. Vui lòng kiểm tra và kết nối lại.",
699
+ "text_notification_content_rename_sub_unit": "Khu vực **old_sub_unit_name**: **unit_name** vừa được đổi tên thành **new_sub_unit_name** bởi **unti_owner_name**.",
700
+ "text_notification_content_remove_sub_unit": "Khu vực **sub_unit_name** vừa được xoá khỏi **%unit_name** bởi **unit_owner_name**.",
701
+ "text_notification_content_remove_device": "Thiết bị **device_name** vừa được xoá khỏi **unit_name** bởi **unit_owner_name**.",
702
+ "text_notification_content_update_address": "Địa chỉ mới của **unit_name** vừa được cập nhật bởi **unit_owner_name** thành **unit_address**.",
703
+ "text_notification_content_emergency": "Một tình huống khẩn cấp vừa được kích hoạt tại **unit_name**: **sub_unit_name**. Vui lòng kiểm tra ngay!",
704
+ "text_notification_content_emergency_resolve": "Tình huống khẩn cấp được kích hoạt tại **unit_name**: **sub_unit_name** đã được giải quyết.",
727
705
  "this_spot_does_not_exsit": "Vị trí đỗ này không tồn tại",
728
706
  "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",
729
707
  "this_spot_does_not_support_to_scan": "Vị trí đỗ này không hỗ trợ quét",
@@ -1003,5 +981,15 @@
1003
981
  "not_activated": "Không kích hoạt",
1004
982
  "open": "Mở",
1005
983
  "close": "Đóng",
1006
- "create_contact_success": "Tạo liên hệ thành công!"
984
+ "create_contact_success": "Tạo liên hệ thành công!",
985
+ "templates": "Mẫu",
986
+ "template": "Mẫu",
987
+ "gateways": "Cổng vào",
988
+ "help": "Hỗ trợ",
989
+ "about_us": "Giới thiệu về chúng tôi",
990
+ "exit_dev_mode": "Thoát khỏi chế độ nhà phát triển",
991
+ "developer_mode": "Chế độ nhà phát triển",
992
+ "what_are_you_looking_for": "Bạn đang tìm kiếm cái gì?",
993
+ "no_template_yet": "Chưa có mẫu nào",
994
+ "add_your_template": "Thêm mẫu của bạn trên web"
1007
995
  }
@@ -147,6 +147,12 @@ const Routes = {
147
147
  UnitMemberInformation: 'UnitMemberInformation',
148
148
  EnterPassword: 'EnterPassword',
149
149
  SelectAddToFavorites: 'SelectAddToFavorites',
150
+ Template: 'Template',
151
+ Gateway: 'Gateway',
152
+ Smart: 'Smart',
153
+ TemplateStack: 'TemplateStack',
154
+ GatewayStack: 'GatewayStack',
155
+ SmartStack: 'SmartStack',
150
156
  };
151
157
 
152
158
  export default Routes;
@@ -1,48 +0,0 @@
1
- import React, { useEffect } from 'react';
2
- import { View, TouchableOpacity, Image } from 'react-native';
3
- import { ModalCustom } from '../../commons/Modal';
4
- import MediaPlayerDetail from '../../commons/MediaPlayerDetail';
5
- import { Images } from '../../configs';
6
- import styles from './Styles/ModalFullVideoStyles';
7
- import { useHiddenStatusBar } from '../../hooks/Common/useStatusBar';
8
-
9
- const ModalFullVideo = ({
10
- animationOut = 'fadeOut',
11
- isVisible = false,
12
- modalStyles,
13
- data,
14
- resizeMode = 'cover',
15
- onClose,
16
- uri,
17
- }) => {
18
- useEffect(() => {
19
- // eslint-disable-next-line react-hooks/rules-of-hooks
20
- useHiddenStatusBar(isVisible);
21
- }, [isVisible]);
22
-
23
- return (
24
- <ModalCustom
25
- animationOut={animationOut}
26
- isVisible={isVisible}
27
- style={modalStyles}
28
- >
29
- <View style={styles.modalContent}>
30
- <MediaPlayerDetail
31
- uri={uri || data?.uri}
32
- thumbnail={data?.thumbnail}
33
- style={styles.camera}
34
- wrapStyles={styles.wrapStyles}
35
- resizeMode={resizeMode}
36
- cameraName={data?.name}
37
- isFullScreen={true}
38
- isPaused={false}
39
- />
40
- <TouchableOpacity onPress={onClose} style={styles.buttonFullScreen}>
41
- <Image source={Images.fullscreen} />
42
- </TouchableOpacity>
43
- </View>
44
- </ModalCustom>
45
- );
46
- };
47
-
48
- export default ModalFullVideo;
@@ -1,26 +0,0 @@
1
- import { StyleSheet } from 'react-native';
2
- import { normalize } from '../../../configs/Constants';
3
-
4
- export default StyleSheet.create({
5
- modalContent: {
6
- position: 'absolute',
7
- zIndex: 10,
8
- top: 0,
9
- left: 0,
10
- right: 0,
11
- bottom: 0,
12
- },
13
- buttonFullScreen: {
14
- position: 'absolute',
15
- zIndex: 10,
16
- width: normalize(40),
17
- height: normalize(40),
18
- bottom: normalize(30),
19
- left: normalize(20),
20
- justifyContent: 'center',
21
- alignItems: 'center',
22
- },
23
- wrapStyles: {
24
- borderRadius: 0,
25
- },
26
- });