@faststore/components 3.98.0-dev.1 → 3.98.0-dev.8

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 (198) hide show
  1. package/dist/cjs/atoms/Link/Link.d.ts +1 -1
  2. package/dist/cjs/atoms/Link/Link.d.ts.map +1 -1
  3. package/dist/cjs/atoms/Link/Link.js.map +1 -1
  4. package/dist/cjs/atoms/List/List.d.ts.map +1 -1
  5. package/dist/cjs/atoms/List/List.js.map +1 -1
  6. package/dist/cjs/hooks/index.d.ts +7 -3
  7. package/dist/cjs/hooks/index.d.ts.map +1 -1
  8. package/dist/cjs/hooks/index.js +12 -6
  9. package/dist/cjs/hooks/index.js.map +1 -1
  10. package/dist/cjs/hooks/useCSVParser.d.ts +43 -0
  11. package/dist/cjs/hooks/useCSVParser.d.ts.map +1 -0
  12. package/dist/cjs/hooks/useCSVParser.js +264 -0
  13. package/dist/cjs/hooks/useCSVParser.js.map +1 -0
  14. package/dist/cjs/hooks/useFileUpload.d.ts +26 -0
  15. package/dist/cjs/hooks/useFileUpload.d.ts.map +1 -0
  16. package/dist/cjs/hooks/useFileUpload.js +68 -0
  17. package/dist/cjs/hooks/useFileUpload.js.map +1 -0
  18. package/dist/cjs/index.d.ts +58 -50
  19. package/dist/cjs/index.d.ts.map +1 -1
  20. package/dist/cjs/index.js +47 -32
  21. package/dist/cjs/index.js.map +1 -1
  22. package/dist/cjs/molecules/Accordion/AccordionItem.d.ts.map +1 -1
  23. package/dist/cjs/molecules/Accordion/AccordionItem.js.map +1 -1
  24. package/dist/cjs/molecules/Dropzone/Dropzone.d.ts +87 -0
  25. package/dist/cjs/molecules/Dropzone/Dropzone.d.ts.map +1 -0
  26. package/dist/cjs/molecules/Dropzone/Dropzone.js +85 -0
  27. package/dist/cjs/molecules/Dropzone/Dropzone.js.map +1 -0
  28. package/dist/cjs/molecules/Dropzone/index.d.ts +3 -0
  29. package/dist/cjs/molecules/Dropzone/index.d.ts.map +1 -0
  30. package/dist/cjs/molecules/Dropzone/index.js +9 -0
  31. package/dist/cjs/molecules/Dropzone/index.js.map +1 -0
  32. package/dist/cjs/molecules/FileUploadCard/FileUploadCard.d.ts +113 -0
  33. package/dist/cjs/molecules/FileUploadCard/FileUploadCard.d.ts.map +1 -0
  34. package/dist/cjs/molecules/FileUploadCard/FileUploadCard.js +169 -0
  35. package/dist/cjs/molecules/FileUploadCard/FileUploadCard.js.map +1 -0
  36. package/dist/cjs/molecules/FileUploadCard/index.d.ts +3 -0
  37. package/dist/cjs/molecules/FileUploadCard/index.d.ts.map +1 -0
  38. package/dist/cjs/molecules/FileUploadCard/index.js +9 -0
  39. package/dist/cjs/molecules/FileUploadCard/index.js.map +1 -0
  40. package/dist/cjs/molecules/FileUploadStatus/FileUploadStatus.d.ts +93 -0
  41. package/dist/cjs/molecules/FileUploadStatus/FileUploadStatus.d.ts.map +1 -0
  42. package/dist/cjs/molecules/FileUploadStatus/FileUploadStatus.js +77 -0
  43. package/dist/cjs/molecules/FileUploadStatus/FileUploadStatus.js.map +1 -0
  44. package/dist/cjs/molecules/FileUploadStatus/index.d.ts +3 -0
  45. package/dist/cjs/molecules/FileUploadStatus/index.d.ts.map +1 -0
  46. package/dist/cjs/molecules/FileUploadStatus/index.js +11 -0
  47. package/dist/cjs/molecules/FileUploadStatus/index.js.map +1 -0
  48. package/dist/cjs/molecules/SearchInputField/SearchInputField.d.ts +23 -1
  49. package/dist/cjs/molecules/SearchInputField/SearchInputField.d.ts.map +1 -1
  50. package/dist/cjs/molecules/SearchInputField/SearchInputField.js +9 -4
  51. package/dist/cjs/molecules/SearchInputField/SearchInputField.js.map +1 -1
  52. package/dist/cjs/molecules/SearchProducts/SearchProductItem.d.ts +1 -1
  53. package/dist/cjs/molecules/SearchProducts/SearchProductItem.d.ts.map +1 -1
  54. package/dist/cjs/molecules/SearchProducts/SearchProductItem.js +2 -2
  55. package/dist/cjs/molecules/SearchProducts/SearchProductItem.js.map +1 -1
  56. package/dist/cjs/molecules/SearchProvider/SearchProvider.d.ts +5 -1
  57. package/dist/cjs/molecules/SearchProvider/SearchProvider.d.ts.map +1 -1
  58. package/dist/cjs/molecules/SearchProvider/SearchProvider.js +2 -2
  59. package/dist/cjs/molecules/SearchProvider/SearchProvider.js.map +1 -1
  60. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawer.d.ts +24 -0
  61. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawer.d.ts.map +1 -0
  62. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawer.js +14 -0
  63. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawer.js.map +1 -0
  64. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.d.ts +16 -0
  65. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.d.ts.map +1 -0
  66. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.js +37 -0
  67. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.js.map +1 -0
  68. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.d.ts +9 -0
  69. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.d.ts.map +1 -0
  70. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.js +24 -0
  71. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.js.map +1 -0
  72. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.d.ts +35 -0
  73. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.d.ts.map +1 -0
  74. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.js +91 -0
  75. package/dist/cjs/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.js.map +1 -0
  76. package/dist/cjs/organisms/QuickOrderDrawer/index.d.ts +11 -0
  77. package/dist/cjs/organisms/QuickOrderDrawer/index.d.ts.map +1 -0
  78. package/dist/cjs/organisms/QuickOrderDrawer/index.js +18 -0
  79. package/dist/cjs/organisms/QuickOrderDrawer/index.js.map +1 -0
  80. package/dist/cjs/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.d.ts +61 -0
  81. package/dist/cjs/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.d.ts.map +1 -0
  82. package/dist/cjs/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.js +86 -0
  83. package/dist/cjs/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.js.map +1 -0
  84. package/dist/cjs/organisms/SearchInput/SearchInput.d.ts +8 -0
  85. package/dist/cjs/organisms/SearchInput/SearchInput.d.ts.map +1 -1
  86. package/dist/cjs/organisms/SearchInput/SearchInput.js +2 -2
  87. package/dist/cjs/organisms/SearchInput/SearchInput.js.map +1 -1
  88. package/dist/esm/atoms/Link/Link.d.ts +1 -1
  89. package/dist/esm/atoms/Link/Link.d.ts.map +1 -1
  90. package/dist/esm/atoms/Link/Link.js.map +1 -1
  91. package/dist/esm/atoms/List/List.d.ts.map +1 -1
  92. package/dist/esm/atoms/List/List.js.map +1 -1
  93. package/dist/esm/hooks/index.d.ts +7 -3
  94. package/dist/esm/hooks/index.d.ts.map +1 -1
  95. package/dist/esm/hooks/index.js +6 -3
  96. package/dist/esm/hooks/index.js.map +1 -1
  97. package/dist/esm/hooks/useCSVParser.d.ts +43 -0
  98. package/dist/esm/hooks/useCSVParser.d.ts.map +1 -0
  99. package/dist/esm/hooks/useCSVParser.js +259 -0
  100. package/dist/esm/hooks/useCSVParser.js.map +1 -0
  101. package/dist/esm/hooks/useFileUpload.d.ts +26 -0
  102. package/dist/esm/hooks/useFileUpload.d.ts.map +1 -0
  103. package/dist/esm/hooks/useFileUpload.js +64 -0
  104. package/dist/esm/hooks/useFileUpload.js.map +1 -0
  105. package/dist/esm/index.d.ts +58 -50
  106. package/dist/esm/index.d.ts.map +1 -1
  107. package/dist/esm/index.js +24 -20
  108. package/dist/esm/index.js.map +1 -1
  109. package/dist/esm/molecules/Accordion/AccordionItem.d.ts.map +1 -1
  110. package/dist/esm/molecules/Accordion/AccordionItem.js.map +1 -1
  111. package/dist/esm/molecules/Dropzone/Dropzone.d.ts +87 -0
  112. package/dist/esm/molecules/Dropzone/Dropzone.d.ts.map +1 -0
  113. package/dist/esm/molecules/Dropzone/Dropzone.js +82 -0
  114. package/dist/esm/molecules/Dropzone/Dropzone.js.map +1 -0
  115. package/dist/esm/molecules/Dropzone/index.d.ts +3 -0
  116. package/dist/esm/molecules/Dropzone/index.d.ts.map +1 -0
  117. package/dist/esm/molecules/Dropzone/index.js +2 -0
  118. package/dist/esm/molecules/Dropzone/index.js.map +1 -0
  119. package/dist/esm/molecules/FileUploadCard/FileUploadCard.d.ts +113 -0
  120. package/dist/esm/molecules/FileUploadCard/FileUploadCard.d.ts.map +1 -0
  121. package/dist/esm/molecules/FileUploadCard/FileUploadCard.js +166 -0
  122. package/dist/esm/molecules/FileUploadCard/FileUploadCard.js.map +1 -0
  123. package/dist/esm/molecules/FileUploadCard/index.d.ts +3 -0
  124. package/dist/esm/molecules/FileUploadCard/index.d.ts.map +1 -0
  125. package/dist/esm/molecules/FileUploadCard/index.js +2 -0
  126. package/dist/esm/molecules/FileUploadCard/index.js.map +1 -0
  127. package/dist/esm/molecules/FileUploadStatus/FileUploadStatus.d.ts +93 -0
  128. package/dist/esm/molecules/FileUploadStatus/FileUploadStatus.d.ts.map +1 -0
  129. package/dist/esm/molecules/FileUploadStatus/FileUploadStatus.js +73 -0
  130. package/dist/esm/molecules/FileUploadStatus/FileUploadStatus.js.map +1 -0
  131. package/dist/esm/molecules/FileUploadStatus/index.d.ts +3 -0
  132. package/dist/esm/molecules/FileUploadStatus/index.d.ts.map +1 -0
  133. package/dist/esm/molecules/FileUploadStatus/index.js +2 -0
  134. package/dist/esm/molecules/FileUploadStatus/index.js.map +1 -0
  135. package/dist/esm/molecules/SearchInputField/SearchInputField.d.ts +23 -1
  136. package/dist/esm/molecules/SearchInputField/SearchInputField.d.ts.map +1 -1
  137. package/dist/esm/molecules/SearchInputField/SearchInputField.js +9 -4
  138. package/dist/esm/molecules/SearchInputField/SearchInputField.js.map +1 -1
  139. package/dist/esm/molecules/SearchProducts/SearchProductItem.d.ts +1 -1
  140. package/dist/esm/molecules/SearchProducts/SearchProductItem.d.ts.map +1 -1
  141. package/dist/esm/molecules/SearchProducts/SearchProductItem.js +2 -2
  142. package/dist/esm/molecules/SearchProducts/SearchProductItem.js.map +1 -1
  143. package/dist/esm/molecules/SearchProvider/SearchProvider.d.ts +5 -1
  144. package/dist/esm/molecules/SearchProvider/SearchProvider.d.ts.map +1 -1
  145. package/dist/esm/molecules/SearchProvider/SearchProvider.js +2 -2
  146. package/dist/esm/molecules/SearchProvider/SearchProvider.js.map +1 -1
  147. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawer.d.ts +24 -0
  148. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawer.d.ts.map +1 -0
  149. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawer.js +11 -0
  150. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawer.js.map +1 -0
  151. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.d.ts +16 -0
  152. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.d.ts.map +1 -0
  153. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.js +34 -0
  154. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.js.map +1 -0
  155. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.d.ts +9 -0
  156. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.d.ts.map +1 -0
  157. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.js +21 -0
  158. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.js.map +1 -0
  159. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.d.ts +35 -0
  160. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.d.ts.map +1 -0
  161. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.js +88 -0
  162. package/dist/esm/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.js.map +1 -0
  163. package/dist/esm/organisms/QuickOrderDrawer/index.d.ts +11 -0
  164. package/dist/esm/organisms/QuickOrderDrawer/index.d.ts.map +1 -0
  165. package/dist/esm/organisms/QuickOrderDrawer/index.js +6 -0
  166. package/dist/esm/organisms/QuickOrderDrawer/index.js.map +1 -0
  167. package/dist/esm/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.d.ts +61 -0
  168. package/dist/esm/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.d.ts.map +1 -0
  169. package/dist/esm/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.js +80 -0
  170. package/dist/esm/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.js.map +1 -0
  171. package/dist/esm/organisms/SearchInput/SearchInput.d.ts +8 -0
  172. package/dist/esm/organisms/SearchInput/SearchInput.d.ts.map +1 -1
  173. package/dist/esm/organisms/SearchInput/SearchInput.js +2 -2
  174. package/dist/esm/organisms/SearchInput/SearchInput.js.map +1 -1
  175. package/package.json +5 -2
  176. package/src/atoms/Link/Link.tsx +4 -1
  177. package/src/atoms/List/List.tsx +18 -16
  178. package/src/hooks/index.ts +11 -3
  179. package/src/hooks/useCSVParser.ts +367 -0
  180. package/src/hooks/useFileUpload.ts +88 -0
  181. package/src/index.ts +97 -66
  182. package/src/molecules/Accordion/AccordionItem.tsx +4 -3
  183. package/src/molecules/Dropzone/Dropzone.tsx +248 -0
  184. package/src/molecules/Dropzone/index.ts +2 -0
  185. package/src/molecules/FileUploadCard/FileUploadCard.tsx +406 -0
  186. package/src/molecules/FileUploadCard/index.tsx +2 -0
  187. package/src/molecules/FileUploadStatus/FileUploadStatus.tsx +258 -0
  188. package/src/molecules/FileUploadStatus/index.tsx +6 -0
  189. package/src/molecules/SearchInputField/SearchInputField.tsx +72 -23
  190. package/src/molecules/SearchProducts/SearchProductItem.tsx +8 -3
  191. package/src/molecules/SearchProvider/SearchProvider.tsx +6 -1
  192. package/src/organisms/QuickOrderDrawer/QuickOrderDrawer.tsx +58 -0
  193. package/src/organisms/QuickOrderDrawer/QuickOrderDrawerFooter.tsx +72 -0
  194. package/src/organisms/QuickOrderDrawer/QuickOrderDrawerHeader.tsx +43 -0
  195. package/src/organisms/QuickOrderDrawer/QuickOrderDrawerProducts.tsx +323 -0
  196. package/src/organisms/QuickOrderDrawer/index.ts +19 -0
  197. package/src/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.tsx +205 -0
  198. package/src/organisms/SearchInput/SearchInput.tsx +6 -0
