@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
@@ -0,0 +1,144 @@
1
+ import React, { useMemo, useRef } from 'react';
2
+ import {
3
+ Animated,
4
+ View,
5
+ TouchableOpacity,
6
+ StyleSheet,
7
+ Image,
8
+ } from 'react-native';
9
+ import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
10
+ import { createDrawerNavigator } from '@react-navigation/drawer';
11
+ import { useNavigation } from '@react-navigation/native';
12
+ import { getStatusBarHeight } from 'react-native-iphone-x-helper';
13
+
14
+ import Tabbar from '../commons/Tabbar';
15
+ import { Colors, Constants, Images } from '../configs';
16
+ import t from '../hooks/Common/useTranslations';
17
+ import Routes from '../utils/Route';
18
+ import GatewayStack from './GatewayStack';
19
+ import SmartStack from './SmartStack';
20
+ import TemplateStack from './TemplateStack';
21
+ import DrawerContainer from '../screens/Drawer';
22
+ import { TESTID } from '../configs/Constants';
23
+ import Text from '../commons/Text';
24
+
25
+ const Tab = createBottomTabNavigator();
26
+ const Drawer = createDrawerNavigator();
27
+
28
+ const getWidth = () => {
29
+ const Width = Constants.width - 12;
30
+ return Width / 3;
31
+ };
32
+
33
+ const MainDevMode = () => {
34
+ const navigation = useNavigation();
35
+
36
+ const listTabName = useMemo(
37
+ () => [
38
+ {
39
+ name: Routes.TemplateStack,
40
+ tabBarLabel: t('templates'),
41
+ component: TemplateStack,
42
+ },
43
+ {
44
+ name: Routes.GatewayStack,
45
+ tabBarLabel: t('gateways'),
46
+ component: GatewayStack,
47
+ },
48
+ {
49
+ name: Routes.SmartStack,
50
+ tabBarLabel: t('smart'),
51
+ component: SmartStack,
52
+ },
53
+ ],
54
+ []
55
+ );
56
+
57
+ const tabOffSetValue = useRef(new Animated.Value(0)).current;
58
+
59
+ const Header = () => {
60
+ return (
61
+ <View style={styles.wrapHeader}>
62
+ <TouchableOpacity
63
+ style={styles.btnMenu}
64
+ onPress={() => navigation.toggleDrawer()}
65
+ testID={TESTID.BURGER_MENU_ICON}
66
+ >
67
+ <Image source={Images.menu} style={styles.menu} />
68
+ </TouchableOpacity>
69
+ <Text style={styles.textHeader}>{t('developer_mode')}</Text>
70
+ </View>
71
+ );
72
+ };
73
+
74
+ return (
75
+ <>
76
+ <Header />
77
+ <Tab.Navigator tabBar={(props) => <Tabbar {...props} />}>
78
+ {listTabName.map((item) => (
79
+ <Tab.Screen
80
+ name={item.name}
81
+ component={item.component}
82
+ options={{
83
+ tabBarLabel: item.tabBarLabel,
84
+ tabOffSetValue,
85
+ }}
86
+ />
87
+ ))}
88
+ </Tab.Navigator>
89
+ <Animated.View
90
+ // eslint-disable-next-line react-native/no-inline-styles
91
+ style={{
92
+ width: getWidth() - 4,
93
+ transform: [{ translateX: tabOffSetValue }],
94
+ height: 2,
95
+ backgroundColor: Colors.Primary,
96
+ position: 'absolute',
97
+ bottom: 70,
98
+ left: 8,
99
+ borderRadius: 1,
100
+ }}
101
+ />
102
+ </>
103
+ );
104
+ };
105
+
106
+ const DevModeStack = () => {
107
+ return (
108
+ <Drawer.Navigator
109
+ backBehavior="none"
110
+ drawerContent={(props) => <DrawerContainer {...props} />}
111
+ drawerStyle={{ paddingTop: getStatusBarHeight() }}
112
+ >
113
+ <Drawer.Screen name={Routes.DrawerMain} component={MainDevMode} />
114
+ </Drawer.Navigator>
115
+ );
116
+ };
117
+
118
+ export default DevModeStack;
119
+
120
+ const styles = StyleSheet.create({
121
+ btnMenu: {
122
+ width: 40,
123
+ height: 40,
124
+ justifyContent: 'center',
125
+ alignItems: 'center',
126
+ marginLeft: 10,
127
+ },
128
+ wrapHeader: {
129
+ height: 100,
130
+ paddingTop: getStatusBarHeight(),
131
+ flexDirection: 'row',
132
+ alignItems: 'center',
133
+ backgroundColor: Colors.Gray2,
134
+ },
135
+ textHeader: {
136
+ fontSize: 20,
137
+ fontWeight: 'bold',
138
+ color: Colors.Gray9,
139
+ },
140
+ menu: {
141
+ width: 24,
142
+ height: 24,
143
+ },
144
+ });
@@ -0,0 +1,23 @@
1
+ import React, { memo } from 'react';
2
+ import { createStackNavigator } from '@react-navigation/stack';
3
+
4
+ import Routes from '../utils/Route';
5
+ import { screenOptions } from './utils';
6
+ import Smart from '../screens/Smart';
7
+
8
+ const Stack = createStackNavigator();
9
+
10
+ const SmartStack = memo(() => {
11
+ return (
12
+ <Stack.Navigator
13
+ screenOptions={{
14
+ ...screenOptions,
15
+ headerShown: false,
16
+ }}
17
+ >
18
+ <Stack.Screen name={Routes.Smart} component={Smart} />
19
+ </Stack.Navigator>
20
+ );
21
+ });
22
+
23
+ export default SmartStack;
@@ -0,0 +1,23 @@
1
+ import React, { memo } from 'react';
2
+ import { createStackNavigator } from '@react-navigation/stack';
3
+
4
+ import Routes from '../utils/Route';
5
+ import { screenOptions } from './utils';
6
+ import Template from '../screens/Template';
7
+
8
+ const Stack = createStackNavigator();
9
+
10
+ const TemplateStack = memo(() => {
11
+ return (
12
+ <Stack.Navigator
13
+ screenOptions={{
14
+ ...screenOptions,
15
+ headerShown: false,
16
+ }}
17
+ >
18
+ <Stack.Screen name={Routes.Template} component={Template} />
19
+ </Stack.Navigator>
20
+ );
21
+ });
22
+
23
+ export default TemplateStack;
@@ -93,7 +93,11 @@ export const UnitStack = memo((props) => {
93
93
  if (!id) {
94
94
  return;
95
95
  }
96
- const { success, data } = await axiosGet(API.UNIT.FAVOURITE_DEVICES(id));
96
+ const { success, data } = await axiosGet(
97
+ API.UNIT.FAVOURITE_DEVICES(id),
98
+ {},
99
+ true
100
+ );
97
101
  success && setAction(Action.SET_FAVORITE_DEVICES, data);
98
102
  };
99
103
  fetchFavoriteDevices();
@@ -102,7 +106,11 @@ export const UnitStack = memo((props) => {
102
106
 
103
107
  useEffect(() => {
104
108
  const fetchStarredScripts = async () => {
105
- const { success, data } = await axiosGet(API.AUTOMATE.STARRED_SCRIPTS());
109
+ const { success, data } = await axiosGet(
110
+ API.AUTOMATE.STARRED_SCRIPTS(),
111
+ {},
112
+ true
113
+ );
106
114
  success && setAction(Action.SET_STARRED_SCRIPTS, data);
107
115
  };
108
116
  fetchStarredScripts();
@@ -226,12 +226,15 @@ const SelectAction = memo(({ route }) => {
226
226
  case 'one_button_action_template':
227
227
  case 'three_button_action_template':
228
228
  case 'OnOffSimpleActionTemplate':
229
+ case 'curtain_action_template':
229
230
  index = newActions.findIndex((item) => {
230
231
  return (
231
232
  item.template === 'on_off_button_action_template' ||
232
233
  item.template === 'one_button_action_template' ||
233
234
  item.template === 'three_button_action_template' ||
234
- item.template === 'OnOffSimpleActionTemplate'
235
+ item.template === 'OnOffSimpleActionTemplate' ||
236
+ item.template === 'curtain_action_template' ||
237
+ item.template === 'OnOffSmartLockActionTemplate'
235
238
  );
236
239
  });
237
240
  break;
@@ -423,6 +426,8 @@ const RenderActionItem = ({ data, onSelectAction }) => {
423
426
  case 'one_button_action_template':
424
427
  case 'three_button_action_template':
425
428
  case 'OnOffSimpleActionTemplate':
429
+ case 'curtain_action_template':
430
+ case 'OnOffSmartLockActionTemplate':
426
431
  actionTemplate.push(item);
427
432
  break;
428
433
  case 'OptionsDropdownActionTemplate':
@@ -4,7 +4,6 @@ import AllCamera from '..';
4
4
  import { act, create } from 'react-test-renderer';
5
5
  import { SCProvider } from '../../../context';
6
6
  import { mockSCStore } from '../../../context/mockStore';
7
- import { ModalFullVideo } from '../../../commons/Modal';
8
7
  import Carousel from 'react-native-snap-carousel';
9
8
 
10
9
  const arrCameras = [
@@ -90,13 +89,7 @@ describe('Test AllCamera screen', () => {
90
89
  });
91
90
  const instance = tree.root;
92
91
  const TouchableOpacities = instance.findAllByType(TouchableOpacity);
93
- expect(TouchableOpacities).toHaveLength(9);
94
- const ModalFullVideos = instance.findAllByType(ModalFullVideo);
95
- expect(ModalFullVideos).toHaveLength(1);
96
- act(() => {
97
- ModalFullVideos[0].props.onClose();
98
- });
99
- expect(mockSetState).toBeCalledWith(false);
92
+ expect(TouchableOpacities).toHaveLength(8);
100
93
  const Carousels = instance.findAllByType(Carousel);
101
94
  expect(Carousels).toHaveLength(1);
102
95
  });
@@ -17,7 +17,6 @@ import { HeaderCustom } from '../../commons/Header';
17
17
  import MediaPlayerDetail from '../../commons/MediaPlayerDetail';
18
18
  import { Constants, normalize } from '../../configs/Constants';
19
19
  import styles from './Styles/index';
20
- import { ModalFullVideo } from '../../commons/Modal';
21
20
  import Routes from '../../utils/Route';
22
21
 
23
22
  const AllCamera = () => {
@@ -32,12 +31,10 @@ const AllCamera = () => {
32
31
  const [activeCamera, setActiveCamera] = useState(data[0]);
33
32
  const [currentPage, setCurrentPage] = useState(1);
34
33
  const [isFullScreen, setIsFullScreen] = useState(false);
35
- const [dataFullScreen, setDataFullScreen] = useState();
36
34
 
37
35
  const handleFullScreen = useCallback(
38
36
  (dataFullscreen) => {
39
37
  setIsFullScreen(!isFullScreen);
40
- setDataFullScreen(dataFullscreen);
41
38
  },
42
39
  [isFullScreen]
43
40
  );
@@ -69,10 +66,6 @@ const AllCamera = () => {
69
66
  [data]
70
67
  );
71
68
 
72
- const onClose = () => {
73
- setIsFullScreen(false);
74
- };
75
-
76
69
  const goToPlayBack = useCallback(
77
70
  (item, itemThumbnail) => () => {
78
71
  navigate(Routes.PlaybackCamera, { item, thumbnail: itemThumbnail });
@@ -249,12 +242,6 @@ const AllCamera = () => {
249
242
  {renderAmount}
250
243
  </View>
251
244
  </View>
252
- <ModalFullVideo
253
- isVisible={isFullScreen}
254
- data={dataFullScreen}
255
- modalStyles={styles.modal}
256
- onClose={onClose}
257
- />
258
245
  </>
259
246
  );
260
247
  };
@@ -0,0 +1,37 @@
1
+ import { renderHook } from '@testing-library/react-hooks';
2
+ import MockAdapter from 'axios-mock-adapter';
3
+ import { API } from '../../../../configs';
4
+ import api from '../../../../utils/Apis/axios';
5
+ import { useEmergencyButton } from '../useEmergencyButton';
6
+
7
+ const mockFetchDataDeviceDetail = jest.fn();
8
+ const mockAcquireLockShowing = jest.fn();
9
+
10
+ const mock = new MockAdapter(api.axiosInstance);
11
+
12
+ describe('Test useEmergencyButton', () => {
13
+ it('Test render', async () => {
14
+ const { result } = renderHook(() =>
15
+ useEmergencyButton(mockFetchDataDeviceDetail, mockAcquireLockShowing)
16
+ );
17
+ jest.useFakeTimers();
18
+ await result.current.onCancelConfirmAlert();
19
+ expect(result.current.showAlertConfirm).toBe(false);
20
+ jest.runAllTimers();
21
+ await result.current.onEmergencyButtonPress();
22
+ mock.onPost(API.EMERGENCY_BUTTON.SEND_ALERT()).reply(200);
23
+ await result.current.onSendNowAlert();
24
+ expect(result.current.showAlertConfirm).toBe(true);
25
+ });
26
+
27
+ it('Test send alert fail', async () => {
28
+ mock.onPost(API.EMERGENCY_BUTTON.SEND_ALERT()).reply(400);
29
+ const { result } = renderHook(() =>
30
+ useEmergencyButton(mockFetchDataDeviceDetail, mockAcquireLockShowing)
31
+ );
32
+ await result.current.onSendNowAlert();
33
+ await result.current.onCloseAlertSent();
34
+ await result.current.onViewDetails();
35
+ expect(result.current.showAlertConfirm).toBe(false);
36
+ });
37
+ });
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { SafeAreaView } from 'react-native';
3
+ import renderer, { act } from 'react-test-renderer';
4
+ import { SCProvider } from '../../context';
5
+ import { mockSCStore } from '../../context/mockStore';
6
+ import Drawer from './index';
7
+
8
+ const wrapComponent = () => (
9
+ <SCProvider initState={mockSCStore({})}>
10
+ <Drawer navigation={jest.fn()} />
11
+ </SCProvider>
12
+ );
13
+
14
+ describe('Drawer', () => {
15
+ let tree;
16
+ test('drawer snapshot', async () => {
17
+ await act(async () => {
18
+ tree = await renderer.create(wrapComponent());
19
+ });
20
+ const instance = tree.root;
21
+ const safeView = instance.findAllByType(SafeAreaView);
22
+ expect(safeView).toHaveLength(1);
23
+ });
24
+ });
@@ -0,0 +1,198 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ Image,
5
+ TouchableOpacity,
6
+ ScrollView,
7
+ SafeAreaView,
8
+ StyleSheet,
9
+ } from 'react-native';
10
+ import { IconOutline } from '@ant-design/icons-react-native';
11
+ import { Icon } from '@ant-design/react-native';
12
+ import t from '../../hooks/Common/useTranslations';
13
+
14
+ import { Images, Colors } from '../../configs';
15
+ import Text from '../../commons/Text';
16
+ import Routes from '../../utils/Route';
17
+ import { TESTID } from '../../configs/Constants';
18
+ import { useSCContextSelector } from '../../context';
19
+ import { CommonActions, useNavigation } from '@react-navigation/native';
20
+
21
+ const DrawerContainer = ({ navigation }) => {
22
+ const user = useSCContextSelector((state) => state.auth.account.user);
23
+ const { dispatch } = useNavigation();
24
+ const doLogout = () => {
25
+ const resetAction = CommonActions.reset({
26
+ index: 0,
27
+ routes: [{ name: Routes.Main }],
28
+ });
29
+ dispatch(resetAction);
30
+ };
31
+
32
+ const goToHelp = () => {};
33
+
34
+ const goToAbloutUs = () => {};
35
+
36
+ return (
37
+ <SafeAreaView style={styles.wrap}>
38
+ <ScrollView contentContainerStyle={styles.scrollView}>
39
+ <View style={[styles.row, styles.logoWrap]}>
40
+ <Image
41
+ source={Images.logo}
42
+ style={styles.logo}
43
+ testID={TESTID.SIDE_MENU_LOGO}
44
+ />
45
+
46
+ <View style={styles.avatarBackground}>
47
+ {user.avatar ? (
48
+ <Image
49
+ source={{ uri: user.avatar }}
50
+ style={styles.avatar}
51
+ testID={TESTID.SIDE_MENU_AVATAR_USER}
52
+ />
53
+ ) : (
54
+ <View style={styles.avatar} testID={TESTID.SIDE_MENU_AVATAR_USER}>
55
+ <Icon name={'user'} size={27} />
56
+ </View>
57
+ )}
58
+ <View style={styles.textContainer}>
59
+ <Text
60
+ style={[styles.fullName]}
61
+ testID={TESTID.SIDE_MENU_USER_NAME}
62
+ >
63
+ {user?.name || ''}
64
+ </Text>
65
+ <Text style={[styles.email]} testID={TESTID.SIDE_MENU_USER_PHONE}>
66
+ {user ? user.phone_number : ''}
67
+ </Text>
68
+ </View>
69
+ </View>
70
+ </View>
71
+ <View style={styles.containerRow}>
72
+ <View>
73
+ <Row onPress={goToHelp} image={'global'} name={t('help')} />
74
+ <Row
75
+ onPress={goToAbloutUs}
76
+ image={'mail'}
77
+ name={t('about_us')}
78
+ testID={TESTID.SIDE_MENU_POLICY_ITEM}
79
+ />
80
+ <Row
81
+ onPress={doLogout}
82
+ image={'export'}
83
+ name={t('exit_dev_mode')}
84
+ />
85
+ </View>
86
+ </View>
87
+ </ScrollView>
88
+ </SafeAreaView>
89
+ );
90
+ };
91
+
92
+ export const Row = ({ name, onPress, image, borderBottom, testID }) => {
93
+ return (
94
+ <TouchableOpacity
95
+ onPress={onPress}
96
+ style={[
97
+ styles.row,
98
+ styles.optionWrap,
99
+ borderBottom && styles.borderBottom,
100
+ ]}
101
+ testID={testID}
102
+ >
103
+ <IconOutline name={image} size={24} />
104
+
105
+ <View style={styles.wrapText}>
106
+ <Text style={[styles.text]}>{name}</Text>
107
+ </View>
108
+ </TouchableOpacity>
109
+ );
110
+ };
111
+
112
+ const styles = StyleSheet.create({
113
+ wrapText: {
114
+ flexDirection: 'row',
115
+ marginLeft: 20,
116
+ },
117
+ text: {
118
+ fontSize: 16,
119
+ color: Colors.Gray9,
120
+ },
121
+ wrap: {
122
+ flex: 1,
123
+ flexDirection: 'column',
124
+ backgroundColor: Colors.White,
125
+ },
126
+ scrollView: {
127
+ flex: 1,
128
+ justifyContent: 'space-between',
129
+ },
130
+ row: {
131
+ flexDirection: 'row',
132
+ alignItems: 'center',
133
+ justifyContent: 'flex-start',
134
+ },
135
+ borderBottom: {
136
+ borderBottomColor: Colors.Gray4,
137
+ borderBottomWidth: 1,
138
+ },
139
+ logoWrap: {
140
+ paddingTop: 32,
141
+ paddingLeft: 28,
142
+ paddingRight: 23,
143
+ },
144
+ optionWrap: {
145
+ paddingTop: 20,
146
+ paddingBottom: 20,
147
+ paddingRight: 32,
148
+ },
149
+ logo: {
150
+ width: 32,
151
+ height: 16,
152
+ position: 'absolute',
153
+ top: 10,
154
+ left: 30,
155
+ },
156
+
157
+ // header
158
+ avatarBackground: {
159
+ flexDirection: 'row',
160
+ flex: 1,
161
+ paddingVertical: 22,
162
+ borderBottomColor: Colors.Gray4,
163
+ borderBottomWidth: 1,
164
+ },
165
+ avatar: {
166
+ height: 50,
167
+ width: 50,
168
+ borderRadius: 25,
169
+ borderWidth: 0.5,
170
+ borderColor: Colors.Gray5,
171
+ justifyContent: 'center',
172
+ alignItems: 'center',
173
+ },
174
+ textContainer: {
175
+ marginLeft: 15,
176
+ justifyContent: 'flex-start',
177
+ flex: 1,
178
+ },
179
+ fullName: {
180
+ backgroundColor: Colors.TextTransparent,
181
+ fontSize: 16,
182
+ marginBottom: 6,
183
+ color: Colors.Black,
184
+ fontWeight: 'bold',
185
+ },
186
+ email: {
187
+ backgroundColor: Colors.TextTransparent,
188
+ fontSize: 14,
189
+ color: Colors.Gray8,
190
+ },
191
+ containerRow: {
192
+ paddingHorizontal: 28,
193
+ flex: 1,
194
+ justifyContent: 'space-between',
195
+ },
196
+ });
197
+
198
+ export default DrawerContainer;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+ import { act, create } from 'react-test-renderer';
4
+ import Gateway from '..';
5
+
6
+ describe('Test Template screen', () => {
7
+ let tree;
8
+ it('Test render', async () => {
9
+ await act(async () => {
10
+ tree = await create(<Gateway />);
11
+ });
12
+ const instance = tree.root;
13
+ const Views = instance.findAllByType(View);
14
+ expect(Views).toHaveLength(1);
15
+ });
16
+ });
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+
4
+ const Gateway = () => {
5
+ return <View />;
6
+ };
7
+
8
+ export default Gateway;