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 +1 -1
- package/src/navigators/HomeNavigator.tsx +6 -0
- package/src/pages/Sessions.tsx +22 -0
- package/themes/kiosk/src/components/BusinessMenu/index.tsx +15 -3
- package/themes/kiosk/src/components/Cart/index.tsx +1 -1
- package/themes/kiosk/src/components/NavBar/index.tsx +15 -6
- package/themes/kiosk/src/components/OrderDetails/index.tsx +30 -25
- package/themes/kiosk/src/components/PaymentOptions/index.tsx +1 -1
- package/themes/kiosk/src/components/ProductItemAccordion/index.tsx +2 -2
- package/themes/kiosk/src/components/ProductOption/index.tsx +1 -1
- package/themes/kiosk/src/components/ProductOptionSubOption/index.tsx +1 -1
- package/themes/original/index.tsx +2 -0
- package/themes/original/src/components/AddressForm/index.tsx +1 -1
- package/themes/original/src/components/AddressList/index.tsx +2 -2
- package/themes/original/src/components/Promotions/index.tsx +128 -128
- package/themes/original/src/components/Sessions/index.tsx +160 -0
- package/themes/original/src/components/Sessions/styles.tsx +15 -0
- package/themes/original/src/components/UpsellingProducts/index.tsx +2 -2
- package/themes/original/src/components/UserProfile/index.tsx +5 -0
- package/themes/original/src/components/UserProfileForm/index.tsx +1 -1
- package/themes/original/src/types/index.tsx +7 -0
package/package.json
CHANGED
|
@@ -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 {
|
|
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 [
|
|
61
|
+
const [orderState] = useOrder()
|
|
62
62
|
const [, t] = useLanguage();
|
|
63
|
-
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
-
<
|
|
409
|
-
{
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
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
|
-
<
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
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>
|
|
@@ -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}
|
|
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>
|
|
@@ -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
|
|
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
|
-
<
|
|
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
|
-
|
|
97
|
-
|
|
94
|
+
onActionLeft={() => navigation.goBack()}
|
|
95
|
+
showCall={false}
|
|
98
96
|
/>
|
|
99
|
-
<
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
97
|
+
<PromotionsContainer>
|
|
98
|
+
<SearchBarContainer>
|
|
99
|
+
<SearchBar
|
|
100
|
+
placeholder={t('SEARCH_OFFERS', 'Search offers')}
|
|
101
|
+
onSearch={handleSearchValue}
|
|
102
|
+
/>
|
|
103
|
+
</SearchBarContainer>
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
+
}
|