@@ -0,0 +1,61 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import type { PriceFormatter } from '../../../atoms/Price';
3
+ export interface Product {
4
+ id: string;
5
+ name: string;
6
+ price: number;
7
+ quantityUpdated: boolean;
8
+ image: {
9
+ url: string;
10
+ alternateName: string;
11
+ };
12
+ inventory: number;
13
+ availability: 'available' | 'outOfStock';
14
+ selectedCount: number;
15
+ }
16
+ export interface VariationProductColumn {
17
+ name: string;
18
+ availability: {
19
+ label: string;
20
+ stockDisplaySettings: 'showStockQuantity' | 'showAvailability';
21
+ };
22
+ price: string;
23
+ quantity: string;
24
+ }
25
+ interface QuickOrderDrawerContextValue {
26
+ products: Product[];
27
+ totalPrice: number;
28
+ itemsCount: number;
29
+ alertMessage: string;
30
+ isLoading: boolean;
31
+ setAlertMessage: (message: string) => void;
32
+ onChangeQuantityItem: (id: string, value: number) => void;
33
+ onDelete: (id: string) => void;
34
+ onAddToCart: () => void;
35
+ formatter?: PriceFormatter;
36
+ }
37
+ export interface AlertMessages {
38
+ notFoundAndOutOfStock?: string;
39
+ notFound?: string;
40
+ outOfStock?: string;
41
+ }
42
+ export interface QuickOrderDrawerProviderProps {
43
+ children: ReactNode;
44
+ initialProducts?: Product[];
45
+ isLoading?: boolean;
46
+ totalRequestedSkus?: number;
47
+ onAddToCart?: (products: Product[], totalPrice: number, itemsCount: number) => void;
48
+ formatter?: PriceFormatter;
49
+ /**
50
+ * Initial alert message for CMS configuration
51
+ */
52
+ initialAlertMessage?: string;
53
+ /**
54
+ * Alert messages from CMS for different scenarios.
55
+ */
56
+ alertMessages?: AlertMessages;
57
+ }
58
+ export declare const QuickOrderDrawerProvider: ({ children, initialProducts, isLoading, totalRequestedSkus, onAddToCart: onAddToCartCallback, formatter, initialAlertMessage, alertMessages, }: QuickOrderDrawerProviderProps) => React.JSX.Element;
59
+ export declare const useQuickOrderDrawer: () => QuickOrderDrawerContextValue;
60
+ export {};
61
+ //# sourceMappingURL=QuickOrderDrawerProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuickOrderDrawerProvider.d.ts","sourceRoot":"","sources":["../../../../../src/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAA;AACd,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,OAAO,CAAA;IACxB,KAAK,EAAE;QACL,GAAG,EAAE,MAAM,CAAA;QACX,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,WAAW,GAAG,YAAY,CAAA;IACxC,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM,CAAA;QACb,oBAAoB,EAAE,mBAAmB,GAAG,kBAAkB,CAAA;KAC/D,CAAA;IACD,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,UAAU,4BAA4B;IACpC,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,OAAO,CAAA;IAClB,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,oBAAoB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACzD,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB,SAAS,CAAC,EAAE,cAAc,CAAA;CAC3B;AAMD,MAAM,WAAW,aAAa;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,SAAS,CAAA;IACnB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAA;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,WAAW,CAAC,EAAE,CACZ,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,KACf,IAAI,CAAA;IACT,SAAS,CAAC,EAAE,cAAc,CAAA;IAC1B;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;OAEG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;CAC9B;AAED,eAAO,MAAM,wBAAwB,mJASlC,6BAA6B,sBAwG/B,CAAA;AAED,eAAO,MAAM,mBAAmB,QAAO,4BAUtC,CAAA"}
@@ -0,0 +1,80 @@
1
+ import React, { createContext, useCallback, useContext, useEffect, useMemo, useState, } from 'react';
2
+ const QuickOrderDrawerContext = createContext(undefined);
3
+ export const QuickOrderDrawerProvider = ({ children, initialProducts = [], isLoading = false, totalRequestedSkus, onAddToCart: onAddToCartCallback, formatter, initialAlertMessage, alertMessages, }) => {
4
+ const [products, setProducts] = useState(initialProducts || []);
5
+ const getAlertMessage = (prods, totalRequestedSkus) => {
6
+ if (prods.length === 0) {
7
+ return '';
8
+ }
9
+ const hasOutOfStock = prods.some((p) => p.availability === 'outOfStock');
10
+ const hasNotFound = totalRequestedSkus !== undefined &&
11
+ totalRequestedSkus > 0 &&
12
+ prods.length < totalRequestedSkus;
13
+ if (hasNotFound && hasOutOfStock) {
14
+ return alertMessages?.notFoundAndOutOfStock ?? '';
15
+ }
16
+ if (hasNotFound) {
17
+ return alertMessages?.notFound ?? '';
18
+ }
19
+ if (hasOutOfStock) {
20
+ return alertMessages?.outOfStock ?? '';
21
+ }
22
+ return '';
23
+ };
24
+ const [alertMessage, setAlertMessage] = useState(initialAlertMessage ?? '');
25
+ useEffect(() => {
26
+ const newProducts = initialProducts || [];
27
+ setProducts(newProducts);
28
+ }, [initialProducts]);
29
+ useEffect(() => {
30
+ if (!isLoading) {
31
+ setAlertMessage(getAlertMessage(products, totalRequestedSkus));
32
+ }
33
+ else if (isLoading) {
34
+ setAlertMessage('');
35
+ }
36
+ }, [products, isLoading, totalRequestedSkus]);
37
+ const { totalPrice, itemsCount } = useMemo(() => {
38
+ const filteredProducts = products.filter((product) => product.selectedCount > 0 && product.availability === 'available');
39
+ return filteredProducts.reduce((prev, curr) => ({
40
+ totalPrice: prev.totalPrice + curr.price * curr.selectedCount,
41
+ itemsCount: prev.itemsCount + curr.selectedCount,
42
+ }), { totalPrice: 0, itemsCount: 0 });
43
+ }, [products]);
44
+ const onChangeQuantityItem = useCallback((id, value) => {
45
+ setProducts((oldProducts) => oldProducts.map((product) => {
46
+ if (product.id !== id) {
47
+ return product;
48
+ }
49
+ return { ...product, selectedCount: value };
50
+ }));
51
+ }, []);
52
+ const onDelete = useCallback((id) => {
53
+ setProducts((oldProducts) => oldProducts.filter((product) => product.id !== id));
54
+ }, []);
55
+ const onAddToCart = useCallback(() => {
56
+ const productsToAdd = products.filter((product) => product.selectedCount > 0 && product.availability === 'available');
57
+ onAddToCartCallback?.(productsToAdd, totalPrice, itemsCount);
58
+ }, [products, totalPrice, itemsCount, onAddToCartCallback]);
59
+ const value = {
60
+ products,
61
+ totalPrice,
62
+ itemsCount,
63
+ alertMessage,
64
+ isLoading,
65
+ setAlertMessage,
66
+ onChangeQuantityItem,
67
+ onDelete,
68
+ onAddToCart,
69
+ formatter,
70
+ };
71
+ return (React.createElement(QuickOrderDrawerContext.Provider, { value: value }, children));
72
+ };
73
+ export const useQuickOrderDrawer = () => {
74
+ const context = useContext(QuickOrderDrawerContext);
75
+ if (context === undefined) {
76
+ throw new Error('useQuickOrderDrawer should be used within a QuickOrderDrawerProvider');
77
+ }
78
+ return context;
79
+ };
80
+ //# sourceMappingURL=QuickOrderDrawerProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuickOrderDrawerProvider.js","sourceRoot":"","sources":["../../../../../src/organisms/QuickOrderDrawer/provider/QuickOrderDrawerProvider.tsx"],"names":[],"mappings":"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"}
@@ -11,6 +11,10 @@ export type SearchInputProps = {
11
11
  * The current status of the Search Dropdown.
12
12
  */
13
13
  visibleDropdown: boolean;
14
+ /**
15
+ * Search result searchId.
16
+ */
17
+ searchId?: string;
14
18
  } & HTMLAttributes<HTMLDivElement> & SearchProviderContextValue;
