@propel-nsl/propel-react-native-sdk 1.0.0

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.
Files changed (221) hide show
  1. package/assets/fonts/Lexend-Black.ttf +0 -0
  2. package/assets/fonts/Lexend-Bold.ttf +0 -0
  3. package/assets/fonts/Lexend-ExtraBold.ttf +0 -0
  4. package/assets/fonts/Lexend-ExtraLight.ttf +0 -0
  5. package/assets/fonts/Lexend-Light.ttf +0 -0
  6. package/assets/fonts/Lexend-Medium.ttf +0 -0
  7. package/assets/fonts/Lexend-Regular.ttf +0 -0
  8. package/assets/fonts/Lexend-SemiBold.ttf +0 -0
  9. package/assets/fonts/Lexend-Thin.ttf +0 -0
  10. package/assets/images/HomeGoods.png +0 -0
  11. package/assets/images/accessories.png +0 -0
  12. package/assets/images/amazon.png +0 -0
  13. package/assets/images/apnaClubLogo.png +0 -0
  14. package/assets/images/apparel.png +0 -0
  15. package/assets/images/backgroundblue.png +0 -0
  16. package/assets/images/bannerCard.png +0 -0
  17. package/assets/images/bottomWave.png +0 -0
  18. package/assets/images/coin_1_1.png +0 -0
  19. package/assets/images/flipkart.png +0 -0
  20. package/assets/images/frame_1171278967.png +0 -0
  21. package/assets/images/gift.png +0 -0
  22. package/assets/images/herobanner.png +0 -0
  23. package/assets/images/hinduPencilsLogo.png +0 -0
  24. package/assets/images/icons/addwhiteicon.png +0 -0
  25. package/assets/images/icons/arrow-back.png +0 -0
  26. package/assets/images/icons/arrowgreen.png +0 -0
  27. package/assets/images/icons/arrowred.png +0 -0
  28. package/assets/images/icons/arrowright.png +0 -0
  29. package/assets/images/icons/arrowup.png +0 -0
  30. package/assets/images/icons/blackarrowdown.png +0 -0
  31. package/assets/images/icons/blackarrowup.png +0 -0
  32. package/assets/images/icons/blackcross.png +0 -0
  33. package/assets/images/icons/call.png +0 -0
  34. package/assets/images/icons/camera.png +0 -0
  35. package/assets/images/icons/cart.png +0 -0
  36. package/assets/images/icons/chat.png +0 -0
  37. package/assets/images/icons/circleblack.png +0 -0
  38. package/assets/images/icons/copy.png +0 -0
  39. package/assets/images/icons/cross.png +0 -0
  40. package/assets/images/icons/delete.png +0 -0
  41. package/assets/images/icons/delivery.png +0 -0
  42. package/assets/images/icons/eVoucher.png +0 -0
  43. package/assets/images/icons/editIcon.png +0 -0
  44. package/assets/images/icons/email.png +0 -0
  45. package/assets/images/icons/eye.png +0 -0
  46. package/assets/images/icons/faq.png +0 -0
  47. package/assets/images/icons/filtericon.png +0 -0
  48. package/assets/images/icons/greyDownArrow.png +0 -0
  49. package/assets/images/icons/help.png +0 -0
  50. package/assets/images/icons/home.png +0 -0
  51. package/assets/images/icons/homeinactive.png +0 -0
  52. package/assets/images/icons/i_blackicon.png +0 -0
  53. package/assets/images/icons/i_icon.png +0 -0
  54. package/assets/images/icons/location.png +0 -0
  55. package/assets/images/icons/logout.png +0 -0
  56. package/assets/images/icons/minus.png +0 -0
  57. package/assets/images/icons/myOrders.png +0 -0
  58. package/assets/images/icons/orders.png +0 -0
  59. package/assets/images/icons/pencillogo.png +0 -0
  60. package/assets/images/icons/pending.png +0 -0
  61. package/assets/images/icons/plus.png +0 -0
  62. package/assets/images/icons/redCross.png +0 -0
  63. package/assets/images/icons/redCrossicon.png +0 -0
  64. package/assets/images/icons/redWarningicon.png +0 -0
  65. package/assets/images/icons/redeem.png +0 -0
  66. package/assets/images/icons/redeemactive.png +0 -0
  67. package/assets/images/icons/redemptionHistory.png +0 -0
  68. package/assets/images/icons/redhelpicon.png +0 -0
  69. package/assets/images/icons/search.png +0 -0
  70. package/assets/images/icons/stopwatch.png +0 -0
  71. package/assets/images/icons/successTick.gif +0 -0
  72. package/assets/images/icons/tick.png +0 -0
  73. package/assets/images/icons/tnc.png +0 -0
  74. package/assets/images/icons/user.png +0 -0
  75. package/assets/images/icons/userredicon.png +0 -0
  76. package/assets/images/icons/wavecorner.png +0 -0
  77. package/assets/images/logo.png +0 -0
  78. package/assets/images/myntra_copy.png +0 -0
  79. package/assets/images/nike.png +0 -0
  80. package/assets/images/oq3p0u0_1.png +0 -0
  81. package/assets/images/profileicon.png +0 -0
  82. package/assets/images/topWave.png +0 -0
  83. package/assets/images/zagglePropelLogo.png +0 -0
  84. package/index.ts +23 -0
  85. package/lib/index.ts +25 -0
  86. package/package.json +70 -0
  87. package/src/PropelSDKScreen.tsx +98 -0
  88. package/src/SDKApp.tsx +540 -0
  89. package/src/bridge/SDKBridge.ts +104 -0
  90. package/src/bridge/index.ts +3 -0
  91. package/src/components/SDKBackHandler.tsx +187 -0
  92. package/src/components/SDKProfile.tsx +87 -0
  93. package/src/components/SDKProfileWrapper.tsx +51 -0
  94. package/src/constants.ts +10 -0
  95. package/src/contexts/SDKContext.tsx +72 -0
  96. package/src/hooks/useSDKBackNavigation.ts +61 -0
  97. package/src/navigation/SDKMainTabNavigator.tsx +315 -0
  98. package/src/navigation/SDKNavigator.tsx +41 -0
  99. package/src/redux/store.ts +32 -0
  100. package/src/screens/Dashboard/index.tsx +531 -0
  101. package/src/screens/Dashboard/styles.ts +512 -0
  102. package/src/screens/DeliveryAddress/index.tsx +221 -0
  103. package/src/screens/DeliveryAddress/styles.ts +122 -0
  104. package/src/screens/E-Vouchers/index.tsx +157 -0
  105. package/src/screens/E-Vouchers/styles.ts +106 -0
  106. package/src/screens/Faq/Faq.constants.ts +164 -0
  107. package/src/screens/Faq/index.tsx +114 -0
  108. package/src/screens/Faq/styles.ts +131 -0
  109. package/src/screens/Help/index.tsx +128 -0
  110. package/src/screens/Help/styles.ts +121 -0
  111. package/src/screens/Login/index.tsx +215 -0
  112. package/src/screens/Login/styles.ts +134 -0
  113. package/src/screens/MyCart/MyCart.constants.ts +13 -0
  114. package/src/screens/MyCart/index.tsx +318 -0
  115. package/src/screens/MyCart/styles.ts +249 -0
  116. package/src/screens/MyOrders/index.tsx +87 -0
  117. package/src/screens/MyOrders/styles.ts +281 -0
  118. package/src/screens/MyProfile/index.tsx +72 -0
  119. package/src/screens/MyProfile/styles.ts +47 -0
  120. package/src/screens/NewDeliveryAddress/index.tsx +360 -0
  121. package/src/screens/NewDeliveryAddress/styles.ts +68 -0
  122. package/src/screens/Onboarding/index.tsx +57 -0
  123. package/src/screens/Onboarding/styles.ts +60 -0
  124. package/src/screens/OrdersDetails/index.tsx +333 -0
  125. package/src/screens/OrdersDetails/styles.ts +262 -0
  126. package/src/screens/OtpVerification/index.tsx +283 -0
  127. package/src/screens/OtpVerification/styles.ts +197 -0
  128. package/src/screens/PaymentMethod/index.tsx +389 -0
  129. package/src/screens/PaymentMethod/styles.ts +246 -0
  130. package/src/screens/PointsLog/index.tsx +286 -0
  131. package/src/screens/PointsLog/styles.ts +156 -0
  132. package/src/screens/ProductDetails/index.tsx +682 -0
  133. package/src/screens/ProductDetails/styles.ts +372 -0
  134. package/src/screens/Profile/index.tsx +368 -0
  135. package/src/screens/Profile/styles.ts +158 -0
  136. package/src/screens/RedemptionHistory/RedemptionHistory.constants.ts +4 -0
  137. package/src/screens/RedemptionHistory/index.tsx +304 -0
  138. package/src/screens/RedemptionHistory/styles.ts +84 -0
  139. package/src/screens/Reedem/index.tsx +345 -0
  140. package/src/screens/Reedem/styles.ts +269 -0
  141. package/src/screens/TnC/TnC.constants.ts +169 -0
  142. package/src/screens/TnC/index.tsx +83 -0
  143. package/src/screens/TnC/styles.ts +88 -0
  144. package/src/screens/TransactionSuccessful/index.tsx +77 -0
  145. package/src/screens/TransactionSuccessful/styles.ts +77 -0
  146. package/src/screens/Verification/index.tsx +58 -0
  147. package/src/screens/Verification/styles.ts +74 -0
  148. package/src/screens/index.ts +23 -0
  149. package/src/types/index.ts +46 -0
  150. package/src-app/components/AmountBreakDownModal/index.tsx +86 -0
  151. package/src-app/components/AmountBreakDownModal/styles.ts +110 -0
  152. package/src-app/components/BottomNavIcons.tsx +125 -0
  153. package/src-app/components/Button.tsx +120 -0
  154. package/src-app/components/Card.tsx +47 -0
  155. package/src-app/components/ConfirmPopup/ConfirmPopup.constants.ts +25 -0
  156. package/src-app/components/ConfirmPopup/index.tsx +48 -0
  157. package/src-app/components/ConfirmPopup/styles.ts +167 -0
  158. package/src-app/components/CustomButton/index.tsx +67 -0
  159. package/src-app/components/CustomButton/styles.ts +44 -0
  160. package/src-app/components/CustomCard/index.tsx +221 -0
  161. package/src-app/components/CustomCard/styles.ts +184 -0
  162. package/src-app/components/CustomError/index.tsx +54 -0
  163. package/src-app/components/CustomError/styles.ts +41 -0
  164. package/src-app/components/CustomImage/index.tsx +37 -0
  165. package/src-app/components/CustomImage/styles.ts +5 -0
  166. package/src-app/components/CustomLoader/index.tsx +45 -0
  167. package/src-app/components/CustomLoader/styles.ts +35 -0
  168. package/src-app/components/CustomMessagePopUp/index.tsx +51 -0
  169. package/src-app/components/CustomMessagePopUp/styles.ts +74 -0
  170. package/src-app/components/CustomProductCard/index.tsx +13 -0
  171. package/src-app/components/CustomProductCard/styles.ts +5 -0
  172. package/src-app/components/FilterModal.tsx +372 -0
  173. package/src-app/components/Footer/index.tsx +23 -0
  174. package/src-app/components/Footer/styles.ts +37 -0
  175. package/src-app/components/Icon.tsx +80 -0
  176. package/src-app/components/Logout/index.tsx +82 -0
  177. package/src-app/components/Logout/styles.ts +116 -0
  178. package/src-app/components/MobileHeader.tsx +141 -0
  179. package/src-app/components/NoDataFound/index.tsx +18 -0
  180. package/src-app/components/NoDataFound/styles.ts +26 -0
  181. package/src-app/components/OTPModal.tsx +747 -0
  182. package/src-app/components/ProfileField.tsx +47 -0
  183. package/src-app/components/QuantityModal/index.tsx +113 -0
  184. package/src-app/components/QuantityModal/styles.ts +84 -0
  185. package/src-app/components/TabBarIcons.tsx +110 -0
  186. package/src-app/components/TextInput.tsx +79 -0
  187. package/src-app/components/ToastConfig.tsx +60 -0
  188. package/src-app/components/index.ts +18 -0
  189. package/src-app/config/env.ts +22 -0
  190. package/src-app/constants/Fonts.ts +12 -0
  191. package/src-app/constants/Formatter.ts +39 -0
  192. package/src-app/constants/HtmlSanitization.ts +46 -0
  193. package/src-app/constants/Images.ts +81 -0
  194. package/src-app/constants/Labels.ts +8 -0
  195. package/src-app/constants/Messages.ts +108 -0
  196. package/src-app/constants/Routes.ts +17 -0
  197. package/src-app/constants/Scaling.ts +5 -0
  198. package/src-app/constants/Text.ts +8 -0
  199. package/src-app/constants/offSets.ts +18 -0
  200. package/src-app/hooks/useAppDispatch.ts +4 -0
  201. package/src-app/hooks/useAppSelector.ts +4 -0
  202. package/src-app/hooks/useBackHandler.ts +47 -0
  203. package/src-app/hooks/useScreenBackHandler.ts +91 -0
  204. package/src-app/navigation/AppNavigator.tsx +34 -0
  205. package/src-app/navigation/MainTabNavigator.tsx +294 -0
  206. package/src-app/redux/authSaga.ts +605 -0
  207. package/src-app/redux/authSlice.ts +754 -0
  208. package/src-app/redux/rootSaga.ts +6 -0
  209. package/src-app/redux/store.ts +25 -0
  210. package/src-app/services/api.ts +14 -0
  211. package/src-app/services/endpoints.ts +33 -0
  212. package/src-app/services/index.ts +574 -0
  213. package/src-app/services/sdkCredentials.ts +44 -0
  214. package/src-app/styles/colors.ts +85 -0
  215. package/src-app/styles/shared.ts +112 -0
  216. package/src-app/types/authTypes.ts +155 -0
  217. package/src-app/types/navigation.ts +99 -0
  218. package/src-app/utils/Validation.ts +48 -0
  219. package/src-app/utils/filterPins.ts +29 -0
  220. package/src-app/utils/navigationUtils.ts +43 -0
  221. package/src-app/utils/useHardwareBack.ts +21 -0
