ordering-ui-react-native 0.15.66-release → 0.15.67-release

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.66-release",
3
+ "version": "0.15.67-release",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, useRef, useEffect } from 'react';
2
2
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
3
3
  import {
4
4
  BusinessController as BusinessSingleCard,
@@ -10,7 +10,7 @@ import {
10
10
  ToastType
11
11
  } from 'ordering-components/native';
12
12
  import { OIcon, OText } from '../shared';
13
- import { StyleSheet, TouchableOpacity, View } from 'react-native';
13
+ import { StyleSheet, TouchableOpacity, View, Animated } from 'react-native';
14
14
  import { InView } from 'react-native-intersection-observer'
15
15
  import { BusinessControllerParams } from '../../types';
16
16
  import { convertHoursToMinutes, shape } from '../../utils';
@@ -57,6 +57,8 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
57
57
  const [, t] = useLanguage();
58
58
  const theme = useTheme()
59
59
  const [isIntersectionObserver, setIsIntersectionObserver] = useState(!enableIntersection)
60
+ const fadeAnim = useRef(new Animated.Value(0)).current;
61
+
60
62
  const styles = StyleSheet.create({
61
63
  headerStyle: {
62
64
  borderTopLeftRadius: 7.6,
@@ -138,8 +140,25 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
138
140
  handleFavoriteBusiness && handleFavoriteBusiness(!business?.favorite)
139
141
  }
140
142
 
143
+ const fadeIn = () => {
144
+ Animated.timing(fadeAnim, {
145
+ toValue: 1,
146
+ duration: 500,
147
+ useNativeDriver: true
148
+ }).start();
149
+ };
150
+
151
+ const handleChangeInterSection = (inView: boolean) => {
152
+ setIsIntersectionObserver(inView)
153
+ fadeIn()
154
+ }
155
+
156
+ useEffect(() => {
157
+ if (!enableIntersection) fadeIn()
158
+ }, [enableIntersection])
159
+
141
160
  return (
142
- <InView style={{ minHeight: 200 }} triggerOnce={true} onChange={(inView: boolean) => setIsIntersectionObserver(inView)}>
161
+ <InView style={{ minHeight: 200 }} triggerOnce={true} onChange={(inView: boolean) => handleChangeInterSection(inView)}>
143
162
  {isIntersectionObserver ? (
144
163
  <Card activeOpacity={1} onPress={() => handleBusinessClick(business)} style={style}>
145
164
  {business?.ribbon?.enabled && (
@@ -161,6 +180,13 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
161
180
  </RibbonBox>
162
181
  )}
163
182
  <BusinessHero>
183
+ <Animated.View
184
+ style={[
185
+ {
186
+ opacity: fadeAnim
187
+ }
188
+ ]}
189
+ >
164
190
  <FastImage
165
191
  style={{ height: 120 }}
166
192
  source={{
@@ -169,6 +195,7 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
169
195
  }}
170
196
  resizeMode={FastImage.resizeMode.cover}
171
197
  />
198
+ </Animated.View>
172
199
  {(businessFeatured ?? business?.featured) && (
173
200
  <View style={styles.featured}>
174
201
  <FontAwesomeIcon name="crown" size={26} color="gold" />
@@ -122,6 +122,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
122
122
  <SingleProductCard
123
123
  key={'prod_' + product.id + `_${i}`}
124
124
  isSoldOut={product.inventoried && !product.quantity}
125
+ enableIntersection
125
126
  product={product}
126
127
  businessId={businessId}
127
128
  categoryState={categoryState}
@@ -148,6 +149,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
148
149
  key={'feat_' + product.id + `_${i}`}
149
150
  isSoldOut={product.inventoried && !product.quantity}
150
151
  product={product}
152
+ enableIntersection
151
153
  businessId={businessId}
152
154
  categoryState={categoryState}
153
155
  onProductClick={onProductClick}
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, useRef, useEffect } from 'react';
2
2
  import {
3
3
  useLanguage,
4
4
  useConfig,
@@ -11,7 +11,7 @@ import {
11
11
  import { useTheme } from 'styled-components/native';
12
12
  import { SingleProductCardParams } from '../../types';
13
13
  import { CardContainer, CardInfo, SoldOut, QuantityContainer, PricesContainer, RibbonBox, LogoWrapper } from './styles';
14
- import { StyleSheet, View, TouchableOpacity, Image } from 'react-native';
14
+ import { StyleSheet, View, TouchableOpacity, Image, Animated } from 'react-native';
15
15
  import { InView } from 'react-native-intersection-observer'
16
16
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
17
17
  import { OButton, OText } from '../shared';
@@ -26,7 +26,7 @@ function SingleProductCardPropsAreEqual(prevProps: any, nextProps: any) {
26
26
  prevProps.categoryState === nextProps.categoryState
27
27
  }
28
28
 
29
- const SinguleProductCardUI = React.memo((props: SingleProductCardParams) => {
29
+ const SingleProductCardUI = React.memo((props: SingleProductCardParams) => {
30
30
  const {
31
31
  product,
32
32
  isSoldOut,
@@ -34,13 +34,18 @@ const SinguleProductCardUI = React.memo((props: SingleProductCardParams) => {
34
34
  productAddedToCartLength,
35
35
  style,
36
36
  handleFavoriteProduct,
37
- enableIntersection
37
+ enableIntersection,
38
+ navigation,
39
+ businessId,
40
+ isPreviously
38
41
  } = props;
39
42
 
40
43
  const theme = useTheme();
41
44
  const [orderingTheme] = useOrderingTheme()
42
45
  const hideAddButton = orderingTheme?.theme?.business_view?.components?.products?.components?.add_to_cart_button?.hidden
43
46
 
47
+ const fadeAnim = useRef(new Animated.Value(0)).current;
48
+
44
49
  const styles = StyleSheet.create({
45
50
  container: {
46
51
  borderWidth: 1,
@@ -89,10 +94,10 @@ const SinguleProductCardUI = React.memo((props: SingleProductCardParams) => {
89
94
  }
90
95
  });
91
96
 
92
-
93
97
  const [, t] = useLanguage();
94
98
  const [stateConfig] = useConfig();
95
- const [{ parsePrice, optimizeImage }] = useUtils();
99
+ const [{ auth }] = useSession()
100
+ const [{ parsePrice, optimizeImage, parseDate }] = useUtils();
96
101
  const [orderState] = useOrder()
97
102
  const [isIntersectionObserver, setIsIntersectionObserver] = useState(!enableIntersection)
98
103
 
@@ -120,13 +125,34 @@ const SinguleProductCardUI = React.memo((props: SingleProductCardParams) => {
120
125
  maxCartProductInventory,
121
126
  );
122
127
 
128
+ const fadeIn = () => {
129
+ Animated.timing(fadeAnim, {
130
+ toValue: 1,
131
+ duration: 500,
132
+ useNativeDriver: true
133
+ }).start();
134
+ };
135
+
123
136
  const handleChangeFavorite = () => {
124
- handleFavoriteProduct && handleFavoriteProduct(!product?.favorite)
137
+ if (auth) {
138
+ handleFavoriteProduct && handleFavoriteProduct(!product?.favorite)
139
+ } else {
140
+ navigation && navigation.navigate('Login');
141
+ }
142
+ }
143
+
144
+ const handleChangeIntersection = () => {
145
+ setIsIntersectionObserver(true);
146
+ fadeIn();
125
147
  }
126
148
 
149
+ useEffect(() => {
150
+ if (!enableIntersection) fadeIn()
151
+ }, [enableIntersection])
152
+
127
153
  return (
128
- <InView style={{ minHeight: 140 }} triggerOnce={true} onChange={(inView: boolean) => setIsIntersectionObserver(true)}>
129
- {isIntersectionObserver && (
154
+ <InView style={{ minHeight: 200 }} triggerOnce={true} onChange={(inView: boolean) => handleChangeIntersection()}>
155
+ {isIntersectionObserver ? (
130
156
  <CardContainer
131
157
  showAddButton={!hideAddButton}
132
158
  style={[
@@ -151,18 +177,20 @@ const SinguleProductCardUI = React.memo((props: SingleProductCardParams) => {
151
177
  weight={'500'}
152
178
  numberOfLines={1}
153
179
  ellipsizeMode="tail"
154
- style={styles.line18}>
180
+ style={{ ...styles.line18, flex: 1 }}>
155
181
  {product?.name}
156
182
  </OText>
157
- <TouchableOpacity
158
- onPress={handleChangeFavorite}
159
- >
160
- <IconAntDesign
161
- name={product?.favorite ? 'heart' : 'hearto'}
162
- color={theme.colors.danger5}
163
- size={18}
164
- />
165
- </TouchableOpacity>
183
+ {!isPreviously && (
184
+ <TouchableOpacity
185
+ onPress={handleChangeFavorite}
186
+ >
187
+ <IconAntDesign
188
+ name={product?.favorite ? 'heart' : 'hearto'}
189
+ color={theme.colors.danger5}
190
+ size={18}
191
+ />
192
+ </TouchableOpacity>
193
+ )}
166
194
  </View>
167
195
  <PricesContainer>
168
196
  <OText color={theme.colors.primary}>{product?.price ? parsePrice(product?.price) : ''}</OText>
@@ -172,12 +200,22 @@ const SinguleProductCardUI = React.memo((props: SingleProductCardParams) => {
172
200
  </PricesContainer>
173
201
  <OText
174
202
  size={10}
175
- numberOfLines={2}
203
+ numberOfLines={!isPreviously ? 2 : 1}
176
204
  ellipsizeMode="tail"
177
205
  color={theme.colors.textSecondary}
178
206
  style={styles.line15}>
179
207
  {product?.description}
180
208
  </OText>
209
+ {isPreviously && (
210
+ <OText
211
+ size={10}
212
+ numberOfLines={1}
213
+ ellipsizeMode="tail"
214
+ color={theme.colors.primary}
215
+ style={styles.line15}>
216
+ {t('LAST_ORDERED_ON', 'Last ordered on')} {parseDate(product?.last_ordered_date, { outputFormat: 'MMM DD, YYYY' })}
217
+ </OText>
218
+ )}
181
219
  </CardInfo>
182
220
  <LogoWrapper>
183
221
  {product?.ribbon?.enabled && (
@@ -198,24 +236,24 @@ const SinguleProductCardUI = React.memo((props: SingleProductCardParams) => {
198
236
  </OText>
199
237
  </RibbonBox>
200
238
  )}
201
- {product?.images ? (
202
- <FastImage
203
- style={styles.productStyle}
204
- source={{
205
- uri: optimizeImage(product?.images, 'h_250,c_limit'),
206
- priority: FastImage.priority.normal,
207
- }}
208
- resizeMode={FastImage.resizeMode.cover}
209
- />
210
- ) : (
211
- <FastImage
212
- style={styles.productStyle}
213
- source={{
214
- uri: Image.resolveAssetSource(theme.images.dummies.product).uri,
215
- priority: FastImage.priority.normal,
216
- }}
217
- resizeMode={FastImage.resizeMode.cover}
218
- />
239
+ {product?.images && (
240
+ <Animated.View
241
+ style={[
242
+ {
243
+ // Bind opacity to animated value
244
+ opacity: fadeAnim
245
+ }
246
+ ]}
247
+ >
248
+ <FastImage
249
+ style={styles.productStyle}
250
+ source={{
251
+ uri: optimizeImage(product?.images, 'h_250,c_limit'),
252
+ priority: FastImage.priority.normal,
253
+ }}
254
+ resizeMode={FastImage.resizeMode.cover}
255
+ />
256
+ </Animated.View>
219
257
  )}
220
258
  </LogoWrapper>
221
259
 
@@ -243,6 +281,20 @@ const SinguleProductCardUI = React.memo((props: SingleProductCardParams) => {
243
281
  />
244
282
  )}
245
283
  </CardContainer>
284
+ ) : (
285
+ <Placeholder style={{ padding: 5 }} Animation={Fade}>
286
+ <View style={{ flexDirection: 'row' }}>
287
+ <PlaceholderLine
288
+ width={24}
289
+ height={70}
290
+ style={{ marginRight: 10, marginBottom: 10 }}
291
+ />
292
+ <Placeholder style={{ paddingVertical: 10 }}>
293
+ <PlaceholderLine width={60} style={{ marginBottom: 25 }} />
294
+ <PlaceholderLine width={20} />
295
+ </Placeholder>
296
+ </View>
297
+ </Placeholder>
246
298
  )}
247
299
  </InView>
248
300
  );
@@ -251,7 +303,7 @@ const SinguleProductCardUI = React.memo((props: SingleProductCardParams) => {
251
303
  export const SingleProductCard = (props: SingleProductCardParams) => {
252
304
  const singleProductCardProps = {
253
305
  ...props,
254
- UIComponent: SinguleProductCardUI
306
+ UIComponent: SingleProductCardUI
255
307
  }
256
308
  return <SingleProductCardController {...singleProductCardProps} />
257
309
  }