ordering-ui-react-native 0.15.78 → 0.15.81

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.15.78",
3
+ "version": "0.15.81",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -20,6 +20,7 @@ import Help from '../pages/Help'
20
20
  import HelpOrder from '../pages/HelpOrder'
21
21
  import HelpGuide from '../pages/HelpGuide'
22
22
  import HelpAccountAndPayment from '../pages/HelpAccountAndPayment'
23
+ import Sessions from '../pages/Sessions';
23
24
  import Splash from '../pages/Splash';
24
25
  import ProductDetails from '../pages/ProductDetails';
25
26
  const Stack = createStackNavigator();
@@ -164,6 +165,11 @@ const HomeNavigator = (e : any) => {
164
165
  component={HelpAccountAndPayment}
165
166
  options={{ headerShown: false }}
166
167
  />
168
+ <Stack.Screen
169
+ name="Sessions"
170
+ component={Sessions}
171
+ options={{ headerShown: false }}
172
+ />
167
173
  </>
168
174
  )}
169
175
  </>
@@ -0,0 +1,22 @@
1
+ import React from 'react'
2
+ import { Container } from '../../themes/original/src/layouts/Container'
3
+ import { Sessions as SessionsController } from '../../themes/original/src/components/Sessions'
4
+
5
+ interface Props {
6
+ navigation: any;
7
+ route: any;
8
+ }
9
+
10
+ const Sessions = (props: Props) => {
11
+ const sessionsProps = {
12
+ ...props
13
+ }
14
+
15
+ return (
16
+ <Container>
17
+ <SessionsController {...sessionsProps} />
18
+ </Container>
19
+ )
20
+ }
21
+
22
+ export default Sessions
@@ -40,7 +40,7 @@ const BusinessMenu = (props:any): React.ReactElement => {
40
40
  const clearCartWhenTimeOut = () => {
41
41
  if (cart?.uuid) clearCart(cart?.uuid)
42
42
  }
43
- const timerId = useRef(false);
43
+ const timerId: any = useRef(false);
44
44
 
45
45
  const clearInactivityTimeout = () =>{
46
46
  clearTimeout(timerId.current);
@@ -93,6 +93,17 @@ const BusinessMenu = (props:any): React.ReactElement => {
93
93
  else showCartBottomSheet();
94
94
  }
95
95
 
96
+ const handleRedirect = () => {
97
+ navigation.navigate('DeliveryType', {
98
+ callback: () => {
99
+ navigation.navigate('Business');
100
+ },
101
+ goBack: () => {
102
+ navigation.goBack();
103
+ },
104
+ });
105
+ };
106
+
96
107
  return (
97
108
  <View style={{
98
109
  flex: 1,
@@ -114,6 +125,7 @@ const BusinessMenu = (props:any): React.ReactElement => {
114
125
  title={t('MENU_V21', 'Menu')}
115
126
  onActionLeft={goToBack}
116
127
  includeOrderTypeSelector
128
+ onClickTypes={handleRedirect}
117
129
  rightComponent={cart && (
118
130
  <TouchableOpacity
119
131
  style={{ paddingHorizontal: 20, flexDirection: 'row', alignItems: 'center' }}
@@ -144,7 +156,7 @@ const BusinessMenu = (props:any): React.ReactElement => {
144
156
  </Container>
145
157
  </View>
146
158
 
147
- <View
159
+ {/* <View
148
160
  style={{
149
161
  flex: bottomSheetVisibility && orientationState?.orientation === PORTRAIT ? 0 : 0.8,
150
162
  display: bottomSheetVisibility ? 'flex' : 'none'
@@ -155,7 +167,7 @@ const BusinessMenu = (props:any): React.ReactElement => {
155
167
  resetInactivityTimeout={resetInactivityTimeout}
156
168
  clearInactivityTimeout={clearInactivityTimeout}
157
169
  />
158
- </View>
170
+ </View> */}
159
171
  </View>
160
172
  );
161
173
  };
@@ -281,7 +281,7 @@ const CartUI = (props: any) => {
281
281
  <OSRow>
282
282
  <OText>
283
283
  {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
284
- ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)} + `}{fee.percentage}%){' '}
284
+ ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)}${fee.percentage > 0 ? ' + ' : ''}`}{fee.percentage > 0 && `${fee.percentage}%`}){' '}
285
285
  </OText>
286
286
  </OSRow>
287
287
  <OText>{parsePrice(fee?.summary?.fixed + (fee?.summary?.percentage_after_discount ?? fee?.summary?.percentage) ?? 0)}</OText>
@@ -1,9 +1,8 @@
1
1
  import * as React from 'react'
2
2
  import styled from 'styled-components/native'
3
3
  import { OIcon, OButton, OText } from '../shared'
4
- import { ImageStyle, TextStyle, View, Platform } from 'react-native'
5
- import { OrderTypeSelector } from '../OrderTypeSelector'
6
- import { useConfig, useLanguage } from 'ordering-components/native'
4
+ import { ImageStyle, TextStyle, View, Platform, TouchableOpacity } from 'react-native'
5
+ import { useConfig, useLanguage, useOrder } from 'ordering-components/native'
7
6
  import { useTheme } from 'styled-components/native'
8
7
  const Wrapper = styled.View`
9
8
  background-color: ${(props: any) => props.theme.colors.white};
@@ -54,13 +53,15 @@ interface Props {
54
53
  paddingTop?: number,
55
54
  includeOrderTypeSelector?: boolean,
56
55
  imgLeftStyle?: ImageStyle
56
+ onClickTypes?: any
57
57
  }
58
58
 
59
59
  const NavBar = (props: Props) => {
60
60
  const theme = useTheme();
61
- const [{ configs }] = useConfig();
61
+ const [orderState] = useOrder()
62
62
  const [, t] = useLanguage();
63
- const configTypes = configs?.order_types_allowed?.value.split('|').map((value: any) => Number(value)) || [];
63
+
64
+ const selectedOrderType = orderState?.options?.type;
64
65
 
65
66
  return (
66
67
  <Wrapper style={{ paddingTop: props.paddingTop, ...props.style }}>
@@ -121,7 +122,15 @@ const NavBar = (props: Props) => {
121
122
  }}
122
123
  >
123
124
  <OText style={{ paddingRight: 5 }}>{t('THIS_ORDER_IS_TO', 'This order is to')}</OText>
124
- <OrderTypeSelector configTypes={configTypes} />
125
+ <TouchableOpacity
126
+ activeOpacity={1}
127
+ onPress={props.onClickTypes}
128
+ >
129
+ <OText color={theme.colors.primary}>
130
+ {selectedOrderType === 2 && t('TAKE_OUT', 'Take out')}
131
+ {selectedOrderType === 3 && t('EAT_IN', 'Eat in')}
132
+ </OText>
133
+ </TouchableOpacity>
125
134
  </View>
126
135
  )}
127
136
 
@@ -396,8 +396,13 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
396
396
  </OSTable>
397
397
 
398
398
  {order?.products?.length && (
399
- <OSTable>
400
- <View>
399
+ <>
400
+ <View
401
+ style={{
402
+ flexDirection: 'row',
403
+ justifyContent: 'space-between'
404
+ }}
405
+ >
401
406
  <OText
402
407
  weight="bold"
403
408
  mBottom={15}
@@ -405,29 +410,29 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
405
410
  {`${order?.products?.length} ${t('ITEMS', 'items')}`}
406
411
  </OText>
407
412
 
408
- <GridContainer style={{ maxWidth: orientationState?.dimensions?.width * 0.6 }}>
409
- {order?.products.map((product: Product, i: number) => (
410
- <OImage
411
- key={product?.id || i}
412
- source={{ uri: product?.images || '' }}
413
- resizeMode="cover"
414
- height={80}
415
- width={80}
416
- borderRadius={8}
417
- style={{ marginEnd: 10, marginBottom: 10 }}
418
- />
419
- ))}
420
- </GridContainer>
413
+ <OText
414
+ color={theme.colors.primary}
415
+ weight="bold"
416
+ >
417
+ {parsePrice((order?.summary?.total || order?.total) - (order?.summary?.discount || order?.discount))}
418
+ </OText>
421
419
  </View>
422
-
423
- <OText
424
- color={theme.colors.primary}
425
- weight="bold"
426
- mRight={30}
427
- >
428
- {parsePrice((order?.summary?.total || order?.total) - (order?.summary?.discount || order?.discount))}
429
- </OText>
430
- </OSTable>
420
+ <OSTable>
421
+ <GridContainer style={{ maxWidth: orientationState?.dimensions?.width * 0.6 }}>
422
+ {order?.products.map((product: Product, i: number) => (
423
+ <OImage
424
+ key={product?.id || i}
425
+ source={{ uri: product?.images || '' }}
426
+ resizeMode="cover"
427
+ height={80}
428
+ width={80}
429
+ borderRadius={8}
430
+ style={{ marginEnd: 10, marginBottom: 10 }}
431
+ />
432
+ ))}
433
+ </GridContainer>
434
+ </OSTable>
435
+ </>
431
436
  )}
432
437
 
433
438
  <OrderBill>
@@ -520,7 +525,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
520
525
  <OSRow>
521
526
  <OText>
522
527
  {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}
523
- ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)} + `}{fee.percentage}%){' '}
528
+ ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)}${fee.percentage > 0 ? ' + ' : ''}`}{fee.percentage > 0 && `${fee.percentage}%`}){' '}
524
529
  </OText>
525
530
  </OSRow>
526
531
  <OText>{parsePrice(fee?.summary?.fixed + (fee?.summary?.percentage_after_discount ?? fee?.summary?.percentage) ?? 0)}</OText>
@@ -189,7 +189,7 @@ const PaymentOptionsUI = (props: any) => {
189
189
 
190
190
  return (
191
191
  <>
192
- <Spinner visible={isLoading || placing} />
192
+ <Spinner visible={isLoading || placing || paymethodsList?.loading} />
193
193
 
194
194
  <Container nestedScrollEnabled>
195
195
  <NavBar
@@ -103,7 +103,7 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
103
103
 
104
104
  const getFormattedSubOptionName = ({ quantity, name, position, price }: { quantity: number, name: string, position: string, price: number }) => {
105
105
  const pos = position ? `(${position})` : ''
106
- return `${quantity} x ${name} ${pos} +${price}`
106
+ return `${quantity} x ${name} ${pos} ${price}`
107
107
  }
108
108
 
109
109
  /*useEffect(() => {
@@ -210,7 +210,7 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
210
210
  quantity: suboption.quantity,
211
211
  name: suboption.name,
212
212
  position: (suboption.position !== 'whole') ? t(suboption.position.toUpperCase(), suboption.position) : '',
213
- price: parsePrice(suboption.price)
213
+ price: suboption.price > 0 ? `+${parsePrice(suboption.price)}` : parsePrice(suboption.price)
214
214
  })}
215
215
  </OText>
216
216
  </ProductSubOption>
@@ -32,7 +32,7 @@ const ProductOptionUI = (props: any) => {
32
32
  <OText
33
33
  size={26}
34
34
  weight="bold"
35
- style={{ width: '80%' }}
35
+ style={{ maxWidth: '80%' }}
36
36
  >
37
37
  {option.name}
38
38
  </OText>
@@ -149,7 +149,7 @@ export const ProductOptionSubOptionUI = (props: any) => {
149
149
  size={16}
150
150
  weight="bold"
151
151
  >
152
- + {parsePrice(price)}
152
+ {price > 0 && '+'} {parsePrice(price)}
153
153
  </OText>
154
154
  </RightSide>
155
155
  </Container>
@@ -77,6 +77,7 @@ import { StripeCardsList } from './src/components/StripeCardsList';
77
77
  import { ProductIngredient } from './src/components/ProductIngredient';
78
78
  import { ProductOption } from './src/components/ProductOption';
79
79
  import { ProductOptionSubOption } from './src/components/ProductOptionSubOption';
80
+ import { Sessions } from './src/components/Sessions';
80
81
  import { SingleProductReview } from './src/components/SingleProductReview';
81
82
  import { LogoutButton } from './src/components/LogoutButton';
82
83
  import { UserFormDetailsUI } from './src/components/UserFormDetails';
@@ -227,6 +228,7 @@ export {
227
228
  ProductIngredient,
228
229
  ProductOption,
229
230
  ProductOptionSubOption,
231
+ Sessions,
230
232
  SingleProductReview,
231
233
  LogoutButton,
232
234
  UserFormDetailsUI,
@@ -510,7 +510,7 @@ const AddressFormUI = (props: AddressFormParams) => {
510
510
  onActionLeft={goToBack}
511
511
  showCall={false}
512
512
  btnStyle={{ paddingLeft: 0 }}
513
- style={{ flexDirection: 'column', alignItems: 'flex-start' }}
513
+ style={{ flexDirection: 'column', alignItems: 'flex-start', marginTop: Platform.OS === 'ios' ? 0 : 30 }}
514
514
  titleWrapStyle={{ paddingHorizontal: 0 }}
515
515
  titleStyle={{ marginRight: 0, marginLeft: 0 }}
516
516
  />
@@ -158,7 +158,7 @@ const AddressListUI = (props: AddressListParams) => {
158
158
  titleAlign={'center'}
159
159
  onActionLeft={goToBack}
160
160
  showCall={false}
161
- style={{ paddingHorizontal: 40, paddingVertical: Platform.OS === 'ios' ? 0 : 20 }}
161
+ style={{ paddingHorizontal: 40, paddingVertical: Platform.OS === 'ios' ? 0 : 20, marginTop: Platform.OS === 'ios' ? 0 : 30 }}
162
162
  />
163
163
  )}
164
164
  {(!addressList.loading || (isFromProductsList || isFromBusinesses || isFromProfile || isProfile)) && (
@@ -179,7 +179,7 @@ const AddressListUI = (props: AddressListParams) => {
179
179
  showCall={false}
180
180
  btnStyle={{ paddingLeft: 0 }}
181
181
  paddingTop={0}
182
- style={{ flexDirection: 'column', alignItems: 'flex-start' }}
182
+ style={{ flexDirection: 'column', alignItems: 'flex-start', marginTop: Platform.OS === 'ios' ? 0 : 40 }}
183
183
  titleWrapStyle={{ paddingHorizontal: 0 }}
184
184
  titleStyle={{ marginLeft: 0, marginRight: 0 }}
185
185
  />
@@ -1,5 +1,5 @@
1
1
  import React, { useState } from 'react'
2
- import { PromotionsController, useLanguage, useUtils, useEvent } from 'ordering-components/native'
2
+ import { PromotionsController, useLanguage, useUtils } from 'ordering-components/native'
3
3
  import {
4
4
  PromotionsContainer,
5
5
  SingleOfferContainer,
@@ -17,9 +17,11 @@ import { useTheme } from 'styled-components/native';
17
17
  import { OButton, OIcon, OModal, OText } from '../shared'
18
18
  import { Placeholder, PlaceholderLine } from 'rn-placeholder'
19
19
  import { NotFoundSource } from '../NotFoundSource'
20
- import { View, StyleSheet, ScrollView } from 'react-native'
20
+ import { View, StyleSheet, ScrollView, Platform } from 'react-native'
21
21
  import FastImage from 'react-native-fast-image'
22
22
  import { PromotionParams } from '../../types'
23
+ import { Container } from '../../layouts/Container'
24
+
23
25
  const PromotionsUI = (props: PromotionParams) => {
24
26
  const {
25
27
  navigation,
@@ -85,139 +87,137 @@ const PromotionsUI = (props: PromotionParams) => {
85
87
  : t('SERVICE_FEE', 'Service fee')
86
88
 
87
89
  return (
88
- <PromotionsContainer>
90
+ <Container noPadding>
89
91
  <NavBar
90
- onActionLeft={() => navigation.goBack()}
91
- btnStyle={{ paddingLeft: 0 }}
92
- paddingTop={20}
93
- style={{ paddingBottom: 0, flexDirection: 'column', alignItems: 'flex-start' }}
94
92
  title={t('PROMOTIONS', 'Promotions')}
95
93
  titleAlign={'center'}
96
- titleStyle={{ fontSize: 16, marginRight: 0, marginLeft: 0, marginBottom: 10 }}
97
- titleWrapStyle={{ paddingHorizontal: 0 }}
94
+ onActionLeft={() => navigation.goBack()}
95
+ showCall={false}
98
96
  />
99
- <SearchBarContainer>
100
- <SearchBar
101
- placeholder={t('SEARCH_OFFERS', 'Search offers')}
102
- onSearch={handleSearchValue}
103
- />
104
- </SearchBarContainer>
97
+ <PromotionsContainer>
98
+ <SearchBarContainer>
99
+ <SearchBar
100
+ placeholder={t('SEARCH_OFFERS', 'Search offers')}
101
+ onSearch={handleSearchValue}
102
+ />
103
+ </SearchBarContainer>
105
104
 
106
- {offersState?.loading && (
107
- <>
108
- {[...Array(5).keys()].map((key, i) => (
109
- <Placeholder key={i} style={{ flexDirection: 'row', marginBottom: 20 }}>
110
- <PlaceholderLine height={10} width={45} />
111
- <PlaceholderLine height={10} width={60} />
112
- <PlaceholderLine height={10} width={75} />
113
- </Placeholder>
114
- ))}
115
- </>
116
- )}
117
- {((!offersState?.loading && filteredOffers?.length === 0) || offersState?.error) && (
118
- <NotFoundSource
119
- content={offersState?.error || t('NOT_FOUND_OFFERS', 'Not found offers')}
120
- />
121
- )}
122
- <ScrollView>
123
- {!offersState?.loading && offersState.offers?.length > 0 && filteredOffers?.map((offer: any) => (
124
- <SingleOfferContainer key={offer.id}>
125
- <OfferInformation>
126
- <OText style={styles.offerTitle} numberOfLines={2}>{offer?.name}</OText>
127
- {offer?.description && (
128
- <OText style={styles.offerDescription} numberOfLines={2}>{offer?.description}</OText>
129
- )}
130
- <OText style={styles.offerExtraInfo}>
131
- {t('EXPIRES', 'Expires')} {parseDate(offer?.end, { outputFormat: 'MMM DD, YYYY' })}
132
- </OText>
133
- <AvailableBusinesses>
134
- <OText style={styles.offerExtraInfo} numberOfLines={1}>
135
- {t('APPLY_FOR', 'Apply for')}:
136
- {offer.businesses.map((business: any, i: number) => (
137
- <React.Fragment key={i}>{' '}{business?.name}{i + 1 < offer.businesses?.length ? ',' : ''}</React.Fragment>
138
- ))}
105
+ {offersState?.loading && (
106
+ <>
107
+ {[...Array(5).keys()].map((key, i) => (
108
+ <Placeholder key={i} style={{ flexDirection: 'row', marginBottom: 20 }}>
109
+ <PlaceholderLine height={10} width={45} />
110
+ <PlaceholderLine height={10} width={60} />
111
+ <PlaceholderLine height={10} width={75} />
112
+ </Placeholder>
113
+ ))}
114
+ </>
115
+ )}
116
+ {((!offersState?.loading && filteredOffers?.length === 0) || offersState?.error) && (
117
+ <NotFoundSource
118
+ content={offersState?.error || t('NOT_FOUND_OFFERS', 'Not found offers')}
119
+ />
120
+ )}
121
+ <ScrollView>
122
+ {!offersState?.loading && offersState.offers?.length > 0 && filteredOffers?.map((offer: any) => (
123
+ <SingleOfferContainer key={offer.id}>
124
+ <OfferInformation>
125
+ <OText style={styles.offerTitle} numberOfLines={2}>{offer?.name}</OText>
126
+ {offer?.description && (
127
+ <OText style={styles.offerDescription} numberOfLines={2}>{offer?.description}</OText>
128
+ )}
129
+ <OText style={styles.offerExtraInfo}>
130
+ {t('EXPIRES', 'Expires')} {parseDate(offer?.end, { outputFormat: 'MMM DD, YYYY' })}
139
131
  </OText>
140
- </AvailableBusinesses>
141
- </OfferInformation>
142
- <OButton
143
- onClick={() => handleClickOffer(offer)}
144
- text={t('VIEW', 'View')}
145
- style={styles.buttonStyle}
146
- textStyle={{ fontSize: 10, color: '#fff', flexWrap: 'nowrap' }}
147
- />
148
- </SingleOfferContainer>
149
- ))}
150
- </ScrollView>
151
- <OModal
152
- open={openModal}
153
- onClose={() => setOpenModal(false)}
154
- entireModal
132
+ <AvailableBusinesses>
133
+ <OText style={styles.offerExtraInfo} numberOfLines={1}>
134
+ {t('APPLY_FOR', 'Apply for')}:
135
+ {offer.businesses.map((business: any, i: number) => (
136
+ <React.Fragment key={i}>{' '}{business?.name}{i + 1 < offer.businesses?.length ? ',' : ''}</React.Fragment>
137
+ ))}
138
+ </OText>
139
+ </AvailableBusinesses>
140
+ </OfferInformation>
141
+ <OButton
142
+ onClick={() => handleClickOffer(offer)}
143
+ text={t('VIEW', 'View')}
144
+ style={styles.buttonStyle}
145
+ textStyle={{ fontSize: 10, color: '#fff', flexWrap: 'nowrap' }}
146
+ />
147
+ </SingleOfferContainer>
148
+ ))}
149
+ </ScrollView>
150
+ <OModal
151
+ open={openModal}
152
+ onClose={() => setOpenModal(false)}
153
+ entireModal
155
154
 
156
- title={``}
157
- >
158
- <View style={{ padding: 20 }}>
159
- <OText style={{ alignSelf: 'center', fontWeight: '700' }} mBottom={20}>
160
- {offerSelected?.name} / {t('VALUE_OF_OFFER', 'Value of offer')}: {offerSelected?.rate_type === 1 ? `${offerSelected?.rate}%` : `${parsePrice(offerSelected?.rate)}`}
161
- </OText>
162
- <OfferData>
163
- {offerSelected?.type === 2 && (
164
- <Code>
165
- <OText>{t('YOUR_CODE', 'Your code')}</OText>
166
- <OText color={theme.colors.primary}>{offerSelected.coupon}</OText>
167
- </Code>
168
- )}
169
- <OText>{t('APPLIES_TO', 'Applies to')}: {targetString}</OText>
170
- {offerSelected?.auto && (
171
- <OText>{t('OFFER_AUTOMATIC', 'This offer applies automatic')}</OText>
172
- )}
173
- {offerSelected?.minimum && (
174
- <OText>{t('MINIMUM_PURCHASE_FOR_OFFER', 'Minimum purchase for use this offer')}: {parsePrice(offerSelected?.minimum)}</OText>
175
- )}
176
- {offerSelected?.max_discount && (
177
- <OText>{t('MAX_DISCOUNT_ALLOWED', 'Max discount allowed')}: {parsePrice(offerSelected?.max_discount)}</OText>
178
- )}
179
- {offerSelected?.description && (
180
- <OText>{offerSelected?.description}</OText>
181
- )}
182
- </OfferData>
183
- <OText style={{ marginTop: 10, marginBottom: 10 }}>
184
- {t('AVAILABLE_BUSINESSES_FOR_OFFER', 'Available businesses for this offer')}:
185
- </OText>
186
- <ScrollView style={{ height: '75%' }}>
187
- {offerSelected?.businesses?.map((business: any) => {
188
- return (
189
- <SingleBusinessOffer key={business.id}>
190
- {business?.logo ? (
191
- <FastImage
192
- style={styles.productStyle}
193
- source={{
194
- uri: optimizeImage(business?.logo, 'h_250,c_limit'),
195
- priority: FastImage.priority.normal,
196
- }}
197
- resizeMode={FastImage.resizeMode.cover}
198
- />
199
- ) : (
200
- <OIcon
201
- src={theme?.images?.dummies?.product}
202
- style={styles.productStyle}
203
- />
204
- )}
205
- <BusinessInfo>
206
- <OText style={{ maxWidth: '60%' }}>{business.name}</OText>
207
- <OButton
208
- onClick={() => handleBusinessClick(business)}
209
- text={t('GO_TO_BUSINESSS', 'Go to business')}
210
- style={styles.modalButtonStyle}
211
- textStyle={{ fontSize: 10, color: '#fff' }}
212
- />
213
- </BusinessInfo>
214
- </SingleBusinessOffer>
215
- )
216
- })}
217
- </ScrollView>
218
- </View>
219
- </OModal>
220
- </PromotionsContainer>
155
+ title={``}
156
+ >
157
+ <View style={{ padding: 20 }}>
158
+ <OText style={{ alignSelf: 'center', fontWeight: '700' }} mBottom={20}>
159
+ {offerSelected?.name} / {t('VALUE_OF_OFFER', 'Value of offer')}: {offerSelected?.rate_type === 1 ? `${offerSelected?.rate}%` : `${parsePrice(offerSelected?.rate)}`}
160
+ </OText>
161
+ <OfferData>
162
+ {offerSelected?.type === 2 && (
163
+ <Code>
164
+ <OText>{t('YOUR_CODE', 'Your code')}</OText>
165
+ <OText color={theme.colors.primary}>{offerSelected.coupon}</OText>
166
+ </Code>
167
+ )}
168
+ <OText>{t('APPLIES_TO', 'Applies to')}: {targetString}</OText>
169
+ {offerSelected?.auto && (
170
+ <OText>{t('OFFER_AUTOMATIC', 'This offer applies automatic')}</OText>
171
+ )}
172
+ {offerSelected?.minimum && (
173
+ <OText>{t('MINIMUM_PURCHASE_FOR_OFFER', 'Minimum purchase for use this offer')}: {parsePrice(offerSelected?.minimum)}</OText>
174
+ )}
175
+ {offerSelected?.max_discount && (
176
+ <OText>{t('MAX_DISCOUNT_ALLOWED', 'Max discount allowed')}: {parsePrice(offerSelected?.max_discount)}</OText>
177
+ )}
178
+ {offerSelected?.description && (
179
+ <OText>{offerSelected?.description}</OText>
180
+ )}
181
+ </OfferData>
182
+ <OText style={{ marginTop: 10, marginBottom: 10 }}>
183
+ {t('AVAILABLE_BUSINESSES_FOR_OFFER', 'Available businesses for this offer')}:
184
+ </OText>
185
+ <ScrollView style={{ height: '75%' }}>
186
+ {offerSelected?.businesses?.map((business: any) => {
187
+ return (
188
+ <SingleBusinessOffer key={business.id}>
189
+ {business?.logo ? (
190
+ <FastImage
191
+ style={styles.productStyle}
192
+ source={{
193
+ uri: optimizeImage(business?.logo, 'h_250,c_limit'),
194
+ priority: FastImage.priority.normal,
195
+ }}
196
+ resizeMode={FastImage.resizeMode.cover}
197
+ />
198
+ ) : (
199
+ <OIcon
200
+ src={theme?.images?.dummies?.product}
201
+ style={styles.productStyle}
202
+ />
203
+ )}
204
+ <BusinessInfo>
205
+ <OText style={{ maxWidth: '60%' }}>{business.name}</OText>
206
+ <OButton
207
+ onClick={() => handleBusinessClick(business)}
208
+ text={t('GO_TO_BUSINESSS', 'Go to business')}
209
+ style={styles.modalButtonStyle}
210
+ textStyle={{ fontSize: 10, color: '#fff' }}
211
+ />
212
+ </BusinessInfo>
213
+ </SingleBusinessOffer>
214
+ )
215
+ })}
216
+ </ScrollView>
217
+ </View>
218
+ </OModal>
219
+ </PromotionsContainer>
220
+ </Container>
221
221
  )
222
222
  }
223
223
 
@@ -0,0 +1,160 @@
1
+ import React, { useState } from 'react'
2
+ import { View, TouchableOpacity } from 'react-native'
3
+ import { useLanguage, useSession, useUtils, Sessions as SessionsController } from 'ordering-components/native'
4
+ import NavBar from '../NavBar'
5
+ import { SessionsParams } from '../../types'
6
+ import { OAlert } from '../../../../../src/components/shared'
7
+ import { OButton, OIcon, OText } from '../shared'
8
+ import { useTheme } from 'styled-components/native'
9
+ import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder'
10
+ import AntIcon from 'react-native-vector-icons/AntDesign'
11
+
12
+ import {
13
+ SessionsWrapper,
14
+ SessionItem,
15
+ DurationWrapper
16
+ } from './styles'
17
+
18
+ export const SessionsUI = (props: SessionsParams) => {
19
+ const {
20
+ navigation,
21
+ sessionsList,
22
+ actionState,
23
+ handleDeleteSession,
24
+ handleDeleteAllSessions
25
+ } = props
26
+
27
+ const [, t] = useLanguage()
28
+ const [{ user }] = useSession()
29
+ const [{ parseDate }] = useUtils()
30
+ const theme = useTheme()
31
+ const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
32
+ const goToBack = () => navigation?.canGoBack() && navigation.goBack()
33
+
34
+ const onDeleteSession = (session: any) => {
35
+ setConfirm({
36
+ open: true,
37
+ title: t('WEB_APPNAME', 'Ordering'),
38
+ content: [t('QUESTION_DELETE_SESSION', 'Are you sure to delete this session?')],
39
+ handleOnAccept: () => {
40
+ handleDeleteSession(session)
41
+ setConfirm({ ...confirm, open: false })
42
+ }
43
+ })
44
+ }
45
+
46
+ const onDeleteAllSessions = (isOldUser: any, deleteCurrent: any) => {
47
+ setConfirm({
48
+ open: true,
49
+ title: t('WEB_APPNAME', 'Ordering'),
50
+ content:
51
+ isOldUser
52
+ ? [t('QUESTION_ENABLE_ALL_SESSIONS', 'Are you sure to enable all sessions?')]
53
+ : deleteCurrent
54
+ ? [t('QUESTION_DELETE_ALL_SESSIONS', 'Are you sure that you want to delete all sessions?')]
55
+ : [t('QUESTION_DELETE_ALL_SESSIONS_EXCEPT_CURRENT', 'Are you sure that you want to delete all sessions except current?')],
56
+ handleOnAccept: () => {
57
+ handleDeleteAllSessions(deleteCurrent)
58
+ setConfirm({ ...confirm, open: false })
59
+ }
60
+ })
61
+ }
62
+
63
+ return (
64
+ <>
65
+ <NavBar
66
+ title={t('SESSIONS', 'Sessions')}
67
+ titleAlign={'center'}
68
+ onActionLeft={goToBack}
69
+ showCall={false}
70
+ paddingTop={10}
71
+ btnStyle={{ paddingLeft: 0 }}
72
+ />
73
+ {user?.session_strategy === 'jwt_session' ? (
74
+ <>
75
+ {sessionsList.loading ? (
76
+ [...Array(5).keys()].map(i => (
77
+ <SessionItem key={i}>
78
+ <Placeholder Animation={Fade}>
79
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
80
+ <View style={{ flex: 1}}>
81
+ <PlaceholderLine width={40} />
82
+ <PlaceholderLine width={40} />
83
+ </View>
84
+ <PlaceholderLine width={5}/>
85
+ </View>
86
+ </Placeholder>
87
+ </SessionItem>
88
+ ))
89
+ ) : (
90
+ sessionsList.sessions.length > 0 ? (
91
+ <SessionsWrapper>
92
+ {sessionsList.sessions.map((session: any) => (
93
+ <SessionItem key={session.id}>
94
+ <DurationWrapper>
95
+ <OText>{parseDate(session.created_at)}</OText>
96
+ <OText>{parseDate(session.valid_thru)}</OText>
97
+ </DurationWrapper>
98
+ {session.current && (
99
+ <OText mLeft={15} style={{ flex: 1 }}>({t('CURRENT', 'Current')})</OText>
100
+ )}
101
+ <TouchableOpacity
102
+ onPress={() => onDeleteSession(session)}
103
+ >
104
+ <AntIcon name='close' size={16} color={theme.colors.red} />
105
+ </TouchableOpacity>
106
+ </SessionItem>
107
+ ))}
108
+ <OButton
109
+ text={t('DELETE_ALL_SESSIONS', 'Delete all sessions')}
110
+ isDisabled={actionState.loading}
111
+ textStyle={{ color: theme.colors.white, fontSize: 14 }}
112
+ onClick={() => onDeleteAllSessions(false, true)}
113
+ style={{ borderRadius: 7.6, marginTop: 30 }}
114
+ />
115
+ <OButton
116
+ text={t('DELETE_ALL_SESSIONS_EXCEPT_CURRENT', 'Delete all sessions except current')}
117
+ isDisabled={actionState.loading}
118
+ textStyle={{ color: theme.colors.white, fontSize: 14 }}
119
+ onClick={() => onDeleteAllSessions(false, false)}
120
+ style={{ borderRadius: 7.6, marginTop: 20 }}
121
+ />
122
+ </SessionsWrapper>
123
+ ) : (
124
+ <OText>{t('YOU_DONT_HAVE_ANY_SESSIONS', 'You don\'t have any sessions')}</OText>
125
+ )
126
+ )}
127
+ </>
128
+ ) : (
129
+ <View>
130
+ <OText>
131
+ {t('YOU_DONT_HAVE_ENABLED_THE_SESSIONS', 'You don\'t have enabled the sessions, please active them to have a better control of your sessions.')}
132
+ </OText>
133
+ <OButton
134
+ text={t('ACTIVE_SESSIONS', 'Active sessions')}
135
+ isDisabled={actionState.loading}
136
+ textStyle={{ color: theme.colors.white, fontSize: 14 }}
137
+ onClick={() => onDeleteAllSessions(true, false)}
138
+ style={{ borderRadius: 7.6, marginTop: 20 }}
139
+ />
140
+ </View>
141
+ )}
142
+ <OAlert
143
+ open={confirm.open}
144
+ title={confirm.title}
145
+ content={confirm.content}
146
+ onAccept={confirm.handleOnAccept}
147
+ onCancel={() => setConfirm({ ...confirm, open: false, title: null })}
148
+ onClose={() => setConfirm({ ...confirm, open: false, title: null })}
149
+ />
150
+ </>
151
+ )
152
+ }
153
+
154
+ export const Sessions = (props: SessionsParams) => {
155
+ const sessionsProps = {
156
+ ...props,
157
+ UIComponent: SessionsUI
158
+ }
159
+ return <SessionsController {...sessionsProps} />
160
+ }
@@ -0,0 +1,15 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const SessionsWrapper = styled.View`
4
+ `
5
+ export const SessionItem = styled.View`
6
+ flex-direction: row;
7
+ align-items: center;
8
+ justify-content: space-between;
9
+ padding-vertical: 15px;
10
+ border-bottom-color: ${(props: any) => props.theme.colors.lightGray};
11
+ border-bottom-width: 1px;
12
+ `
13
+ export const DurationWrapper = styled.View`
14
+ /* flex-direction: row; */
15
+ `
@@ -163,7 +163,7 @@ const UpsellingProductsUI = (props: UpsellingProductsParams) => {
163
163
  const UpsellingContent = () => {
164
164
  return (
165
165
  <>
166
- <View style={{ ...styles.headerItem, flex: 1 }}>
166
+ <View style={{ ...styles.headerItem, flex: 1, marginTop: Platform.OS == 'ios' ? 35 : 70 }}>
167
167
  <OButton
168
168
  imgLeftSrc={theme.images.general.arrow_left}
169
169
  imgRightSrc={null}
@@ -172,7 +172,7 @@ const UpsellingProductsUI = (props: UpsellingProductsParams) => {
172
172
  imgLeftStyle={{ tintColor: theme.colors.textNormal, width: 16 }}
173
173
  />
174
174
  </View>
175
- <ScrollView style={{ marginBottom: props.isPage ? 40 : bottom + (Platform.OS == 'ios' ? 96 : 130) }} showsVerticalScrollIndicator={false}>
175
+ <ScrollView style={{ marginTop: 10, marginBottom: props.isPage ? 40 : bottom + (Platform.OS == 'ios' ? 96 : 130) }} showsVerticalScrollIndicator={false}>
176
176
  {productsList.length > 0 &&
177
177
  <View style={{ paddingHorizontal: 40, overflow: 'visible' }}>
178
178
  <OText size={16} lineHeight={24} weight={'500'}>{t('WANT_SOMETHING_ELSE', 'Do you want something else?')}</OText>
@@ -17,6 +17,7 @@ import { LanguageSelector } from '../LanguageSelector'
17
17
  import MessageCircle from 'react-native-vector-icons/AntDesign'
18
18
  import Ionicons from 'react-native-vector-icons/Ionicons'
19
19
  import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
20
+ import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
20
21
  import FastImage from 'react-native-fast-image'
21
22
  import { OAlert } from '../../../../../src/components/shared'
22
23
 
@@ -214,6 +215,10 @@ const ProfileListUI = (props: ProfileParams) => {
214
215
  <OIcon src={theme.images.general.ic_help} width={16} color={theme.colors.textNormal} style={{ marginEnd: 14 }} />
215
216
  <OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('HELP', 'Help')}</OText>
216
217
  </ListItem>
218
+ <ListItem onPress={() => navigation.navigate('Sessions')} activeOpacity={0.7}>
219
+ <Ionicons name='md-list-outline' style={styles.messageIconStyle} color={theme.colors.textNormal} />
220
+ <OText size={14} lineHeight={24} weight={'400'} color={theme.colors.textNormal}>{t('SESSIONS', 'Sessions')}</OText>
221
+ </ListItem>
217
222
  </Actions>
218
223
 
219
224
  <Actions>
@@ -283,7 +283,7 @@ const ProfileUI = (props: ProfileParams) => {
283
283
  titleAlign={'center'}
284
284
  onActionLeft={() => navigation.goBack()}
285
285
  showCall={false}
286
- style={{ paddingHorizontal: 40, paddingVertical: Platform.OS === 'ios' ? 0 : 30 }}
286
+ style={{ paddingHorizontal: 40, paddingVertical: Platform.OS === 'ios' ? 0 : 30 , marginTop: Platform.OS === 'ios' ? 50 : 40 }}
287
287
  />
288
288
  <KeyboardAvoidingView behavior={Platform.OS == 'ios' ? 'padding' : 'height'} enabled style={{ flex: 1, flexDirection: 'column', justifyContent: 'center' }}>
289
289
  <Container noPadding>
@@ -591,3 +591,10 @@ export interface PromotionParams {
591
591
  offerSelected: any,
592
592
  setOfferSelected: any,
593
593
  }
594
+ export interface SessionsParams {
595
+ navigation: any,
596
+ sessionsList: any,
597
+ actionState: any,
598
+ handleDeleteSession: any,
599
+ handleDeleteAllSessions: any
600
+ }