ordering-ui-react-native 0.12.21 → 0.12.25

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 (33) hide show
  1. package/package.json +1 -1
  2. package/src/components/ActiveOrders/index.tsx +31 -14
  3. package/src/components/Messages/index.tsx +59 -4
  4. package/src/components/Messages/styles.tsx +3 -0
  5. package/themes/business/src/components/Chat/index.tsx +56 -8
  6. package/themes/business/src/components/Chat/styles.tsx +4 -0
  7. package/themes/doordash/src/components/Messages/index.tsx +62 -4
  8. package/themes/doordash/src/components/Messages/styles.tsx +2 -0
  9. package/themes/doordash/src/components/shared/OButton.tsx +2 -1
  10. package/themes/instacart/src/components/Messages/index.tsx +60 -5
  11. package/themes/instacart/src/components/Messages/styles.tsx +2 -0
  12. package/themes/kiosk/src/components/BusinessProductsListing/index.tsx +7 -1
  13. package/themes/kiosk/src/components/CartBottomSheet/styles.tsx +1 -1
  14. package/themes/kiosk/src/components/CategoriesMenu/index.tsx +8 -1
  15. package/themes/original/src/components/Messages/index.tsx +61 -5
  16. package/themes/original/src/components/Messages/styles.tsx +2 -2
  17. package/themes/original/src/components/ProductForm/index.tsx +40 -24
  18. package/themes/single-business/index.tsx +4 -0
  19. package/themes/single-business/src/components/AddressList/index.tsx +2 -2
  20. package/themes/single-business/src/components/BusinessProductsCategories/index.tsx +89 -16
  21. package/themes/single-business/src/components/BusinessProductsList/index.tsx +22 -8
  22. package/themes/single-business/src/components/BusinessProductsList/styles.tsx +1 -1
  23. package/themes/single-business/src/components/BusinessProductsListing/index.tsx +71 -26
  24. package/themes/single-business/src/components/LoginForm/index.tsx +43 -26
  25. package/themes/single-business/src/components/OrderListOption/index.tsx +231 -0
  26. package/themes/single-business/src/components/OrderListOption/styles.tsx +62 -0
  27. package/themes/single-business/src/components/OrdersListing/index.tsx +112 -0
  28. package/themes/single-business/src/components/SignupForm/index.tsx +15 -16
  29. package/themes/single-business/src/components/UserProfile/index.tsx +9 -3
  30. package/themes/single-business/src/types/index.tsx +9 -0
  31. package/themes/single-business/src/utils/index.tsx +32 -1
  32. package/themes/uber-eats/src/components/Messages/index.tsx +59 -4
  33. package/themes/uber-eats/src/components/Messages/styles.tsx +2 -0
@@ -5,9 +5,9 @@ import { launchImageLibrary } from 'react-native-image-picker'
5
5
  import { GiftedChat, Actions, ActionsProps, InputToolbar, Composer, Send, Bubble, MessageImage, InputToolbarProps, ComposerProps } from 'react-native-gifted-chat'
6
6
  import { USER_TYPE } from '../../config/constants'
7
7
  import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons'
8
- import { OIcon, OIconButton, OText } from '../shared'
8
+ import { OIcon, OIconButton, OText, OButton } from '../shared'
9
9
  import { TouchableOpacity, ActivityIndicator, StyleSheet, View, Platform, Keyboard } from 'react-native'
10
- import { Header, TitleHeader, Wrapper } from './styles'
10
+ import { Header, TitleHeader, Wrapper, QuickMessageContainer } from './styles'
11
11
  import { MessagesParams } from '../../types'
12
12
  import { useWindowDimensions } from 'react-native'
