react-native-srschat 0.1.83 → 0.1.85

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 (59) hide show
  1. package/lib/commonjs/components/email.js +5 -9
  2. package/lib/commonjs/components/email.js.map +1 -1
  3. package/lib/commonjs/components/productCard.js +91 -86
  4. package/lib/commonjs/components/productCard.js.map +1 -1
  5. package/lib/commonjs/components/welcomeButton.js +4 -4
  6. package/lib/commonjs/components/welcomeButton.js.map +1 -1
  7. package/lib/commonjs/contexts/AppContext.js +46 -45
  8. package/lib/commonjs/contexts/AppContext.js.map +1 -1
  9. package/lib/commonjs/hooks/Stream.js +399 -74
  10. package/lib/commonjs/hooks/Stream.js.map +1 -1
  11. package/lib/commonjs/layout/disclaimer.js +36 -32
  12. package/lib/commonjs/layout/disclaimer.js.map +1 -1
  13. package/lib/commonjs/layout/welcome.js +8 -7
  14. package/lib/commonjs/layout/welcome.js.map +1 -1
  15. package/lib/commonjs/layout/window.js +152 -131
  16. package/lib/commonjs/layout/window.js.map +1 -1
  17. package/lib/commonjs/utils/audioRecorder.js.map +1 -1
  18. package/lib/commonjs/utils/storage.js +1 -1
  19. package/lib/module/components/email.js +5 -9
  20. package/lib/module/components/email.js.map +1 -1
  21. package/lib/module/components/productCard.js +94 -89
  22. package/lib/module/components/productCard.js.map +1 -1
  23. package/lib/module/components/welcomeButton.js +4 -4
  24. package/lib/module/components/welcomeButton.js.map +1 -1
  25. package/lib/module/contexts/AppContext.js +47 -46
  26. package/lib/module/contexts/AppContext.js.map +1 -1
  27. package/lib/module/hooks/Stream.js +400 -75
  28. package/lib/module/hooks/Stream.js.map +1 -1
  29. package/lib/module/layout/disclaimer.js +41 -37
  30. package/lib/module/layout/disclaimer.js.map +1 -1
  31. package/lib/module/layout/welcome.js +8 -7
  32. package/lib/module/layout/welcome.js.map +1 -1
  33. package/lib/module/layout/window.js +152 -131
  34. package/lib/module/layout/window.js.map +1 -1
  35. package/lib/module/utils/audioRecorder.js.map +1 -1
  36. package/lib/module/utils/storage.js +1 -1
  37. package/lib/typescript/components/email.d.ts.map +1 -1
  38. package/lib/typescript/components/productCard.d.ts +1 -1
  39. package/lib/typescript/components/productCard.d.ts.map +1 -1
  40. package/lib/typescript/components/welcomeButton.d.ts.map +1 -1
  41. package/lib/typescript/contexts/AppContext.d.ts +2 -2
  42. package/lib/typescript/contexts/AppContext.d.ts.map +1 -1
  43. package/lib/typescript/hooks/Stream.d.ts.map +1 -1
  44. package/lib/typescript/layout/disclaimer.d.ts +1 -1
  45. package/lib/typescript/layout/disclaimer.d.ts.map +1 -1
  46. package/lib/typescript/layout/welcome.d.ts.map +1 -1
  47. package/lib/typescript/layout/window.d.ts.map +1 -1
  48. package/lib/typescript/utils/audioRecorder.d.ts.map +1 -1
  49. package/package.json +2 -1
  50. package/src/components/email.js +4 -16
  51. package/src/components/productCard.js +279 -203
  52. package/src/components/welcomeButton.js +10 -10
  53. package/src/contexts/AppContext.js +185 -106
  54. package/src/hooks/Stream.js +607 -237
  55. package/src/layout/disclaimer.js +125 -78
  56. package/src/layout/welcome.js +58 -20
  57. package/src/layout/window.js +279 -140
  58. package/src/utils/audioRecorder.js +40 -34
  59. package/src/utils/storage.ts +2 -2
@@ -1,13 +1,32 @@
1
- import React, { useState, useContext, useEffect } from "react";
2
- import { View, Text, Image, TouchableOpacity, TextInput, StyleSheet, Platform, Keyboard, ActionSheetIOS, Alert } from "react-native";
3
- import { AppContext } from "../contexts/AppContext";
1
+ import React, { useState, useContext, useEffect } from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ Image,
6
+ TouchableOpacity,
7
+ TextInput,
8
+ StyleSheet,
9
+ Platform,
10
+ Keyboard,
11
+ ActionSheetIOS,
12
+ Alert,
13
+ } from 'react-native';
14
+ import { AppContext } from '../contexts/AppContext';
4
15
  import Ionicons from 'react-native-vector-icons/Ionicons';
5
16
 
6
-
7
17
  export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