15
19
  declare const SearchInput: React.ForwardRefExoticComponent<{
16
20
  /**
@@ -22,6 +26,10 @@ declare const SearchInput: React.ForwardRefExoticComponent<{
22
26
  * The current status of the Search Dropdown.
23
27
  */
24
28
  visibleDropdown: boolean;
29
+ /**
30
+ * Search result searchId.
31
+ */
32
+ searchId?: string | undefined;
25
33
  } & React.HTMLAttributes<HTMLDivElement> & SearchProviderContextValue & React.RefAttributes<HTMLDivElement>>;
26
34
  export default SearchInput;
27
35
  //# sourceMappingURL=SearchInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SearchInput.d.ts","sourceRoot":"","sources":["../../../../src/organisms/SearchInput/SearchInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAA;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAuB,EACrB,KAAK,0BAA0B,EAChC,MAAM,gCAAgC,CAAA;AAEvC,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,eAAe,EAAE,OAAO,CAAA;CACzB,GAAG,cAAc,CAAC,cAAc,CAAC,GAChC,0BAA0B,CAAA;AAE5B,QAAA,MAAM,WAAW;IAZf;;;OAGG;;IAEH;;OAEG;qBACc,OAAO;4GAuCzB,CAAA;AAED,eAAe,WAAW,CAAA"}
