ordering-ui-react-native 0.21.49 → 0.21.50

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.21.49",
3
+ "version": "0.21.50",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -47,10 +47,10 @@ export const getTraduction = (key: string, t: any) => {
47
47
  */
48
48
  export const convertHoursToMinutes = (time: any) => {
49
49
  const [, t] = useLanguage()
50
- if (!time) return '0min'
50
+ if (!time) return `0 ${t('TIME_MIN', 'min')}`
51
51
  const [hour, minute] = time.split(':')
52
52
  const result = (parseInt(hour, 10) * 60) + parseInt(minute, 10)
53
- return `${result}${t('MIN', 'min')}`
53
+ return `${result}${t('TIME_MIN', 'min')}`
54
54
  }
55
55
 
56
56
  export const getIconCard = (brand: string, size: number) => {
@@ -1,6 +1,7 @@
1
1
  //Components
2
2
  import { AcceptOrRejectOrder } from './src/components/AcceptOrRejectOrder';
3
3
  import { BusinessController } from './src/components/BusinessController';
4
+ import { BusinessProductList } from './src/components/BusinessProductList';
4
5
  import { Chat } from './src/components/Chat';
5
6
  import { FloatingButton } from './src/components/FloatingButton';
6
7
  import { ForgotPasswordForm } from './src/components/ForgotPasswordForm';
@@ -70,6 +71,7 @@ export {
70
71
  //Components
71
72
  AcceptOrRejectOrder,
72
73
  BusinessController,
74
+ BusinessProductList,
73
75
  Chat,
74
76
  DriverMap,
75
77
  FloatingButton,
@@ -0,0 +1,63 @@
1
+ import { OText } from "../shared"
2
+ import React, { useState } from "react"
3
+ import { View } from "react-native"
4
+ import { TouchableOpacity } from "react-native-gesture-handler"
5
+ import AntDesignIcon from 'react-native-vector-icons/AntDesign'
6
+ import ToggleSwitch from 'toggle-switch-react-native';
7
+ import { useTheme } from 'styled-components/native';
8
+ import { CategoryTab } from './styles'
9
+
10
+ export const AccordionDropdown = (props: any) => {
11
+ const { category, IterateCategories, handlerClickCategory, updateCategory } = props
12
+
13
+ const theme = useTheme();
14
+ const [isOpen, setIsOpen] = useState(false)
15
+
16
+ const handleSwitch = (enabled: boolean, categoryId: any) => {
17
+ updateCategory && updateCategory(categoryId, { enabled })
18
+ };
19
+
20
+ return (
21
+ <View style={{ marginLeft: !!category?.parent_category_id ? 10 : 0 }}>
22
+ <CategoryTab>
23
+ <View style={{ flexDirection: 'row', alignItems: 'center', flex: 1, marginRight: 5 }}>
24
+ <TouchableOpacity onPress={() => setIsOpen(prev => !prev)} style={{ marginRight: 10 }}>
25
+ <AntDesignIcon
26
+ name={isOpen ? 'caretdown' : 'caretright'}
27
+ size={14}
28
+ />
29
+ </TouchableOpacity>
30
+ <TouchableOpacity onPress={() => handlerClickCategory(category)} style={{ flex: 1 }}>
31
+ <OText numberOfLines={1}>
32
+ {category.name}
33
+ </OText>
34
+ </TouchableOpacity>
35
+ </View>
36
+ <View>
37
+ <ToggleSwitch
38
+ isOn={category?.enabled}
39
+ onColor={theme.colors.primary}
40
+ offColor={theme.colors.offColor}
41
+ size="small"
42
+ onToggle={(value: boolean) => handleSwitch(value, category.id)}
43
+ // disabled={loading}
44
+ animationSpeed={200}
45
+ />
46
+ </View>
47
+ </CategoryTab>
48
+ {
49
+ isOpen && (
50
+ <View>
51
+ <IterateCategories
52
+ list={category.subcategories}
53
+ isSub
54
+ currentCat={category}
55
+ handlerClickCategory={handlerClickCategory}
56
+ updateCategory={updateCategory}
57
+ />
58
+ </View>
59
+ )
60
+ }
61
+ </View>
62
+ )
63
+ }
@@ -0,0 +1,108 @@
1
+ import React from "react"
2
+ import { View, TouchableOpacity } from "react-native"
3
+ import { OText } from "../shared"
4
+ import ToggleSwitch from 'toggle-switch-react-native';
5
+ import { AccordionDropdown } from './AccordionDropdown'
6
+ import { useTheme } from 'styled-components/native';
7
+ import { CategoryTab } from './styles'
8
+
9
+ export const IterateCategories = (props: any) => {
10
+ const { list, currentCat, isSub, handlerClickCategory, updateCategory } = props
11
+
12
+ const theme = useTheme();
13
+
14
+ const handleSwitch = (enabled: boolean, categoryId: any) => {
15
+ updateCategory && updateCategory(categoryId, { enabled })
16
+ };
17
+
18
+ return (
19
+ <>
20
+ {list?.length > 0 && list.map((category: any, i: number) => (
21
+ <View key={`${category?.id}_${i}`}>
22
+ {(category?.subcategories?.length > 0 || isSub) ? (
23
+ <>
24
+ {category?.subcategories?.length > 0 && (
25
+ <>
26
+ <View>
27
+ <AccordionDropdown
28
+ category={category}
29
+ IterateCategories={IterateCategories}
30
+ handlerClickCategory={handlerClickCategory}
31
+ updateCategory={updateCategory}
32
+ />
33
+ </View>
34
+ </>
35
+ )}
36
+ {isSub && !category?.subcategories?.length && (
37
+ <CategoryTab isSpace={!!category?.parent_category_id}>
38
+ <TouchableOpacity
39
+ style={{ flex: 1, marginRight: 5 }}
40
+ onPress={() => handlerClickCategory(category)}
41
+ >
42
+ <OText numberOfLines={1}>
43
+ {category.name}
44
+ </OText>
45
+ </TouchableOpacity>
46
+ <View>
47
+ <ToggleSwitch
48
+ isOn={category?.enabled}
49
+ onColor={theme.colors.primary}
50
+ offColor={theme.colors.offColor}
51
+ size="small"
52
+ onToggle={(value: boolean) => handleSwitch(value, category.id)}
53
+ // disabled={loading}
54
+ animationSpeed={200}
55
+ />
56
+ </View>
57
+ </CategoryTab>
58
+ )}
59
+ </>
60
+ ) : (
61
+ <CategoryTab
62
+ isSpace={!!category?.parent_category_id}
63
+ >
64
+ <TouchableOpacity onPress={() => handlerClickCategory(category)} style={{ flex: 1, marginRight: 5 }}>
65
+ <OText numberOfLines={1}>
66
+ {category.name}
67
+ </OText>
68
+ </TouchableOpacity>
69
+ <View>
70
+ <ToggleSwitch
71
+ isOn={category?.enabled}
72
+ onColor={theme.colors.primary}
73
+ offColor={theme.colors.offColor}
74
+ size="small"
75
+ onToggle={(value: boolean) => handleSwitch(value, category.id)}
76
+ // disabled={loading}
77
+ animationSpeed={200}
78
+ />
79
+ </View>
80
+ </CategoryTab>
81
+ )}
82
+ </View>
83
+ ))}
84
+ {list && list?.length === 0 && isSub && (
85
+ <CategoryTab
86
+ isSpace={!!currentCat?.parent_category_id}
87
+ >
88
+ <TouchableOpacity onPress={() => handlerClickCategory(currentCat)} style={{ flex: 1, marginRight: 5 }}>
89
+ <OText numberOfLines={1}>
90
+ {currentCat.name}
91
+ </OText>
92
+ </TouchableOpacity>
93
+ <View>
94
+ <ToggleSwitch
95
+ isOn={currentCat?.enabled}
96
+ onColor={theme.colors.primary}
97
+ offColor={theme.colors.offColor}
98
+ size="small"
99
+ onToggle={(value: boolean) => handleSwitch(value, currentCat.id)}
100
+ // disabled={loading}
101
+ animationSpeed={200}
102
+ />
103
+ </View>
104
+ </CategoryTab>
105
+ )}
106
+ </>
107
+ )
108
+ }
@@ -0,0 +1,151 @@
1
+ import React from 'react'
2
+ import { ScrollView, StyleSheet, View } from 'react-native'
3
+ import { useTheme } from 'styled-components/native';
4
+ import { OIcon, OText, OIconButton } from '../shared';
5
+ import { NotFoundSource } from '../NotFoundSource';
6
+ import ToggleSwitch from 'toggle-switch-react-native';
7
+ import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
8
+ import {
9
+ useLanguage,
10
+ useUtils
11
+ } from 'ordering-components/native'
12
+
13
+ export const ProductList = (props: any) => {
14
+ const { categoryState, onClose, updateProduct } = props
15
+
16
+ const { loading, products, error } = categoryState
17
+
18
+ const theme = useTheme()
19
+ const [{ optimizeImage }] = useUtils();
20
+ const [, t] = useLanguage()
21
+
22
+ const styles = StyleSheet.create({
23
+ container: {
24
+ paddingBottom: 20,
25
+ marginBottom: 0,
26
+ flex: 1,
27
+ },
28
+ header: {
29
+ flexDirection: 'row',
30
+ justifyContent: 'space-between',
31
+ marginBottom: 10,
32
+ },
33
+ arrowLeft: {
34
+ maxWidth: 40,
35
+ height: 25,
36
+ justifyContent: 'flex-end',
37
+ marginTop: 8
38
+ },
39
+ sectionTitle: {
40
+ fontStyle: 'normal',
41
+ fontWeight: '600',
42
+ fontSize: 24,
43
+ color: theme.colors.textGray,
44
+ },
45
+ logo: {
46
+ padding: 2,
47
+ borderRadius: 18,
48
+ shadowColor: '#000',
49
+ shadowOffset: {
50
+ width: 0,
51
+ height: 1.5,
52
+ },
53
+ shadowOpacity: 0.21,
54
+ shadowRadius: 3,
55
+ elevation: 7,
56
+ },
57
+ icon: {
58
+ borderRadius: 7.6,
59
+ width: 35,
60
+ height: 35,
61
+ marginRight: 5
62
+ },
63
+ });
64
+
65
+ const handleSwitch = (enabled: boolean, categoryId: any, productId: any) => {
66
+ updateProduct && updateProduct(categoryId, productId, { enabled })
67
+ };
68
+
69
+ return (
70
+ <View style={{ flex: 1, paddingHorizontal: 20, paddingVertical: 20 }}>
71
+ <View style={styles.header}>
72
+ <OIconButton
73
+ icon={theme.images.general.arrow_left}
74
+ borderColor={theme.colors.clear}
75
+ iconStyle={{ width: 20, height: 20 }}
76
+ style={styles.arrowLeft}
77
+ onClick={onClose}
78
+ />
79
+ <OText style={styles.sectionTitle}>{t('PRODUCTS', 'Products')}</OText>
80
+ </View>
81
+ <ScrollView
82
+ showsVerticalScrollIndicator={false}
83
+ style={styles.container}>
84
+ {!loading && products?.length === 0 && (
85
+ <NotFoundSource
86
+ content={t('NO_RESULTS_FOUND', 'Sorry, no results found')}
87
+ image={theme.images.general.notFound}
88
+ conditioned={false}
89
+ />
90
+ )}
91
+ {!loading && products?.length > 0 && (
92
+ <View style={{ borderTopColor: theme.colors.borderTops, borderTopWidth: 1 }}>
93
+ {products.map((product: any, i: number) => (
94
+ <View
95
+ key={i}
96
+ style={{
97
+ flexDirection: 'row',
98
+ justifyContent: 'space-between',
99
+ borderBottomColor: theme.colors.borderTops,
100
+ borderBottomWidth: 1,
101
+ paddingVertical: 10
102
+ }}
103
+ >
104
+ <View style={{ flex: 1, flexDirection: 'row', alignItems: 'center', marginRight: 36 }}>
105
+ <OIcon
106
+ url={optimizeImage(product?.images, 'h_300,c_limit')}
107
+ src={!product?.images && theme?.images?.dummies?.businessLogo}
108
+ style={styles.icon}
109
+ />
110
+ <OText numberOfLines={2} size={12} ellipsizeMode='tail'>{product?.name}</OText>
111
+ </View>
112
+ <ToggleSwitch
113
+ isOn={product?.enabled}
114
+ onColor={theme.colors.primary}
115
+ offColor={theme.colors.offColor}
116
+ size="small"
117
+ onToggle={(value: boolean) => handleSwitch(value, product?.category_id, product.id)}
118
+ disabled={loading}
119
+ animationSpeed={200}
120
+ />
121
+ </View>
122
+ ))}
123
+ </View>
124
+ )}
125
+ {loading && (
126
+ <View style={{ borderTopColor: theme.colors.borderTops, borderTopWidth: 1 }}>
127
+ {[...Array(6)].map((item, i) => (
128
+ <Placeholder key={i} Animation={Fade}>
129
+ <View
130
+ style={{
131
+ flex: 1,
132
+ flexDirection: 'row',
133
+ justifyContent: 'space-between',
134
+ alignItems: 'center',
135
+ marginBottom: 10,
136
+ borderBottomColor: theme.colors.borderTops,
137
+ borderBottomWidth: 1,
138
+ paddingVertical: 10
139
+ }}
140
+ >
141
+ <PlaceholderLine width={50} />
142
+ <PlaceholderLine width={20} />
143
+ </View>
144
+ </Placeholder>
145
+ ))}
146
+ </View>
147
+ )}
148
+ </ScrollView>
149
+ </View>
150
+ )
151
+ }
@@ -0,0 +1,164 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { View, StyleSheet, ScrollView, Dimensions } from 'react-native';
3
+ import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
4
+ import { useTheme } from 'styled-components/native';
5
+ import {
6
+ ToastType,
7
+ useToast,
8
+ useLanguage,
9
+ BusinessAndProductList,
10
+ } from 'ordering-components/native';
11
+ import { NotFoundSource } from '../NotFoundSource';
12
+ import { OText, OIconButton } from '../shared';
13
+ import { IterateCategories } from './IterateCategories';
14
+ import { ProductList } from './ProductList'
15
+
16
+ const BusinessProductListUI = (props: any) => {
17
+ const {
18
+ navigation,
19
+ businessState,
20
+ handleChangeCategory,
21
+ categoryState,
22
+ updateStoreCategory,
23
+ updateStoreProduct
24
+ } = props;
25
+
26
+ const { loading, error, business } = businessState;
27
+
28
+ const [, t] = useLanguage();
29
+ const [, { showToast }] = useToast();
30
+ const theme = useTheme();
31
+
32
+ const [showModal, setShowModal] = useState(false)
33
+
34
+ const handleOpenProducts = (category: any) => {
35
+ handleChangeCategory(category)
36
+ setShowModal(true)
37
+ }
38
+
39
+ useEffect(() => {
40
+ if (error) {
41
+ showToast(
42
+ ToastType.Error,
43
+ error || error[0] || t('NETWORK_ERROR', 'Network Error'),
44
+ );
45
+ }
46
+ }, [loading]);
47
+
48
+ const styles = StyleSheet.create({
49
+ container: {
50
+ paddingBottom: 20,
51
+ marginBottom: 0,
52
+ flex: 1,
53
+ },
54
+ header: {
55
+ flexDirection: 'row',
56
+ justifyContent: 'space-between',
57
+ marginBottom: 10,
58
+ },
59
+ sectionTitle: {
60
+ fontStyle: 'normal',
61
+ fontWeight: '600',
62
+ fontSize: 24,
63
+ color: theme.colors.textGray,
64
+ },
65
+ arrowLeft: {
66
+ maxWidth: 40,
67
+ height: 25,
68
+ justifyContent: 'flex-end',
69
+ marginTop: 8
70
+ },
71
+ });
72
+
73
+ return (
74
+ <>
75
+ <View style={styles.header}>
76
+ <OIconButton
77
+ icon={theme.images.general.arrow_left}
78
+ borderColor={theme.colors.clear}
79
+ iconStyle={{ width: 20, height: 20 }}
80
+ style={styles.arrowLeft}
81
+ onClick={() => navigation?.canGoBack() && navigation.goBack()}
82
+ />
83
+ <OText style={styles.sectionTitle}>{t('CATEGORIES', 'Categories')}</OText>
84
+ </View>
85
+ <ScrollView
86
+ showsVerticalScrollIndicator={false}
87
+ style={styles.container}>
88
+ {!loading && business?.categories?.length === 0 && (
89
+ <NotFoundSource
90
+ content={t('NO_RESULTS_FOUND', 'Sorry, no results found')}
91
+ image={theme.images.general.notFound}
92
+ conditioned={false}
93
+ />
94
+ )}
95
+ {!error && !loading && business?.categories?.length > 0 && (
96
+ <View
97
+ style={{
98
+ borderTopColor: theme.colors.borderTops,
99
+ borderTopWidth: 1
100
+ }}
101
+ >
102
+ <IterateCategories
103
+ list={business?.categories}
104
+ handlerClickCategory={handleOpenProducts}
105
+ updateCategory={updateStoreCategory}
106
+ />
107
+ </View>
108
+ )}
109
+ {loading && (
110
+ <View style={{ borderTopColor: theme.colors.borderTops, borderTopWidth: 1 }}>
111
+ {[...Array(6)].map((item, i) => (
112
+ <Placeholder key={i} Animation={Fade}>
113
+ <View
114
+ style={{
115
+ flex: 1,
116
+ flexDirection: 'row',
117
+ justifyContent: 'space-between',
118
+ alignItems: 'center',
119
+ marginBottom: 10,
120
+ borderBottomColor: theme.colors.borderTops,
121
+ borderBottomWidth: 1,
122
+ paddingVertical: 10
123
+ }}
124
+ >
125
+ <PlaceholderLine width={50} />
126
+ <PlaceholderLine width={20} />
127
+ </View>
128
+ </Placeholder>
129
+ ))}
130
+ </View>
131
+ )}
132
+ </ScrollView>
133
+ {showModal && (
134
+ <View
135
+ style={{
136
+ flex: 1,
137
+ position: 'absolute',
138
+ top: 0,
139
+ width: Dimensions.get('window').width,
140
+ height: Dimensions.get('window').height,
141
+ backgroundColor: theme.colors.backgroundLight,
142
+ left: 0
143
+ }}
144
+ >
145
+ <ProductList
146
+ categoryState={categoryState}
147
+ updateProduct={updateStoreProduct}
148
+ onClose={() => setShowModal(false)}
149
+ />
150
+ </View>
151
+ )}
152
+ </>
153
+ );
154
+ };
155
+
156
+ export const BusinessProductList = (props: any) => {
157
+ const businessProductListProps = {
158
+ ...props,
159
+ isFetchAllProducts: true,
160
+ UIComponent: BusinessProductListUI,
161
+ };
162
+
163
+ return <BusinessAndProductList {...businessProductListProps} />;
164
+ };
@@ -0,0 +1,10 @@
1
+ import styled from 'styled-components/native';
2
+
3
+ export const CategoryTab = styled.View`
4
+ flex-direction: row;
5
+ justify-content: space-between;
6
+ padding-vertical: 10px;
7
+ border-bottom-color: ${(props: any) => props.theme.colors.borderTops};
8
+ border-bottom-width: 1px;
9
+ margin-left: ${(props: any) => props.isSpace ? '10px' : '0px'};
10
+ `
@@ -209,7 +209,7 @@ export const Timer = () => {
209
209
  return (
210
210
  <TimerInputWrapper>
211
211
  <OText style={styles.settingTime} color={theme.colors.disabled}>{configs?.order_deadlines_delayed_time?.value}</OText>
212
- <OText>{t('MIN', 'min')}</OText>
212
+ <OText>{t('TIME_MIN', 'min')}</OText>
213
213
  </TimerInputWrapper>
214
214
  )
215
215
  }
@@ -921,7 +921,7 @@ export const Timer = () => {
921
921
  return (
922
922
  <TimerInputWrapper>
923
923
  <OText style={styles.settingTime} color={theme.colors.disabled}>{configs?.order_deadlines_delayed_time?.value}</OText>
924
- <OText>{t('MIN', 'min')}</OText>
924
+ <OText>{t('TIME_MIN', 'min')}</OText>
925
925
  </TimerInputWrapper>
926
926
  )
927
927
  }
@@ -28,7 +28,7 @@ export const MaxSectionItem = (props: any) => {
28
28
  return filter === 'max_distance'
29
29
  ? `${option / 1000} ${t('KM', 'Km')}`
30
30
  : filter === 'max_eta'
31
- ? `${option} ${t('MIN', 'min')}`
31
+ ? `${option} ${t('TIME_MIN', 'min')}`
32
32
  : parsePrice(option)
33
33
  }
34
34
  return (
@@ -800,7 +800,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
800
800
  parentStyle={{ marginTop: 29, marginEnd: 15 }}
801
801
  onClick={() => navigation.navigate('BottomTab', { screen: 'MyOrders' })}
802
802
  />
803
- {(reorderStatus?.includes(parseInt(order?.status)) && order?.cart) && (
803
+ {(reorderStatus?.includes(parseInt(order?.status)) && order?.cart) && !isGiftCardOrder && (
804
804
  <OButton
805
805
  text={order.id === reorderState?.loading ? t('LOADING', 'Loading..') : t('REORDER', 'Reorder')}
806
806
  textStyle={{ fontSize: 14, color: theme.colors.primary }}
@@ -53,6 +53,7 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
53
53
  const [isPressed, setIsPressed] = useState(false)
54
54
 
55
55
  const allowedOrderStatus = [1, 2, 5, 6, 10, 11, 12, 15];
56
+ const isGiftCardOrder = !order?.business_id
56
57
 
57
58
  const styles = StyleSheet.create({
58
59
  container: {
@@ -290,7 +291,7 @@ const SingleOrderCardUI = (props: SingleOrderCardParams) => {
290
291
  )}
291
292
  </>
292
293
  )}
293
- {!!pastOrders && (
294
+ {!!pastOrders && !isGiftCardOrder && (
294
295
  <ButtonWrapper>
295
296
  {!hideReviewOrderButton &&
296
297
  allowedOrderStatus.includes(parseInt(order?.status)) &&