13
13
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
@@ -43,6 +43,17 @@ const MessagesUI = (props: MessagesParams) => {
43
43
 
44
44
  const theme = useTheme();
45
45
 
46
+ const quickMessageList = [
47
+ { key: 'customer_message_1', text: t('CUSTOMER_MESSAGE_1', 'Lorem ipsum 1') },
48
+ { key: 'customer_message_2', text: t('CUSTOMER_MESSAGE_2', 'Lorem ipsum 2') },
49
+ { key: 'customer_message_3', text: t('CUSTOMER_MESSAGE_3', 'Lorem ipsum 3') },
50
+ { key: 'customer_message_4', text: t('CUSTOMER_MESSAGE_4', 'Lorem ipsum 4') }
51
+ ]
52
+
53
+ const handleClickQuickMessage = (text: string) => {
54
+ setMessage && setMessage(`${message}${text}`)
55
+ }
56
+
46
57
  const onChangeMessage = (val: string) => {
47
58
  setMessage && setMessage(val)
48
59
  }
@@ -227,13 +238,48 @@ const MessagesUI = (props: MessagesParams) => {
227
238
  )
228
239
  }
229
240
 
241
+ const renderAccessory = () => {
242
+ return (
243
+ <QuickMessageContainer
244
+ style={{
245
+ marginLeft: 10,
246
+ marginBottom: 10
247
+ }}
248
+ contentContainerStyle={{
249
+ alignItems: 'center',
250
+ }}
251
+ horizontal
252
+ showsHorizontalScrollIndicator={false}
253
+ >
254
+ {quickMessageList.map((quickMessage, i) => (
255
+ <OButton
256
+ key={i}
257
+ text={quickMessage.text}
258
+ bgColor='#E9ECEF'
259
+ borderColor='#E9ECEF'
260
+ imgRightSrc={null}
261
+ textStyle={{
262
+ fontSize: 11,
263
+ lineHeight: 16,
264
+ color: '#414954'
265
+ }}
266
+ style={{ ...styles.editButton }}
267
+ onClick={() => handleClickQuickMessage(quickMessage.text)}
268
+ />
269
+ ))}
270
+ </QuickMessageContainer>
271
+ )
272
+ }
273
+
230
274
  const renderInputToolbar = (props: typeof InputToolbarProps) => (
231
275
  <InputToolbar
232
276
  {...props}
233
277
  containerStyle={{
234
- padding: Platform.OS === 'ios' && isKeyboardShow ? 0 : 10
278
+ padding: Platform.OS === 'ios' && isKeyboardShow ? 0 : 10,
279
+ flexDirection: 'column-reverse'
235
280
  }}
236
281
  primaryStyle={{ alignItems: 'center', justifyContent: 'flex-start' }}
282
+ renderAccessory={() => renderAccessory()}
237
283
  />
238
284
  )
239
285
 
@@ -385,8 +431,9 @@ const MessagesUI = (props: MessagesParams) => {
385
431
  renderMessageImage={renderMessageImage}
386
432
  scrollToBottomComponent={() => renderScrollToBottomComponent()}
387
433
  messagesContainerStyle={{
388
- paddingVertical: 18,
434
+ paddingTop: 18,
389
435
  paddingHorizontal: 28,
436
+ paddingBottom: 55
390
437
  }}
391
438
  isLoadingEarlier={messages.loading}
392
439
  renderLoading={() => <ActivityIndicator size="small" color="#000" />}
@@ -412,7 +459,16 @@ const styles = StyleSheet.create({
412
459
  alignItems: 'center',
413
460
  justifyContent: 'center',
414
461
  marginHorizontal: 4
415
- }
462
+ },
463
+ editButton : {
464
+ borderRadius: 50,
465
+ backgroundColor: '#E9ECEF',
466
+ marginRight: 10,
467
+ height: 24,
468
+ borderWidth: 1,
469
+ paddingLeft: 0,
470
+ paddingRight: 0
471
+ }
416
472
  })
417
473
 
418
474
  export const Messages = (props: MessagesParams) => {
@@ -14,6 +14,6 @@ export const Header = styled.View`
14
14
  padding-horizontal: 20px;
15
15
  `
16
16
 
17
- export const TitleHeader = styled.View`
17
+ export const TitleHeader = styled.View``
18
18
 
19
- `
19
+ export const QuickMessageContainer = styled.ScrollView``
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from 'react';
1
+ import React, { useEffect, useRef } from 'react';
2
2
  import {
3
3
  ProductForm as ProductOptions,
4
4
  useSession,
@@ -120,13 +120,13 @@ export const ProductOptionsUI = (props: any) => {
120
120
  height: 258,
121
121
  },
122
122
  swiperButton: {
123
- marginHorizontal: 30,
123
+ marginHorizontal: 25,
124
124
  alignItems: 'center',
125
125
  justifyContent: 'center',
126
126
  width: 32,
127
127
  height: 32,
128
128
  borderRadius: 16,
129
- backgroundColor: 'rgba(255,255,255,0.3)'
129
+ backgroundColor: 'rgba(208,208,208,0.5)'
130
130
  }
131
131
  });
