ordering-ui-react-native 0.17.94-release → 0.17.95-release

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.17.94-release",
3
+ "version": "0.17.95-release",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -76,6 +76,7 @@
76
76
  "react-native-color-matrix-image-filters": "^5.2.10",
77
77
  "react-native-country-picker-modal": "^2.0.0",
78
78
  "react-native-credit-card-input": "^0.4.1",
79
+ "react-native-date-picker": "^4.2.13",
79
80
  "react-native-device-info": "^8.7.1",
80
81
  "react-native-document-picker": "^5.2.0",
81
82
  "react-native-elements": "^3.0.0-alpha.1",
@@ -47,10 +47,10 @@ export const getTraduction = (key: string, t: any) => {
47
47
  */
48
48
  export const convertHoursToMinutes = (time: any) => {
49
49
  const [, t] = useLanguage()
50
- if (!time) return '0min'
50
+ if (!time) return `0 ${t('TIME_MIN', 'min')}`
51
51
  const [hour, minute] = time.split(':')
52
52
  const result = (parseInt(hour, 10) * 60) + parseInt(minute, 10)
53
- return `${result}${t('MIN', 'min')}`
53
+ return `${result}${t('TIME_MIN', 'min')}`
54
54
  }
55
55
 
56
56
  export const getIconCard = (brand: string, size: number) => {
@@ -12,6 +12,7 @@ import { PreviousMessages } from '../PreviousMessages';
12
12
  import { FiltersTab, TabsContainer, TagsContainer, Tag } from './styles';
13
13
  import { MessagesOptionParams } from '../../types';
14
14
  import { useDeviceOrientation } from '../../../../../src/hooks/DeviceOrientation';
15
+ import { WebsocketStatus } from '../WebsocketStatus'
15
16
 
16
17
  const MessagesOptionUI = (props: MessagesOptionParams) => {
17
18
  const {
@@ -163,7 +164,7 @@ const MessagesOptionUI = (props: MessagesOptionParams) => {
163
164
  <View style={styles.header}>
164
165
  <OText style={styles.title}>{t('MESSAGES', 'Messages')}</OText>
165
166
  </View>
166
-
167
+ <WebsocketStatus />
167
168
  <FiltersTab>
168
169
  <TabsContainer width={dimensions.width - 42}>
169
170
  {tabs.map((tab: any) => (
@@ -40,6 +40,7 @@ import { OrdersOptionPaymethod } from '../OrdersOptionPaymethod';
40
40
  import { OrdersOptionDriver } from '../OrdersOptionDriver';
41
41
  import { OrdersOptionDate } from '../OrdersOptionDate';
42
42
  import { OrderDetailsBusiness } from '../OrderDetails/Business';
43
+ import { WebsocketStatus } from '../WebsocketStatus'
43
44
 
44
45
  const { useDeviceOrientation, PORTRAIT } = DeviceOrientationMethods
45
46
 
@@ -314,7 +315,11 @@ const OrdersListManagerUI = (props: OrdersOptionParams) => {
314
315
  </View>
315
316
  {configState?.configs?.order_deadlines_enabled?.value === '1' && (
316
317
  <View style={styles.SLAwrapper}>
317
- <View style={{ flex: 0.5 }}>
318
+ <View style={{ flex: 1 }}>
319
+ <WebsocketStatus />
320
+ </View>
321
+ <View style={{ width: 10, height: '100%' }} />
322
+ <View style={{ flex: 1 }}>
318
323
  <OButton
319
324
  text={t('SLA_SETTING', 'SLA’s Settings')}
320
325
  textStyle={{ color: theme.colors.backArrow }}
@@ -330,7 +335,7 @@ const OrdersListManagerUI = (props: OrdersOptionParams) => {
330
335
  />
331
336
  </View>
332
337
  <View style={{ width: 10, height: '100%' }} />
333
- <View style={{ flex: 0.5, justifyContent: 'center' }}>
338
+ <View style={{ flex: 1, justifyContent: 'center' }}>
334
339
  <SelectDropdown
335
340
  defaultButtonText={t('SLA', 'SLA\'s')}
336
341
  data={preorderTypeList}
@@ -209,7 +209,7 @@ export const Timer = () => {
209
209
  return (
210
210
  <TimerInputWrapper>
211
211
  <OText style={styles.settingTime} color={theme.colors.disabled}>{configs?.order_deadlines_delayed_time?.value}</OText>
212
- <OText>{t('MIN', 'min')}</OText>
212
+ <OText>{t('TIME_MIN', 'min')}</OText>
213
213
  </TimerInputWrapper>
214
214
  )
215
215
  }
@@ -11,6 +11,7 @@ import { useTheme } from 'styled-components/native';
11
11
  import { DeviceOrientationMethods } from '../../../../../src/hooks/DeviceOrientation'
12
12
  import { NotificationSetting } from '../../../../../src/components/NotificationSetting'
13
13
  import { NewOrderNotification } from '../NewOrderNotification';
14
+ import { WebsocketStatus } from '../WebsocketStatus'
14
15
 
15
16
  import { OText, OButton, OModal, OInput, OIcon } from '../shared';
16
17
  import { NotFoundSource } from '../NotFoundSource';
@@ -402,6 +403,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
402
403
  />
403
404
  </IconWrapper>
404
405
  </View>
406
+ <WebsocketStatus />
405
407
  {configState?.configs?.order_deadlines_enabled?.value === '1' && (
406
408
  <View style={styles.SLAwrapper}>
407
409
  <View style={{ flex: 0.5 }}>
@@ -914,7 +916,7 @@ export const Timer = () => {
914
916
  return (
915
917
  <TimerInputWrapper>
916
918
  <OText style={styles.settingTime} color={theme.colors.disabled}>{configs?.order_deadlines_delayed_time?.value}</OText>
917
- <OText>{t('MIN', 'min')}</OText>
919
+ <OText>{t('TIME_MIN', 'min')}</OText>
918
920
  </TimerInputWrapper>
919
921
  )
920
922
  }
@@ -0,0 +1,171 @@
1
+ import React, { useState } from 'react'
2
+ import { useLanguage, useUtils, WebsocketStatus as WebsocketStatusController } from 'ordering-components/native'
3
+ import { TouchableOpacity, View, StyleSheet } from 'react-native'
4
+ import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons';
5
+ import { useTheme } from 'styled-components/native'
6
+ import RNRestart from 'react-native-restart'
7
+ import { OModal, OButton, OText, OIcon } from '../shared'
8
+
9
+ import {
10
+ Container,
11
+ ModalContainer,
12
+ ModalTitle,
13
+ StatusItemWrapper,
14
+ StatusText
15
+ } from './styles'
16
+
17
+ const SocketStatusUI = (props: any) => {
18
+ const {
19
+ socketStatus,
20
+ connectedDate
21
+ } = props
22
+
23
+ const theme = useTheme()
24
+ const [, t] = useLanguage()
25
+ const [{ parseDate }] = useUtils()
26
+ const [openModal, setOpenModal] = useState(false)
27
+
28
+ const styles = StyleSheet.create({
29
+ btnBackArrow: {
30
+ borderWidth: 0,
31
+ width: 32,
32
+ height: 32,
33
+ tintColor: theme.colors.textGray,
34
+ backgroundColor: theme.colors.clear,
35
+ borderColor: theme.colors.clear,
36
+ shadowColor: theme.colors.clear,
37
+ paddingLeft: 0,
38
+ paddingRight: 0,
39
+ marginBottom: 30,
40
+ marginTop: 30
41
+ },
42
+ })
43
+
44
+ const getStatusColor = (status: number) => {
45
+ switch (status) {
46
+ case 0:
47
+ return '#FF9922';
48
+ case 1:
49
+ return '#00D27A';
50
+ case 2:
51
+ return '#E63757';
52
+ default:
53
+ return '#FF9922';
54
+ }
55
+ }
56
+
57
+ return (
58
+ <Container>
59
+ <TouchableOpacity
60
+ style={{
61
+ flexDirection: 'row',
62
+ alignItems: 'center',
63
+ justifyContent: 'center',
64
+ backgroundColor: theme.colors.inputChat,
65
+ borderRadius: 7.6,
66
+ marginVertical: 10,
67
+ paddingVertical: 10,
68
+ paddingHorizontal: 15,
69
+ }}
70
+ activeOpacity={0.6}
71
+ onPress={() => setOpenModal(true)}
72
+ >
73
+ <OText
74
+ style={{ color: theme.colors.backArrow, fontSize: 16, marginBottom: 0, lineHeight: 16 }}
75
+ >
76
+ {t('CONNECTION_STATUS', 'Connection status')}
77
+ </OText>
78
+ <MaterialIcon
79
+ name='circle'
80
+ size={12}
81
+ color={getStatusColor(socketStatus)}
82
+ style={{ marginLeft: 8 }}
83
+ />
84
+ </TouchableOpacity>
85
+
86
+ <OModal
87
+ open={openModal}
88
+ onClose={() => setOpenModal(false)}
89
+ entireModal
90
+ customClose
91
+ >
92
+ <ModalContainer nestedScrollEnabled={true}>
93
+ <TouchableOpacity
94
+ onPress={() => setOpenModal(false)}
95
+ style={styles.btnBackArrow}
96
+ >
97
+ <OIcon src={theme.images.general.arrow_left} color={theme.colors.textGray} />
98
+ </TouchableOpacity>
99
+ <View>
100
+ <ModalTitle>{t('CONNECTION_STATUS', 'Connection status')}</ModalTitle>
101
+ <OText style={{ marginBottom: 20 }}>
102
+ {t('LAST_UPDATE', 'Last update')}: {parseDate(connectedDate)}
103
+ </OText>
104
+ <StatusItemWrapper>
105
+ <MaterialIcon
106
+ name='circle'
107
+ size={12}
108
+ color={getStatusColor(1)}
109
+ style={{ marginTop: 10, marginHorizontal: 8 }}
110
+ />
111
+ <View style={{ marginLeft: 16 }}>
112
+ <StatusText>{t('OK', 'Ok')}</StatusText>
113
+ <OText style={{ color: theme.colors.backArrow, fontSize: 14 }}>{t('WEBSOCKET_OK', 'The websocket works normally.')}</OText>
114
+ </View>
115
+ </StatusItemWrapper>
116
+ <StatusItemWrapper>
117
+ <MaterialIcon
118
+ name='circle'
119
+ size={12}
120
+ color={getStatusColor(0)}
121
+ style={{ marginTop: 10, marginHorizontal: 8 }}
122
+ />
123
+ <View style={{ marginLeft: 16 }}>
124
+ <StatusText>{t('CONNECTING', 'Connecting')}</StatusText>
125
+ <OText style={{ color: theme.colors.backArrow, fontSize: 14 }}>{t('WEBSOCKET_CONNECTING', 'The websocket is connecting.')}</OText>
126
+ </View>
127
+ </StatusItemWrapper>
128
+ <StatusItemWrapper>
129
+ <MaterialIcon
130
+ name='circle'
131
+ size={12}
132
+ color={getStatusColor(2)}
133
+ style={{ marginTop: 10, marginHorizontal: 8 }}
134
+ />
135
+ <View style={{ marginLeft: 16 }}>
136
+ <StatusText>{t('DISCONNECTED', 'Disconnected')}</StatusText>
137
+ <OText style={{ color: theme.colors.backArrow, fontSize: 14 }}>{t('WEBSOCKET_DISCONNECTED', 'The server is slow, please reload.')}</OText>
138
+ </View>
139
+ </StatusItemWrapper>
140
+
141
+ <View style={{ flexDirection: 'row', marginTop: 50 }}>
142
+ <OButton
143
+ onClick={() => setOpenModal(false)}
144
+ bgColor={theme.colors.white}
145
+ borderColor={theme.colors.primary}
146
+ textStyle={{ color: theme.colors.primary }}
147
+ style={{ borderRadius: 8, height: 48 }}
148
+ text={t('CLOSE', 'Close')}
149
+ />
150
+ <OButton
151
+ onClick={() => RNRestart.Restart()}
152
+ borderColor={theme.colors.primary}
153
+ textStyle={{ color: theme.colors.white }}
154
+ style={{ borderRadius: 8, marginLeft: 16, height: 48 }}
155
+ text={t('UPDATE', 'Update')}
156
+ />
157
+ </View>
158
+ </View>
159
+ </ModalContainer>
160
+ </OModal>
161
+ </Container>
162
+ )
163
+ }
164
+
165
+ export const WebsocketStatus = (props: any) => {
166
+ const socketProps = {
167
+ ...props,
168
+ UIComponent: SocketStatusUI
169
+ }
170
+ return <WebsocketStatusController {...socketProps} />
171
+ }
@@ -0,0 +1,28 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const Container = styled.View`
4
+ display: flex;
5
+ flex-direction: column;
6
+ `
7
+ export const ModalContainer = styled.ScrollView`
8
+ padding: 0px 30px;
9
+ `
10
+ export const ModalTitle = styled.Text`
11
+ font-family: Poppins;
12
+ font-style: normal;
13
+ font-weight: bold;
14
+ font-size: 20px;
15
+ color: ${(props: any) => props.theme.colors.textGray};
16
+ margin-bottom: 10px;
17
+ `
18
+ export const StatusItemWrapper = styled.View`
19
+ flex-direction: row;
20
+ margin-bottom: 16px;
21
+ `
22
+ export const StatusText = styled.Text`
23
+ font-family: Poppins;
24
+ font-style: normal;
25
+ font-weight: 500;
26
+ font-size: 18px;
27
+ color: ${(props: any) => props.theme.colors.textGray};
28
+ `
@@ -99,6 +99,7 @@ import { Promotions } from './src/components/Promotions'
99
99
  import { MultiCart } from './src/components/MultiCart'
100
100
  import { PageBanner } from './src/components/PageBanner'
101
101
  import { USER_TYPE, ORDER_TYPES } from './src/config/constants'
102
+ import { DatePickerUI } from './src/components/DatePicker'
102
103
 
103
104
  import { OSBill, OSTable, OSCoupon, OSTotal, OSRow } from './src/components/OrderSummary/styles';
104
105
 
@@ -263,7 +264,7 @@ export {
263
264
  Promotions,
264
265
  PageBanner,
265
266
  MyOrders,
266
- MultiCart,
267
+ MultiCart,
267
268
  ORDER_TYPES,
268
269
  USER_TYPE,
269
270
 
@@ -340,5 +341,8 @@ export {
340
341
  _retrieveStoreData,
341
342
  _setStoreData,
342
343
  _removeStoreData,
343
- _clearStoreData
344
+ _clearStoreData,
345
+
346
+ // Date Picker
347
+ DatePickerUI
344
348
  }
@@ -23,7 +23,8 @@ export const BusinessItemAccordion = (props: any) => {
23
23
  handleClickCheckout,
24
24
  checkoutButtonDisabled,
25
25
  isMultiCheckout,
26
- isFromUpselling
26
+ isFromUpselling,
27
+ isGiftCart
27
28
  } = props
28
29
 
29
30
  const [orderState] = useOrder();
@@ -75,7 +76,7 @@ export const BusinessItemAccordion = (props: any) => {
75
76
  <BIContentInfo>
76
77
  <OText size={16} lineHeight={24} weight={'600'}>{cart?.business?.name}</OText>
77
78
  <View style={{ flexDirection: 'row' }}>
78
- {props.onNavigationRedirect && !isClosed && (
79
+ {props.onNavigationRedirect && !isClosed && !isGiftCart && (
79
80
  <>
80
81
  <TouchableOpacity onPress={() => props.onNavigationRedirect('Business', { store: cart?.business?.slug })}>
81
82
  <OText color={theme.colors.primary} size={12} lineHeight={18} style={{ textDecorationLine: 'underline' }}>{t('GO_TO_STORE', 'Go to store')}</OText>
@@ -84,7 +85,9 @@ export const BusinessItemAccordion = (props: any) => {
84
85
  )}
85
86
  {!isCartPending && (
86
87
  <>
87
- <OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
88
+ {!isGiftCart && (
89
+ <OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
90
+ )}
88
91
  <OAlert
89
92
  title={t('DELETE_CART', 'Delete Cart')}
90
93
  message={t('QUESTION_DELETE_CART', 'Are you sure to you wants delete the selected cart')}
@@ -94,7 +97,7 @@ export const BusinessItemAccordion = (props: any) => {
94
97
  </OAlert>
95
98
  </>
96
99
  )}
97
- {isBusinessChangeEnabled && props.handleChangeStore && (
100
+ {isBusinessChangeEnabled && props.handleChangeStore && !isGiftCart && (
98
101
  <>
99
102
  <OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
100
103
  <TouchableOpacity
@@ -28,7 +28,7 @@ export const MaxSectionItem = (props: any) => {
28
28
  return filter === 'max_distance'
29
29
  ? `${option / 1000} ${t('KM', 'Km')}`
30
30
  : filter === 'max_eta'
31
- ? `${option} ${t('MIN', 'min')}`
31
+ ? `${option} ${t('TIME_MIN', 'min')}`
32
32
  : parsePrice(option)
33
33
  }
34
34
  return (
@@ -218,6 +218,7 @@ const CartUI = (props: any) => {
218
218
  checkoutButtonDisabled={(openUpselling && !canOpenUpselling) || subtotalWithTaxes < cart?.minimum || !cart?.valid_address}
219
219
  isMultiCheckout={isMultiCheckout}
220
220
  isFromUpselling={isFromUpselling}
221
+ isGiftCart={!cart?.business_id}
221
222
  >
222
223
  {cart?.products?.length > 0 && cart?.products.map((product: any, i: number) => (
223
224
  <ProductItemAccordion
@@ -408,6 +409,7 @@ const CartUI = (props: any) => {
408
409
  cart?.status !== 2 &&
409
410
  validationFields?.fields?.checkout?.driver_tip?.enabled &&
410
411
  driverTipsOptions && driverTipsOptions?.length > 0 &&
412
+ cart?.business_id &&
411
413
  (
412
414
  <DriverTipsContainer>
413
415
  <OText size={14} lineHeight={20} color={theme.colors.textNormal}>
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import DatePicker from 'react-native-date-picker'
3
+ import { DateContainer } from './styles';
4
+
5
+ export const DatePickerUI = (props: any) => {
6
+ const {
7
+ birthdate,
8
+ handleChangeDate
9
+ } = props;
10
+
11
+ return (
12
+ <DateContainer>
13
+ <DatePicker mode="date" date={birthdate ? new Date(birthdate) : new Date()} onDateChange={handleChangeDate} />
14
+ </DateContainer>
15
+ );
16
+ };
17
+
@@ -0,0 +1,20 @@
1
+ import styled from 'styled-components/native';
2
+
3
+ export const DateContainer = styled.View`
4
+ display: flex;
5
+ align-items: center;
6
+ margin-bottom: 20px;
7
+
8
+ input {
9
+ border-radius: 20px;
10
+ width: 140px;
11
+ outline: none;
12
+ padding: 10px 15px;
13
+ border: 1px solid #E9ECEF;
14
+ }
15
+
16
+ .react-datepicker__triangle {
17
+ transform: translate(40px, 0px) !important;
18
+ }
19
+
20
+ `
@@ -13,6 +13,8 @@ import { OAlert } from '../../../../../src/components/shared'
13
13
  import { PhoneInputNumber } from '../PhoneInputNumber';
14
14
  import { sortInputFields } from '../../utils';
15
15
  import { ListItem } from '../UserProfile/styles';
16
+ import moment from 'moment';
17
+ import { DatePickerUI } from '../DatePicker';
16
18
 
17
19
  export const UserFormDetailsUI = (props: any) => {
18
20
  const {
@@ -81,6 +83,8 @@ export const UserFormDetailsUI = (props: any) => {
81
83
  const [isValid, setIsValid] = useState(false)
82
84
  const [isChanged, setIsChanged] = useState(false)
83
85
  const [isModalOpen, setIsModalOpen] = useState(false)
86
+ const [birthdate, setBirthdate] = useState(user?.birthdate ?? null)
87
+ const [showDatePicker, setShowDatePicker] = useState(false)
84
88
  const [phoneInputData, setPhoneInputData] = useState({
85
89
  error: '',
86
90
  phone: {
@@ -92,6 +96,7 @@ export const UserFormDetailsUI = (props: any) => {
92
96
 
93
97
  const isAdmin = user?.level === 0
94
98
  const showInputPhoneNumber = (validationFields?.fields?.checkout?.cellphone?.enabled ?? false) || configs?.verification_phone_required?.value === '1'
99
+ const showInputBirthday = validationFields?.fields?.checkout?.birthdate?.enabled ?? false
95
100
 
96
101
  const handleSuccessSignup = (user: any) => {
97
102
  login({
@@ -206,6 +211,13 @@ export const UserFormDetailsUI = (props: any) => {
206
211
  handleChangeInput(countryCode, true);
207
212
  }
208
213
 
214
+ const _handleChangeDate = (date: any) => {
215
+ setBirthdate(date)
216
+ const _birthdate = moment(date).format('YYYY-MM-DD')
217
+ handleChangeInput({ target: { name: 'birthdate', value: _birthdate } })
218
+ setShowDatePicker(false)
219
+ }
220
+
209
221
  const onRemoveAccount = () => {
210
222
  setConfirm({
211
223
  open: true,
@@ -268,6 +280,14 @@ export const UserFormDetailsUI = (props: any) => {
268
280
  }
269
281
  }, [phoneInputData, configs?.verification_phone_required?.value, isChanged])
270
282
 
283
+ useEffect(() => {
284
+ if (!validationFields.loading && birthdate) {
285
+ setValue('birthdate', formState?.result?.result
286
+ ? formState?.result?.result?.birthdate
287
+ : formState?.changes?.birthdate ?? (user && user?.birthdate) ?? '')
288
+ }
289
+ }, [validationFields, birthdate])
290
+
271
291
  useEffect(() => {
272
292
  if (!requiredFields || formState?.changes?.length === 0) return
273
293
  const _isValid = requiredFields.every((key: any) => formState?.changes[key])
@@ -359,7 +379,21 @@ export const UserFormDetailsUI = (props: any) => {
359
379
  </React.Fragment>
360
380
  ),
361
381
  )}
362
-
382
+ {showInputBirthday && (
383
+ <WrapperPhone>
384
+ <OText size={14} lineHeight={21} color={theme.colors.textNormal} weight={'500'} style={{ textTransform: 'capitalize', alignSelf: 'flex-start' }}>
385
+ {t('BIRTHDATE', 'Birthdate')}
386
+ </OText>
387
+ <TouchableOpacity onPress={() => setShowDatePicker(!showDatePicker)}>
388
+ <OText size={14} lineHeight={21} color={theme.colors.textNormal} weight={'500'} style={{ alignSelf: 'flex-start' }}>
389
+ {birthdate ? moment(birthdate).format('YYYY-MM-DD') : ''}
390
+ </OText>
391
+ </TouchableOpacity>
392
+ {showDatePicker && (
393
+ <DatePickerUI birthdate={birthdate} handleChangeDate={_handleChangeDate} />
394
+ )}
395
+ </WrapperPhone>
396
+ )}
363
397
  {!!showInputPhoneNumber && ((requiredFields && requiredFields.includes('cellphone')) || !requiredFields) && (
364
398
  <WrapperPhone>
365
399
  <OText size={14} lineHeight={21} weight={'500'} color={theme.colors.textNormal}>{t('PHONE', 'Phone')}</OText>