8
- const { onProductCardClick, onAddToCartClick, sessionId, data, ADD_TO_CART_URL } = useContext(AppContext);
9
- const [keyboardVisible, setKeyboardVisible] = useState(false);
18
+ useEffect(() => {
19
+ console.log('What is prod: ', prod);
20
+ }, []);
10
21
 
22
+ const {
23
+ onProductCardClick,
24
+ onAddToCartClick,
25
+ sessionId,
26
+ data,
27
+ ADD_TO_CART_URL,
28
+ } = useContext(AppContext);
29
+ const [keyboardVisible, setKeyboardVisible] = useState(false);
11
30
  // Validation: Check for incomplete product information
12
31
  const hasValidProductDetails = () => {
13
32
  if (!prod || !prod.product_details) {
@@ -37,16 +56,18 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
37
56
  // Check if at least one UOM has valid pricing
38
57
  const hasValidPricing = uomKeys.some(uom => {
39
58
  const uomInfo = uomData[uom];
40
- return uomInfo &&
41
- typeof uomInfo.gross_price === 'number' &&
42
- uomInfo.gross_price > 0;
59
+ return (
60
+ uomInfo &&
61
+ typeof uomInfo.gross_price === 'number' &&
62
+ uomInfo.gross_price > 0
63
+ );
43
64
  });
44
65
 
45
66
  return hasValidPricing;
46
67
  };
47
68
 
48
69
  // Return null if product lacks essential information
49
- if (!hasValidProductDetails() || !hasValidInventoryInfo()) {
70
+ if (!hasValidProductDetails()) {
50
71
  return null;
51
72
  }
52
73
 
@@ -56,11 +77,11 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
56
77
  const defaultUom = prod.inventory_info.default_uom;
57
78
  return availableUoms.includes(defaultUom) ? defaultUom : availableUoms[0];
58
79
  }
59
- return "EA";
80
+ return 'EA';
60
81
  });
61
82
 
62
83
  // Helper function to get min_pack_qty, defaulting to 1 if not applicable
63
- const getMinPackQtyForUom = (uomKey) => {
84
+ const getMinPackQtyForUom = uomKey => {
64
85
  const minPackStr = prod.inventory_info?.info_by_uom?.[uomKey]?.min_pack_qty;
65
86
  if (minPackStr) {
66
87
  const minPackNum = parseFloat(minPackStr);
@@ -74,25 +95,30 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
74
95
 
75
96
  const uoms = prod.inventory_info?.info_by_uom
76
97
  ? Object.keys(prod.inventory_info.info_by_uom)
77
- : ["EA"];
78
-
98
+ : ['EA'];
99
+
79
100
  const uomInfo = prod.inventory_info?.info_by_uom?.[selectedUom] || {};
80
101
  const grossPrice = uomInfo.gross_price || 0;
81
102
  const netPrice = uomInfo.net_price || 0;
82
103
  const isOnSale = uomInfo.is_on_sale || false;
83
- const discountsArray = Array.isArray(uomInfo.discounts) ? uomInfo.discounts : [];
84
- const discountsString = uomInfo.discounts ? uomInfo.discounts : "";
85
-
104
+ const discountsArray = Array.isArray(uomInfo.discounts)
105
+ ? uomInfo.discounts
106
+ : [];
107
+ const discountsString = uomInfo.discounts ? uomInfo.discounts : '';
108
+
86
109
  // maxQuantity is for display purposes only now
87
- const maxQuantity = Math.floor(uomInfo.quantity_available || 0);
110
+ const maxQuantity = Math.floor(uomInfo.quantity_available || 0);
88
111
  const valid = prod.inventory_info?.is_valid || false;
112
+
113
+ console.log(prod.inventory_info);
114
+
89
115
  // inStock is for display purposes or if specific logic still needs it, but not for quantity restriction
90
- const inStock = maxQuantity > 0;
91
-
116
+ const inStock = maxQuantity > 0;
117
+
92
118
  const currentMinPackQtyForSelectedUom = getMinPackQtyForUom(selectedUom);
93
119
 
94
120
  const [quantity, setQuantity] = useState(0);
95
- const [quantityText, setQuantityText] = useState("0"); // Track the text input separately
121
+ const [quantityText, setQuantityText] = useState('0'); // Track the text input separately
96
122
 
97
123
  // Add keyboard listeners to detect when keyboard appears/disappears
98
124
  useEffect(() => {
@@ -104,14 +130,14 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
104
130
  if (onFocusQuantityInput) {
105
131
  onFocusQuantityInput(prod.part_number);
106
132
  }
107
- }
133
+ },
108
134
  );
109
-
135
+
110
136
  const keyboardDidHideListener = Keyboard.addListener(
111
137
  'keyboardDidHide',
112
138
  () => {
113
139
  setKeyboardVisible(false);
114
- }
140
+ },
115
141
  );
116
142
 
117
143
  return () => {
@@ -121,31 +147,31 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
121
147
  }, []);
