ordering-ui-react-native 0.12.92 → 0.12.96

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.12.92",
3
+ "version": "0.12.96",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -418,6 +418,7 @@ const LoginFormUI = (props: LoginParams) => {
418
418
  open={isModalVisible}
419
419
  onClose={() => setIsModalVisible(false)}
420
420
  entireModal
421
+ title={t('VERIFY_PHONE', 'Verify Phone')}
421
422
  >
422
423
  <VerifyPhone
423
424
  phone={phoneInputData.phone}
@@ -426,6 +427,7 @@ const LoginFormUI = (props: LoginParams) => {
426
427
  handleCheckPhoneCode={handleCheckPhoneCode}
427
428
  setCheckPhoneCodeState={setCheckPhoneCodeState}
428
429
  handleVerifyCodeClick={handleVerifyCodeClick}
430
+ onClose={() => setIsModalVisible(false)}
429
431
  />
430
432
  </OModal>
431
433
  <Spinner visible={isLoadingSocialButton} />
@@ -440,4 +442,4 @@ export const LoginForm = (props: any) => {
440
442
  handleSuccessLogin: () => _removeStoreData('isGuestUser')
441
443
  };
442
444
  return <LoginFormController {...loginProps} />;
443
- };
445
+ };
@@ -1,5 +1,12 @@
1
- import React, { useEffect, useState } from 'react';
2
- import { Pressable, StyleSheet, TextInput } from 'react-native';
1
+ import React, { useEffect, useState, useRef } from 'react';
2
+ import {
3
+ SafeAreaView,
4
+ StyleSheet,
5
+ Text,
6
+ View,
7
+ TextInput,
8
+ Pressable,
9
+ } from 'react-native';
3
10
  import { useLanguage } from 'ordering-components/native';
4
11
  import Spinner from 'react-native-loading-spinner-overlay';
5
12
  import { getTraduction } from '../../utils'
