ordering-ui-react-native 0.14.5 → 0.14.9

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.14.5",
3
+ "version": "0.14.9",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -34,7 +34,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
34
34
  return (
35
35
  <ProductsContainer>
36
36
  {category.id && (
37
- categoryState.products?.map((product: any) => (
37
+ categoryState.products?.sort((a: any, b: any) => a.rank - b.rank).map((product: any) => (
38
38
  <SingleProductCard
39
39
  key={product.id}
40
40
  isSoldOut={(product.inventoried && !product.quantity)}
@@ -51,7 +51,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
51
51
  <>
52
52
  <OText size={18} weight='bold' mBottom={10}>{t('FEATURED', 'Featured')}</OText>
53
53
  <>
54
- {categoryState.products?.map((product: any) => product.featured && (
54
+ {categoryState.products?.sort((a: any, b: any) => a.rank - b.rank).map((product: any) => product.featured && (
55
55
  <SingleProductCard
56
56
  key={product.id}
57
57
  isSoldOut={(product.inventoried && !product.quantity)}
@@ -77,7 +77,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
77
77
  <OText size={18} weight='bold' mBottom={10}>{category.name}</OText>
78
78
  <>
79
79
  {
80
- products.map((product: any) => (
80
+ products?.sort((a: any, b: any) => a.rank - b.rank).map((product: any) => (
81
81
  <SingleProductCard
82
82
  key={product.id}
83
83
  isSoldOut={product.inventoried && !product.quantity}
@@ -133,9 +133,8 @@ export const ProductOptionsUI = (props: any) => {
133
133
  <>
134
134
  <View style={{ flexDirection: 'column', width: '100%' }}>
135
135
  <OText size={20} style={{ flex: I18nManager.isRTL ? 0 : 1, marginBottom: 10 }}>{product?.name || productCart.name}</OText>
136
- <View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 10 }}>
137
- <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
138
- <OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={'#909BA9'}>
136
+ {(product?.estimated_person || (product?.sku && product?.sku !== '-1' && product?.sku !== '1')) && (
137
+ <OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0, marginBottom: 10 }} color={'#909BA9'}>
139
138
  {
140
139
  ((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (productCart?.sku && productCart?.sku !== '-1' && productCart?.sku !== '1'))
141
140
  && <>{t('SKU', 'Sku')}{' '}{product?.sku || productCart?.sku}</>
@@ -147,6 +146,12 @@ export const ProductOptionsUI = (props: any) => {
147
146
  && <>{product?.estimated_person}{' '}{t('ESTIMATED_PERSONS', 'persons')}</>
148
147
  }
149
148
  </OText>
149
+ )}
150
+ <View style={{ flexDirection: 'row', marginBottom: 10}}>
151
+ <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
152
+ {product?.offer_price && (
153
+ <OText style={styles.regularPriceStyle}>{parsePrice(product?.offer_price)}</OText>
154
+ )}
150
155
  </View>
151
156
  </View>
152
157
  </>
@@ -369,6 +374,13 @@ const styles = StyleSheet.create({
369
374
  resizeMode: 'cover',
370
375
  minHeight: 200,
371
376
  zIndex: 0
377
+ },
378
+ regularPriceStyle: {
379
+ fontSize: 14,
380
+ color: '#808080',
381
+ textDecorationLine: 'line-through',
382
+ marginLeft: 7,
383
+ marginRight: 7
372
384
  }
373
385
  })
374
386
 
@@ -4,7 +4,8 @@ import { SingleProductCardParams } from '../../types'
4
4
  import {
5
5
  CardContainer,
6
6
  CardInfo,
7
- SoldOut
7
+ SoldOut,
8
+ PricesContainer
8
9
  } from './styles'
9
10
  import { StyleSheet } from 'react-native'
10
11
  import { OText, OIcon } from '../shared'
@@ -40,6 +41,13 @@ export const SingleProductCard = (props: SingleProductCardParams) => {
40
41
  width: 75,
41
42
  height: 75,
42
43
  borderRadius: 10,
44
+ },
45
+ regularPriceStyle: {
46
+ fontSize: 12,
47
+ color: '#808080',
48
+ textDecorationLine: 'line-through',
49
+ marginLeft: 7,
50
+ marginRight: 7
43
51
  }
44
52
  })
45
53
 
@@ -76,7 +84,12 @@ export const SingleProductCard = (props: SingleProductCardParams) => {
76
84
  <CardInfo>
77
85
  <OText numberOfLines={1} ellipsizeMode='tail' style={styles.textStyle}>{product?.name}</OText>
78
86
  <OText size={12} numberOfLines={2} ellipsizeMode='tail' style={styles.textStyle}>{product?.description}</OText>
79
- <OText color={theme.colors.primary}>{parsePrice(product?.price)}</OText>
87
+ <PricesContainer>
88
+ <OText color={theme.colors.primary}>{parsePrice(product?.price)}</OText>
89
+ {product?.offer_price && (
90
+ <OText style={styles.regularPriceStyle}>{parsePrice(product?.offer_price)}</OText>
91
+ )}
92
+ </PricesContainer>
80
93
  </CardInfo>
81
94
 
82
95
  {(isSoldOut || maxProductQuantity <= 0) && (
@@ -22,3 +22,7 @@ export const SoldOut = styled.View`
22
22
  bottom: 5px;
23
23
  right: 5px;
24
24
  `
25
+ export const PricesContainer = styled.View`
26
+ flex-direction: row;
27
+ align-items: center;
28
+ `
@@ -196,7 +196,7 @@ export const VerifyPhone = (props: any) => {
196
196
  <WrappCountdown>
197
197
  <CountDownContainer color={timer === '00:00' ? theme.colors.error: theme.colors.success}>
198
198
  <OText
199
- size={28}
199
+ size={26}
200
200
  color={timer === '00:00' ? theme.colors.error: theme.colors.success}
201
201
  >
202
202
  {timer}
@@ -2,13 +2,13 @@ import styled from 'styled-components/native';
2
2
 
3
3
  export const Container = styled.View`
4
4
  width: 100%;
5
- padding: 0 30px;
5
+ padding: 0 43px;
6
6
  `
7
7
 
8
8
  export const CountDownContainer = styled.View`
9
9
  background-color: ${(props: any) => `${props.color}4D`};
10
10
  border-radius: 30px;
11
- padding: 5px 80px 0px;
11
+ padding: 5px 0px 0px;
12
12
  margin: 0 auto;
13
13
  display: flex;
14
14
  justify-content: center;
@@ -20,6 +20,7 @@ export const ResendSection = styled.View`
20
20
  display: flex;
21
21
  flex-direction: row;
22
22
  justify-content: center;
23
+ flex-wrap: wrap;
23
24
  `
24
25
 
25
26
  export const WrappCountdown = styled.View`
@@ -9,6 +9,7 @@ import { AppleLogin } from './src/components/AppleLogin';
9
9
  import { BusinessesListing } from './src/components/BusinessesListing';
10
10
  import { BusinessProductsListing } from './src/components/BusinessProductsListing';
11
11
  import { CartContent } from './src/components/CartContent';
12
+ import { BusinessCart } from './src/components/BusinessCart';
12
13
  import { Checkout } from './src/components/Checkout';
13
14
  import { ForgotPasswordForm } from './src/components/ForgotPasswordForm';
14
15
  import { MomentOption } from './src/components/MomentOption';
@@ -66,6 +67,7 @@ export {
66
67
  BusinessesListing,
67
68
  BusinessProductsListing,
68
69
  CartContent,
70
+ BusinessCart,
69
71
  Checkout,
70
72
  ForgotPasswordForm,
71
73
  MomentOption,
@@ -110,4 +112,4 @@ export {
110
112
  _setStoreData,
111
113
  _removeStoreData,
112
114
  _clearStoreData
113
- }
115
+ }
@@ -0,0 +1,182 @@
1
+ import React from 'react';
2
+ import { StyleSheet, TouchableOpacity, View, ActivityIndicator } from 'react-native';
3
+ import {
4
+ useUtils,
5
+ useLanguage,
6
+ useOrder
7
+ } from 'ordering-components/native'
8
+
9
+ import { useTheme } from 'styled-components/native';
10
+ import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
11
+ import { OIcon, OText } from '../shared';
12
+ import { convertHoursToMinutes } from '../../utils';
13
+
14
+ import {
15
+ Card,
16
+ BusinessContent,
17
+ BusinessInfo,
18
+ BusinessActions,
19
+ Metadata,
20
+ Reviews,
21
+ BtnWrapper
22
+ } from './styles'
23
+
24
+ export const BusinessCart = (props: any) => {
25
+ const {
26
+ business,
27
+ isLoading,
28
+ isDisabled,
29
+ isSkeleton,
30
+ handleCartStoreClick
31
+ } = props
32
+
33
+ const [, t] = useLanguage()
34
+ const theme = useTheme();
35
+ const [orderState] = useOrder()
36
+ const [{ parsePrice, parseDistance, parseNumber }] = useUtils();
37
+
38
+ const styles = StyleSheet.create({
39
+ starIcon: {
40
+ marginHorizontal: 2,
41
+ marginTop: -5,
42
+ },
43
+ bullet: {
44
+ flexDirection: 'row',
45
+ alignItems: 'center',
46
+ justifyContent: 'flex-start',
47
+ },
48
+ });
49
+
50
+ return (
51
+ <Card>
52
+ <BusinessContent>
53
+ <BusinessInfo>
54
+ {business?.name && (
55
+ <OText
56
+ size={12}
57
+ weight={'500'}>
58
+ {business?.name}
59
+ </OText>
60
+ )}
61
+ {isSkeleton && (
62
+ <Placeholder
63
+ Animation={Fade}
64
+ style={{ marginBottom: 5 }}
65
+ >
66
+ <PlaceholderLine
67
+ height={10}
68
+ width={40}
69
+ style={{ marginBottom: 5 }}
70
+ />
71
+ </Placeholder>
72
+ )}
73
+ {!!business?.address && (
74
+ <OText
75
+ size={10}
76
+ numberOfLines={1}
77
+ ellipsizeMode={'tail'}
78
+ style={{ marginBottom: 5 }}
79
+ >
80
+ {business?.address}
81
+ </OText>
82
+ )}
83
+ {isSkeleton && (
84
+ <Placeholder
85
+ Animation={Fade}
86
+ style={{ marginBottom: 5 }}
87
+ >
88
+ <PlaceholderLine
89
+ height={10}
90
+ width={80}
91
+ style={{ marginBottom: 5 }}
92
+ />
93
+ </Placeholder>
94
+ )}
95
+ <Metadata>
96
+ {!isSkeleton ? (
97
+ <View style={styles.bullet}>
98
+ <OText size={10} color={theme.colors.textSecondary}>
99
+ {`${t('DELIVERY_FEE', 'Delivery fee')} ${parsePrice(business?.delivery_price) + ' \u2022 '}`}
100
+ </OText>
101
+ <OText size={10} color={theme.colors.textSecondary}>{`${convertHoursToMinutes(
102
+ orderState?.options?.type === 1
103
+ ? business?.delivery_time
104
+ : business?.pickup_time,
105
+ )} \u2022 `}</OText>
106
+ <OText size={10} color={theme.colors.textSecondary}>{parseDistance(business?.distance)}</OText>
107
+ </View>
108
+ ) : (
109
+ <Placeholder
110
+ Animation={Fade}
111
+ style={{ marginBottom: 5 }}
112
+ >
113
+ <PlaceholderLine
114
+ height={10}
115
+ width={60}
116
+ style={{ marginBottom: 5 }}
117
+ />
118
+ </Placeholder>
119
+ )}
120
+ </Metadata>
121
+ </BusinessInfo>
122
+ <BusinessActions>
123
+ {business?.reviews?.total > 0 && (
124
+ <Reviews>
125
+ <OIcon src={theme.images.general.star} width={12} style={styles.starIcon} />
126
+ <OText size={10} style={{ lineHeight: 15 }}>
127
+ {parseNumber(business?.reviews?.total ?? 1, { separator: '.' })}
128
+ </OText>
129
+ </Reviews>
130
+ )}
131
+ <BtnWrapper>
132
+ {handleCartStoreClick && (
133
+ <TouchableOpacity
134
+ activeOpacity={1}
135
+ disabled={isDisabled}
136
+ onPress={() => handleCartStoreClick && handleCartStoreClick(business?.id)}
137
+ style={{
138
+ backgroundColor: isDisabled ? theme.colors.disabled : theme.colors.white,
139
+ borderColor: isDisabled ? theme.colors.disabled : theme.colors.primary,
140
+ justifyContent: 'center',
141
+ position: 'relative',
142
+ flexDirection: 'row',
143
+ alignItems: 'center',
144
+ paddingRight: 10,
145
+ paddingLeft: 10,
146
+ borderRadius: 7.6,
147
+ borderWidth: 1,
148
+ height: 30,
149
+ }}
150
+ >
151
+ <OText
152
+ style={{
153
+ color: isDisabled ? theme.colors.white : theme.colors.primary,
154
+ fontSize: 12,
155
+ }}
156
+ >
157
+ {isLoading ? (
158
+ <ActivityIndicator size="small" color={theme.colors.primary} />
159
+ ) : (
160
+ t('SELECT', 'Select')
161
+ )}
162
+ </OText>
163
+ </TouchableOpacity>
164
+ )}
165
+ {isSkeleton && (
166
+ <Placeholder
167
+ Animation={Fade}
168
+ style={{ marginBottom: 5 }}
169
+ >
170
+ <PlaceholderLine
171
+ height={30}
172
+ width={80}
173
+ style={{ marginBottom: 5 }}
174
+ />
175
+ </Placeholder>
176
+ )}
177
+ </BtnWrapper>
178
+ </BusinessActions>
179
+ </BusinessContent>
180
+ </Card>
181
+ )
182
+ }
@@ -0,0 +1,46 @@
1
+ import styled from 'styled-components/native';
2
+
3
+ export const Card = styled.View`
4
+ margin-bottom: 20px;
5
+ border-radius: 7.6px;
6
+ width: 100%;
7
+ position: relative;
8
+ `
9
+
10
+ export const BusinessContent = styled.View`
11
+ border-radius: 7.6px;
12
+ overflow: visible;
13
+ flex-direction: row;
14
+ justify-content: space-between;
15
+ width: 100%;
16
+ `;
17
+
18
+ export const BusinessInfo = styled.View`
19
+ width: 70%;
20
+ flex-direction: column;
21
+ justify-content: space-between;
22
+ align-items: flex-start;
23
+ `;
24
+
25
+ export const BusinessActions = styled.View`
26
+ width: 30%;
27
+ flex-direction: column;
28
+ align-items: flex-end;
29
+ `
30
+
31
+ export const Metadata = styled.View`
32
+ flex-direction: row;
33
+ `;
34
+
35
+ export const Reviews = styled.View`
36
+ flex-direction: row;
37
+ align-items: center;
38
+ margin-top: 5px;
39
+ `
40
+
41
+ export const BtnWrapper = styled.View`
42
+ display: flex;
43
+ flex-direction: row;
44
+ align-items: center;
45
+ justify-content: center;
46
+ `
@@ -84,6 +84,23 @@ export const BusinessItemAccordion = (props: any) => {
84
84
  <OText size={12} lineHeight={18} color={theme.colors.textSecondary} style={{ textDecorationLine: 'underline' }}>{t('CLEAR_CART', 'Clear cart')}</OText>
85
85
  </OAlert>
86
86
  )}
87
+ {props.handleChangeStore && (
88
+ <>
89
+ <OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
90
+ <TouchableOpacity
91
+ onPress={props.handleChangeStore}
92
+ >
93
+ <OText
94
+ size={12}
95
+ lineHeight={18}
96
+ color={theme.colors.textSecondary}
97
+ style={{ textDecorationLine: 'underline' }}
98
+ >
99
+ {t('CHANGE_STORE', 'Change store')}
100
+ </OText>
101
+ </TouchableOpacity>
102
+ </>
103
+ )}
87
104
  </View>
88
105
  </BIContentInfo>
89
106
  </BIInfo>
@@ -277,7 +277,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
277
277
  />
278
278
  </OrderProgressWrapper>
279
279
  )}
280
- {featuredBusiness && featuredBusiness.length > 0 && (
280
+ {!props.franchiseId && featuredBusiness && featuredBusiness.length > 0 && (
281
281
  <FeaturedWrapper>
282
282
  <OText size={16} style={{ marginLeft: 40 }} weight={Platform.OS === 'ios' ? '600' : 'bold'}>{t('FEATURED_BUSINESS', 'Featured business')}</OText>
283
283
  <ScrollView
@@ -306,7 +306,9 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
306
306
  </FeaturedWrapper>
307
307
  )}
308
308
  <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100 }} />
309
- <HighestRatedBusinesses onBusinessClick={handleBusinessClick} navigation={navigation} />
309
+ {!props.franchiseId && (
310
+ <HighestRatedBusinesses onBusinessClick={handleBusinessClick} navigation={navigation} />
311
+ )}
310
312
  <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100 }} />
311
313
  <ListWrapper>
312
314
  <BusinessTypeFilter
@@ -23,6 +23,7 @@ import { verifyDecimals } from '../../utils';
23
23
  import { ActivityIndicator, TouchableOpacity, View } from 'react-native';
24
24
  import AntIcon from 'react-native-vector-icons/AntDesign'
25
25
  import { TaxInformation } from '../TaxInformation';
26
+ import { CartStoresListing } from '../CartStoresListing';
26
27
 
27
28
  const CartUI = (props: any) => {
28
29
  const {
@@ -51,12 +52,16 @@ const CartUI = (props: any) => {
51
52
  const [openProduct, setModalIsOpen] = useState(false)
52
53
  const [curProduct, setCurProduct] = useState<any>(null)
53
54
  const [openUpselling, setOpenUpselling] = useState(false)
55
+ const [openChangeStore, setOpenChangeStore] = useState(false)
54
56
  const [canOpenUpselling, setCanOpenUpselling] = useState(false)
55
57
  const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null })
56
58
 
57
59
  const isCartPending = cart?.status === 2
58
60
  const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled
59
61
 
62
+ const business: any = (orderState?.carts && Object.values(orderState.carts).find((_cart: any) => _cart?.uuid === props.cartuuid)) ?? {}
63
+ const businessId = business?.business_id ?? null
64
+
60
65
  const momentFormatted = !orderState?.option?.moment
61
66
  ? t('RIGHT_NOW', 'Right Now')
62
67
  : parseDate(orderState?.option?.moment, { outputFormat: 'YYYY-MM-DD HH:mm' })
@@ -116,6 +121,7 @@ const CartUI = (props: any) => {
116
121
  handleClearProducts={handleClearProducts}
117
122
  handleCartOpen={handleCartOpen}
118
123
  onNavigationRedirect={props.onNavigationRedirect}
124
+ handleChangeStore={props.isFranchiseApp ? () => setOpenChangeStore(true) : null}
119
125
  >
120
126
  {cart?.products?.length > 0 && cart?.products.map((product: any) => (
121
127
  <ProductItemAccordion
@@ -217,7 +223,7 @@ const CartUI = (props: any) => {
217
223
  <OSTable>
218
224
  <OSCoupon>
219
225
  <CouponControl
220
- businessId={cart.business_id}
226
+ businessId={businessId}
221
227
  price={cart.total}
222
228
  />
223
229
  </OSCoupon>
@@ -299,20 +305,31 @@ const CartUI = (props: any) => {
299
305
  isCartProduct
300
306
  productCart={curProduct}
301
307
  businessSlug={cart?.business?.slug}
302
- businessId={cart?.business_id}
308
+ businessId={businessId}
303
309
  categoryId={curProduct?.category_id}
304
310
  productId={curProduct?.id}
305
311
  onSave={handlerProductAction}
306
312
  onClose={() => setModalIsOpen(false)}
307
313
  />
314
+ </OModal>
308
315
 
316
+ <OModal
317
+ open={openChangeStore && props.isFranchiseApp}
318
+ entireModal
319
+ customClose
320
+ onClose={() => setOpenChangeStore(false)}
321
+ >
322
+ <CartStoresListing
323
+ cartuuid={cart?.uuid}
324
+ onClose={() => setOpenChangeStore(false)}
325
+ />
309
326
  </OModal>
310
327
 
311
328
  {openUpselling && (
312
329
  <UpsellingProducts
313
330
  handleUpsellingPage={handleUpsellingPage}
314
331
  openUpselling={openUpselling}
315
- businessId={cart?.business_id}
332
+ businessId={businessId}
316
333
  business={cart?.business}
317
334
  cartProducts={cart?.products}
318
335
  canOpenUpselling={canOpenUpselling}
@@ -25,12 +25,14 @@ export const CartContent = (props: any) => {
25
25
  <OText size={24} lineHeight={36} weight={'600'} style={{ marginBottom: 20 }}>
26
26
  {carts.length > 1 ? t('MY_CARTS', 'My Carts') : t('CART', 'Cart')}
27
27
  </OText>
28
- {carts.map((cart: any) => (
29
- <CCList key={cart.uuid} style={{ overflow: 'visible' }}>
28
+ {carts.map((cart: any, i: number) => (
29
+ <CCList key={i} style={{ overflow: 'visible' }}>
30
30
  {cart.products.length > 0 && (
31
31
  <>
32
32
  <Cart
33
+ isFranchiseApp={props.isFranchiseApp}
33
34
  cart={cart}
35
+ cartuuid={cart.uuid}
34
36
  onNavigationRedirect={props.onNavigationRedirect}
35
37
  isCartsLoading={isCartsLoading}
36
38
  setIsCartsLoading={setIsCartsLoading}
@@ -0,0 +1,98 @@
1
+ import React from 'react';
2
+ import { useTheme } from 'styled-components/native';
3
+ import {
4
+ CartStoresListing as StoresListingController,
5
+ useOrder,
6
+ useLanguage
7
+ } from 'ordering-components/native'
8
+
9
+ import { NotFoundSource } from '../NotFoundSource'
10
+ import { BusinessCart } from '../BusinessCart'
11
+ import { OIcon } from '../shared';
12
+
13
+ import {
14
+ Container,
15
+ ItemListing,
16
+ TopHeader,
17
+ HeaderItem
18
+ } from './styles';
19
+
20
+ const CartStoresListingUI = (props: any) => {
21
+ const {
22
+ businessIdSelect,
23
+ storesState,
24
+ changeStoreState,
25
+ handleCartStoreChange,
26
+ } = props
27
+
28
+ const [, t] = useLanguage()
29
+ const theme = useTheme();
30
+ const [orderState] = useOrder()
31
+ const business: any = (orderState?.carts && Object.values(orderState.carts).find((_cart: any) => _cart?.uuid === props.cartuuid)) ?? {}
32
+ const businessId = business?.business_id ?? null
33
+
34
+ return(
35
+ <>
36
+ <TopHeader>
37
+ <HeaderItem
38
+ onPress={props.onClose}>
39
+ <OIcon src={theme.images.general.close} width={16} />
40
+ </HeaderItem>
41
+ </TopHeader>
42
+ <Container>
43
+ {!storesState?.loading && !storesState?.error && storesState?.result && (
44
+ <>
45
+ {storesState?.result?.length > 0 ? (
46
+ <ItemListing
47
+ horizontal={false}
48
+ >
49
+ {storesState?.result.map((store: any) => (
50
+ <BusinessCart
51
+ key={store.id}
52
+ business={store}
53
+ isLoading={changeStoreState.loading && businessIdSelect === store.id}
54
+ isDisabled={(changeStoreState?.result?.business_id ?? businessId) === store.id}
55
+ handleCartStoreClick={handleCartStoreChange}
56
+ />
57
+ ))}
58
+ </ItemListing>
59
+ ) : (
60
+ <NotFoundSource
61
+ content={t('NOT_FOUND_CART_STORES', 'No businesses to show at this time.')}
62
+ />
63
+ )}
64
+ </>
65
+ )}
66
+
67
+ {storesState?.loading && (
68
+ <ItemListing>
69
+ {[...Array(8).keys()].map(i => (
70
+ <BusinessCart
71
+ key={i}
72
+ business={{}}
73
+ isSkeleton
74
+ />
75
+ ))}
76
+ </ItemListing>
77
+ )}
78
+
79
+ {!storesState?.loading && storesState?.error && (
80
+ <NotFoundSource
81
+ content={t('ERROR_NOT_FOUND_CART_STORES', 'Sorry, an error has occurred')}
82
+ />
83
+ )}
84
+ </Container>
85
+ </>
86
+ )
87
+ }
88
+
89
+ export const CartStoresListing = (props: any) => {
90
+ const storeProps = {
91
+ ...props,
92
+ UIComponent: CartStoresListingUI
93
+ }
94
+
95
+ return (
96
+ <StoresListingController {...storeProps} />
97
+ )
98
+ }
@@ -0,0 +1,30 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const Container = styled.View`
4
+ display: flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ flex-direction: row;
8
+ width: 100%;
9
+ `
10
+
11
+ export const ItemListing = styled.ScrollView`
12
+ padding: 0 40px;
13
+ margin: 0 0 140px;
14
+ `
15
+
16
+ export const TopHeader = styled.View`
17
+ width: 100%;
18
+ flex-direction: row;
19
+ align-items: center;
20
+ justify-content: space-between;
21
+ z-index: 1;
22
+ padding: 0 40px;
23
+ `
24
+
25
+ export const HeaderItem = styled.TouchableOpacity`
26
+ overflow: hidden;
27
+ background-color: ${(props: any) => props.theme.colors.clear};
28
+ width: 35px;
29
+ margin: 18px 0;
30
+ `
@@ -16,7 +16,7 @@ import {
16
16
  ToastType,
17
17
  } from 'ordering-components/native';
18
18
  import { useTheme } from 'styled-components/native';
19
- import { OText, OIcon } from '../shared';
19
+ import { OText, OIcon, OModal } from '../shared';
20
20
 
21
21
  import { AddressDetails } from '../AddressDetails';
22
22
  import { PaymentOptions } from '../PaymentOptions';
@@ -46,6 +46,7 @@ import { Container } from '../../layouts/Container';
46
46
  import NavBar from '../NavBar';
47
47
  import { OrderSummary } from '../OrderSummary';
48
48
  import { getTypesText } from '../../utils';
49
+ import { CartStoresListing } from '../CartStoresListing';
49
50
 
50
51
  const mapConfigs = {
51
52
  mapZoom: 16,
@@ -71,6 +72,7 @@ const CheckoutUI = (props: any) => {
71
72
  errors,
72
73
  placing,
73
74
  cartState,
75
+ cartUuid,
74
76
  businessDetails,
75
77
  paymethodSelected,
76
78
  handlePaymethodChange,
@@ -120,6 +122,7 @@ const CheckoutUI = (props: any) => {
120
122
  const [userErrors, setUserErrors] = useState<any>([]);
121
123
  const [isUserDetailsEdit, setIsUserDetailsEdit] = useState(false);
122
124
  const [phoneUpdate, setPhoneUpdate] = useState(false);
125
+ const [openChangeStore, setOpenChangeStore] = useState(false)
123
126
  const [isDeliveryOptionModalVisible, setIsDeliveryOptionModalVisible] = useState(false)
124
127
 
125
128
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
@@ -433,7 +436,7 @@ const CheckoutUI = (props: any) => {
433
436
  location={businessDetails?.business?.location}
434
437
  businessLogo={businessDetails?.business?.logo}
435
438
  isCartPending={cart?.status === 2}
436
- businessId={cart?.business_id}
439
+ uuid={cartUuid}
437
440
  apiKey={configs?.google_maps_api_key?.value}
438
441
  mapConfigs={mapConfigs}
439
442
  />
@@ -456,6 +459,7 @@ const CheckoutUI = (props: any) => {
456
459
  {t('DRIVER_TIPS', 'Driver Tips')}
457
460
  </OText>
458
461
  <DriverTips
462
+ uuid={cartUuid}
459
463
  businessId={cart?.business_id}
460
464
  driverTipsOptions={driverTipsOptions}
461
465
  isFixedPrice={parseInt(configs?.driver_tip_type?.value, 10) === 1 || !!parseInt(configs?.driver_tip_use_custom?.value, 10)}
@@ -513,6 +517,21 @@ const CheckoutUI = (props: any) => {
513
517
  <OText size={16} lineHeight={24} color={theme.colors.textNormal}>
514
518
  {t('ORDER_SUMMARY', 'Order Summary')}
515
519
  </OText>
520
+ {props.isFranchiseApp && (
521
+ <TouchableOpacity
522
+ onPress={() => setOpenChangeStore(true)}
523
+ style={{alignSelf: 'flex-start'}}
524
+ >
525
+ <OText
526
+ size={12}
527
+ lineHeight={18}
528
+ color={theme.colors.textSecondary}
529
+ style={{ textDecorationLine: 'underline' }}
530
+ >
531
+ {t('CHANGE_STORE', 'Change store')}
532
+ </OText>
533
+ </TouchableOpacity>
534
+ )}
516
535
  <OrderSummary
517
536
  cart={cart}
518
537
  isCartPending={cart?.status === 2}
@@ -555,6 +574,17 @@ const CheckoutUI = (props: any) => {
555
574
  </ChErrors>
556
575
  </ChSection>
557
576
  )}
577
+ <OModal
578
+ open={openChangeStore && props.isFranchiseApp}
579
+ entireModal
580
+ customClose
581
+ onClose={() => setOpenChangeStore(false)}
582
+ >
583
+ <CartStoresListing
584
+ cartuuid={cart?.uuid}
585
+ onClose={() => setOpenChangeStore(false)}
586
+ />
587
+ </OModal>
558
588
  </ChContainer>
559
589
  </Container>
560
590
  {!cartState.loading && cart && cart?.status !== 2 && (
@@ -732,7 +762,7 @@ export const Checkout = (props: any) => {
732
762
  ...props,
733
763
  UIComponent: CheckoutUI,
734
764
  cartState,
735
- businessId: cartState.cart?.business_id
765
+ [props.isFranchiseApp ? 'uuid' : 'businessId']: props.isFranchiseApp ? cartUuid : cartState.cart?.business_id
736
766
  }
737
767
 
738
768
  return (
@@ -128,6 +128,7 @@ export interface BusinessesListingParams {
128
128
  images?: any;
129
129
  businessTypes?: any;
130
130
  defaultBusinessType?: any;
131
+ franchiseId?: any;
131
132
  }
132
133
  export interface HighestRatedBusinessesParams {
133
134
  businessesList: { businesses: Array<any>, loading: boolean, error: null | string };
@@ -472,4 +473,4 @@ export interface HelpAccountAndPaymentParams {
472
473
 
473
474
  export interface MessageListingParams {
474
475
  navigation: any;
475
- }
476
+ }
@@ -90,8 +90,9 @@ const MessagesUI = (props: MessagesParams) => {
90
90
  console.log('ImagePicker Error: ', response.errorMessage);
91
91
  showToast(ToastType.Error, response.errorMessage);
92
92
  } else {
93
- if (response.uri) {
94
- const url = `data:${response.type};base64,${response.base64}`
93
+ if (response?.assets?.length > 0) {
94
+ const image = response?.assets[0]
95
+ const url = `data:${image.type};base64,${image.base64}`
95
96
  setImage && setImage(url);
96
97
  } else {
97
98
  showToast(ToastType.Error, t('IMAGE_NOT_FOUND', 'Image not found'));
@@ -109,7 +110,7 @@ const MessagesUI = (props: MessagesParams) => {
109
110
  const messageConsole = (message: any) => {
110
111
  return message.change?.attribute !== 'driver_id'
111
112
  ?
112
- `${t('ORDER', 'Order')} ${message.change.attribute} ${t('CHANGED_FROM', 'Changed from')} ${message.change.old !== null && t(ORDER_STATUS[parseInt(message.change.old, 10)])} ${t('TO', 'to')} ${t(ORDER_STATUS[parseInt(message.change.new, 10)])}`
113
+ `${t('ORDER', 'Order')} ${t(message.change.attribute.toUpperCase(), message.change.attribute.replace('_', ' '))} ${t('CHANGED_FROM', 'Changed from')} ${message.change.old !== null && t(ORDER_STATUS[parseInt(message.change.old, 10)])} ${t('TO', 'to')} ${t(ORDER_STATUS[parseInt(message.change.new, 10)])}`
113
114
  : message.change.new
114
115
  ?
115
116
  `${message.driver?.name} ${message.driver?.lastname !== null ? message.driver.lastname : ''} ${t('WAS_ASSIGNED_AS_DRIVER', 'Was assigned as driver')} ${message.comment ? message.comment.length : ''}`
@@ -233,11 +234,11 @@ const MessagesUI = (props: MessagesParams) => {
233
234
  <InputToolbar
234
235
  {...props}
235
236
  containerStyle={{
236
- padding: Platform.OS === 'ios' && isKeyboardShow ? 0 : 10,
237
- flexDirection: 'column-reverse'
237
+ marginBottom: Platform.OS === 'ios' && isKeyboardShow ? 0 : 10,
238
+ flexDirection: Platform.OS === 'ios' && isKeyboardShow ? 'column' : 'column-reverse'
238
239
  }}
239
240
  primaryStyle={{ alignItems: 'center', justifyContent: 'flex-start' }}
240
- renderAccessory={() => renderAccessory()}
241
+ renderAccessory={() => !isKeyboardShow && renderAccessory()}
241
242
  />
242
243
  )
243
244
 
@@ -76,18 +76,18 @@ const OBottomPopup = (props: Props) => {
76
76
  visible={open}
77
77
  onRequestClose={() => onClose()}
78
78
  >
79
- <View style={styles.container}>
80
- <TouchableWithoutFeedback
81
- style={styles.touchableOutsideStyle}
82
- onPress={() => onClose()}
83
- >
84
- <View style={styles.touchableOutsideStyle} />
85
- </TouchableWithoutFeedback>
86
- <View style={styles.bottomContainer}>
87
- <KeyboardView
88
- enabled
89
- behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
79
+ <KeyboardView
80
+ enabled
81
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
82
+ >
83
+ <View style={styles.container}>
84
+ <TouchableWithoutFeedback
85
+ style={styles.touchableOutsideStyle}
86
+ onPress={() => onClose()}
90
87
  >
88
+ <View style={styles.touchableOutsideStyle} />
89
+ </TouchableWithoutFeedback>
90
+ <View style={styles.bottomContainer}>
91
91
  <ScrollView showsVerticalScrollIndicator={false} >
92
92
  {customHeaderShow ? (
93
93
  <View style={styles.customHeaderStyle}>
@@ -108,9 +108,9 @@ const OBottomPopup = (props: Props) => {
108
108
  )}
109
109
  {children}
110
110
  </ScrollView>
111
- </KeyboardView>
111
+ </View>
112
112
  </View>
113
- </View>
113
+ </KeyboardView>
114
114
  </Modal>
115
115
  )
116
116
  }