1
+ {"version":3,"file":"SearchInput.d.ts","sourceRoot":"","sources":["../../../../src/organisms/SearchInput/SearchInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAA;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAuB,EACrB,KAAK,0BAA0B,EAChC,MAAM,gCAAgC,CAAA;AAEvC,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,eAAe,EAAE,OAAO,CAAA;IACxB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,GAAG,cAAc,CAAC,cAAc,CAAC,GAChC,0BAA0B,CAAA;AAE5B,QAAA,MAAM,WAAW;IAhBf;;;OAGG;;IAEH;;OAEG;qBACc,OAAO;IACxB;;OAEG;;4GA0CJ,CAAA;AAED,eAAe,WAAW,CAAA"}
@@ -1,8 +1,8 @@
1
1
  import React, { forwardRef } from 'react';
2
2
  import SearchProvider from '../../molecules/SearchProvider';
3
- const SearchInput = forwardRef(function SearchInput({ children, visibleDropdown = false, testId = 'fs-search-input', isLoading, products, term, terms, onSearchSelection, ...otherProps }, ref) {
3
+ const SearchInput = forwardRef(function SearchInput({ children, visibleDropdown = false, testId = 'fs-search-input', isLoading, products, term, terms, onSearchSelection, searchId, ...otherProps }, ref) {
4
4
  return (React.createElement("div", { ref: ref, "data-fs-search-input": true, "data-fs-search-input-dropdown-visible": visibleDropdown, "data-testid": testId, ...otherProps },
5
- React.createElement(SearchProvider, { onSearchSelection: onSearchSelection, isLoading: isLoading, term: term, products: products, terms: terms }, children)));
5
+ React.createElement(SearchProvider, { onSearchSelection: onSearchSelection, isLoading: isLoading, term: term, products: products, terms: terms, searchId: searchId }, children)));
6
6
  });
7
7
  export default SearchInput;
8
8
  //# sourceMappingURL=SearchInput.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SearchInput.js","sourceRoot":"","sources":["../../../../src/organisms/SearchInput/SearchInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAEzC,OAAO,cAEN,MAAM,gCAAgC,CAAA;AAevC,MAAM,WAAW,GAAG,UAAU,CAC5B,SAAS,WAAW,CAClB,EACE,QAAQ,EACR,eAAe,GAAG,KAAK,EACvB,MAAM,GAAG,iBAAiB,EAC1B,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,iBAAiB,EACjB,GAAG,UAAU,EACd,EACD,GAAG;IAEH,OAAO,CACL,6BACE,GAAG,EAAE,GAAG,yEAE+B,eAAe,iBACzC,MAAM,KACf,UAAU;QAEd,oBAAC,cAAc,IACb,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,KAAK,IAEX,QAAQ,CACM,CACb,CACP,CAAA;AACH,CAAC,CACF,CAAA;AAED,eAAe,WAAW,CAAA"}
1
+ {"version":3,"file":"SearchInput.js","sourceRoot":"","sources":["../../../../src/organisms/SearchInput/SearchInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAEzC,OAAO,cAEN,MAAM,gCAAgC,CAAA;AAmBvC,MAAM,WAAW,GAAG,UAAU,CAC5B,SAAS,WAAW,CAClB,EACE,QAAQ,EACR,eAAe,GAAG,KAAK,EACvB,MAAM,GAAG,iBAAiB,EAC1B,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,iBAAiB,EACjB,QAAQ,EACR,GAAG,UAAU,EACd,EACD,GAAG;IAEH,OAAO,CACL,6BACE,GAAG,EAAE,GAAG,yEAE+B,eAAe,iBACzC,MAAM,KACf,UAAU;QAEd,oBAAC,cAAc,IACb,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,IAEjB,QAAQ,CACM,CACb,CACP,CAAA;AACH,CAAC,CACF,CAAA;AAED,eAAe,WAAW,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/components",
3
- "version": "3.98.0-dev.1",
3
+ "version": "3.98.0-dev.8",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "typings": "dist/esm/index.d.ts",
@@ -34,6 +34,8 @@
34
34
  "react-dom": "^18.2.0"
35
35
  },
36
36
  "dependencies": {
37
+ "papaparse": "^5.5.3",
38
+ "react-dropzone": "^14.3.8",
37
39
  "react-intersection-observer": "^8.32.5",
38
40
  "react-swipeable": "^7.0.0",
39
41
  "tabbable": "^5.2.1"
@@ -44,6 +46,7 @@
44
46
  "@testing-library/react": "^14.3.0",
45
47
  "@types/jest": "29.1.0",
46
48
  "@types/jest-axe": "^3.5.9",
49
+ "@types/papaparse": "^5.5.0",
47
50
  "@types/react": "^18.2.42",
48
51
  "@types/react-dom": "^18.2.17",
49
52
  "@types/tabbable": "^3.1.1",
@@ -59,5 +62,5 @@
59
62
  "publishConfig": {
60
63
  "access": "public"
61
64
  },
62
- "gitHead": "8318044a7a7cc95564b9305dfe3099dd8589c182"
65
+ "gitHead": "c1d0239ddbd1a792e45d82ef15f018d47b854ca0"
63
66
  }
@@ -29,7 +29,10 @@ export type LinkElementType = ElementType
29
29
  export type LinkProps<C extends LinkElementType = 'a'> =
30
30
  PolymorphicComponentPropsWithRef<C, LinkBaseProps>
31
31
 
32
- const Link = forwardRef(function Link<C extends LinkElementType = 'a'>(
32
+ const Link = forwardRef<
33
+ HTMLAnchorElement,
34
+ Omit<LinkProps<LinkElementType>, 'ref'>
35
+ >(function Link<C extends LinkElementType = 'a'>(
33
36
  {
34
37
  as,
35
38
  children,
@@ -24,22 +24,24 @@ type ListComponent = <T extends ElementType = 'ul'>(
24
24
  props: ListProps<T>
25
25
  ) => ReactElement | null
26
26
 
27
- const List = forwardRef(function List<T extends ElementType = 'ul'>(
28
- { as, marker, testId = 'fs-list', ...otherProps }: ListProps<T>,
29
- ref: PolymorphicRef<T>
30
- ) {
31
- const Component = as ?? 'ul'
27
+ const List = forwardRef<HTMLUListElement, Omit<ListProps<'ul'>, 'ref'>>(
28
+ function List<T extends ElementType = 'ul'>(
29
+ { as, marker, testId = 'fs-list', ...otherProps }: ListProps<T>,
30
+ ref: PolymorphicRef<T>
31
+ ) {
32
+ const Component = as ?? 'ul'
32
33
 
33
- return (
34
- <Component
35
- ref={ref}
36
- role="list"
37
- data-fs-list
38
- data-fs-list-marker={marker}
39
- data-testid={testId}
40
- {...otherProps}
41
- />
42
- )
43
- }) as ListComponent
34
+ return (
35
+ <Component
36
+ ref={ref}
37
+ role="list"
38
+ data-fs-list
39
+ data-fs-list-marker={marker}
40
+ data-testid={testId}
41
+ {...otherProps}
42
+ />
43
+ )
44
+ }
45
+ ) as ListComponent
44
46
 
45
47
  export default List
@@ -1,11 +1,20 @@
1
1
  export {
2
- regionSliderTypes,
3
2
  Toast as ToastProps,
4
3
  default as UIProvider,
4
+ regionSliderTypes,
5
5
  useUI,
6
6
  } from './UIProvider'
7
+ export { useCSVParser } from './useCSVParser'
8
+ export type {
9
+ CSVData,
10
+ CSVParserError,
11
+ CSVParserOptions,
12
+ } from './useCSVParser'
7
13
  export { useFadeEffect } from './useFadeEffect'
14
+ export { useFileUpload } from './useFileUpload'
8
15
  export { useOnClickOutside } from './useOnClickOutside'
16
+ export { useProductComparison } from './useProductComparison'
17
+ export { useRTL } from './useRTL'
9
18
  export { useScrollDirection } from './useScrollDirection'
10
19
  export { useSearch } from './useSearch'
11
20
  export { useSKUMatrix } from './useSKUMatrix'
@@ -18,5 +27,4 @@ export type {
18
27
  } from './useSlider'
19
28
  export { useSlideVisibility } from './useSlideVisibility'
20
29
  export { useTrapFocus } from './useTrapFocus'
21
- export { useProductComparison } from './useProductComparison'
22
- export { useRTL } from './useRTL'
30
+ export { FileRejectionCode } from './useFileUpload'
@@ -0,0 +1,367 @@
1
+ import Papa from 'papaparse'
2
+ import { useCallback, useMemo, useState } from 'react'
3
+
4
+ export interface WorkerCSVData {
5
+ data: Array<{ sku: string; quantity: number }>
6
+ fileName: string
7
+ totalRows: number
8
+ fileSize: number
9
+ }
10
+
11
+ export interface WorkerCSVOptions {
12
+ skuColumnNames?: string[]
13
+ quantityColumnNames?: string[]
14
+ delimiter?: string
15
+ skipEmptyLines?: boolean
16
+ chunkSize?: number
17
+ onProgress?: (progress: {
18
+ processed: number
19
+ total: number
20
+ percentage: number
21
+ }) => void
22
+ }
23
+
24
+ export type CSVData = WorkerCSVData
25
+ export type CSVParserOptions = WorkerCSVOptions
26
+
27
+ export type CSVParserError = {
28
+ message: string
29
+ type: 'PARSE_ERROR' | 'VALIDATION_ERROR' | 'FILE_ERROR'
30
+ }
31
+
32
+ const defaultOptions: CSVParserOptions = {}
33
+
34
+ /**
35
+ * Hook to parse CSV files containing SKU and Quantity columns.
36
+ * Utilizes PapaParse's native Web Worker for efficient parsing of large files.
37
+ * Supports both comma (,) and semicolon (;) delimiters - automatically detects which one is used.
38
+ * @param options CSV parsing options
39
+ * @returns Object containing parsing state and functions
40
+ */
41
+ export function useCSVParser(options?: CSVParserOptions) {
42
+ const [error, setError] = useState<CSVParserError | null>(null)
43
+ const [isParsing, setIsParsing] = useState(false)
44
+ const [isGeneratingTemplate, setIsGeneratingTemplate] = useState(false)
45
+
46
+ const mergedOptions = useMemo(
47
+ () => ({ ...defaultOptions, ...options }),
48
+ [options]
49
+ )
50
+
51
+ const onParseFile = useCallback(
52
+ async (file: File): Promise<CSVData | null> => {
53
+ try {
54
+ setError(null)
55
+ setIsParsing(true)
56
+
57
+ const result = await parseCSVFile(file, mergedOptions)
58
+ return result
59
+ } catch (err) {
60
+ const error: CSVParserError = {
61
+ message:
62
+ err instanceof Error ? err.message : 'Failed to parse CSV file',
63
+ type: 'PARSE_ERROR',
64
+ }
65
+ setError(error)
66
+ return null
67
+ } finally {
68
+ setIsParsing(false)
69
+ }
70
+ },
71
+ [mergedOptions]
72
+ )
73
+
74
+ const onGenerateTemplate = useCallback(async (): Promise<string | null> => {
75
+ try {
76
+ setIsGeneratingTemplate(true)
77
+ const csvContent = generateCSVTemplate()
78
+ return csvContent
79
+ } catch (err) {
80
+ const error: CSVParserError = {
81
+ message:
82
+ err instanceof Error ? err.message : 'Failed to generate template',
83
+ type: 'PARSE_ERROR',
84
+ }
85
+ setError(error)
86
+ return null
87
+ } finally {
88
+ setIsGeneratingTemplate(false)
89
+ }
90
+ }, [])
91
+
92
+ const onClearError = useCallback(() => {
93
+ setError(null)
94
+ }, [])
95
+
96
+ return {
97
+ error,
98
+ isParsing,
99
+ isGeneratingTemplate,
100
+ onParseFile,
101
+ onGenerateTemplate,
102
+ onClearError,
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Parse CSV file using PapaParse's native Web Worker
108
+ */
109
+ const parseCSVFile = (
110
+ file: File,
111
+ options: WorkerCSVOptions = {}
112
+ ): Promise<WorkerCSVData> => {
113
+ return new Promise(async (resolve, reject) => {
114
+ const defaultOptions = {
115
+ skuColumnNames: ['sku', 'id', 'product', 'productid', 'item'],
116
+ quantityColumnNames: ['quantity', 'qty', 'amount', 'count'],
117
+ delimiter: '',
118
+ skipEmptyLines: true,
119
+ chunkSize: 1024 * 1024,
120
+ }
121
+
122
+ const config = { ...defaultOptions, ...options }
123
+
124
+ const detectDelimiter = (): Promise<string> => {
125
+ if (config.delimiter) {
126
+ return Promise.resolve(config.delimiter)
127
+ }
128
+
129
+ return new Promise((resolveDelimiter) => {
130
+ const reader = new FileReader()
131
+ reader.onload = (e) => {
132
+ const text = e.target?.result as string
133
+ const firstLine = (text.split(/\r?\n/)[0] || '').replace(/\r$/, '')
134
+
135
+ const commaCount = (firstLine.match(/,/g) || []).length
136
+ const semicolonCount = (firstLine.match(/;/g) || []).length
137
+ const tabCount = (firstLine.match(/\t/g) || []).length
138
+
139
+ if (semicolonCount > 0 && semicolonCount >= commaCount) {
140
+ resolveDelimiter(';')
141
+ } else if (tabCount > commaCount && tabCount > semicolonCount) {
142
+ resolveDelimiter('\t')
143
+ } else {
144
+ resolveDelimiter(',')
145
+ }
146
+ }
147
+ reader.onerror = () => resolveDelimiter(',')
148
+ reader.readAsText(file.slice(0, 1024))
149
+ })
150
+ }
151
+
152
+ const detectedDelimiter = await detectDelimiter()
153
+
154
+ let headers: string[] = []
155
+ let skuIndex = -1
156
+ let quantityIndex = -1
157
+ let isHeaderProcessed = false
158
+
159
+ const transformedData: Array<{ sku: string; quantity: number }> = []
160
+ const errors: string[] = []
161
+ let processedRows = 0
162
+ let totalEstimatedRows = 0
163
+
164
+ const findColumnIndex = (
165
+ headers: string[],
166
+ columnNames: string[]
167
+ ): number => {
168
+ return headers.findIndex((header) =>
169
+ columnNames.some(
170
+ (name) => header.toLowerCase().trim() === name.toLowerCase()
171
+ )
172
+ )
173
+ }
174
+
175
+ const validateAndTransformRow = (row: unknown[], rowIndex: number) => {
176
+ try {
177
+ const sku = row[skuIndex]
178
+ const quantity = row[quantityIndex]
179
+
180
+ if (!sku || sku === '' || quantity === undefined || quantity === '') {
181
+ return null
182
+ }
183
+
184
+ const trimmedSku = String(sku).trim()
185
+ const numericQuantity = Number(quantity)
186
+
187
+ if (!trimmedSku) {
188
+ throw new Error('Empty SKU found')
189
+ }
190
+
191
+ if (Number.isNaN(numericQuantity) || numericQuantity < 0) {
192
+ throw new Error(
193
+ `Invalid quantity value: ${quantity} for SKU: ${trimmedSku}`
194
+ )
195
+ }
196
+
197
+ return {
198
+ sku: trimmedSku,
199
+ quantity: numericQuantity,
200
+ }
201
+ } catch (err) {
202
+ const errorMessage =
203
+ err instanceof Error ? err.message : 'Unknown error'
204
+ errors.push(`Row ${rowIndex + 2}: ${errorMessage}`)
205
+
206
+ if (errors.length > 1000) {
207
+ errors.splice(0, 500)
208
+ }
209
+
210
+ return null
211
+ }
212
+ }
213
+
214
+ const estimateRows = (fileSize: number) => {
215
+ const avgBytesPerRow = 50
216
+ return Math.floor(fileSize / avgBytesPerRow)
217
+ }
218
+
219
+ totalEstimatedRows = estimateRows(file.size)
220
+
221
+ Papa.parse(file, {
222
+ header: false,
223
+ dynamicTyping: false,
224
+ skipEmptyLines: config.skipEmptyLines,
225
+ delimiter: detectedDelimiter,
226
+
227
+ worker: true,
228
+
229
+ chunk: (
230
+ results: { data: unknown[][] },
231
+ parser: { abort: () => void }
232
+ ) => {
233
+ try {
234
+ let rows = results.data
235
+
236
+ if (!isHeaderProcessed && rows.length > 0) {
237
+ headers = rows[0] as string[]
238
+
239
+ skuIndex = findColumnIndex(headers, config.skuColumnNames)
240
+ quantityIndex = findColumnIndex(headers, config.quantityColumnNames)
241
+
242
+ if (skuIndex === -1) {
243
+ parser.abort()
244
+ reject(
245
+ new Error(
246
+ `SKU column not found. Expected one of: ${config.skuColumnNames.join(', ')}`
247
+ )
248
+ )
249
+ return
250
+ }
251
+
252
+ if (quantityIndex === -1) {
253
+ parser.abort()
254
+ reject(
255
+ new Error(
256
+ `Quantity column not found. Expected one of: ${config.quantityColumnNames.join(', ')}`
257
+ )
258
+ )
259
+ return
260
+ }
261
+
262
+ rows = rows.slice(1)
263
+ isHeaderProcessed = true
264
+ }
265
+
266
+ rows.forEach((row, index) => {
267
+ const globalRowIndex = processedRows + index
268
+ const transformedRow = validateAndTransformRow(row, globalRowIndex)
269
+
270
+ if (transformedRow) {
271
+ transformedData.push(transformedRow)
272
+ }
273
+ })
274
+
275
+ processedRows += rows.length
276
+
277
+ if (config.onProgress) {
278
+ const percentage = Math.min(
279
+ 100,
280
+ Math.round((processedRows / totalEstimatedRows) * 100)
281
+ )
282
+ config.onProgress({
283
+ processed: processedRows,
284
+ total: totalEstimatedRows,
285
+ percentage,
286
+ })
287
+ }
288
+ } catch (err) {
289
+ parser.abort()
290
+ reject(err)
291
+ }
292
+ },
293
+
294
+ complete: () => {
295
+ try {
296
+ if (transformedData.length === 0) {
297
+ if (errors.length > 0) {
298
+ reject(
299
+ new Error(
300
+ `No valid data found. First few errors:\n${errors.slice(0, 5).join('\n')}`
301
+ )
302
+ )
303
+ } else {
304
+ reject(new Error('No valid data found in file'))
305
+ }
306
+ return
307
+ }
308
+
309
+ if (errors.length > 0) {
310
+ console.warn(
311
+ `CSV parsing completed with ${errors.length} warnings. Sample:`,
312
+ errors.slice(0, 10)
313
+ )
314
+ }
315
+
316
+ if (config.onProgress) {
317
+ config.onProgress({
318
+ processed: processedRows,
319
+ total: processedRows,
320
+ percentage: 100,
321
+ })
322
+ }
323
+
324
+ resolve({
325
+ data: transformedData,
326
+ fileName: file.name,
327
+ totalRows: transformedData.length,
328
+ fileSize: file.size,
329
+ })
330
+ } catch (err) {
331
+ reject(err)
332
+ }
333
+ },
334
+
335
+ error: (error: unknown) => {
336
+ const errorMessage =
337
+ error instanceof Error ? error.message : 'Unknown parsing error'
338
+ reject(new Error(`PapaParse error: ${errorMessage}`))
339
+ },
340
+
341
+ fastMode: false,
342
+ chunkSize: config.chunkSize,
343
+ preview: 0,
344
+ encoding: 'UTF-8',
345
+ })
346
+ })
347
+ }
348
+
349
+ /**
350
+ * Generate CSV template with sample data
351
+ */
352
+ const generateCSVTemplate = (): string => {
353
+ const templateData = [
354
+ { sku: 'PROD-001', quantity: 5 },
355
+ { sku: 'ITEM-234', quantity: 12 },
356
+ { sku: 'SKU789', quantity: 3 },
357
+ { sku: 'ABC-XYZ-456', quantity: 8 },
358
+ { sku: 'SAMPLE-100', quantity: 25 },
359
+ ]
360
+
361
+ return Papa.unparse(templateData, {
362
+ header: true,
363
+ delimiter: ',',
364
+ newline: '\n',
365
+ skipEmptyLines: true,
366
+ })
367
+ }