@@ -0,0 +1,372 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ TouchableOpacity,
6
+ StyleSheet,
7
+ Dimensions,
8
+ ScrollView,
9
+ TouchableWithoutFeedback,
10
+ } from 'react-native';
11
+ import { spacing, typography, borderRadius } from '../styles/shared';
12
+ import { useAppDispatch } from '../hooks/useAppDispatch';
13
+ import {
14
+ myProductsListRequest,
15
+ productCategoriesByTypeRequest,
16
+ } from '../redux/authSlice';
17
+ import { useAppSelector } from '../hooks/useAppSelector';
18
+ import { RootState } from '../redux/store';
19
+ import FontFamily from '../constants/Fonts';
20
+ import { colors } from '../styles/colors';
21
+
22
+ const { height: screenHeight, width: screenWidth } = Dimensions.get('window');
23
+
24
+ interface FilterModalProps {
25
+ visible: boolean;
26
+ onClose: () => void;
27
+ onApply: (filters: FilterState) => void;
28
+ onClear: () => void;
29
+ data: any;
30
+ initialFilters?: FilterState;
31
+ }
32
+
33
+ interface FilterState {
34
+ productType: string;
35
+ categories: string[];
36
+ }
37
+
38
+ const DEFAULT_PRODUCT_TYPE = 'Physical Voucher';
39
+
40
+ const FilterModal: React.FC<FilterModalProps> = ({
41
+ visible,
42
+ onClose,
43
+ onApply,
44
+ onClear,
45
+ data,
46
+ initialFilters,
47
+ }) => {
48
+ const [filters, setFilters] = useState<FilterState>(
49
+ initialFilters || { productType: DEFAULT_PRODUCT_TYPE, categories: [] }
50
+ );
51
+ const isClearDisabled =
52
+ filters.productType === DEFAULT_PRODUCT_TYPE &&
53
+ filters.categories.length === 0;
54
+
55
+ const dispatch = useAppDispatch();
56
+ const { productCategoriesByTypeData } = useAppSelector(
57
+ (state: RootState) => state?.auth,
58
+ );
59
+
60
+ useEffect(() => {
61
+ if (visible) {
62
+ setFilters(initialFilters || { productType: DEFAULT_PRODUCT_TYPE, categories: [] });
63
+
64
+ dispatch?.(
65
+ productCategoriesByTypeRequest?.({
66
+ product_type: initialFilters?.productType || DEFAULT_PRODUCT_TYPE,
67
+ }),
68
+ );
69
+ }
70
+ }, [visible, initialFilters]);
71
+
72
+ const handleProductTypeSelect = (type: string) => {
73
+ setFilters(prev => ({
74
+ ...prev,
75
+ productType: type,
76
+ }));
77
+ dispatch?.(
78
+ productCategoriesByTypeRequest?.({
79
+ product_type: type,
80
+ }),
81
+ );
82
+ };
83
+
84
+ const handleCategoryToggle = (categoryId: string) => {
85
+ setFilters(prev => {
86
+ const updatedCategories = prev?.categories?.includes?.(categoryId)
87
+ ? prev?.categories?.filter?.(c => c !== categoryId)
88
+ : [...(prev?.categories ?? []), categoryId];
89
+ return { ...prev, categories: updatedCategories };
90
+ });
91
+ };
92
+
93
+ const handleClear = () => {
94
+ const resetFilters = {
95
+ productType: DEFAULT_PRODUCT_TYPE,
96
+ categories: [],
97
+ };
98
+ setFilters(resetFilters); // update state
99
+ dispatch(productCategoriesByTypeRequest?.({ product_type: resetFilters.productType }));
100
+ };
101
+
102
+ const handleApply = () => {
103
+ const payload: any = {};
104
+ if (filters?.productType) payload.product_types = filters?.productType;
105
+ if (filters?.categories?.length > 0) {
106
+ payload.category_ids = filters?.categories?.join?.(',');
107
+ }
108
+ dispatch?.(myProductsListRequest?.(payload));
109
+ onApply?.(filters);
110
+ onClose?.();
111
+ };
112
+
113
+ if (!visible) {
114
+ return null;
115
+ }
116
+
117
+ return (
118
+ <View style={styles.absoluteContainer} pointerEvents="box-none">
119
+ <TouchableWithoutFeedback onPress={onClose}>
120
+ <View style={styles.overlay} />
121
+ </TouchableWithoutFeedback>
122
+
123
+ <View style={styles.modalContainer}>
124
+ <ScrollView
125
+ keyboardShouldPersistTaps="handled"
126
+ contentContainerStyle={styles.sheetContent}
127
+ showsVerticalScrollIndicator={false}
128
+ >
129
+ <View style={styles.handleBar} />
130
+
131
+ <View style={styles.headerRow}>
132
+ <Text style={styles.sectionHeader}>Product Type</Text>
133
+ <Text style={styles.sectionHeader}>Category</Text>
134
+ </View>
135
+
136
+ <View style={styles.content}>
137
+ {/* Product Type Section */}
138
+ <View style={styles.productTypeSection}>
139
+ {Array.isArray(data) &&
140
+ data?.length > 0 &&
141
+ data?.map?.((item: any) => {
142
+ const key = Object.keys(item ?? {})?.[0];
143
+ const value = item?.[key];
144
+
145
+ return (
146
+ <TouchableOpacity
147
+ key={key}
148
+ style={[
149
+ styles.productTypeItem,
150
+ filters?.productType === key &&
151
+ styles.productTypeItemSelected,
152
+ ]}
153
+ onPress={() => handleProductTypeSelect(key)}
154
+ >
155
+ <Text style={styles.productTypeText}>{value}</Text>
156
+ </TouchableOpacity>
157
+ );
158
+ })}
159
+ </View>
160
+
161
+ {/* Category Section */}
162
+ <ScrollView
163
+ style={styles.categorySection}
164
+ showsVerticalScrollIndicator={false}
165
+ contentContainerStyle={{paddingBottom:40}}
166
+ >
167
+ {Array.isArray(productCategoriesByTypeData) &&
168
+ productCategoriesByTypeData?.map?.(
169
+ (category: any, index: number) => (
170
+ <TouchableOpacity
171
+ key={index}
172
+ style={styles.categoryItem}
173
+ onPress={() => handleCategoryToggle(category?.id)}
174
+ >
175
+ <View
176
+ style={[
177
+ styles.checkbox,
178
+ filters?.categories?.includes?.(category?.id) &&
179
+ styles.checkboxSelected,
180
+ ]}
181
+ >
182
+ {filters?.categories?.includes?.(category?.id) && (
183
+ <Text style={styles.checkmark}>✓</Text>
184
+ )}
185
+ </View>
186
+ <Text style={styles.categoryText}>{category?.name}</Text>
187
+ </TouchableOpacity>
188
+ ))}
189
+ </ScrollView>
190
+ </View>
191
+
192
+ {/* Footer Buttons */}
193
+ <View style={styles.footer}>
194
+ <TouchableOpacity
195
+ onPress={handleClear}
196
+ activeOpacity={0.7}
197
+ disabled={isClearDisabled}
198
+ style={[styles.clearButton, isClearDisabled && {opacity:0.4}]}
199
+ >
200
+ <Text style={styles.clearButtonText}>Clear</Text>
201
+ </TouchableOpacity>
202
+
203
+ <TouchableOpacity
204
+ style={styles.applyButton}
205
+ onPress={handleApply}
206
+ >
207
+ <Text style={styles.applyButtonText}>Apply</Text>
208
+ </TouchableOpacity>
209
+ </View>
210
+ </ScrollView>
211
+ </View>
212
+ </View>
213
+ );
214
+ };
215
+
216
+ const styles = StyleSheet.create({
217
+ absoluteContainer: {
218
+ position: 'absolute',
219
+ top: 0,
220
+ left: 0,
221
+ right: 0,
222
+ bottom: 0,
223
+ width: screenWidth,
224
+ height: screenHeight,
225
+ justifyContent: 'flex-end',
226
+ zIndex: 50000,
227
+ elevation: 50000,
228
+ },
229
+ overlay: {
230
+ position: 'absolute',
231
+ top: 0,
232
+ left: 0,
233
+ right: 0,
234
+ bottom: 0,
235
+ backgroundColor: 'rgba(0, 0, 0, 0.7)',
236
+ },
237
+ modalContainer: {
238
+ backgroundColor: colors.background,
239
+ borderTopLeftRadius: 30,
240
+ borderTopRightRadius: 30,
241
+ paddingHorizontal: 20,
242
+ paddingTop: 18,
243
+ paddingBottom: 36,
244
+ height: '80%',
245
+ shadowColor: '#000',
246
+ shadowOffset: {
247
+ width: 0,
248
+ height: -2,
249
+ },
250
+ shadowOpacity: 0.25,
251
+ shadowRadius: 3.84,
252
+ elevation: 50001,
253
+ },
254
+ sheetContent: {
255
+ paddingBottom:150
256
+ },
257
+ handleBar: {
258
+ width: 48,
259
+ height: 4,
260
+ backgroundColor: colors.outline,
261
+ borderRadius: 6,
262
+ alignSelf: 'center',
263
+ marginBottom: 15,
264
+ },
265
+ headerRow: {
266
+ flexDirection: 'row',
267
+ paddingHorizontal: 0,
268
+ marginBottom: spacing.md,
269
+ },
270
+ sectionHeader: {
271
+ ...typography.bodySmall,
272
+ color: colors.onSurfaceVariant,
273
+ fontWeight: '500',
274
+ flex: 1,
275
+ fontFamily: FontFamily.LEXEND_REGULAR,
276
+ },
277
+ content: {
278
+ flexDirection: 'row',
279
+ flex: 1,
280
+ minHeight: 300,
281
+ },
282
+ productTypeSection: {
283
+ width: 156,
284
+ backgroundColor: 'rgba(243, 244, 247, 0.65)',
285
+ marginRight: spacing.md,
286
+ },
287
+ productTypeItem: {
288
+ padding: spacing.sm,
289
+ borderLeftWidth: 2,
290
+ borderLeftColor: 'transparent',
291
+ },
292
+ productTypeItemSelected: {
293
+ borderLeftColor: colors.primary,
294
+ backgroundColor: 'rgba(237, 59, 65, 0.15)',
295
+ },
296
+ productTypeText: {
297
+ ...typography.caption,
298
+ color: colors.onSurface,
299
+ lineHeight: 18,
300
+ fontFamily: FontFamily.LEXEND_REGULAR,
301
+ },
302
+ categorySection: {
303
+ flex: 1,
304
+ },
305
+ categoryItem: {
306
+ flexDirection: 'row',
307
+ alignItems: 'center',
308
+ padding: spacing.sm,
309
+ gap: spacing.sm,
310
+ },
311
+ checkbox: {
312
+ width: 16,
313
+ height: 16,
314
+ borderRadius: 4,
315
+ borderWidth: 1,
316
+ borderColor: colors.outline,
317
+ backgroundColor: colors.background,
318
+ justifyContent: 'center',
319
+ alignItems: 'center',
320
+ },
321
+ checkboxSelected: {
322
+ backgroundColor: '#DC291E',
323
+ borderColor: '#DC291E',
324
+ },
325
+ checkmark: {
326
+ color: colors.background,
327
+ fontSize: 10,
328
+ fontWeight: 'bold',
329
+ },
330
+ categoryText: {
331
+ ...typography.caption,
332
+ color: colors.onSurface,
333
+ fontFamily: FontFamily.LEXEND_REGULAR,
334
+ },
335
+ footer: {
336
+ flexDirection: 'row',
337
+ paddingTop: spacing.xl,
338
+ gap: spacing.md,
339
+ },
340
+ clearButton: {
341
+ flex: 1,
342
+ height: 55,
343
+ borderRadius: borderRadius.md,
344
+ borderWidth: 1,
345
+ borderColor: colors.onSurface,
346
+ backgroundColor: colors.background,
347
+ justifyContent: 'center',
348
+ alignItems: 'center',
349
+ },
350
+ clearButtonText: {
351
+ ...typography.button,
352
+ color: colors.onSurface,
353
+ fontWeight: '400',
354
+ fontFamily: FontFamily.LEXEND_REGULAR,
355
+ },
356
+ applyButton: {
357
+ flex: 1,
358
+ height: 55,
359
+ borderRadius: borderRadius.md,
360
+ backgroundColor: '#DC291E',
361
+ justifyContent: 'center',
362
+ alignItems: 'center',
363
+ },
364
+ applyButtonText: {
365
+ ...typography.button,
366
+ color: colors.background,
367
+ fontWeight: '700',
368
+ fontFamily: FontFamily.LEXEND_REGULAR,
369
+ },
370
+ });
371
+
372
+ export default FilterModal;
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { View, Text } from 'react-native';
3
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
+ import styles from './styles';
5
+ import { MIN_PADDING_BOTTOM } from './styles';
6
+ import Images from '../../constants/Images';
7
+ import CustomImage from '../CustomImage';
8
+
9
+ const Footer = () => {
10
+ const insets = useSafeAreaInsets();
11
+ const bottomPadding = Math.max(MIN_PADDING_BOTTOM, insets.bottom);
12
+
13
+ return (
14
+ <View style={[styles.footer, { paddingBottom: bottomPadding }]}>
15
+ <View style={styles.footerContent}>
16
+ <Text style={styles.poweredByText}>Powered By</Text>
17
+ <CustomImage source={Images?.zaggleLogo} imgStyle={styles.logo} />
18
+ </View>
19
+ </View>
20
+ );
21
+ };
22
+
23
+ export default Footer;
@@ -0,0 +1,37 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import FontFamily from '../../constants/Fonts';
3
+ import { SCALE, VSCALE } from '../../constants/Scaling';
4
+
5
+ export const MIN_PADDING_BOTTOM = VSCALE(4);
6
+
7
+ const styles = StyleSheet.create({
8
+ footer: {
9
+ // position: 'absolute',
10
+ // bottom: 0,
11
+ // left: 0,
12
+ // right: 0,
13
+ backgroundColor: '#FFFFFF',
14
+ alignItems: 'center',
15
+ height: VSCALE(40),
16
+ // zIndex: 1,
17
+ },
18
+ footerContent: {
19
+ flexDirection: 'row',
20
+ alignItems: 'center',
21
+ justifyContent: 'center',
22
+ gap: SCALE(4),
23
+ top: VSCALE(12),
24
+ },
25
+ poweredByText: {
26
+ fontFamily: FontFamily.LEXEND_REGULAR,
27
+ fontSize: SCALE(8),
28
+ color: '#6B7280',
29
+ },
30
+ logo: {
31
+ width: SCALE(103),
32
+ height: VSCALE(20),
33
+ resizeMode: 'contain',
34
+ },
35
+ });
36
+
37
+ export default styles;
@@ -0,0 +1,80 @@
1
+ import React from "react";
2
+ import { Text, StyleSheet } from "react-native";
3
+
4
+ interface IconProps {
5
+ name: string;
6
+ size?: number;
7
+ color?: string;
8
+ style?: any;
9
+ }
10
+
11
+ const Icon: React.FC<IconProps> = ({
12
+ name,
13
+ size = 24,
14
+ color = "#000",
15
+ style,
16
+ }) => {
17
+ const getIconText = (iconName: string) => {
18
+ switch (iconName) {
19
+ case "home":
20
+ return "🏠";
21
+ case "card-giftcard":
22
+ return "🎁";
23
+ case "person":
24
+ return "👤";
25
+ case "headset":
26
+ return "🎧";
27
+ case "help":
28
+ return "❓";
29
+ case "shopping-cart":
30
+ return "🛒";
31
+ case "arrow-back":
32
+ return "←";
33
+ case "keyboard-arrow-down":
34
+ return "▼";
35
+ case "info-outline":
36
+ return "ℹ️";
37
+ case "trending-up":
38
+ return "📈";
39
+ case "check-circle":
40
+ return "✅";
41
+ case "shopping-bag":
42
+ return "🛍️";
43
+ case "wifi":
44
+ return "📶";
45
+ case "history":
46
+ return "🕐";
47
+ case "trending-down":
48
+ return "📉";
49
+ case "filter":
50
+ return "📋";
51
+ case "search":
52
+ return "🔍";
53
+ default:
54
+ return "•";
55
+ }
56
+ };
57
+
58
+ return (
59
+ <Text
60
+ style={[
61
+ styles.icon,
62
+ {
63
+ fontSize: size,
64
+ color: color,
65
+ },
66
+ style,
67
+ ]}
68
+ >
69
+ {getIconText(name)}
70
+ </Text>
71
+ );
72
+ };
73
+
74
+ const styles = StyleSheet.create({
75
+ icon: {
76
+ textAlign: "center",
77
+ },
78
+ });
79
+
80
+ export default Icon;
@@ -0,0 +1,82 @@
1
+ import React, { useRef, useEffect } from 'react';
2
+ import {
3
+ View,
4
+ Modal,
5
+ Animated,
6
+ TouchableWithoutFeedback,
7
+ Dimensions,
8
+ Text,
9
+ } from 'react-native';
10
+ import styles from './styles';
11
+ import CustomButton from '../CustomButton';
12
+
13
+ const { height: screenHeight } = Dimensions.get('window');
14
+
15
+ interface LogoutProps {
16
+ visible: boolean;
17
+ onClose: () => void;
18
+ onPress: () => void;
19
+ }
20
+
21
+ const Logout: React.FC<LogoutProps> = ({ visible, onClose, onPress }) => {
22
+ const slideAnim = useRef(new Animated.Value(screenHeight)).current;
23
+
24
+ useEffect(() => {
25
+ if (visible) {
26
+ Animated.timing(slideAnim, {
27
+ toValue: 0,
28
+ duration: 300,
29
+ useNativeDriver: true,
30
+ }).start();
31
+ } else {
32
+ Animated.timing(slideAnim, {
33
+ toValue: screenHeight,
34
+ duration: 300,
35
+ useNativeDriver: true,
36
+ }).start();
37
+ }
38
+ }, [visible]);
39
+
40
+ if (!visible) return null;
41
+
42
+ return (
43
+ <Modal
44
+ transparent
45
+ visible={visible}
46
+ animationType="none"
47
+ onRequestClose={onClose}
48
+ >
49
+ <TouchableWithoutFeedback onPress={onClose}>
50
+ <View style={styles.overlay}>
51
+ <TouchableWithoutFeedback>
52
+ <Animated.View
53
+ style={[
54
+ styles.modalContainer,
55
+ {
56
+ transform: [{ translateY: slideAnim }],
57
+ },
58
+ ]}
59
+ >
60
+ <Text style={styles.title}>Are you sure you want Logout ?</Text>
61
+ <View style={styles.row}>
62
+ <CustomButton
63
+ title="No"
64
+ onPress={onClose}
65
+ buttonStyle={styles.leftButton}
66
+ textStyle={styles.leftButtonText}
67
+ />
68
+ <CustomButton
69
+ title="Yes"
70
+ onPress={onPress}
71
+ customButtonContainerStyle={styles.buttonContainer}
72
+ />
73
+ </View>
74
+ </Animated.View>
75
+ </TouchableWithoutFeedback>
76
+ </View>
77
+ </TouchableWithoutFeedback>
78
+ </Modal>
79
+ );
80
+ };
81
+
82
+ export default Logout;
@@ -0,0 +1,116 @@
1
+ import { StyleSheet } from 'react-native';
2
+ import FontFamily from '../../constants/Fonts';
3
+ import { VSCALE } from '../../constants/Scaling';
4
+ import { colors } from '../../styles/colors';
5
+
6
+ const styles = StyleSheet.create({
7
+ overlay: {
8
+ flex: 1,
9
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
10
+ justifyContent: 'flex-end',
11
+ alignItems: 'center',
12
+ },
13
+ modalContainer: {
14
+ width: '100%',
15
+ maxWidth: '100%',
16
+ height: '30%',
17
+ backgroundColor: '#FFFFFF',
18
+ borderTopLeftRadius: 30,
19
+ borderTopRightRadius: 30,
20
+ paddingHorizontal: 20,
21
+ paddingTop: 18,
22
+ paddingBottom: 36,
23
+ },
24
+ handleBar: {
25
+ width: 48,
26
+ height: 4,
27
+ backgroundColor: '#D1D5DB',
28
+ borderRadius: 6,
29
+ alignSelf: 'center',
30
+ marginBottom: 27,
31
+ },
32
+ title: {
33
+ fontFamily: FontFamily.LEXEND_REGULAR,
34
+ fontSize: 16,
35
+ fontWeight: '500',
36
+ color: colors.logOutTitle,
37
+ // textTransform: 'capitalize',
38
+ marginBottom: VSCALE(8),
39
+ textAlign: 'center',
40
+ marginTop: VSCALE(29),
41
+ },
42
+ icon: {
43
+ height: 24,
44
+ width: 24,
45
+ bottom: 3,
46
+ },
47
+ row: {
48
+ flexDirection: 'row',
49
+ alignItems: 'center',
50
+ justifyContent: 'space-between',
51
+ gap: VSCALE(10),
52
+ marginTop: VSCALE(20),
53
+ },
54
+ leftText: {
55
+ fontFamily: FontFamily.LEXEND_REGULAR,
56
+ fontSize: 12,
57
+ fontWeight: '500',
58
+ color: '#6B7280',
59
+ textTransform: 'capitalize',
60
+ marginBottom: VSCALE(12),
61
+ },
62
+ amountText: {
63
+ fontFamily: FontFamily.LEXEND_REGULAR,
64
+ fontSize: 12,
65
+ fontWeight: '600',
66
+ color: '#6B7280',
67
+ textTransform: 'capitalize',
68
+ marginTop: 10,
69
+ },
70
+ separator: {
71
+ height: 1.2,
72
+ backgroundColor: 'transparent',
73
+ marginVertical: 8,
74
+ width: '100%',
75
+ alignSelf: 'center',
76
+ borderTopWidth: 1,
77
+ borderTopColor: 'rgba(209, 213, 219, 0.65)',
78
+ },
79
+ content: {
80
+ marginTop: 20,
81
+ },
82
+ rightText: {
83
+ fontFamily: FontFamily.LEXEND_REGULAR,
84
+ fontSize: 14,
85
+ fontWeight: '600',
86
+ color: '#1F2937',
87
+ textTransform: 'capitalize',
88
+ marginBottom: 12,
89
+ },
90
+ amountPoints: {
91
+ fontFamily: FontFamily.LEXEND_REGULAR,
92
+ fontSize: 16,
93
+ fontWeight: '600',
94
+ color: '#1F2937',
95
+ textTransform: 'capitalize',
96
+ marginTop: 10,
97
+ },
98
+ buttonContainer: {
99
+ width: VSCALE(130),
100
+ },
101
+ leftButton: {
102
+ width: VSCALE(130),
103
+ borderWidth: 1,
104
+ borderColor: colors.black,
105
+ backgroundColor: colors.white,
106
+ },
107
+ leftButtonText: {
108
+ color: colors.black,
109
+ fontFamily: FontFamily.LEXEND_MEDIUM,
110
+ fontSize: 14,
111
+ fontWeight: '600',
112
+ textTransform: 'capitalize',
113
+ },
114
+ });
115
+
116
+ export default styles;