react-native-srschat 0.1.56 → 0.1.57

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.
@@ -24,7 +24,8 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
24
24
  if (minPackStr) {
25
25
  const minPackNum = parseFloat(minPackStr);
26
26
  if (!isNaN(minPackNum) && minPackNum > 1.0) {
27
- return minPackNum;
27
+ // Round to 2 decimal places for decimal min pack quantities
28
+ return Math.round(minPackNum * 100) / 100;
28
29
  }
29
30
  }
30
31
  return 1; // Default min pack quantity for individual purchase
@@ -50,6 +51,7 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
50
51
  const currentMinPackQtyForSelectedUom = getMinPackQtyForUom(selectedUom);
51
52
 
52
53
  const [quantity, setQuantity] = useState(0);
54
+ const [quantityText, setQuantityText] = useState("0"); // Track the text input separately
53
55
 
54
56
  // Add keyboard listeners to detect when keyboard appears/disappears
55
57
  useEffect(() => {
@@ -80,49 +82,67 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
80
82
  // Called on every keystroke in the quantity input
81
83
  const handleQuantityChange = (text) => {
82
84
  const rawValue = text.trim();
85
+
86
+ // Update the text display immediately
87
+ setQuantityText(rawValue);
88
+
89
+ // Handle empty input
83
90
  if (rawValue === "") {
84
91
  setQuantity(0);
85
92
  return;
86
93
  }
87
- const numericValue = parseInt(rawValue, 10);
94
+
95
+ // Allow partial decimal inputs like "." or "1."
96
+ if (rawValue === "." || rawValue.endsWith(".")) {
97
+ // Don't update quantity state for partial decimal inputs, just keep the text
98
+ return;
99
+ }
100
+
101
+ const numericValue = parseFloat(rawValue);
88
102
  if (!isNaN(numericValue) && numericValue >= 0) {
89
- setQuantity(numericValue);
103
+ // Round to 2 decimal places to handle decimal min pack quantities
104
+ setQuantity(Math.round(numericValue * 100) / 100);
90
105
  } else {
91
- setQuantity(0);
106
+ // Invalid input, reset quantity but keep the text for user feedback
107
+ setQuantity(0);
92
108
  }
93
109
  };
94
110
 
95
111
  // Called when the quantity input loses focus (onEndEditing)
96
112
  const handleQuantityBlur = () => {
97
- const currentQuantityFromState = quantity;
98
- const uom = selectedUom;
99
- const minPack = getMinPackQtyForUom(uom);
100
113
  const isProdValid = prod.inventory_info?.is_valid || false;
101
114
 
102
- if (!isProdValid) {
103
- if (quantity !== 0) setQuantity(0);
104
- return;
115
+ // Parse the final text input
116
+ const rawValue = quantityText.trim();
117
+ let finalQuantity = 0;
118
+
119
+ if (rawValue !== "") {
120
+ const numericValue = parseFloat(rawValue);
121
+ if (!isNaN(numericValue) && numericValue >= 0) {
122
+ finalQuantity = Math.round(numericValue * 100) / 100;
123
+ }
105
124
  }
106
125
 
107
- if (currentQuantityFromState === 0) {
108
- if (quantity !== 0) setQuantity(0);
126
+ // Only basic validation - don't auto-correct to min pack quantities
127
+ if (!isProdValid) {
128
+ setQuantity(0);
129
+ setQuantityText("0");
109
130
  return;
110
131
  }
111
132
 
112
- let adjustedValue;
113
- if (minPack <= 1) {
114
- adjustedValue = currentQuantityFromState;
115
- } else {
116
- adjustedValue = Math.round(currentQuantityFromState / minPack) * minPack;
117
- if (currentQuantityFromState > 0 && adjustedValue === 0) {
118
- adjustedValue = minPack;
119
- }
133
+ // Just ensure quantity is not negative, but allow any positive decimal value
134
+ if (finalQuantity < 0) {
135
+ setQuantity(0);
136
+ setQuantityText("0");
137
+ return;
120
138
  }
121
139
 
122
- const finalQuantity = Math.max(0, adjustedValue);
123
- if (quantity !== finalQuantity) {
124
- setQuantity(finalQuantity);
125
- }
140
+ // Update both states with the final parsed value
141
+ setQuantity(finalQuantity);
142
+ setQuantityText(finalQuantity.toString());
143
+
144
+ // Keep the user's input as-is for valid products
145
+ // Validation and alerts will happen in handleAddToCart
126
146
  };
127
147
 
128
148
  const incrementQuantity = () => {
@@ -131,13 +151,28 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
131
151
 
132
152
  setQuantity(prevQuantity => {
133
153
  let newQuantity;
134
- if (prevQuantity === 0 && minPackForUom > 0) {
154
+
155
+ if (prevQuantity === 0) {
156
+ // If starting from 0, go to first min pack
135
157
  newQuantity = minPackForUom;
136
- } else {
158
+ } else if (minPackForUom <= 1) {
159
+ // If min pack is 1 or less, just increment by min pack
137
160
  newQuantity = prevQuantity + minPackForUom;
161
+ } else {
162
+ // Find the next valid multiple of min pack quantity
163
+ const nextMultiple = Math.ceil(prevQuantity / minPackForUom) * minPackForUom;
164
+ // If current quantity is already a perfect multiple, go to next multiple
165
+ if (Math.abs(prevQuantity % minPackForUom) < 0.01) {
166
+ newQuantity = prevQuantity + minPackForUom;
167
+ } else {
168
+ newQuantity = nextMultiple;
169
+ }
138
170
  }
139
171
 
140
- return newQuantity;
172
+ // Round to 2 decimal places to handle decimal min pack quantities
173
+ const finalQuantity = Math.round(newQuantity * 100) / 100;
174
+ setQuantityText(finalQuantity.toString());
175
+ return finalQuantity;
141
176
  });
142
177
  };
143
178
 
@@ -146,21 +181,33 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
146
181
  const minPackForUom = getMinPackQtyForUom(uomForCalc);
147
182
 
148
183
  setQuantity(prevQuantity => {
149
- if (prevQuantity === 0) return 0; // Cannot go below 0
150
-
151
- let newQuantity = prevQuantity - minPackForUom;
152
-
153
- if (newQuantity < 0) {
154
- newQuantity = 0;
184
+ if (prevQuantity === 0) {
185
+ setQuantityText("0");
186
+ return 0; // Cannot go below 0
155
187
  }
188
+
189
+ let newQuantity;
156
190
 
157
- // If new quantity is positive but less than minPackForUom, it should be 0
158
- // (as any purchase must be in multiples of minPackForUom or 0)
159
- if (newQuantity > 0 && newQuantity < minPackForUom) {
160
- newQuantity = 0;
191
+ if (minPackForUom <= 1) {
192
+ // If min pack is 1 or less, just decrement by min pack
193
+ newQuantity = Math.max(0, prevQuantity - minPackForUom);
194
+ } else {
195
+ // Find the previous valid multiple of min pack quantity
196
+ const prevMultiple = Math.floor(prevQuantity / minPackForUom) * minPackForUom;
197
+
198
+ // If current quantity is already a perfect multiple, go to previous multiple
199
+ if (Math.abs(prevQuantity % minPackForUom) < 0.01) {
200
+ newQuantity = Math.max(0, prevQuantity - minPackForUom);
201
+ } else {
202
+ // If not a perfect multiple, go to the lower multiple
203
+ newQuantity = prevMultiple;
204
+ }
161
205
  }
162
206
 
163
- return newQuantity;
207
+ // Round to 2 decimal places to handle decimal min pack quantities
208
+ const finalQuantity = Math.round(newQuantity * 100) / 100;
209
+ setQuantityText(finalQuantity.toString());
210
+ return finalQuantity;
164
211
  });
165
212
  };
166
213
 
@@ -201,8 +248,9 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
201
248
  });
202
249
  };
203
250
 
204
- if (currentMinPackQtyForSelectedUom > 1 && quantity % currentMinPackQtyForSelectedUom !== 0) {
205
- const roundedResult = Math.ceil(quantity / currentMinPackQtyForSelectedUom) * currentMinPackQtyForSelectedUom;
251
+ // Check if quantity is valid for min pack requirements
252
+ if (currentMinPackQtyForSelectedUom > 1 && Math.abs(quantity % currentMinPackQtyForSelectedUom) > 0.01) {
253
+ const roundedResult = Math.round(Math.ceil(quantity / currentMinPackQtyForSelectedUom) * currentMinPackQtyForSelectedUom * 100) / 100;
206
254
 
207
255
  Alert.alert(
208
256
  `Item #${prod.part_number} is sold in multiples of ${currentMinPackQtyForSelectedUom} ${selectedUom}`,
@@ -211,7 +259,7 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
211
259
  {
212
260
  text: 'Cancel',
213
261
  onPress: () => {
214
- setQuantity(0); // Reset quantity to 0
262
+ // Keep the user's input, don't reset to 0
215
263
  },
216
264
  style: 'cancel',
217
265
  },
@@ -246,6 +294,7 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
246
294
 
247
295
  // Always set quantity to 0 when UOM changes
248
296
  setQuantity(0);
297
+ setQuantityText("0");
249
298
  };
250
299
 
251
300
  const openUomPicker = () => {
@@ -376,7 +425,7 @@ export const ProductCard = ({ prod, onFocusQuantityInput, messageId }) => {
376
425
  </TouchableOpacity>
377
426
 
378
427
  <TextInput
379
- value={quantity.toString()}
428
+ value={quantityText}
380
429
  onChangeText={handleQuantityChange}
381
430
  onEndEditing={handleQuantityBlur}
382
431
  keyboardType="numeric"
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import { View, ScrollView, StyleSheet, Text } from 'react-native';
3
+ import { ProductCard } from './productCard';
4
+
5
+ const mockProduct = {
6
+ "part_number": "AEQO177",
7
+ "inventory_info": {
8
+ "default_uom": "EA",
9
+ "is_valid": true,
10
+ "info_by_uom": {
11
+ "EA": {
12
+ "gross_price": 7.83,
13
+ "net_price": 7.83,
14
+ "is_on_sale": false,
15
+ "quantity_available": 0,
16
+ "discounts": null,
17
+ "min_pack_qty": 1.5
18
+ }
19
+ }
20
+ },
21
+ "product_details": {
22
+ "product_name": "Aladdin Hayward SPX1600S SuperPump Lid Gasket | O-177-2",
23
+ "part_number": "AEQO177",
24
+ "manufacturer_id": "O-177-2",
25
+ "heritage_link": "https://www.heritagepoolplus.com/aeqo177-aladdin-o-ring-o-177-o-177-2-o-177-2",
26
+ "image_url": "https://media.heritageplus.com/image/upload/v1668157956/image/AEQO177_0.jpg"
27
+ }
28
+ };
29
+
30
+ export const TestProductCard = () => {
31
+ return (
32
+ <ScrollView style={styles.container}>
33
+ <Text style={styles.title}>Test Product Card</Text>
34
+ <ProductCard
35
+ prod={mockProduct}
36
+ onFocusQuantityInput={(partNumber) => console.log('Focus on:', partNumber)}
37
+ messageId="test-message-123"
38
+ />
39
+ </ScrollView>
40
+ );
41
+ };
42
+
43
+ const styles = StyleSheet.create({
44
+ container: {
45
+ flex: 1,
46
+ backgroundColor: '#f6f6f6',
47
+ padding: 16,
48
+ },
49
+ title: {
50
+ fontSize: 18,
51
+ fontWeight: 'bold',
52
+ marginBottom: 16,
53
+ textAlign: 'center',
54
+ },
55
+ });
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
- import { View, Button, StyleSheet, TouchableOpacity, Text } from 'react-native';
2
+ import { View, Button, StyleSheet, TouchableOpacity, Text, ScrollView } from 'react-native';
3
+ import { ProductCard } from './productCard';
3
4
 
4
5
  export const Testing = ({ onProductCardClick, onAddToCartClick }) => {
5
6
 
@@ -14,7 +15,8 @@ export const Testing = ({ onProductCardClick, onAddToCartClick }) => {
14
15
  "net_price": 7.83,
15
16
  "is_on_sale": false,
16
17
  "quantity_available": 0,
17
- "discounts": null
18
+ "discounts": null,
19
+ "min_pack_qty": 1.5
18
20
  }
19
21
  }
20
22
  },
@@ -28,25 +30,52 @@ export const Testing = ({ onProductCardClick, onAddToCartClick }) => {
28
30
  }
29
31
 
30
32
  return (
31
- <View style={styles.container}>
32
- <TouchableOpacity style={styles.button} onPress={() => onProductCardClick(product)}>
33
- <Text style={styles.buttonText}>Product Card Click</Text>
34
- </TouchableOpacity>
35
- <TouchableOpacity style={styles.button} onPress={() => onAddToCartClick({"quantity":1,"product":product})}>
36
- <Text style={styles.buttonText}>Add to Cart</Text>
37
- </TouchableOpacity>
38
- </View>
33
+ <ScrollView style={styles.container}>
34
+ <Text style={styles.title}>Test Product Card</Text>
35
+
36
+ {/* Display the actual product card */}
37
+ <View style={styles.productCardContainer}>
38
+ <ProductCard
39
+ prod={product}
40
+ onFocusQuantityInput={(partNumber) => console.log('Focus on:', partNumber)}
41
+ messageId="test-message-123"
42
+ />
43
+ </View>
44
+
45
+ {/* Test buttons */}
46
+ <View style={styles.buttonContainer}>
47
+ <TouchableOpacity style={styles.button} onPress={() => onProductCardClick(product)}>
48
+ <Text style={styles.buttonText}>Product Card Click</Text>
49
+ </TouchableOpacity>
50
+ <TouchableOpacity style={styles.button} onPress={() => onAddToCartClick({"quantity":1,"product":product})}>
51
+ <Text style={styles.buttonText}>Add to Cart</Text>
52
+ </TouchableOpacity>
53
+ </View>
54
+ </ScrollView>
39
55
  );
40
56
  };
41
57
 
42
58
  const styles = StyleSheet.create({
43
59
  container: {
60
+ backgroundColor: '#f6f6f6',
61
+ borderTopWidth: 1,
62
+ borderTopColor: '#DDD',
63
+ },
64
+ title: {
65
+ fontSize: 18,
66
+ fontWeight: 'bold',
67
+ textAlign: 'center',
68
+ padding: 16,
69
+ },
70
+ productCardContainer: {
71
+ paddingHorizontal: 16,
72
+ },
73
+ buttonContainer: {
44
74
  flexDirection: 'row',
45
75
  alignItems: 'center',
46
76
  justifyContent: 'space-evenly',
47
77
  paddingHorizontal: 16,
48
- borderTopWidth: 1,
49
- borderTopColor: '#DDD',
78
+ paddingVertical: 20,
50
79
  },
51
80
  button: {
52
81
  backgroundColor: "#d4d4d4",
@@ -54,7 +83,9 @@ const styles = StyleSheet.create({
54
83
  paddingHorizontal: 12,
55
84
  borderRadius: 5,
56
85
  alignItems: "center",
57
- marginBottom: 10,
58
- marginTop: 10,
86
+ },
87
+ buttonText: {
88
+ fontSize: 14,
89
+ fontWeight: 'bold',
59
90
  },
60
91
  });