132
132
 
@@ -142,6 +142,8 @@ export const ProductOptionsUI = (props: any) => {
142
142
  const { height } = useWindowDimensions();
143
143
  const [selOpt, setSelectedOpt] = useState(0);
144
144
 
145
+ const swiperRef: any = useRef(null)
146
+
145
147
  const isError = (id: number) => {
146
148
  let bgColor = theme.colors.white;
147
149
  if (errors[`id:${id}`]) {
@@ -175,9 +177,17 @@ export const ProductOptionsUI = (props: any) => {
175
177
  };
176
178
 
177
179
  const handleChangeMainIndex = (index: number) => {
180
+ if (index < 0 || index > gallery.length - 1) {
181
+ setThumbsSwiper(0)
182
+ return
183
+ }
178
184
  setThumbsSwiper(index)
179
185
  }
180
186
 
187
+ const handleClickThumb = (index: number) => {
188
+ swiperRef?.current.scrollBy(index - thumbsSwiper, true);
189
+ }
190
+
181
191
  const handleRedirectLogin = () => {
182
192
  onClose();
183
193
  navigation.navigate('Login');
@@ -186,8 +196,10 @@ export const ProductOptionsUI = (props: any) => {
186
196
  useEffect(() => {
187
197
  const productImgList: any = []
188
198
  product?.images && productImgList.push(product.images)
189
- for (const img of product?.gallery) {
190
- productImgList.push(img.file)
199
+ if(product?.gallery && product?.gallery.length > 0) {
200
+ for (const img of product?.gallery) {
201
+ productImgList.push(img.file)
202
+ }
191
203
  }
192
204
  setGallery(productImgList)
193
205
  }, [product])
@@ -273,9 +285,10 @@ export const ProductOptionsUI = (props: any) => {
273
285
  <>
274
286
  <Swiper
275
287
  loop={false}
288
+ ref={swiperRef}
276
289
  showsButtons={true}
277
290
  style={styles.mainSwiper}
278
- // index={thumbsSwiper}
291
+ showsPagination={false}
279
292
  onIndexChanged={(index) => handleChangeMainIndex(index)}
280
293
  prevButton={
281
294
  <View style={styles.swiperButton}>
@@ -321,29 +334,32 @@ export const ProductOptionsUI = (props: any) => {
321
334
  }}
322
335
  >
323
336
  {gallery.length > 0 && gallery.map((img, index) => (
324
- <View
337
+ <TouchableOpacity
325
338
  key={index}
326
- style={{
327
- height: 56,
328
- borderRadius: 8,
329
- margin: 8,
330
- opacity: index === thumbsSwiper ? 1 : 0.8
331
- }}
339
+ onPress={() => handleClickThumb(index)}
332
340
  >
333
- <OIcon
334
- url={img}
341
+ <View
335
342
  style={{
336
- borderColor: theme.colors.lightGray,
343
+ height: 56,
337
344
  borderRadius: 8,
338
- minHeight: '100%'
345
+ margin: 8,
346
+ opacity: index === thumbsSwiper ? 1 : 0.8
339
347
  }}
340
- width={56}
341
- height={56}
342
- cover
343
- />
344
- {/* {thumbsSwiper === 2 && <OText color='red'>{index.toString()}</OText>}
345
- {thumbsSwiper === 3 && <OText color='red'>{index.toString()}</OText>} */}
346
- </View>
348
+ >
349
+ <OIcon
350
+ url={img}
351
+ style={{
352
+ borderColor: theme.colors.lightGray,
353
+ borderRadius: 8,
354
+ minHeight: '100%'
355
+ }}
356
+ width={56}
357
+ height={56}
358
+ cover
359
+ />
360
+ </View>
361
+ </TouchableOpacity>
362
+
347
363
  ))}
348
364
  </ScrollView>
349
365
  </>
@@ -45,6 +45,8 @@ import { OrderDetails } from './src/components/OrderDetails';
45
45
  import { OrdersOption } from './src/components/OrdersOption';
46
46
  import { OrderSummary } from './src/components/OrderSummary';
47
47
  import { OrderTypeSelector } from './src/components/OrderTypeSelector';
48
+ import { OrdersListing } from './src/components/OrdersListing';
49
+ import { OrderListOption } from './src/components/OrderListOption';
48
50
  import { PaymentOptionCash } from './src/components/PaymentOptionCash';
49
51
  import { PaymentOptions } from './src/components/PaymentOptions';
50
52
  import { PaymentOptionStripe } from './src/components/PaymentOptionStripe';
@@ -125,6 +127,8 @@ export {
125
127
  HelpOrder,
126
128
  HelpAccountAndPayment,
127
129
  OrderTypeSelector,
130
+ OrdersListing,
131
+ OrderListOption,
128
132
  Notifications,
129
133
  BottomWrapper,
130
134
  BusinessBasicInformation,
@@ -257,7 +257,7 @@ const AddressListUI = (props: AddressListParams) => {
257
257
  {!(
258
258
  route && (route?.params?.isFromBusinesses || route?.params?.isFromCheckout)
259
259
  ) && !isProfile && (
260
- <OText size={24}>
260
+ <OText size={20} style={{ marginTop: 20 }}>
261
261
  {t('WHERE_DELIVER_NOW', 'Where do we deliver you?')}
262
262
  </OText>
263
263
  )}
@@ -320,7 +320,7 @@ const styles = StyleSheet.create({
320
320
  position: 'absolute',
321
321
  },
322
322
  button: {
323
- marginTop: 30,
323
+ marginTop: 20,
324
324
  marginBottom: 0,
325
325
  borderRadius: 7.6,
326
326
  borderWidth: 1,
@@ -1,7 +1,7 @@
1
- import React from 'react';
1
+ import React, { useEffect, useState, useRef } from 'react';
2
2
  import { BusinessProductsCategories as ProductsCategories } from 'ordering-components/native';
3
3
  import { useTheme } from 'styled-components/native';
4
- import { ScrollView, StyleSheet, View } from 'react-native';
4
+ import { ScrollView, StyleSheet, View, Dimensions } from 'react-native';
5
5
  import { Tab } from './styles';
6
6
  import { OText } from '../shared';
7
7
  import { BusinessProductsCategoriesParams } from '../../types';
@@ -11,28 +11,79 @@ const BusinessProductsCategoriesUI = (props: any) => {
11
11
  const {
12
12
  featured,
13
13
  categories,
14
- handlerClickCategory,
15
14
  categorySelected,
16
15
  loading,
16
+ scrollViewRef,
17
+ productListLayout,
18
+ categoriesLayout,
19
+ selectedCategoryId,
20
+ setSelectedCategoryId,
21
+ handlerClickCategory,
22
+ lazyLoadProductsRecommended
17
23
  } = props;
18
24
 
19
25
  const theme = useTheme();
26
+ const windowWidth = Dimensions.get('window').width
27
+ const [tabLayouts, setTabLayouts] = useState<any>({})
28
+ const [scrollOffsetX, setScrollOffsetX] = useState<any>(0)
29
+ const tabsRef = useRef<any>(null)
30
+
20
31
  const styles = StyleSheet.create({
21
32
  container: {
22
- paddingVertical: 14,
33
+ paddingVertical: 5,
23
34
  borderColor: theme.colors.clear,
35
+ backgroundColor: '#FFF'
24
36
  },
25
37
  featuredStyle: {
26
38
  display: 'none',
27
39
  },
28
40
  });
29
41
 
42
+ const handleCategoryScroll = (category: any) => {
43
+ if (!lazyLoadProductsRecommended) {
44
+ if (category?.id || category.name === 'All') {
45
+ scrollViewRef.current.scrollTo({
46
+ y: categoriesLayout[`cat_${category?.id ?? category?.name}`]?.y + productListLayout?.y - 120,
47
+ animated: true
48
+ })
49
+ } else {
50
+ scrollViewRef.current.scrollTo({
51
+ y: productListLayout?.y - 120,
52
+ animated: true
53
+ })
54
+ }
55
+ } else {
56
+ handlerClickCategory(category)
57
+ }
58
+ }
59
+
60
+ const handleOnLayout = (event: any, categoryId: any) => {
61
+ const _tabLayouts = { ...tabLayouts }
62
+ const categoryKey = 'cat_' + categoryId
63
+ _tabLayouts[categoryKey] = event.nativeEvent.layout
64
+ setTabLayouts(_tabLayouts)
65
+ }
66
+
67
+ useEffect(() => {
68
+ if (!selectedCategoryId || Object.keys(tabLayouts).length === 0) return
69
+ tabsRef.current.scrollTo({
70
+ x: tabLayouts[selectedCategoryId]?.x - 40,
71
+ animated: true
72
+ })
73
+ }, [selectedCategoryId, tabLayouts])
74
+
75
+ const initialCategory = featured ? 0 : 1
76
+
30
77
  return (
31
78
  <ScrollView
79
+ ref={tabsRef}
32
80
  horizontal
33
81
  style={{ ...styles.container, borderBottomWidth: loading ? 0 : 1 }}
34
82
  contentContainerStyle={{ paddingHorizontal: 40 }}
35
- showsHorizontalScrollIndicator={false}>
83
+ showsHorizontalScrollIndicator={false}
84
+ onScroll={(e: any) => setScrollOffsetX(e.nativeEvent.contentOffset.x)}
85
+ scrollEventThrottle={16}
86
+ >
36
87
  {loading && (
37
88
  <Placeholder Animation={Fade}>
38
89
  <View style={{ flexDirection: 'row' }}>
@@ -45,26 +96,44 @@ const BusinessProductsCategoriesUI = (props: any) => {
45
96
  {!loading &&
46
97
  categories &&
47
98
  categories.length &&
48
- categories.map((category: any) => (
99
+ categories.map((category: any, i: number) => (
49
100
  <Tab
50
101
  key={category.name}
51
- onPress={() => handlerClickCategory(category)}
102
+ onPress={() => handleCategoryScroll(category)}
52
103
  style={[
53
104
  category.id === 'featured' && !featured && styles.featuredStyle,
54
105
  {
55
106
  borderColor:
56
- categorySelected?.id === category.id
57
- ? theme.colors.textNormal
58
- : theme.colors.border,
107
+ (!lazyLoadProductsRecommended
108
+ ? (selectedCategoryId === (`cat_${category.id}`) || (i === initialCategory && selectedCategoryId === null))
109
+ : (categorySelected?.id === category.id))
110
+ ? theme.colors.textNormal
111
+ : theme.colors.border,
59
112
  },
60
- ]}>
113
+ ]}
114
+ onLayout={(event: any) => handleOnLayout(event, category.id)}
115
+ >
61
116
  <OText
62
- size={categorySelected?.id === category.id ? 14 : 12}
63
- weight={categorySelected?.id === category.id ? '600' : '400'}
117
+ size={
118
+ (!lazyLoadProductsRecommended
119
+ ? (selectedCategoryId === (`cat_${category.id}`) || (i === initialCategory && selectedCategoryId === null))
120
+ : (categorySelected?.id === category.id))
121
+ ? 14
122
+ : 12
123
+ }
124
+ weight={
125
+ (!lazyLoadProductsRecommended
126
+ ? (selectedCategoryId === (`cat_${category.id}`) || (i === initialCategory && selectedCategoryId === null))
127
+ : (categorySelected?.id === category.id))
128
+ ? '600'
129
+ : '400'
130
+ }
64
131
  color={
65
- categorySelected?.id === category.id
66
- ? theme.colors.textNormal
67
- : theme.colors.textSecondary
132
+ (!lazyLoadProductsRecommended
133
+ ? (selectedCategoryId === (`cat_${category.id}`) || (i === initialCategory && selectedCategoryId === null))
134
+ : (categorySelected?.id === category.id))
135
+ ? theme.colors.textNormal
136
+ : theme.colors.textSecondary
68
137
  }
69
138
  style={{ alignSelf: 'center' }}>
70
139
  {category.name}
@@ -78,8 +147,12 @@ const BusinessProductsCategoriesUI = (props: any) => {
78
147
  export const BusinessProductsCategories = (
79
148
  props: BusinessProductsCategoriesParams,
80
149
  ) => {
150
+ const categoriesToSend = !props.lazyLoadProductsRecommended
151
+ ? props.categories.filter((category: any) => category.id)
152
+ : props.categories
81
153
  const businessProductsCategoriesProps = {
82
154
  ...props,
155
+ categories: categoriesToSend,
83
156
  UIComponent: BusinessProductsCategoriesUI,
84
157
  };
85
158
 
@@ -24,11 +24,20 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
24
24
  handleClearSearch,
25
25
  errorQuantityProducts,
26
26
  handleCancelSearch,
27
+ categoriesLayout,
28
+ setCategoriesLayout
27
29
  } = props;
28
30
 
29
31
  const [, t] = useLanguage();
30
32
  const [{ optimizeImage }] = useUtils()
31
33
 
34
+ const handleOnLayout = (event: any, categoryId: any) => {
35
+ const _categoriesLayout = { ...categoriesLayout }
36
+ const categoryKey = 'cat_' + categoryId
37
+ _categoriesLayout[categoryKey] = event.nativeEvent.layout
38
+ setCategoriesLayout(_categoriesLayout)
39
+ }
40
+
32
41
  return (
33
42
  <ProductsContainer>
34
43
  {category.id &&
@@ -45,16 +54,18 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
45
54
  {!category.id &&
46
55
  featured &&
47
56
  categoryState?.products?.find((product: any) => product.featured) && (
48
- <>
57
+ <View
58
+ onLayout={(event: any) => handleOnLayout(event, 'featured')}
59
+ >
49
60
  <OText size={16} weight={'600'} mBottom={15}>
50
61
  {t('FEATURED', 'Featured')}
51
62
  </OText>
52
63
  <>
53
64
  {categoryState.products?.map(
54
- (product: any) =>
65
+ (product: any, i: any) =>
55
66
  product.featured && (
56
67
  <SingleProductCard
57
- key={product.id}
68
+ key={i}
58
69
  isSoldOut={product.inventoried && !product.quantity}
59
70
  product={product}
60
71
  businessId={businessId}
@@ -63,7 +74,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
63
74
  ),
64
75
  )}
65
76
  </>
66
- </>
77
+ </View>
67
78
  )}
68
79
 
69
80
  {!category.id &&
@@ -79,7 +90,10 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
79
90
  <React.Fragment key={'cat_' + category.id}>
80
91
  {products.length > 0 && (
81
92
  <>
82
- <View style={bpStyles.catWrap}>
93
+ <View
94
+ style={bpStyles.catWrap}
95
+ onLayout={(event: any) => handleOnLayout(event, category?.id)}
96
+ >
83
97
  <View style={bpStyles.catIcon}>
84
98
  <OIcon
85
99
  url={optimizeImage(category.image, 'h_100,c_limit')}
@@ -88,14 +102,14 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
88
102
  style={{ borderRadius: 7.6 }}
89
103
  />
90
104
  </View>
91
- <OText size={16} weight={'600'}>
105
+ <OText size={16} weight="600">
92
106
  {category.name}
93
107
  </OText>
94
108
  </View>
95
109
  <>
96
- {products.map((product: any) => (
110
+ {products.map((product: any, i: any) => (
97
111
  <SingleProductCard
98
- key={product.id}
112
+ key={i}
99
113
  isSoldOut={product.inventoried && !product.quantity}
100
114
  businessId={businessId}
101
115
  product={product}
@@ -11,4 +11,4 @@ export const ErrorMessage = styled.View`
11
11
 
12
12
  export const WrapperNotFound = styled.View`
13
13
  height: 500px;
14
- `
14
+ `