@@ -17,6 +24,7 @@ import {
17
24
  import { useTheme } from 'styled-components/native';
18
25
 
19
26
  const TIME_COUNTDOWN = 60 * 10 // 10 minutes
27
+ const CODE_LENGTH = 4;
20
28
 
21
29
  export const VerifyPhone = (props: any) => {
22
30
  const {
@@ -26,36 +34,91 @@ export const VerifyPhone = (props: any) => {
26
34
  checkPhoneCodeState,
27
35
  setCheckPhoneCodeState,
28
36
  handleCheckPhoneCode,
29
- handleVerifyCodeClick
37
+ handleVerifyCodeClick,
38
+ onClose
30
39
  } = props
31
40
 
32
41
  const theme = useTheme();
33
-
34
- const styles = StyleSheet.create({
35
- inputStyle: {
36
- width: 80,
37
- height: 80,
38
- marginBottom: 25,
39
- borderWidth: 1,
40
- borderColor: theme.colors.disabled,
42
+ const [, t] = useLanguage()
43
+ const ref = useRef<TextInput>(null);
44
+
45
+ const style = StyleSheet.create({
46
+ container: {
47
+ flex: 1,
48
+ alignItems: 'center',
49
+ justifyContent: 'center',
50
+ },
51
+ inputsContainer: {
52
+ width: '80%',
53
+ flexDirection: 'row',
54
+ justifyContent: 'space-between',
55
+ },
56
+ inputContainer: {
57
+ borderWidth: 2,
41
58
  borderRadius: 20,
42
- textAlign: 'center',
43
- fontSize: 40
44
- }
59
+ padding: 20,
60
+ borderColor: theme.colors.disabled,
61
+ },
62
+ inputContainerFocused: {
63
+ borderColor: theme.colors.primary,
64
+ },
65
+ inputText: {
66
+ fontSize: 24,
67
+ },
68
+ hiddenCodeInput: {
69
+ position: 'absolute',
70
+ height: 0,
71
+ width: 0,
72
+ opacity: 0,
73
+ },
45
74
  });
46
75
 
47
- const [, t] = useLanguage()
48
-
49
76
  const [timer, setTimer] = useState(`${TIME_COUNTDOWN / 60}:00`)
50
- const [verifyCode, setVerifyCode] = useState({ 0: '', 1: '', 2: '', 3: '' })
51
77
  const [isSendCodeAgain, setIsSendCodeAgain] = useState(false)
52
-
53
- const lastNumbers = phone?.cellphone &&
54
- `${phone?.cellphone.charAt(phone?.cellphone.length-2)}${phone?.cellphone.charAt(phone?.cellphone.length-1)}`
55
-
56
- const handleChangeCode = (val: number, i: number) => {
57
- setVerifyCode({ ...verifyCode, [i]: val })
58
- }
78
+ const [code, setCode] = useState('');
79
+ const [containerIsFocused, setContainerIsFocused] = useState(false);
80
+
81
+ const codeDigitsArray = new Array(CODE_LENGTH).fill(0);
82
+ const phoneLength = phone?.cellphone.split('').length
83
+ const lastNumbers = phone?.cellphone && phone?.cellphone.split('').fill('*', 0, phoneLength - 2).join('')
84
+
85
+ const handleOnPress = () => {
86
+ setContainerIsFocused(true);
87
+ ref?.current?.focus();
88
+ };
89
+
90
+ const handleOnBlur = () => {
91
+ setContainerIsFocused(false);
92
+ };
93
+
94
+ const toDigitInput = (_value: number, idx: number) => {
95
+ const emptyInputChar = '0';
96
+ const digit = code[idx] || emptyInputChar;
97
+
98
+ const isCurrentDigit = idx === code.length;
99
+ const isLastDigit = idx === CODE_LENGTH - 1;
100
+ const isCodeFull = code.length === CODE_LENGTH;
101
+
102
+ const isFocused = isCurrentDigit || (isLastDigit && isCodeFull);
103
+
104
+ const containerStyle =
105
+ containerIsFocused && isFocused
106
+ ? {...style.inputContainer, ...style.inputContainerFocused}
107
+ : style.inputContainer;
108
+
109
+ return (
110
+ <View key={idx} style={containerStyle}>
111
+ <Text
112
+ style={{
113
+ ...style.inputText,
114
+ color: code[idx] ? theme.colors.black : theme.colors.disabled
115
+ }}
116
+ >
117
+ {digit}
118
+ </Text>
119
+ </View>
120
+ );
121
+ };
59
122
 
60
123
  const checkResult = (result: any) => {
61
124
  if (!result) return
@@ -106,27 +169,28 @@ export const VerifyPhone = (props: any) => {
106
169
  }, [isSendCodeAgain])
107
170
 
108
171
  useEffect(() => {
109
- const codes = Object.keys(verifyCode).length
110
- const isFullInputs = codes && Object.values(verifyCode).every(val => val)
111
- if (codes === 4 && isFullInputs) {
172
+ if (code.length === CODE_LENGTH) {
112
173
  const values = {
113
174
  ...formValues,
114
175
  cellphone: phone.cellphone,
115
176
  country_phone_code: `+${phone.country_phone_code}`,
116
- code: Object.values(verifyCode).join().replace(/,/g, '')
177
+ code
117
178
  }
118
179
  handleCheckPhoneCode && handleCheckPhoneCode(values)
119
180
  }
120
- }, [verifyCode])
181
+ }, [code]);
182
+
183
+ useEffect(() => {
184
+ if (verifyPhoneState?.result?.error) {
185
+ onClose && onClose()
186
+ }
187
+ }, [verifyPhoneState]);
121
188
 
122
189
  return (
123
190
  <Container>
124
- <OText size={30} style={{ textAlign: 'left' }}>
125
- {t('VERIFY_PHONE', 'Verify Phone')}
126
- </OText>
127
191
  {lastNumbers && (
128
- <OText size={20} color={theme.colors.disabled}>
129
- {`${t('MESSAGE_ENTER_VERIFY_CODE', 'Please, enter the verification code we sent to your mobile ending with')} **${lastNumbers}`}
192
+ <OText size={18} color={theme.colors.disabled}>
193
+ {`${t('MESSAGE_ENTER_VERIFY_CODE', 'Please, enter the verification code we sent to your mobile ending with')} ${lastNumbers}`}
130
194
  </OText>
131
195
  )}
132
196
  <WrappCountdown>
@@ -140,30 +204,34 @@ export const VerifyPhone = (props: any) => {
140
204
  </CountDownContainer>
141
205
  </WrappCountdown>
142
206
  <InputsSection>
143
- {[...Array(4),].map((_: any, i: number) => (
207
+ <SafeAreaView style={style.container}>
208
+ <Pressable style={style.inputsContainer} onPress={handleOnPress} disabled={code.length === CODE_LENGTH}>
209
+ {codeDigitsArray.map(toDigitInput)}
210
+ </Pressable>
144
211
  <TextInput
145
- key={i}
146
- keyboardType='number-pad'
147
- placeholder={'0'}
148
- style={styles.inputStyle}
149
- onChangeText={(val: any) => handleChangeCode(val, i)}
150
- maxLength={1}
151
- editable={timer !== '00:00'}
212
+ ref={ref}
213
+ value={code}
214
+ placeholder='0'
215
+ onChangeText={setCode}
216
+ onSubmitEditing={handleOnBlur}
217
+ keyboardType="number-pad"
218
+ returnKeyType="done"
219
+ textContentType="oneTimeCode"
220
+ maxLength={CODE_LENGTH}
221
+ style={style.hiddenCodeInput}
152
222
  />
153
- ))}
223
+ </SafeAreaView>
154
224
  </InputsSection>
155
- {(verifyPhoneState?.result?.error ? verifyPhoneState : checkPhoneCodeState) &&
156
- !(verifyPhoneState?.result?.error ? verifyPhoneState : checkPhoneCodeState)?.loading &&
157
- (verifyPhoneState?.result?.error ? verifyPhoneState : checkPhoneCodeState)?.result?.error &&
158
- (verifyPhoneState?.result?.error ? verifyPhoneState : checkPhoneCodeState).result?.result &&
225
+ {checkPhoneCodeState &&
226
+ !checkPhoneCodeState?.loading &&
227
+ checkPhoneCodeState?.result?.error &&
228
+ checkPhoneCodeState?.result?.result &&
159
229
  (
160
230
  <ErrorSection>
161
- {checkResult((
162
- verifyPhoneState?.result?.error ? verifyPhoneState : checkPhoneCodeState
163
- ).result?.result)?.map((e: any, i: number) => (
231
+ {checkResult((checkPhoneCodeState).result?.result)?.map((e: any, i: number) => (
164
232
  <OText
165
233
  key={i}
166
- size={20}
234
+ size={16}
167
235
  color={theme.colors.error}
168
236
  >
169
237
  {`* ${getTraduction(e, t)}`}
@@ -2,9 +2,7 @@ import styled from 'styled-components/native';
2
2
 
3
3
  export const Container = styled.View`
4
4
  width: 100%;
5
- padding-top: 5px;
6
- padding-left: 20px;
7
- padding-right: 20px;
5
+ padding: 0 30px;
8
6
  `
9
7
 
10
8
  export const CountDownContainer = styled.View`
@@ -14,24 +12,26 @@ export const CountDownContainer = styled.View`
14
12
  margin: 0 auto;
15
13
  display: flex;
16
14
  justify-content: center;
15
+ align-items: center;
16
+ width: 80%;
17
17
  `
18
18
 
19
19
  export const ResendSection = styled.View`
20
20
  display: flex;
21
21
  flex-direction: row;
22
22
  justify-content: center;
23
- margin-bottom: 30px;
24
23
  `
25
24
 
26
25
  export const WrappCountdown = styled.View`
27
- padding-top: 20px;
28
26
  padding-bottom: 20px;
27
+ padding-top: 20px;
29
28
  `
30
29
 
31
30
  export const InputsSection = styled.View`
32
31
  display: flex;
33
32
  flex-direction: row;
34
33
  justify-content: space-between;
34
+ padding-bottom: 20px;
35
35
  `
36
36
 
37
37
  export const ErrorSection = styled.View`
@@ -6,7 +6,7 @@ import { useTheme } from 'styled-components/native';
6
6
  import { NotFound, NotFoundImage } from './styles';
7
7
 
8
8
  export const NotFoundSource = (props: NotFoundSourceParams) => {
9
- const { image, content, btnTitle, conditioned, onClickButton } = props;
9
+ const { image, content, btnTitle, conditioned, onClickButton, textSize } = props;
10
10
  const theme = useTheme();
11
11
 
12
12
  const errorImage = image || theme.images.general.notFound;
@@ -21,7 +21,7 @@ export const NotFoundSource = (props: NotFoundSourceParams) => {
21
21
  {content && conditioned && !errorImage && (
22
22
  <OText
23
23
  color={theme.colors.textSecondary}
24
- size={18}
24
+ size={textSize ?? 18}
25
25
  style={{ textAlign: 'center' }}>
26
26
  {content}
27
27
  </OText>
@@ -29,7 +29,7 @@ export const NotFoundSource = (props: NotFoundSourceParams) => {
29
29
  {content && !conditioned && (
30
30
  <OText
31
31
  color={theme.colors.textSecondary}
32
- size={18}
32
+ size={textSize ?? 18}
33
33
  style={{ textAlign: 'center' }}>
34
34
  {content}
35
35
  </OText>
@@ -16,7 +16,8 @@ import {
16
16
  IconWrapper,
17
17
  ModalContainer,
18
18
  ModalTitle,
19
- FilterBtnWrapper
19
+ FilterBtnWrapper,
20
+ TabPressable
20
21
  } from './styles';
21
22
  import { PreviousOrders } from '../PreviousOrders';
22
23
  import { OrdersOptionParams } from '../../types';
@@ -324,7 +325,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
324
325
  horizontal
325
326
  nestedScrollEnabled={true}
326
327
  >
327
- <TabsContainer width={WIDTH_SCREEN}>
328
+ <TabsContainer>
328
329
  {isLogisticActivated && (
329
330
  <Pressable
330
331
  style={styles.pressable}
@@ -344,15 +345,16 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
344
345
  </Pressable>
345
346
  )}
346
347
  {tabs.map((tab: any) => (
347
- <Pressable
348
+ <TabPressable
348
349
  key={tab.key}
349
- style={styles.pressable}
350
- onPress={() => setCurrentTabSelected(tab?.title)}>
350
+ onPress={() => setCurrentTabSelected(tab?.title)}
351
+ isSelected={tab.title === currentTabSelected ? 1 : 0}
352
+ >
351
353
  <OText
352
354
  style={{
353
355
  ...styles.tab,
354
356
  fontSize: tab.title === currentTabSelected ? 16 : 14,
355
- borderBottomWidth: tab.title === currentTabSelected ? 1 : 0,
357
+ borderBottomWidth: Platform.OS === 'ios' && tab.title === currentTabSelected ? 1 : 0,
356
358
  }}
357
359
  color={
358
360
  tab.title === currentTabSelected
@@ -363,7 +365,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
363
365
  >
364
366
  {tab.text}
365
367
  </OText>
366
- </Pressable>
368
+ </TabPressable>
367
369
  ))}
368
370
  </TabsContainer>
369
371
  </ScrollView>
@@ -3,14 +3,15 @@ import styled from 'styled-components/native';
3
3
  export const FiltersTab = styled.View`
4
4
  margin-bottom: 20px;
5
5
  max-height: 35px;
6
+ flex: 1;
6
7
  `;
7
8
 
8
9
  export const TabsContainer = styled.View`
9
- width: ${({ width }: { width: number }) => `${width-42}px`};
10
10
  display: flex;
11
11
  flex-direction: row;
12
12
  justify-content: space-between;
13
13
  border-bottom-width: 1px;
14
+ flex: 1;
14
15
  border-bottom-color: ${(props: any) => props.theme.colors.tabBar};
15
16
  `;
16
17
 
@@ -53,3 +54,10 @@ export const FilterBtnWrapper = styled.TouchableOpacity`
53
54
  justify-content: space-between;
54
55
  margin-bottom: 24px;
55
56
  `
57
+
58
+ export const TabPressable = styled.Pressable`
59
+ align-items: center;
60
+ border-color: ${(props: any) => props.theme.colors.textGray};
61
+ border-bottom-width: ${(props: any) => props.isSelected ? '1px' : '0px'};
62
+ padding-horizontal: 10px;
63
+ `
@@ -232,6 +232,7 @@ export interface NotFoundSourceParams {
232
232
  conditioned?: boolean;
233
233
  onClickButton?: any;
234
234
  children?: any;
235
+ textSize?: number;
235
236
  }
236
237
  export interface MessagesOptionParams {
237
238
  orders?: any;
@@ -1,41 +1,49 @@
1
- import React, { useState } from 'react'
1
+ import React from 'react'
2
2
  import { useLanguage, BusinessMenuListing } from 'ordering-components/native'
3
- import { OModal, OText } from '../shared'
3
+ import { OText } from '../shared'
4
4
  import { BusinessMenuListParams } from '../../types'
5
- import { View, StyleSheet, TouchableOpacity, Text } from 'react-native'
5
+ import { View, StyleSheet, Dimensions } from 'react-native'
6
6
  import { useTheme } from 'styled-components/native'
7
7
  import IconAntDesign from 'react-native-vector-icons/AntDesign'
8
- import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
9
8
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'
10
- import { MenuListWrapper, DropOption } from './styles'
9
+ import SelectDropdown from 'react-native-select-dropdown'
10
+
11
+ const windowHeight = Dimensions.get('window').height;
11
12
 
12
13
  const BusinessMenuListUI = (props: BusinessMenuListParams) => {
13
14
  const {
14
- menu,
15
15
  businessMenuList,
16
16
  setMenu
17
17
  } = props
18
18
 
19
19
  const [, t] = useLanguage()
20
20
  const theme = useTheme()
21
- const [isShowMenuList, setIsShowMenuList] = useState(false)
22
21
 
23
22
  const styles = StyleSheet.create({
23
+ container: {
24
+ height: windowHeight
25
+ },
24
26
  selectOption: {
25
27
  backgroundColor: theme.colors.backgroundGray100,
26
28
  borderRadius: 7.6,
27
29
  paddingVertical: 10,
28
30
  paddingHorizontal: 14,
29
- flexDirection: 'row',
31
+ flexDirection: 'row-reverse',
30
32
  alignItems: 'center',
31
33
  justifyContent: 'space-between',
32
- height: 44
34
+ height: 44,
35
+ width: '100%'
33
36
  }
34
37
  })
35
38
 
36
- const handleClickMenu = (option: any) => {
37
- setMenu(option)
38
- setIsShowMenuList(false)
39
+ const dropDownIcon = () => {
40
+ return (
41
+ <IconAntDesign
42
+ name='down'
43
+ color={theme.colors.textThird}
44
+ size={16}
45
+ />
46
+ )
39
47
  }
40
48
 
41
49
  return (
@@ -47,82 +55,62 @@ const BusinessMenuListUI = (props: BusinessMenuListParams) => {
47
55
  </View>
48
56
  </Placeholder>
49
57
  ) : (
50
- <TouchableOpacity onPress={() => setIsShowMenuList(true)}>
51
- <View style={styles.selectOption}>
52
- <OText
53
- size={14}
54
- color={theme.colors.disabled}
55
- style={{
56
- lineHeight: 24,
57
- flex: 1
58
- }}
59
- numberOfLines={1}
60
- ellipsizeMode="tail"
61
- >
62
- {menu?.name || t('MENU_NAME', 'Menu name')}
63
- </OText>
64
- <IconAntDesign
65
- name='down'
66
- color={theme.colors.textThird}
67
- size={16}
68
- />
69
- </View>
70
- </TouchableOpacity>
71
- )}
58
+ <>
59
+ {
60
+ businessMenuList?.menus && businessMenuList?.menus.length > 0 && (
61
+ <SelectDropdown
62
+ defaultButtonText={t('MENU_NAME', 'Menu name')}
63
+ data={businessMenuList?.menus}
64
+ disabled={businessMenuList?.loading || businessMenuList?.menus?.length === 0}
65
+ onSelect={(selectedItem, index) => {
66
+ setMenu(selectedItem)
67
+ }}
68
+ buttonTextAfterSelection={(selectedItem, index) => {
69
+ return selectedItem.name
70
+ }}
71
+ rowTextForSelection={(item, index) => {
72
+ return item.name
73
+ }}
74
+ buttonStyle={styles.selectOption}
75
+ buttonTextStyle={{
76
+ color: theme.colors.disabled,
77
+ fontSize: 14,
78
+ textAlign: 'left',
79
+ marginHorizontal: 0
80
+ }}
81
+ dropdownStyle={{
82
+ borderRadius: 8,
83
+ borderColor: theme.colors.lightGray,
84
+ marginTop: 5,
85
+ maxHeight: 160
86
+ }}
87
+ rowStyle={{
88
+ borderBottomColor: theme.colors.backgroundGray100,
89
+ backgroundColor: theme.colors.backgroundGray100,
90
+ height: 40,
91
+ flexDirection: 'column',
92
+ alignItems: 'flex-start',
93
+ paddingTop: 8,
94
+ paddingHorizontal: 14
95
+ }}
96
+ rowTextStyle={{
97
+ color: theme.colors.disabled,
98
+ fontSize: 14,
99
+ marginHorizontal: 0
100
+ }}
101
+ renderDropdownIcon={() => dropDownIcon()}
102
+ dropdownOverlayColor='transparent'
103
+ />
104
+ )
105
+ }
72
106
 
73
- <OModal
74
- open={isShowMenuList}
75
- onClose={() => setIsShowMenuList(false)}
76
- customClose
77
- entireModal
78
- >
79
- <MenuListWrapper>
80
- <TouchableOpacity onPress={() => setIsShowMenuList(false)} style={{ marginBottom: 12 }}>
81
- <IconAntDesign
82
- name='close'
83
- color={theme.colors.textThird}
84
- style={{ marginLeft: 7 }}
85
- size={24}
86
- />
87
- </TouchableOpacity>
88
- {businessMenuList?.menus && businessMenuList?.menus.length > 0 && businessMenuList.menus.map((option: any, index: number) => (
89
- <TouchableOpacity
90
- key={index}
91
- onPress={() => handleClickMenu(option)}
92
- >
93
- <DropOption
94
- selected={option.id === menu.id}
95
- >
96
- <View style={{ marginRight: 10 }}>
97
- {option.id === menu.id ? (
98
- <MaterialCommunityIcons
99
- name='radiobox-marked'
100
- size={24}
101
- color={theme.colors.primary}
102
- />
103
- ) : (
104
- <MaterialCommunityIcons
105
- name='radiobox-blank'
106
- size={24}
107
- color={theme.colors.arrowColor}
108
- />
109
- )}
110
- </View>
111
- <Text
112
- numberOfLines={1}
113
- ellipsizeMode="tail"
114
- style={{flex: 1}}
115
- >{option.name}</Text>
116
- </DropOption>
117
- </TouchableOpacity>
118
- ))}
119
107
  {businessMenuList?.menus && businessMenuList?.menus.length === 0 && (
120
108
  <View>
121
109
  <OText>{t('NO_RESULTS_FOUND', 'Sorry, no results found')}</OText>
122
110
  </View>
123
111
  )}
124
- </MenuListWrapper>
125
- </OModal>
112
+ </>
113
+ )}
126
114
  </>
127
115
 
128
116
  )
@@ -1,15 +0,0 @@
1
- import styled from 'styled-components/native'
2
-
3
- export const MenuListWrapper = styled.ScrollView`
4
- padding: 20px 40px 30px 40px;
5
- `
6
-
7
- export const DropOption = styled.View`
8
- padding: 10px;
9
- margin-bottom: 5px;
10
- font-size: 16px;
11
- border-bottom-width: 1px;
12
- border-bottom-color: ${(props: any) => props.theme.colors.lightGray};
13
- flex-direction: row;
14
- align-items: center;
15
- `
@@ -1,16 +1,16 @@
1
1
  import React, { useState, useEffect } from 'react'
2
- import { TouchableOpacity, StyleSheet, View, Text } from 'react-native'
2
+ import { TouchableOpacity, StyleSheet, View, Dimensions } from 'react-native'
3
3
  import { useLanguage, useUtils, useConfig, useOrder, MomentOption } from 'ordering-components/native'
4
- import { OButton, OModal, OText } from '../shared'
4
+ import { OButton, OText } from '../shared'
5
5
  import { useTheme } from 'styled-components/native'
6
6
  import IconAntDesign from 'react-native-vector-icons/AntDesign'
7
7
  import FastImage from 'react-native-fast-image'
8
8
  import CalendarStrip from 'react-native-calendar-strip'
9
- import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
10
9
  import { BusinessMenuList } from '../BusinessMenuList'
11
10
  import Spinner from 'react-native-loading-spinner-overlay'
12
11
  import { BusinessPreorderParams } from '../../types'
13
12
  import moment from 'moment'
13
+ import SelectDropdown from 'react-native-select-dropdown'
14
14
  import {
15
15
  PreOrderContainer,
16
16
  BusinessInfoWrapper,
@@ -19,11 +19,11 @@ import {
19
19
  OrderTimeWrapper,
20
20
  TimeListWrapper,
21
21
  TimeContentWrapper,
22
- TimeItem,
23
- PreorderTypeListWrapper,
24
- DropOption
22
+ TimeItem
25
23
  } from './styles'
26
24
 
25
+ const windowHeight = Dimensions.get('window').height;
26
+
27
27
  const BusinessPreorderUI = (props: BusinessPreorderParams) => {
28
28
  const {
29
29
  goToBack,
@@ -42,14 +42,18 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
42
42
  const [{ optimizeImage, parseTime }] = useUtils()
43
43
  const [{ configs }] = useConfig()
44
44
  const [orderState] = useOrder()
45
- const [selectedPreorderType, setSelectedPreorderType] = useState({ key: 'business_hours', name: t('BUSINESS_HOURS', 'Business hours') })
46
- const [isPreorderTypeList, setIsPreorderTypeList] = useState(false)
45
+ const [selectedPreorderType, setSelectedPreorderType] = useState(0)
47
46
  const [menu, setMenu] = useState({})
48
47
  const [timeList, setTimeList] = useState<any>([])
49
48
  const [selectDate, setSelectedDate] = useState<any>(null)
50
49
  const [datesWhitelist, setDateWhitelist] = useState<any>([{start: null, end: null}])
51
50
 
52
51
  const styles = StyleSheet.create({
52
+ container: {
53
+ height: windowHeight,
54
+ paddingVertical: 30,
55
+ paddingHorizontal: 40
56
+ },
53
57
  businessLogo: {
54
58
  backgroundColor: 'white',
55
59
  width: 60,
@@ -68,10 +72,11 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
68
72
  borderRadius: 7.6,
69
73
  paddingVertical: 10,
70
74
  paddingHorizontal: 14,
71
- flexDirection: 'row',
75
+ flexDirection: 'row-reverse',
72
76
  alignItems: 'center',
73
77
  justifyContent: 'space-between',
74
- height: 44
78
+ height: 44,
79
+ width: '100%'
75
80
  },
76
81
  calendar: {
77
82
  paddingBottom: 15,
@@ -123,30 +128,14 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
123
128
  color: '#B1BCCC',
124
129
  fontSize: 14,
125
130
  fontWeight: '500'
126
- },
127
- wrapperIcon: {
128
- overflow: 'hidden',
129
- backgroundColor: 'transparent',
130
- marginBottom: 12,
131
- width: 25,
132
- height: 25,
133
- marginStart: 7,
134
- alignItems: 'center',
135
- justifyContent: 'center',
136
- zIndex: 99999
137
131
  }
138
132
  })
139
133
 
140
134
  const preorderTypeList = [
141
- { key: 'business_menu', name: t('BUSINESS_MENU', 'Business menu') },
142
- { key: 'business_hours', name: t('BUSINESS_HOURS', 'Business hours') }
135
+ { key: 'business_hours', name: t('BUSINESS_HOURS', 'Business hours') },
136
+ { key: 'business_menu', name: t('BUSINESS_MENU', 'Business menu') }
143
137
  ]
144
138
 
145
- const handleClickPreorderType = (option: any) => {
146
- setSelectedPreorderType(option)
147
- setIsPreorderTypeList(false)
148
- }
149
-
150
139
  const getTimes = (curdate: any, menu: any) => {
151
140
  const date = new Date()
152
141
  var dateSeleted = new Date(curdate)
@@ -239,6 +228,16 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
239
228
  handleBusinessClick && handleBusinessClick(business)
240
229
  }
241
230
 
231
+ const dropDownIcon = () => {
232
+ return (
233
+ <IconAntDesign
234
+ name='down'
235
+ color={theme.colors.textThird}
236
+ size={16}
237
+ />
238
+ )
239
+ }
240
+
242
241
  useEffect(() => {
243
242
  if (hoursList.length === 0) return
244
243
  if (Object.keys(menu).length > 0) {
@@ -262,7 +261,7 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
262
261
  }, [selectDate, hoursList, menu])
263
262
 
264
263
  useEffect(() => {
265
- if (selectedPreorderType.key === 'business_hours' && Object.keys(menu).length > 0) setMenu({})
264
+ if (selectedPreorderType === 0 && Object.keys(menu).length > 0) setMenu({})
266
265
  }, [selectedPreorderType])
267
266
 
268
267
  useEffect(() => {
@@ -275,7 +274,7 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
275
274
 
276
275
  return (
277
276
  <>
278
- <PreOrderContainer contentContainerStyle={{ paddingVertical: 30, paddingHorizontal: 40 }}>
277
+ <PreOrderContainer contentContainerStyle={{ paddingVertical: 32, paddingHorizontal: 40 }}>
279
278
  <TouchableOpacity onPress={() => goToBack && goToBack()} style={{ marginBottom: 12 }}>
280
279
  <IconAntDesign
281
280
  name='close'
@@ -313,26 +312,50 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
313
312
  >
314
313
  {t('PREORDER_TYPE', 'Preorder type')}
315
314
  </OText>
316
- <TouchableOpacity onPress={() => setIsPreorderTypeList(true)}>
317
- <View style={styles.selectOption}>
318
- <OText
319
- size={14}
320
- color={theme.colors.disabled}
321
- style={{
322
- lineHeight: 24
323
- }}
324
- >
325
- {selectedPreorderType.name}
326
- </OText>
327
- <IconAntDesign
328
- name='down'
329
- color={theme.colors.textThird}
330
- size={16}
331
- />
332
- </View>
333
- </TouchableOpacity>
315
+ <SelectDropdown
316
+ defaultValueByIndex={selectedPreorderType}
317
+ data={preorderTypeList}
318
+ // disabled={orderState.loading}
319
+ onSelect={(selectedItem, index) => {
320
+ setSelectedPreorderType(index)
321
+ }}
322
+ buttonTextAfterSelection={(selectedItem, index) => {
323
+ return selectedItem.name
324
+ }}
325
+ rowTextForSelection={(item, index) => {
326
+ return item.name
327
+ }}
328
+ buttonStyle={styles.selectOption}
329
+ buttonTextStyle={{
330
+ color: theme.colors.disabled,
331
+ fontSize: 14,
332
+ textAlign: 'left',
333
+ marginHorizontal: 0
334
+ }}
335
+ dropdownStyle={{
336
+ borderRadius: 8,
337
+ borderColor: theme.colors.lightGray,
338
+ marginTop: 5
339
+ }}
340
+ rowStyle={{
341
+ borderBottomColor: theme.colors.backgroundGray100,
342
+ backgroundColor: theme.colors.backgroundGray100,
343
+ height: 40,
344
+ flexDirection: 'column',
345
+ alignItems: 'flex-start',
346
+ paddingTop: 8,
347
+ paddingHorizontal: 14
348
+ }}
349
+ rowTextStyle={{
350
+ color: theme.colors.disabled,
351
+ fontSize: 14,
352
+ marginHorizontal: 0
353
+ }}
354
+ renderDropdownIcon={() => dropDownIcon()}
355
+ dropdownOverlayColor='transparent'
356
+ />
334
357
  </PreorderTypeWrapper>
335
- {selectedPreorderType?.key === 'business_menu' && (
358
+ {selectedPreorderType === 1 && (
336
359
  <MenuWrapper>
337
360
  <OText
338
361
  size={16}
@@ -415,51 +438,6 @@ const BusinessPreorderUI = (props: BusinessPreorderParams) => {
415
438
  />
416
439
  </PreOrderContainer>
417
440
  <Spinner visible={orderState.loading} />
418
- <OModal
419
- open={isPreorderTypeList}
420
- onClose={() => setIsPreorderTypeList(false)}
421
- customClose
422
- entireModal
423
- >
424
- <PreorderTypeListWrapper contentContainerStyle={{ paddingVertical: 20, paddingHorizontal: 40}}>
425
- <TouchableOpacity onPress={() => setIsPreorderTypeList(false)} style={styles.wrapperIcon}>
426
- <IconAntDesign
427
- name='close'
428
- color={theme.colors.textThird}
429
- size={24}
430
- />
431
- </TouchableOpacity>
432
- {preorderTypeList?.map((option: any, index: number) => (
433
- <TouchableOpacity
434
- key={index}
435
- onPress={() => handleClickPreorderType(option)}
436
- style={{ zIndex: 99999 }}
437
- >
438
- <DropOption
439
- numberOfLines={1}
440
- selected={option.key === selectedPreorderType.key}
441
- >
442
- <View style={{ marginRight: 10 }}>
443
- {option.key === selectedPreorderType.key ? (
444
- <MaterialCommunityIcons
445
- name='radiobox-marked'
446
- size={24}
447
- color={theme.colors.primary}
448
- />
449
- ) : (
450
- <MaterialCommunityIcons
451
- name='radiobox-blank'
452
- size={24}
453
- color={theme.colors.arrowColor}
454
- />
455
- )}
456
- </View>
457
- <Text>{option.name}</Text>
458
- </DropOption>
459
- </TouchableOpacity>
460
- ))}
461
- </PreorderTypeListWrapper>
462
- </OModal>
463
441
  </>
464
442
  )
465
443
  }
@@ -42,15 +42,3 @@ export const TimeItem = styled.View`
42
42
  background: #F5F9FF;
43
43
  `}
44
44
  `
45
-
46
- export const PreorderTypeListWrapper = styled.ScrollView``
47
-
48
- export const DropOption = styled.View`
49
- padding: 10px;
50
- margin-bottom: 5px;
51
- font-size: 16px;
52
- border-bottom-width: 1px;
53
- border-bottom-color: ${(props: any) => props.theme.colors.lightGray};
54
- flex-direction: row;
55
- align-items: center;
56
- `
@@ -567,86 +567,87 @@ export const ProductOptionsUI = (props: any) => {
567
567
 
568
568
  {!loading && !error && product && (
569
569
  <ProductActions>
570
- <OText size={16} lineHeight={24} weight={'600'}>
571
- {productCart.total ? parsePrice(productCart?.total) : ''}
572
- </OText>
573
570
  {productCart && !isSoldOut && maxProductQuantity > 0 && (
574
- <View style={styles.quantityControl}>
575
- <TouchableOpacity
576
- onPress={decrement}
577
- disabled={productCart.quantity === 1 || isSoldOut}>
578
- <OIcon
579
- src={theme.images.general.minus}
580
- width={16}
581
- color={
582
- productCart.quantity === 1 || isSoldOut
583
- ? theme.colors.backgroundGray
584
- : theme.colors.backgroundDark
585
- }
586
- />
587
- </TouchableOpacity>
588
- <OText
589
- size={12}
590
- lineHeight={18}
591
- style={{ minWidth: 29, textAlign: 'center' }}>
592
- {productCart.quantity}
571
+ <>
572
+ <OText size={16} lineHeight={24} weight={'600'}>
573
+ {productCart.total ? parsePrice(productCart?.total) : ''}
593
574
  </OText>
594
- <TouchableOpacity
595
- onPress={increment}
596
- disabled={
597
- maxProductQuantity <= 0 ||
598
- productCart.quantity >= maxProductQuantity ||
599
- isSoldOut
600
- }>
601
- <OIcon
602
- src={theme.images.general.plus}
603
- width={16}
604
- color={
575
+ <View style={styles.quantityControl}>
576
+ <TouchableOpacity
577
+ onPress={decrement}
578
+ disabled={productCart.quantity === 1 || isSoldOut}>
579
+ <OIcon
580
+ src={theme.images.general.minus}
581
+ width={16}
582
+ color={
583
+ productCart.quantity === 1 || isSoldOut
584
+ ? theme.colors.backgroundGray
585
+ : theme.colors.backgroundDark
586
+ }
587
+ />
588
+ </TouchableOpacity>
589
+ <OText
590
+ size={12}
591
+ lineHeight={18}
592
+ style={{ minWidth: 29, textAlign: 'center' }}>
593
+ {productCart.quantity}
594
+ </OText>
595
+ <TouchableOpacity
596
+ onPress={increment}
597
+ disabled={
605
598
  maxProductQuantity <= 0 ||
606
- productCart.quantity >= maxProductQuantity ||
607
- isSoldOut
608
- ? theme.colors.backgroundGray
609
- : theme.colors.backgroundDark
610
- }
611
- />
612
- </TouchableOpacity>
613
- </View>
599
+ productCart.quantity >= maxProductQuantity ||
600
+ isSoldOut
601
+ }>
602
+ <OIcon
603
+ src={theme.images.general.plus}
604
+ width={16}
605
+ color={
606
+ maxProductQuantity <= 0 ||
607
+ productCart.quantity >= maxProductQuantity ||
608
+ isSoldOut
609
+ ? theme.colors.backgroundGray
610
+ : theme.colors.backgroundDark
611
+ }
612
+ />
613
+ </TouchableOpacity>
614
+ </View>
615
+ </>
614
616
  )}
615
617
  <View
616
- style={{
617
- width: isSoldOut || maxProductQuantity <= 0 ? '100%' : '40%',
618
- }}>
618
+ style={{ width: isSoldOut || maxProductQuantity <= 0 ? '100%' : '40%'}}
619
+ >
619
620
  {productCart &&
620
621
  !isSoldOut &&
621
622
  maxProductQuantity > 0 &&
622
623
  auth &&
623
- orderState.options?.address_id && (
624
- <OButton
625
- onClick={() => handleSaveProduct()}
626
- imgRightSrc=""
627
- text={`${orderState.loading
628
- ? t('LOADING', 'Loading')
629
- : editMode
630
- ? t('UPDATE', 'Update')
631
- : t('ADD', 'Add')
632
- }`}
633
- textStyle={{
634
- color: saveErrors ? theme.colors.primary : theme.colors.white,
635
- }}
636
- style={{
637
- backgroundColor: saveErrors ? theme.colors.white : theme.colors.primary,
638
- borderColor: saveErrors ? theme.colors.white : theme.colors.primary,
639
- opacity: saveErrors ? 0.3 : 1,
640
- borderRadius: 7.6,
641
- height: 44,
642
- shadowOpacity: 0,
643
- borderWidth: 1,
644
- }}
645
- />
646
- )}
647
- {auth &&
648
- !orderState.options?.address_id &&
649
- (orderState.loading ? (
624
+ orderState.options?.address_id &&
625
+ (
626
+ <OButton
627
+ onClick={() => handleSaveProduct()}
628
+ imgRightSrc=""
629
+ text={`${orderState.loading
630
+ ? t('LOADING', 'Loading')
631
+ : editMode
632
+ ? t('UPDATE', 'Update')
633
+ : t('ADD', 'Add')
634
+ }`}
635
+ textStyle={{
636
+ color: saveErrors ? theme.colors.primary : theme.colors.white,
637
+ }}
638
+ style={{
639
+ backgroundColor: saveErrors ? theme.colors.white : theme.colors.primary,
640
+ borderColor: saveErrors ? theme.colors.white : theme.colors.primary,
641
+ opacity: saveErrors ? 0.3 : 1,
642
+ borderRadius: 7.6,
643
+ height: 44,
644
+ shadowOpacity: 0,
645
+ borderWidth: 1,
646
+ }}
647
+ />
648
+ )}
649
+ {auth && !orderState.options?.address_id &&(
650
+ orderState.loading ? (
650
651
  <OButton
651
652
  isDisabled
652
653
  text={t('LOADING', 'Loading')}
@@ -654,7 +655,8 @@ export const ProductOptionsUI = (props: any) => {
654
655
  />
655
656
  ) : (
656
657
  <OButton onClick={navigation.navigate('AddressList')} />
657
- ))}
658
+ ))
659
+ }
658
660
  {(!auth || isSoldOut || maxProductQuantity <= 0) && (
659
661
  <OButton
660
662
  isDisabled={isSoldOut || maxProductQuantity <= 0}
@@ -669,6 +671,7 @@ export const ProductOptionsUI = (props: any) => {
669
671
  style={{
670
672
  borderColor: theme.colors.primary,
671
673
  backgroundColor: theme.colors.white,
674
+ borderRadius: 8
672
675
  }}
673
676
  />
674
677
  )}