122
148
 
123
149
  // Called on every keystroke in the quantity input
124
- const handleQuantityChange = (text) => {
150
+ const handleQuantityChange = text => {
125
151
  const rawValue = text.trim();
126
-
152
+
127
153
  // Update the text display immediately
128
154
  setQuantityText(rawValue);
129
-
155
+
130
156
  // Handle empty input
131
- if (rawValue === "") {
132
- setQuantity(0);
133
- return;
157
+ if (rawValue === '') {
158
+ setQuantity(0);
159
+ return;
134
160
  }
135
-
161
+
136
162
  // Allow partial decimal inputs like "." or "1."
137
- if (rawValue === "." || rawValue.endsWith(".")) {
138
- // Don't update quantity state for partial decimal inputs, just keep the text
139
- return;
163
+ if (rawValue === '.' || rawValue.endsWith('.')) {
164
+ // Don't update quantity state for partial decimal inputs, just keep the text
165
+ return;
140
166
  }
141
-
167
+
142
168
  const numericValue = parseFloat(rawValue);
143
169
  if (!isNaN(numericValue) && numericValue >= 0) {
144
- // Round to 2 decimal places to handle decimal min pack quantities
145
- setQuantity(Math.round(numericValue * 100) / 100);
170
+ // Round to 2 decimal places to handle decimal min pack quantities
171
+ setQuantity(Math.round(numericValue * 100) / 100);
146
172
  } else {
147
- // Invalid input, reset quantity but keep the text for user feedback
148
- setQuantity(0);
173
+ // Invalid input, reset quantity but keep the text for user feedback
174
+ setQuantity(0);
149
175
  }
150
176
  };
151
177
 
@@ -156,32 +182,32 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
156
182
  // Parse the final text input
157
183
  const rawValue = quantityText.trim();
158
184
  let finalQuantity = 0;
159
-
160
- if (rawValue !== "") {
161
- const numericValue = parseFloat(rawValue);
162
- if (!isNaN(numericValue) && numericValue >= 0) {
163
- finalQuantity = Math.round(numericValue * 100) / 100;
164
- }
185
+
186
+ if (rawValue !== '') {
187
+ const numericValue = parseFloat(rawValue);
188
+ if (!isNaN(numericValue) && numericValue >= 0) {
189
+ finalQuantity = Math.round(numericValue * 100) / 100;
190
+ }
165
191
  }
166
192
 
167
193
  // Only basic validation - don't auto-correct to min pack quantities
168
194
  if (!isProdValid) {
169
- setQuantity(0);
170
- setQuantityText("0");
171
- return;
195
+ setQuantity(0);
196
+ setQuantityText('0');
197
+ return;
172
198
  }
173
199
 
174
200
  // Just ensure quantity is not negative, but allow any positive decimal value
175
201
  if (finalQuantity < 0) {
176
- setQuantity(0);
177
- setQuantityText("0");
178
- return;
202
+ setQuantity(0);
203
+ setQuantityText('0');
204
+ return;
179
205
  }
180
206
 
181
207
  // Update both states with the final parsed value
182
208
  setQuantity(finalQuantity);
183
209
  setQuantityText(finalQuantity.toString());
184
-
210
+
185
211
  // Keep the user's input as-is for valid products
186
212
  // Validation and alerts will happen in handleAddToCart
187
213
  };
@@ -189,10 +215,10 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
189
215
  const incrementQuantity = () => {
190
216
  const uomForCalc = selectedUom;
191
217
  const minPackForUom = getMinPackQtyForUom(uomForCalc);
192
-
218
+
193
219
  setQuantity(prevQuantity => {
194
220
  let newQuantity;
195
-
221
+
196
222
  if (prevQuantity === 0) {
197
223
  // If starting from 0, go to first min pack
198
224
  newQuantity = minPackForUom;
@@ -201,7 +227,8 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
201
227
  newQuantity = prevQuantity + minPackForUom;
202
228
  } else {
203
229
  // Find the next valid multiple of min pack quantity
204
- const nextMultiple = Math.ceil(prevQuantity / minPackForUom) * minPackForUom;
230
+ const nextMultiple =
231
+ Math.ceil(prevQuantity / minPackForUom) * minPackForUom;
205
232
  // If current quantity is already a perfect multiple, go to next multiple
206
233
  if (Math.abs(prevQuantity % minPackForUom) < 0.01) {
207
234
  newQuantity = prevQuantity + minPackForUom;
@@ -223,19 +250,20 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
223
250
 
224
251
  setQuantity(prevQuantity => {
225
252
  if (prevQuantity === 0) {
226
- setQuantityText("0");
253
+ setQuantityText('0');
227
254
  return 0; // Cannot go below 0
228
255
  }
229
256
 
230
257
  let newQuantity;
231
-
258
+
232
259
  if (minPackForUom <= 1) {
233
260
  // If min pack is 1 or less, just decrement by min pack
234
261
  newQuantity = Math.max(0, prevQuantity - minPackForUom);
235
262
  } else {
236
263
  // Find the previous valid multiple of min pack quantity
237
- const prevMultiple = Math.floor(prevQuantity / minPackForUom) * minPackForUom;
238
-
264
+ const prevMultiple =
265
+ Math.floor(prevQuantity / minPackForUom) * minPackForUom;
266
+
239
267
  // If current quantity is already a perfect multiple, go to previous multiple
240
268
  if (Math.abs(prevQuantity % minPackForUom) < 0.01) {
241
269
  newQuantity = Math.max(0, prevQuantity - minPackForUom);
@@ -244,7 +272,7 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
244
272
  newQuantity = prevMultiple;
245
273
  }
246
274
  }
247
-
275
+
248
276
  // Round to 2 decimal places to handle decimal min pack quantities
249
277
  const finalQuantity = Math.round(newQuantity * 100) / 100;
250
278
  setQuantityText(finalQuantity.toString());
@@ -253,25 +281,29 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
253
281
  };
254
282
 
255
283
  const handleAddToCart = () => {
256
- if (!valid ) {
284
+ if (!valid) {
257
285
  return;
258
286
  }
259
287
 
260
- const executeAddToCartLogic = (qtyToAdd) => {
288
+ const executeAddToCartLogic = qtyToAdd => {
261
289
  try {
262
- const discount = discountsString ? discountsString : (Array.isArray(discountsArray) ? discountsArray.join(", ") : "");
290
+ const discount = discountsString
291
+ ? discountsString
292
+ : Array.isArray(discountsArray)
293
+ ? discountsArray.join(', ')
294
+ : '';
263
295
  const payload = {
264
296
  product_name: prod.product_details.product_name,
265
297
  time_stamp: new Date().toISOString(),
266
298
  user_id: data.user_id,
267
- session_id : data.session_id || data.session || sessionId,
299
+ session_id: data.session_id || data.session || sessionId,
268
300
  quantity: qtyToAdd,
269
301
  uom: selectedUom,
270
302
  is_sale: isOnSale,
271
303
  discount_string: discount,
272
- message_id: messageId
304
+ message_id: messageId,
273
305
  };
274
- console.log("add to cart payload", payload);
306
+ console.log('add to cart payload', payload);
275
307
  fetch(ADD_TO_CART_URL, {
276
308
  method: 'POST',
277
309
  headers: {
@@ -286,18 +318,18 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
286
318
  return response.json();
287
319
  })
288
320
  .then(data => {
289
- console.log("log addToCart response", data);
321
+ console.log('log addToCart response', data);
290
322
  })
291
323
  .catch(error => {
292
- console.log("log addToCart error", error);
324
+ console.log('log addToCart error', error);
293
325
  });
294
326
  } catch (error) {
295
- console.log("log addToCart error", error);
327
+ console.log('log addToCart error', error);
296
328
  }
297
329
  onAddToCartClick({
298
330
  selectedUom: selectedUom,
299
331
  quantity: qtyToAdd,
300
- product: prod
332
+ product: prod,
301
333
  });
302
334
  };
303
335
 
@@ -306,12 +338,20 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
306
338
  if (requestedQty <= 0) {
307
339
  requestedQty = 1;
308
340
  setQuantity(1);
309
- setQuantityText("1");
341
+ setQuantityText('1');
310
342
  }
311
343
 
312
344
  // Check if quantity is valid for min pack requirements
313
- if (currentMinPackQtyForSelectedUom > 1 && Math.abs(requestedQty % currentMinPackQtyForSelectedUom) > 0.01) {
314
- const roundedResult = Math.round(Math.ceil(requestedQty / currentMinPackQtyForSelectedUom) * currentMinPackQtyForSelectedUom * 100) / 100;
345
+ if (
346
+ currentMinPackQtyForSelectedUom > 1 &&
347
+ Math.abs(requestedQty % currentMinPackQtyForSelectedUom) > 0.01
348
+ ) {
349
+ const roundedResult =
350
+ Math.round(
351
+ Math.ceil(requestedQty / currentMinPackQtyForSelectedUom) *
352
+ currentMinPackQtyForSelectedUom *
353
+ 100,
354
+ ) / 100;
315
355
 
316
356
  Alert.alert(
317
357
  `Item #${prod.part_number} is sold in multiples of ${currentMinPackQtyForSelectedUom} ${selectedUom}`,
@@ -332,7 +372,7 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
332
372
  },
333
373
  },
334
374
  ],
335
- { cancelable: true } // User can dismiss the alert by tapping outside on Android
375
+ { cancelable: true }, // User can dismiss the alert by tapping outside on Android
336
376
  );
337
377
  } else {
338
378
  // No rounding needed, or item is sold individually (min pack <= 1)
@@ -340,24 +380,24 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
340
380
  executeAddToCartLogic(requestedQty);
341
381
  }
342
382
  };
343
-
383
+
344
384
  const handleProductClick = () => {
345
385
  const prodWithSku = {
346
- ...prod,
347
- sku: prod.product_details.sku // Using the SKU from product_details
386
+ ...prod,
387
+ sku: prod.product_details.sku, // Using the SKU from product_details
348
388
  };
349
- console.log("Product clicked:", JSON.stringify(prodWithSku, null, 2));
350
- onProductCardClick(prodWithSku);
389
+ console.log('Product clicked:', JSON.stringify(prodWithSku, null, 2));
390
+ onProductCardClick(prodWithSku);
351
391
  };
352
-
353
- const handleUomChange = (newUom) => {
354
- setSelectedUom(newUom);
392
+
393
+ const handleUomChange = newUom => {
394
+ setSelectedUom(newUom);
355
395
 
356
396
  // Always set quantity to 0 when UOM changes
357
397
  setQuantity(0);
358
- setQuantityText("0");
398
+ setQuantityText('0');
359
399
  };
360
-
400
+
361
401
  const openUomPicker = () => {
362
402
  if (Platform.OS === 'ios') {
363
403
  ActionSheetIOS.showActionSheetWithOptions(
@@ -366,34 +406,29 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
366
406
  cancelButtonIndex: uoms.length,
367
407
  title: 'Select Unit',
368
408
  },
369
- (buttonIndex) => {
409
+ buttonIndex => {
370
410
  if (buttonIndex !== uoms.length) {
371
411
  handleUomChange(uoms[buttonIndex]);
372
412
  }
373
- }
413
+ },
374
414
  );
375
415
  } else if (Platform.OS === 'android') {
376
416
  // Android implementation
377
417
  const buttons = uoms.map(uom => ({
378
418
  text: uom,
379
- onPress: () => handleUomChange(uom)
419
+ onPress: () => handleUomChange(uom),
380
420
  }));
381
-
421
+
382
422
  // Add cancel button
383
423
  buttons.push({
384
424
  text: 'Cancel',
385
- style: 'cancel'
425
+ style: 'cancel',
386
426
  });
387
-
388
- Alert.alert(
389
- 'Select Unit',
390
- '',
391
- buttons,
392
- { cancelable: true }
393
- );
427
+
428
+ Alert.alert('Select Unit', '', buttons, { cancelable: true });
394
429
  }
395
430
  };
396
-
431
+
397
432
  return (
398
433
  <View style={styles.card}>
399
434
  {/* Two-column layout */}
@@ -406,53 +441,89 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
406
441
  <Text style={styles.saleTagText}>SALE</Text>
407
442
  </View>
408
443
  )}
409
- <Image source={{ uri: prod.product_details.image_url }} style={styles.image} />
444
+ <Image
445
+ source={
446
+ prod.product_details.image_url
447
+ ? { uri: prod.product_details.image_url }
448
+ : require('../assets/heritage.png')
449
+ }
450
+ style={styles.image}
451
+ defaultSource={require('../assets/heritage.png')}
452
+ />
410
453
  </TouchableOpacity>
411
- {valid &&
454
+ {valid && (
412
455
  <>
413
- <View style={styles.priceContainer}>
456
+ <View style={styles.priceContainer}>
414
457
  {isOnSale ? (
415
- <>
416
- <Text style={styles.originalPrice} allowFontScaling={false}>${Number(grossPrice).toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}</Text>
417
- <Text style={styles.salePrice} allowFontScaling={false}>${Number(netPrice).toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}</Text>
458
+ <>
459
+ <Text style={styles.originalPrice} allowFontScaling={false}>
460
+ $
461
+ {Number(grossPrice).toLocaleString('en-US', {
462
+ minimumFractionDigits: 2,
463
+ maximumFractionDigits: 2,
464
+ })}
465
+ </Text>
466
+ <Text style={styles.salePrice} allowFontScaling={false}>
467
+ $
468
+ {Number(netPrice).toLocaleString('en-US', {
469
+ minimumFractionDigits: 2,
470
+ maximumFractionDigits: 2,
471
+ })}
472
+ </Text>
418
473
  <Text style={styles.perUnit}>/ {selectedUom}</Text>
419
- </>
474
+ </>
420
475
  ) : (
421
- <>
422
- <Text style={styles.price} allowFontScaling={false}>${Number(grossPrice).toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}</Text>
476
+ <>
477
+ <Text style={styles.price} allowFontScaling={false}>
478
+ $
479
+ {Number(grossPrice).toLocaleString('en-US', {
480
+ minimumFractionDigits: 2,
481
+ maximumFractionDigits: 2,
482
+ })}
483
+ </Text>
423
484
  <Text style={styles.perUnit}>/ {selectedUom}</Text>
424
- </>
485
+ </>
425
486
  )}
426
- </View>
427
- <Text style={styles.availability}>
428
- {maxQuantity === 0 ? "0 available" : maxQuantity > 1000 ? "1000+ available" : `${maxQuantity} available`}
429
- </Text>
487
+ </View>
488
+ <Text style={styles.availability}>
489
+ {maxQuantity === 0
490
+ ? '0 available'
491
+ : maxQuantity > 1000
492
+ ? '1000+ available'
493
+ : `${maxQuantity} available`}
494
+ </Text>
430
495
  </>
431
- }
496
+ )}
432
497
  </View>
433
498
 
434
499
  {/* Right Column (Product Details) */}
435
500
  <View style={styles.rightColumn}>
436
501
  <TouchableOpacity onPress={handleProductClick}>
437
- <Text style={styles.productName}>{prod.product_details.product_name}</Text>
502
+ <Text style={styles.productName}>
503
+ {prod.product_details.product_name}
504
+ </Text>
438
505
  </TouchableOpacity>
439
506
 
440
507
  <Text style={styles.details}>
441
- <Text style={styles.boldText}>MFG # </Text>{prod.product_details.manufacturer_id}
508
+ <Text style={styles.boldText}>MFG # </Text>
509
+ {prod.product_details.manufacturer_id}
442
510
  </Text>
443
511
  <Text style={styles.details}>
444
- <Text style={styles.boldText}>Part # </Text>{prod.part_number}
512
+ <Text style={styles.boldText}>Part # </Text>
513
+ {prod.part_number}
445
514
  </Text>
446
515
 
447
516
  {/* Display discounts if available */}
448
517
  {discountsArray.length > 0 && (
449
518
  <View style={styles.discountContainer}>
450
519
  {discountsArray.map((discount, index) => (
451
- <Text key={index} style={styles.discountText}>{discount}</Text>
520
+ <Text key={index} style={styles.discountText}>
521
+ {discount}
522
+ </Text>
452
523
  ))}
453
524
  </View>
454
525
  )}
455
- {discountsString == 0 && discountsString !== "" && (
526
+ {discountsString == 0 && discountsString !== '' && (
456
527
  <Text style={styles.discountText}>{discountsString}</Text>
457
528
  )}
458
529
 
@@ -461,33 +532,36 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
461
532
  {uoms.length > 1 ? (
462
533
  <View style={styles.uomSelectorContainer}>
463
534
  <Text style={styles.inputLabel}>Unit</Text>
464
- <TouchableOpacity
535
+ <TouchableOpacity
465
536
  style={styles.dropdownButton}
466
537
  onPress={openUomPicker}
467
- disabled={!valid}
468
- >
538
+ disabled={!valid}>
469
539
  <Text style={styles.dropdownButtonText}>{selectedUom}</Text>
470
540
  </TouchableOpacity>
471
541
  </View>
472
542
  ) : null}
473
-
543
+
474
544
  <View style={styles.quantityContainer}>
475
545
  <Text style={styles.inputLabel}>
476
- Qty {currentMinPackQtyForSelectedUom > 1 ? `(Sold in multiples of ${currentMinPackQtyForSelectedUom})` : ''}
546
+ Qty{' '}
547
+ {currentMinPackQtyForSelectedUom > 1
548
+ ? `(Sold in multiples of ${currentMinPackQtyForSelectedUom})`
549
+ : ''}
477
550
  </Text>
478
551
  <View style={styles.quantityInputContainer}>
479
- <TouchableOpacity
552
+ <TouchableOpacity
480
553
  style={styles.quantityButton}
481
554
  onPress={decrementQuantity}
482
- disabled={!valid || quantity <= 0}
483
- >
484
- <Ionicons
485
- name="remove"
486
- size={18}
487
- color={valid && quantity > 0 ? "#367cb6" : "rgba(0, 0, 0, 0.23)"}
555
+ disabled={!valid || quantity <= 0}>
556
+ <Ionicons
557
+ name="remove"
558
+ size={18}
559
+ color={
560
+ valid && quantity > 0 ? '#367cb6' : 'rgba(0, 0, 0, 0.23)'
561
+ }
488
562
  />
489
563
  </TouchableOpacity>
490
-
564
+
491
565
  <TextInput
492
566
  value={quantityText}
493
567
  onChangeText={handleQuantityChange}
@@ -503,16 +577,15 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
503
577
  disableFullscreenUI={true}
504
578
  defaultValue="0"
505
579
  />
506
-
507
- <TouchableOpacity
580
+
581
+ <TouchableOpacity
508
582
  style={styles.quantityButton}
509
583
  onPress={incrementQuantity}
510
- disabled={!valid}
511
- >
512
- <Ionicons
513
- name="add"
514
- size={18}
515
- color={valid ? "#367cb6" : "rgba(0, 0, 0, 0.23)"}
584
+ disabled={!valid}>
585
+ <Ionicons
586
+ name="add"
587
+ size={18}
588
+ color={valid ? '#367cb6' : 'rgba(0, 0, 0, 0.23)'}
516
589
  />
517
590
  </TouchableOpacity>
518
591
  </View>
@@ -520,15 +593,18 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
520
593
  </View>
521
594
 
522
595
  {/* Add to Cart Button on a new line */}
523
- <TouchableOpacity
524
- onPress={handleAddToCart}
596
+ <TouchableOpacity
597
+ onPress={handleAddToCart}
525
598
  disabled={!valid}
526
599
  style={[
527
600
  styles.addToCartButton,
528
- valid ? styles.activeButton : styles.disabledButton
529
- ]}
530
- >
531
- <Text style={[styles.buttonText, valid ? styles.activeText : styles.disabledText]}>
601
+ valid ? styles.activeButton : styles.disabledButton,
602
+ ]}>
603
+ <Text
604
+ style={[
605
+ styles.buttonText,
606
+ valid ? styles.activeText : styles.disabledText,
607
+ ]}>
532
608
  Add to Cart
533
609
  </Text>
534
610
  </TouchableOpacity>
@@ -540,110 +616,110 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
540
616
 
541
617
  const styles = StyleSheet.create({
542
618
  card: {
543
- backgroundColor: "#fff",
619
+ backgroundColor: '#fff',
544
620
  width: '100%',
545
621
  padding: 12,
546
622
  paddingHorizontal: 16,
547
623
  borderRadius: 12,
548
- marginBottom: 5
624
+ marginBottom: 5,
549
625
  },
550
626
  row: {
551
- flexDirection: "row",
552
- alignItems: "flex-start",
627
+ flexDirection: 'row',
628
+ alignItems: 'flex-start',
553
629
  },
554
630
  leftColumn: {
555
- width: "25%",
556
- alignItems: "center",
557
- position: "relative",
631
+ width: '25%',
632
+ alignItems: 'center',
633
+ position: 'relative',
558
634
  },
559
635
  rightColumn: {
560
- width: "75%",
636
+ width: '75%',
561
637
  paddingLeft: 12,
562
638
  },
563
639
  image: {
564
640
  width: 80,
565
641
  height: 80,
566
- resizeMode: "contain",
642
+ resizeMode: 'contain',
567
643
  marginBottom: 5,
568
644
  },
569
645
  saleTag: {
570
- position: "absolute",
646
+ position: 'absolute',
571
647
  top: 0,
572
648
  left: 0,
573
- backgroundColor: "red",
649
+ backgroundColor: 'red',
574
650
  borderRadius: 4,
575
651
  paddingVertical: 2,
576
652
  paddingHorizontal: 5,
577
653
  zIndex: 1,
578
654
  },
579
655
  saleTagText: {
580
- color: "#fff",
656
+ color: '#fff',
581
657
  fontSize: 10,
582
- fontWeight: "bold",
658
+ fontWeight: 'bold',
583
659
  },
584
660
  price: {
585
661
  fontSize: 14,
586
- fontWeight: "bold",
587
- color: "#161616",
588
- textAlign: "center",
589
- textBreakStrategy: "simple",
590
- alignSelf: "stretch",
662
+ fontWeight: 'bold',
663
+ color: '#161616',
664
+ textAlign: 'center',
665
+ textBreakStrategy: 'simple',
666
+ alignSelf: 'stretch',
591
667
  lineHeight: 20,
592
668
  includeFontPadding: false,
593
669
  textAlignVertical: 'center',
594
670
  },
595
671
  priceContainer: {
596
- flexDirection: "column",
597
- alignItems: "center",
598
- justifyContent: "center",
672
+ flexDirection: 'column',
673
+ alignItems: 'center',
674
+ justifyContent: 'center',
599
675
  paddingHorizontal: 2,
600
676
  },
601
677
  originalPrice: {
602
678
  fontSize: 14,
603
- textDecorationLine: "line-through",
604
- color: "gray",
605
- textAlign: "center",
606
- textBreakStrategy: "simple",
679
+ textDecorationLine: 'line-through',
680
+ color: 'gray',
681
+ textAlign: 'center',
682
+ textBreakStrategy: 'simple',
607
683
  lineHeight: 20,
608
684
  includeFontPadding: false,
609
685
  textAlignVertical: 'center',
610
686
  },
611
687
  salePrice: {
612
688
  fontSize: 16,
613
- fontWeight: "bold",
614
- color: "red",
615
- textAlign: "center",
616
- textBreakStrategy: "simple",
689
+ fontWeight: 'bold',
690
+ color: 'red',
691
+ textAlign: 'center',
692
+ textBreakStrategy: 'simple',
617
693
  lineHeight: 22,
618
694
  includeFontPadding: false,
619
695
  textAlignVertical: 'center',
620
696
  },
621
697
  perUnit: {
622
698
  fontSize: 12,
623
- color: "gray",
624
- textAlign: "center",
699
+ color: 'gray',
700
+ textAlign: 'center',
625
701
  },
626
702
  availability: {
627
703
  fontSize: 12,
628
- color: "gray",
629
- textAlign: "center",
704
+ color: 'gray',
705
+ textAlign: 'center',
630
706
  marginTop: 3,
631
707
  },
632
708
  productName: {
633
709
  fontSize: 16,
634
- fontWeight: "medium",
635
- color: "#161616",
710
+ fontWeight: 'medium',
711
+ color: '#161616',
636
712
  marginBottom: 5,
637
- textDecorationLine: "underline",
638
- textDecorationColor: "#367CB6"
713
+ textDecorationLine: 'underline',
714
+ textDecorationColor: '#367CB6',
639
715
  },
640
716
  details: {
641
717
  fontSize: 13,
642
- color: "#555",
718
+ color: '#555',
643
719
  marginTop: 3,
644
720
  },
645
721
  boldText: {
646
- fontWeight: "bold",
722
+ fontWeight: 'bold',
647
723
  },
648
724
  discountContainer: {
649
725
  marginTop: 5,
@@ -651,13 +727,13 @@ const styles = StyleSheet.create({
651
727
  },
652
728
  discountText: {
653
729
  fontSize: 13,
654
- color: "#e41e31",
655
- fontWeight: "500",
730
+ color: '#e41e31',
731
+ fontWeight: '500',
656
732
  marginTop: 3,
657
733
  },
658
734
  inputRow: {
659
- flexDirection: "row",
660
- alignItems: "flex-end",
735
+ flexDirection: 'row',
736
+ alignItems: 'flex-end',
661
737
  marginTop: 10,
662
738
  marginBottom: 10,
663
739
  },
@@ -666,7 +742,7 @@ const styles = StyleSheet.create({
666
742
  },
667
743
  inputLabel: {
668
744
  fontSize: 12,
669
- color: "rgba(0, 0, 0, 0.6)",
745
+ color: 'rgba(0, 0, 0, 0.6)',
670
746
  marginBottom: 4,
671
747
  },
672
748
  dropdownButton: {
@@ -689,51 +765,51 @@ const styles = StyleSheet.create({
689
765
  flex: 1,
690
766
  },
691
767
  quantityInputContainer: {
692
- flexDirection: "row",
693
- alignItems: "center",
768
+ flexDirection: 'row',
769
+ alignItems: 'center',
694
770
  height: 40,
695
771
  borderWidth: 1,
696
- borderColor: "rgba(0, 0, 0, 0.23)",
772
+ borderColor: 'rgba(0, 0, 0, 0.23)',
697
773
  borderRadius: 4,
698
774
  },
699
775
  quantityButton: {
700
776
  width: 40,
701
777
  height: 40,
702
- justifyContent: "center",
703
- alignItems: "center",
778
+ justifyContent: 'center',
779
+ alignItems: 'center',
704
780
  },
705
781
  quantityInput: {
706
782
  flex: 1,
707
783
  height: 40,
708
- textAlign: "center",
784
+ textAlign: 'center',
709
785
  paddingHorizontal: 5,
710
786
  fontSize: 14,
711
787
  minWidth: 40,
712
- color: "#000",
788
+ color: '#000',
713
789
  },
714
790
  addToCartButton: {
715
791
  height: 40,
716
- justifyContent: "center",
717
- alignItems: "center",
792
+ justifyContent: 'center',
793
+ alignItems: 'center',
718
794
  borderRadius: 4,
719
795
  marginTop: 5,
720
796
  },
721
797
  activeButton: {
722
- backgroundColor: "#367cb6",
798
+ backgroundColor: '#367cb6',
723
799
  },
724
800
  disabledButton: {
725
- backgroundColor: "transparent",
801
+ backgroundColor: 'transparent',
726
802
  borderWidth: 1,
727
- borderColor: "rgba(0, 0, 0, 0.23)",
803
+ borderColor: 'rgba(0, 0, 0, 0.23)',
728
804
  },
729
805
  buttonText: {
730
806
  fontSize: 14,
731
- fontWeight: "bold",
807
+ fontWeight: 'bold',
732
808
  },
733
809
  activeText: {
734
- color: "#fff",
810
+ color: '#fff',
735
811
  },
736
812
  disabledText: {
737
- color: "rgba(0, 0, 0, 0.60)",
813
+ color: 'rgba(0, 0, 0, 0.60)',
738
814
  },
739
815
  });