@faststore/core 3.98.0-dev.1 → 3.98.0-dev.10

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 (378) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +124 -123
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/config.json +3 -3
  5. package/.next/cache/webpack/client-production/0.pack +0 -0
  6. package/.next/cache/webpack/client-production/index.pack +0 -0
  7. package/.next/cache/webpack/server-production/0.pack +0 -0
  8. package/.next/cache/webpack/server-production/index.pack +0 -0
  9. package/.next/next-minimal-server.js.nft.json +1 -1
  10. package/.next/next-server.js.nft.json +1 -1
  11. package/.next/prerender-manifest.js +1 -1
  12. package/.next/prerender-manifest.json +1 -1
  13. package/.next/react-loadable-manifest.json +167 -163
  14. package/.next/required-server-files.json +1 -1
  15. package/.next/routes-manifest.json +1 -1
  16. package/.next/server/chunks/{5796.js → 1027.js} +1 -1
  17. package/.next/server/chunks/1197.js +1 -0
  18. package/.next/server/chunks/{3483.js → 1313.js} +1 -1
  19. package/.next/server/chunks/1419.js +1 -0
  20. package/.next/server/chunks/1576.js +1 -0
  21. package/.next/server/chunks/{7275.js → 1588.js} +1 -1
  22. package/.next/server/chunks/1741.js +3 -0
  23. package/.next/server/chunks/221.js +1 -0
  24. package/.next/server/chunks/2259.js +9 -0
  25. package/.next/server/chunks/2513.js +1 -0
  26. package/.next/server/chunks/2955.js +1 -0
  27. package/.next/server/chunks/3114.js +1 -0
  28. package/.next/server/chunks/3327.js +1 -0
  29. package/.next/server/chunks/3488.js +1 -0
  30. package/.next/server/chunks/{1917.js → 3513.js} +1 -1
  31. package/.next/server/chunks/3683.js +1 -0
  32. package/.next/server/chunks/{8563.js → 3724.js} +1 -1
  33. package/.next/server/chunks/3977.js +1 -0
  34. package/.next/server/chunks/426.js +1 -0
  35. package/.next/server/chunks/4573.js +1 -0
  36. package/.next/server/chunks/4681.js +1 -0
  37. package/.next/server/chunks/5133.js +3 -0
  38. package/.next/server/chunks/5212.js +7 -0
  39. package/.next/server/chunks/5608.js +1 -0
  40. package/.next/server/chunks/5628.js +12 -0
  41. package/.next/server/chunks/{1607.js → 5764.js} +1 -1
  42. package/.next/server/chunks/{9740.js → 6259.js} +1 -1
  43. package/.next/server/chunks/6698.js +1 -1
  44. package/.next/server/chunks/689.js +1 -0
  45. package/.next/server/chunks/6952.js +1 -0
  46. package/.next/server/chunks/7121.js +1 -0
  47. package/.next/server/chunks/7371.js +1 -1
  48. package/.next/server/chunks/7417.js +1 -0
  49. package/.next/server/chunks/{1280.js → 7722.js} +1 -1
  50. package/.next/server/chunks/7796.js +1 -0
  51. package/.next/server/chunks/7956.js +1 -0
  52. package/.next/server/chunks/{6804.js → 7976.js} +3 -3
  53. package/.next/server/chunks/{9985.js → 8146.js} +1 -1
  54. package/.next/server/chunks/8290.js +1 -0
  55. package/.next/server/chunks/8376.js +13 -0
  56. package/.next/server/chunks/8466.js +6 -0
  57. package/.next/server/chunks/8569.js +1 -1
  58. package/.next/server/chunks/8659.js +1 -0
  59. package/.next/server/chunks/8741.js +1 -0
  60. package/.next/server/chunks/8971.js +493 -0
  61. package/.next/server/chunks/9088.js +1 -1
  62. package/.next/server/chunks/9237.js +1 -1
  63. package/.next/server/chunks/9374.js +13 -0
  64. package/.next/server/chunks/{8068.js → 9425.js} +1 -1
  65. package/.next/server/chunks/{UINavbarSlider.js → 9984.js} +1 -1
  66. package/.next/server/chunks/9986.js +1 -0
  67. package/.next/server/chunks/ButtonSignIn.js +1 -1
  68. package/.next/server/chunks/FilterSkeleton.js +1 -1
  69. package/.next/server/chunks/ScrollToTopButton.js +1 -1
  70. package/.next/server/chunks/UIBannerText.js +1 -1
  71. package/.next/server/chunks/UISKUMatrixSidebar.js +1 -1
  72. package/.next/server/functions-config-manifest.json +1 -1
  73. package/.next/server/middleware-build-manifest.js +1 -1
  74. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  75. package/.next/server/pages/404.js +1 -1
  76. package/.next/server/pages/404.js.nft.json +1 -1
  77. package/.next/server/pages/500.js +1 -1
  78. package/.next/server/pages/500.js.nft.json +1 -1
  79. package/.next/server/pages/[...slug].js +1 -1
  80. package/.next/server/pages/[...slug].js.nft.json +1 -1
  81. package/.next/server/pages/[slug]/p.js +1 -1
  82. package/.next/server/pages/[slug]/p.js.nft.json +1 -1
  83. package/.next/server/pages/_app.js +1 -1
  84. package/.next/server/pages/_app.js.nft.json +1 -1
  85. package/.next/server/pages/_document.js +1 -1
  86. package/.next/server/pages/_document.js.nft.json +1 -1
  87. package/.next/server/pages/_error.js +1 -1
  88. package/.next/server/pages/_error.js.nft.json +1 -1
  89. package/.next/server/pages/api/fs/logout.js +1 -1
  90. package/.next/server/pages/api/fs/logout.js.nft.json +1 -1
  91. package/.next/server/pages/api/graphql.js +3 -3
  92. package/.next/server/pages/api/graphql.js.nft.json +1 -1
  93. package/.next/server/pages/api/health/live.js +1 -1
  94. package/.next/server/pages/api/health/live.js.nft.json +1 -1
  95. package/.next/server/pages/api/health/ready.js +1 -1
  96. package/.next/server/pages/api/health/ready.js.nft.json +1 -1
  97. package/.next/server/pages/api/preview.js +1 -1
  98. package/.next/server/pages/api/preview.js.nft.json +1 -1
  99. package/.next/server/pages/checkout.js +1 -1
  100. package/.next/server/pages/checkout.js.nft.json +1 -1
  101. package/.next/server/pages/en-US/404.html +2 -2
  102. package/.next/server/pages/en-US/404.json +1 -1
  103. package/.next/server/pages/en-US/500.html +2 -2
  104. package/.next/server/pages/en-US/500.json +1 -1
  105. package/.next/server/pages/en-US/checkout.html +2 -2
  106. package/.next/server/pages/en-US/checkout.json +1 -1
  107. package/.next/server/pages/en-US/login.html +2 -2
  108. package/.next/server/pages/en-US/login.json +1 -1
  109. package/.next/server/pages/en-US/s.html +2 -2
  110. package/.next/server/pages/en-US/s.json +1 -1
  111. package/.next/server/pages/en-US.html +2 -2
  112. package/.next/server/pages/en-US.json +1 -1
  113. package/.next/server/pages/index.js +1 -1
  114. package/.next/server/pages/index.js.nft.json +1 -1
  115. package/.next/server/pages/login.js +1 -1
  116. package/.next/server/pages/login.js.nft.json +1 -1
  117. package/.next/server/pages/pvt/account/403.js +1 -1
  118. package/.next/server/pages/pvt/account/403.js.nft.json +1 -1
  119. package/.next/server/pages/pvt/account/404.js +1 -1
  120. package/.next/server/pages/pvt/account/404.js.nft.json +1 -1
  121. package/.next/server/pages/pvt/account/[...unknown].js +1 -1
  122. package/.next/server/pages/pvt/account/[...unknown].js.nft.json +1 -1
  123. package/.next/server/pages/pvt/account/orders/[id].js +1 -1
  124. package/.next/server/pages/pvt/account/orders/[id].js.nft.json +1 -1
  125. package/.next/server/pages/pvt/account/orders.js +1 -1
  126. package/.next/server/pages/pvt/account/orders.js.nft.json +1 -1
  127. package/.next/server/pages/pvt/account/profile.js +1 -1
  128. package/.next/server/pages/pvt/account/profile.js.nft.json +1 -1
  129. package/.next/server/pages/pvt/account/security.js +1 -1
  130. package/.next/server/pages/pvt/account/security.js.nft.json +1 -1
  131. package/.next/server/pages/pvt/account/user-details.js +1 -1
  132. package/.next/server/pages/pvt/account/user-details.js.nft.json +1 -1
  133. package/.next/server/pages/pvt/account.js +1 -1
  134. package/.next/server/pages/pvt/account.js.nft.json +1 -1
  135. package/.next/server/pages/s.js +1 -1
  136. package/.next/server/pages/s.js.nft.json +1 -1
  137. package/.next/server/pages-manifest.json +1 -1
  138. package/.next/server/webpack-runtime.js +1 -1
  139. package/.next/static/Xu5Fn6_Qwp_x6LicEI8BU/_buildManifest.js +1 -0
  140. package/.next/static/chunks/{5796.4351370494d8b8b6.js → 1027.f17a7c96c17ce487.js} +1 -1
  141. package/.next/static/chunks/1313.bba028de90630608.js +1 -0
  142. package/.next/static/chunks/1756.89b7f413bb26ba74.js +1 -0
  143. package/.next/static/chunks/{8325.dabe9aa22eaadeed.js → 1911.fb72de1df3c3715c.js} +1 -1
  144. package/.next/static/chunks/2221-f8edfdaa4839bdf0.js +2 -0
  145. package/.next/static/chunks/2564.273fd8b0db75b1c4.js +1 -0
  146. package/.next/static/chunks/2811.cf089090a8b79215.js +1 -0
  147. package/.next/static/chunks/346.2840f007e6d1054c.js +1 -0
  148. package/.next/static/chunks/3496.bcb4d219501a8b6b.js +1 -0
  149. package/.next/static/chunks/3753-74460a0793c0a75c.js +8 -0
  150. package/.next/static/chunks/3802.1e0df8a20802da16.js +1 -0
  151. package/.next/static/chunks/3883-ebdbb60b50a90c59.js +28 -0
  152. package/.next/static/chunks/4436.9b2b6e1c3f79424d.js +1 -0
  153. package/.next/static/chunks/4681.318feb830c746e3b.js +1 -0
  154. package/.next/static/chunks/484.9fdcaa9ffd8dac08.js +1 -0
  155. package/.next/static/chunks/6218.e8ba8bf8602ec880.js +1 -0
  156. package/.next/static/chunks/{6393.e4b26fee060438d6.js → 6393.f5f13a004beeef40.js} +1 -1
  157. package/.next/static/chunks/6656-efc464f20ffeaa51.js +1 -0
  158. package/.next/static/chunks/6797-ff5656c8624c4265.js +1 -0
  159. package/.next/static/chunks/6943.6bc97e925b54493d.js +1 -0
  160. package/.next/static/chunks/7417.55a6e20779dd3702.js +1 -0
  161. package/.next/static/chunks/7534.ee76e63d58ddd222.js +1 -0
  162. package/.next/static/chunks/7796.a30626656a270831.js +1 -0
  163. package/.next/static/chunks/9105.354374e349da85cb.js +1 -0
  164. package/.next/static/chunks/9222.04daf7868c957e52.js +1 -0
  165. package/.next/static/chunks/{9237.7555603703f81bf7.js → 9237.2d7e1a4978875414.js} +1 -1
  166. package/.next/static/chunks/9399.199f217093e4af1e.js +1 -0
  167. package/.next/static/chunks/{8068.43663fb64762f7b8.js → 9425.9d8b3da847111f21.js} +1 -1
  168. package/.next/static/chunks/9701.f9a0bfffba8807dc.js +1 -0
  169. package/.next/static/chunks/BannerNewsletter.b5770016d20acfd2.js +1 -0
  170. package/.next/static/chunks/{BannerText.4061ccfc191e6b96.js → BannerText.5ba50fbe683158ec.js} +1 -1
  171. package/.next/static/chunks/{ButtonSignIn.f6e210eaca873e48.js → ButtonSignIn.639d8dfc65ded368.js} +1 -1
  172. package/.next/static/chunks/CartItem.3c2ceb3a4ee542bc.js +1 -0
  173. package/.next/static/chunks/CartSidebar.89b0dd6237c025ec.js +1 -0
  174. package/.next/static/chunks/{EmptyCart.320e2f94a0d5e6b1.js → EmptyCart.aa60d42ae8eb5264.js} +1 -1
  175. package/.next/static/chunks/{FilterSkeleton.7ab99e28f92341c9.js → FilterSkeleton.8f1b651c40e06f0b.js} +1 -1
  176. package/.next/static/chunks/Footer.cd83c4dc0252494a.js +1 -0
  177. package/.next/static/chunks/Gift.4c97f836f82d5ebe.js +1 -0
  178. package/.next/static/chunks/Newsletter.bdec43379ca9191a.js +1 -0
  179. package/.next/static/chunks/OrderSummary.994b7314f2d004af.js +1 -0
  180. package/.next/static/chunks/PreviewTag.696854f6690e1b9e.js +1 -0
  181. package/.next/static/chunks/ProductShelf.fe1f19bc68859695.js +1 -0
  182. package/.next/static/chunks/ProductTiles.2c63ae178a75d5b6.js +1 -0
  183. package/.next/static/chunks/{RegionModal.a7be32d2d7832ba4.js → RegionModal.fbbdd54ee2422522.js} +1 -1
  184. package/.next/static/chunks/RegionSlider.49e558b340a5506a.js +1 -0
  185. package/.next/static/chunks/{ScrollToTopButton.c15431f2e8bb93ef.js → ScrollToTopButton.55e3a1233d04b8eb.js} +1 -1
  186. package/.next/static/chunks/ShoppingAssistant.8772fe90bd678202.js +1 -0
  187. package/.next/static/chunks/Toast.f083d9966a9a181e.js +1 -0
  188. package/.next/static/chunks/UISKUMatrixSidebar.01f8f5222dcdf80f.js +1 -0
  189. package/.next/static/chunks/main-edeb2c6a5c48bb3f.js +1 -0
  190. package/.next/static/chunks/pages/404-1e8f91fa1bca3ab8.js +1 -0
  191. package/.next/static/chunks/pages/500-f21feacbb9810e94.js +1 -0
  192. package/.next/static/chunks/pages/[...slug]-400781188d59cfd6.js +1 -0
  193. package/.next/static/chunks/pages/[slug]/p-f324b592d1c566b9.js +1 -0
  194. package/.next/static/chunks/pages/_app-735c745509e1e8d6.js +1 -0
  195. package/.next/static/chunks/pages/{_error-2b0148be56a716e9.js → _error-464097ff69347627.js} +1 -1
  196. package/.next/static/chunks/pages/checkout-6076b4baf0ca1aa6.js +1 -0
  197. package/.next/static/chunks/pages/index-3266ece2e885bb3a.js +1 -0
  198. package/.next/static/chunks/pages/login-add3b376f68ce39a.js +1 -0
  199. package/.next/static/chunks/pages/pvt/account/403-d44b70591d2c86dc.js +1 -0
  200. package/.next/static/chunks/pages/pvt/account/404-646fb609f579101e.js +1 -0
  201. package/.next/static/chunks/pages/pvt/account/[...unknown]-3fb3963ca3d77c0b.js +1 -0
  202. package/.next/static/chunks/pages/pvt/account/orders/[id]-cda2266c9693d552.js +1 -0
  203. package/.next/static/chunks/pages/pvt/account/orders-ec545a2679db206e.js +1 -0
  204. package/.next/static/chunks/pages/pvt/account/profile-27164b37098c553f.js +1 -0
  205. package/.next/static/chunks/pages/pvt/account/security-4bd3e75771a120ec.js +1 -0
  206. package/.next/static/chunks/pages/pvt/account/user-details-a48a44dfdc07c1e9.js +1 -0
  207. package/.next/static/chunks/pages/pvt/account-5a6dcae3b380b672.js +1 -0
  208. package/.next/static/chunks/pages/s-0fe527a651dd5989.js +1 -0
  209. package/.next/static/chunks/webpack-d3e4f545845241c4.js +1 -0
  210. package/.next/static/css/094ad5cc00c74e64.css +1 -0
  211. package/.next/static/css/{b684b347c5cc6514.css → 1154064b68a7f35e.css} +1 -1
  212. package/.next/static/css/1b7e34d448a42825.css +1 -0
  213. package/.next/static/css/23857075311e4d06.css +1 -0
  214. package/.next/static/css/482e6fa149885bc2.css +1 -0
  215. package/.next/static/css/4b2af1aaeb961465.css +1 -0
  216. package/.next/static/css/{837662922091162f.css → 52ab64b6a2b14e3e.css} +1 -1
  217. package/.next/static/css/5cd37b7508dd5190.css +1 -0
  218. package/.next/static/css/72f154a00f1cf621.css +1 -0
  219. package/.next/static/css/8a513f4b536b0ab0.css +1 -0
  220. package/.next/static/css/9b4c21dcd3bc4a17.css +1 -0
  221. package/.next/static/css/d0930b8076866831.css +1 -0
  222. package/.next/static/css/e028eb9f46d42611.css +1 -0
  223. package/.next/static/css/e68c313e4ce2fd1b.css +1 -0
  224. package/.next/static/css/f16438bcf4508fb3.css +1 -0
  225. package/.next/trace +142 -140
  226. package/.turbo/turbo-build.log +46 -66
  227. package/.turbo/turbo-test.log +7 -7
  228. package/@generated/gql.ts +22 -14
  229. package/@generated/graphql.ts +148 -55
  230. package/@generated/persisted-documents.json +5 -4
  231. package/@generated/schema.graphql +4 -0
  232. package/CHANGELOG.md +56 -4
  233. package/cms/faststore/base.jsonc +3 -3
  234. package/cms/faststore/components/cms_component__productshelf.jsonc +2 -2
  235. package/cms/faststore/components/cms_component__producttiles.jsonc +2 -2
  236. package/cms/faststore/schema.json +2510 -2482
  237. package/cms/faststore/sections.json +485 -4
  238. package/cypress/tsconfig.json +7 -0
  239. package/discovery.config.default.js +2 -0
  240. package/jest.config.js +3 -0
  241. package/next.config.js +4 -0
  242. package/package.json +5 -4
  243. package/public/icons.svg +62 -0
  244. package/src/components/ThirdPartyScripts/index.ts +1 -0
  245. package/src/components/ThirdPartyScripts/useShoppingAssistant.tsx +30 -0
  246. package/src/components/account/MyAccountDrawer/OrganizationDrawer/OrganizationDrawer.tsx +27 -18
  247. package/src/components/account/MyAccountDrawer/OrganizationDrawer/useReloadAfterLogoutReturn.ts +75 -0
  248. package/src/components/cms/global/Components.ts +8 -0
  249. package/src/components/product/ProductGrid/ProductGrid.tsx +26 -1
  250. package/src/components/search/SearchDropdown/SearchDropdown.tsx +11 -2
  251. package/src/components/search/SearchInput/SearchInput.tsx +492 -5
  252. package/src/components/sections/Navbar/Navbar.tsx +67 -0
  253. package/src/components/sections/Navbar/section.module.scss +3 -0
  254. package/src/components/sections/ProductDetails/ProductDetails.tsx +1 -0
  255. package/src/components/sections/ShoppingAssistant/ShoppingAssistant.tsx +24 -0
  256. package/src/components/sections/ShoppingAssistant/index.ts +1 -0
  257. package/src/components/sections/ShoppingAssistant/section.module.scss +5 -0
  258. package/src/components/templates/ProductListingPage/ProductListing.tsx +1 -1
  259. package/src/components/ui/ProductGallery/ProductGalleryPage.tsx +17 -0
  260. package/src/pages/[slug]/p.tsx +2 -0
  261. package/src/pages/_app.tsx +2 -0
  262. package/src/sdk/graphql/request.ts +1 -1
  263. package/src/sdk/graphql/useQuery.ts +23 -6
  264. package/src/sdk/product/convertProductToQuickOrder.ts +85 -0
  265. package/src/sdk/product/useBulkProductsQuery.ts +128 -0
  266. package/src/sdk/product/usePageProductsQuery.ts +11 -9
  267. package/src/sdk/search/useSuggestions.ts +1 -0
  268. package/src/styles/global/index.scss +2 -1
  269. package/src/utils/cookieCacheBusting.ts +35 -41
  270. package/src/utils/utilities.ts +62 -0
  271. package/test/tsconfig.json +7 -0
  272. package/test/utils/cookieCacheBusting.test.ts +54 -47
  273. package/.next/server/chunks/1554.js +0 -1
  274. package/.next/server/chunks/1780.js +0 -1
  275. package/.next/server/chunks/2249.js +0 -1
  276. package/.next/server/chunks/2430.js +0 -1
  277. package/.next/server/chunks/2445.js +0 -12
  278. package/.next/server/chunks/2570.js +0 -1
  279. package/.next/server/chunks/294.js +0 -1
  280. package/.next/server/chunks/3029.js +0 -1
  281. package/.next/server/chunks/3836.js +0 -1
  282. package/.next/server/chunks/3890.js +0 -492
  283. package/.next/server/chunks/3945.js +0 -1
  284. package/.next/server/chunks/3951.js +0 -7
  285. package/.next/server/chunks/4194.js +0 -1
  286. package/.next/server/chunks/4365.js +0 -1
  287. package/.next/server/chunks/4803.js +0 -1
  288. package/.next/server/chunks/4913.js +0 -13
  289. package/.next/server/chunks/5683.js +0 -1
  290. package/.next/server/chunks/5723.js +0 -13
  291. package/.next/server/chunks/6789.js +0 -1
  292. package/.next/server/chunks/6886.js +0 -1
  293. package/.next/server/chunks/7098.js +0 -9
  294. package/.next/server/chunks/7692.js +0 -1
  295. package/.next/server/chunks/772.js +0 -6
  296. package/.next/server/chunks/7799.js +0 -1
  297. package/.next/server/chunks/83.js +0 -1
  298. package/.next/server/chunks/8307.js +0 -1
  299. package/.next/server/chunks/8482.js +0 -1
  300. package/.next/server/chunks/8598.js +0 -1
  301. package/.next/server/chunks/8687.js +0 -1
  302. package/.next/server/chunks/870.js +0 -1
  303. package/.next/server/chunks/9117.js +0 -1
  304. package/.next/server/chunks/948.js +0 -2
  305. package/.next/server/chunks/9563.js +0 -3
  306. package/.next/server/chunks/9853.js +0 -1
  307. package/.next/server/chunks/9990.js +0 -1
  308. package/.next/static/Q4xA-lP9ZZhP1GXzClxiR/_buildManifest.js +0 -1
  309. package/.next/static/chunks/1208-9118a8f14ecf05c8.js +0 -8
  310. package/.next/static/chunks/1841.a1b15f2c88e02d32.js +0 -1
  311. package/.next/static/chunks/2284.dffe7b0e5a5bfb4a.js +0 -1
  312. package/.next/static/chunks/2500.d6beb5af6ee00a9e.js +0 -1
  313. package/.next/static/chunks/2851.e68ed3c8d27a032a.js +0 -1
  314. package/.next/static/chunks/3155.7bc4c730a79d9ecb.js +0 -1
  315. package/.next/static/chunks/3399.3e1f685c992c345b.js +0 -1
  316. package/.next/static/chunks/3483.ef53d632a763da3f.js +0 -1
  317. package/.next/static/chunks/349.235b18ceb82aa256.js +0 -1
  318. package/.next/static/chunks/3836.612763339fc4c64c.js +0 -1
  319. package/.next/static/chunks/4803.9822f0b7e469b933.js +0 -1
  320. package/.next/static/chunks/5859.3bc094416cffd966.js +0 -1
  321. package/.next/static/chunks/6031-b0b111f48a7d504d.js +0 -28
  322. package/.next/static/chunks/6700.a72869377e81146c.js +0 -1
  323. package/.next/static/chunks/6789.960162355435a81d.js +0 -1
  324. package/.next/static/chunks/7191-5ede6e7ef625ea77.js +0 -1
  325. package/.next/static/chunks/7522-9010743f5d7e8aca.js +0 -1
  326. package/.next/static/chunks/7692.8d5bf4560341a2f6.js +0 -1
  327. package/.next/static/chunks/83.98ce246c274ee7e4.js +0 -1
  328. package/.next/static/chunks/9173-ab3c4d9d8f978c4b.js +0 -1
  329. package/.next/static/chunks/9399.48251a278809f7d3.js +0 -1
  330. package/.next/static/chunks/941.3e2782ab9c490eb0.js +0 -1
  331. package/.next/static/chunks/9465.e09b81f7e6195587.js +0 -1
  332. package/.next/static/chunks/9701.b0e8741551995fbb.js +0 -1
  333. package/.next/static/chunks/9909.787576b171184aa5.js +0 -1
  334. package/.next/static/chunks/BannerNewsletter.90d4a98c15a35cea.js +0 -1
  335. package/.next/static/chunks/CartItem.092df07db9e8b271.js +0 -1
  336. package/.next/static/chunks/CartSidebar.f0c16e2bc6f96e9e.js +0 -1
  337. package/.next/static/chunks/Footer.63a7682a81a96f8e.js +0 -1
  338. package/.next/static/chunks/Gift.08db4da8c89cacf1.js +0 -1
  339. package/.next/static/chunks/Newsletter.dbf35a8ea6d2067e.js +0 -1
  340. package/.next/static/chunks/OrderSummary.f9adad5622605046.js +0 -1
  341. package/.next/static/chunks/PreviewTag.f4f0c8710a7bcad9.js +0 -1
  342. package/.next/static/chunks/ProductShelf.7ebce1c763b4508e.js +0 -1
  343. package/.next/static/chunks/ProductTiles.18f55314e61957f4.js +0 -1
  344. package/.next/static/chunks/RegionSlider.b4dd4e7c0483966d.js +0 -1
  345. package/.next/static/chunks/Toast.2e9b26159af29889.js +0 -1
  346. package/.next/static/chunks/UISKUMatrixSidebar.87ba393b7d738e99.js +0 -1
  347. package/.next/static/chunks/main-ec03882c4375091d.js +0 -1
  348. package/.next/static/chunks/pages/404-4b3f1e22c77f849a.js +0 -1
  349. package/.next/static/chunks/pages/500-bb2de0c11524b2b8.js +0 -1
  350. package/.next/static/chunks/pages/[...slug]-3579b3b8b8309552.js +0 -1
  351. package/.next/static/chunks/pages/[slug]/p-7ac98274c47b0ff4.js +0 -1
  352. package/.next/static/chunks/pages/_app-1595678557980d65.js +0 -1
  353. package/.next/static/chunks/pages/checkout-dc07d72b3514c83d.js +0 -1
  354. package/.next/static/chunks/pages/index-1f8bf0fb351b90f4.js +0 -1
  355. package/.next/static/chunks/pages/login-e97ef92769456bf6.js +0 -1
  356. package/.next/static/chunks/pages/pvt/account/403-91597100f8956385.js +0 -1
  357. package/.next/static/chunks/pages/pvt/account/404-c68124bed7cb7c48.js +0 -1
  358. package/.next/static/chunks/pages/pvt/account/[...unknown]-f80f645594d2740c.js +0 -1
  359. package/.next/static/chunks/pages/pvt/account/orders/[id]-e03ebb0393ac92a2.js +0 -1
  360. package/.next/static/chunks/pages/pvt/account/orders-12a215899ae6f3eb.js +0 -1
  361. package/.next/static/chunks/pages/pvt/account/profile-b6cdbf02d4682544.js +0 -1
  362. package/.next/static/chunks/pages/pvt/account/security-e6289a40e745d3c4.js +0 -1
  363. package/.next/static/chunks/pages/pvt/account/user-details-fba1822e52e7de26.js +0 -1
  364. package/.next/static/chunks/pages/pvt/account-65fefcc699344bdb.js +0 -1
  365. package/.next/static/chunks/pages/s-41cffb20de1d2617.js +0 -1
  366. package/.next/static/chunks/webpack-345c083b2f1f8bb9.js +0 -1
  367. package/.next/static/css/05c399956ff24b77.css +0 -1
  368. package/.next/static/css/08d03445f1797608.css +0 -1
  369. package/.next/static/css/0f070d03aacd9cc5.css +0 -1
  370. package/.next/static/css/0fae3d432331aae9.css +0 -1
  371. package/.next/static/css/0fc6b2ff69142c6a.css +0 -1
  372. package/.next/static/css/31380ebc6e671486.css +0 -1
  373. package/.next/static/css/40a294d0a24ad01d.css +0 -1
  374. package/.next/static/css/47f1b4e8de15d314.css +0 -1
  375. package/.next/static/css/973dd40d4773e8cd.css +0 -1
  376. package/.next/static/css/9d403a1bee48c9fc.css +0 -1
  377. package/.next/static/css/a6a4ebbe01adbbad.css +0 -1
  378. /package/.next/static/{Q4xA-lP9ZZhP1GXzClxiR → Xu5Fn6_Qwp_x6LicEI8BU}/_ssgManifest.js +0 -0
@@ -3,8 +3,11 @@ import {
3
3
  Suspense,
4
4
  forwardRef,
5
5
  lazy,
6
+ useCallback,
6
7
  useDeferredValue,
8
+ useEffect,
7
9
  useImperativeHandle,
10
+ useMemo,
8
11
  useRef,
9
12
  useState,
10
13
  } from 'react'
@@ -15,15 +18,25 @@ import { useRouter } from 'next/router'
15
18
  import type { SearchEvent, SearchState } from '@faststore/sdk'
16
19
 
17
20
  import {
21
+ FileUploadCard,
22
+ FileUploadErrorType,
23
+ QuickOrderDrawer,
24
+ QuickOrderDrawerFooter,
25
+ QuickOrderDrawerHeader,
26
+ QuickOrderDrawerProducts,
18
27
  Icon as UIIcon,
19
28
  IconButton as UIIconButton,
20
29
  SearchInput as UISearchInput,
30
+ useCSVParser,
21
31
  useOnClickOutside,
32
+ useUI,
22
33
  } from '@faststore/ui'
23
34
 
24
35
  import type {
25
36
  SearchInputFieldProps as UISearchInputFieldProps,
26
37
  SearchInputFieldRef as UISearchInputFieldRef,
38
+ CSVData,
39
+ Product,
27
40
  } from '@faststore/ui'
28
41
 
29
42
  import type { SearchProviderContextValue } from '@faststore/ui'
@@ -32,7 +45,12 @@ import type { NavbarProps } from 'src/components/sections/Navbar'
32
45
  import useSearchHistory from 'src/sdk/search/useSearchHistory'
33
46
  import useSuggestions from 'src/sdk/search/useSuggestions'
34
47
 
48
+ import { cartStore } from 'src/sdk/cart'
49
+ import { convertProductToQuickOrder } from 'src/sdk/product/convertProductToQuickOrder'
50
+ import { useBulkProductsQuery } from 'src/sdk/product/useBulkProductsQuery'
51
+ import { usePriceFormatter } from 'src/sdk/product/useFormattedPrice'
35
52
  import { formatSearchPath } from 'src/sdk/search/formatSearchPath'
53
+ import { formatFileName, formatFileSize } from 'src/utils/utilities'
36
54
 
37
55
  const SearchDropdown = lazy(
38
56
  /* webpackChunkName: "SearchDropdown" */
@@ -43,7 +61,6 @@ const UISearchInputField = dynamic<UISearchInputFieldProps & any>(() =>
43
61
  /* webpackChunkName: "UISearchInputField" */
44
62
  import('@faststore/ui').then((module) => module.SearchInputField)
45
63
  )
46
-
47
64
  const MAX_SUGGESTIONS = 5
48
65
 
49
66
  export type SearchInputProps = {
@@ -53,7 +70,12 @@ export type SearchInputProps = {
53
70
  placeholder?: string
54
71
  quickOrderSettings?: NavbarProps['searchInput']['quickOrderSettings']
55
72
  sort?: string
56
- } & Omit<UISearchInputFieldProps, 'onSubmit'>
73
+ /**
74
+ * Called when the user clicks Search in the file upload card, with the parsed CSV data.
75
+ * Use this to run bulk search, add to cart, or analytics.
76
+ */
77
+ onFileSearch?: (data: CSVData) => void
78
+ } & Omit<UISearchInputFieldProps, 'onSubmit' | 'attachmentButtonIcon'>
57
79
 
58
80
  export type SearchInputRef = UISearchInputFieldRef & {
59
81
  resetSearchInput: () => void
@@ -77,6 +99,7 @@ const SearchInput = forwardRef<SearchInputRef, SearchInputProps>(
77
99
  sort,
78
100
  placeholder,
79
101
  quickOrderSettings,
102
+ onFileSearch,
80
103
  ...otherProps
81
104
  },
82
105
  ref
@@ -90,15 +113,62 @@ const SearchInput = forwardRef<SearchInputRef, SearchInputProps>(
90
113
  const searchQueryDeferred = useDeferredValue(searchQuery)
91
114
  const [searchDropdownVisible, setSearchDropdownVisible] =
92
115
  useState<boolean>(false)
116
+ const [fileUploadVisible, setFileUploadVisible] = useState<boolean>(false)
117
+ const [isUploadOpen, setIsUploadOpen] = useState(false)
118
+ const [hasFile, setHasFile] = useState(false)
119
+ const [isQuickOrderDrawerOpen, setIsQuickOrderDrawerOpen] = useState(false)
120
+ const [quickOrderProducts, setQuickOrderProducts] = useState<Product[]>([])
121
+ const [noProductsError, setNoProductsError] = useState<boolean>(false)
93
122
 
94
123
  const searchRef = useRef<HTMLDivElement>(null)
95
124
  const { addToSearchHistory } = useSearchHistory()
96
125
  const router = useRouter()
126
+ const priceFormatter = usePriceFormatter()
127
+ const { pushToast } = useUI()
128
+
129
+ const [csvData, setCsvData] = useState<CSVData | null>(null)
130
+ const [selectedFile, setSelectedFile] = useState<File | null>(null)
131
+ const [skusToFetch, setSkusToFetch] = useState<string[]>([])
132
+ const [skuQuantityMap, setSkuQuantityMap] = useState<
133
+ Record<string, number>
134
+ >({})
135
+ const [isLoadingWithDelay, setIsLoadingWithDelay] = useState(false)
136
+
137
+ const csvParserOptions = useMemo(
138
+ () => ({ delimiter: ',' as const, skipEmptyLines: true }),
139
+ []
140
+ )
141
+
142
+ const csvParser = useCSVParser(csvParserOptions)
143
+ const {
144
+ error: csvError,
145
+ isParsing: isCsvProcessing,
146
+ onParseFile,
147
+ onClearError,
148
+ onGenerateTemplate,
149
+ } = csvParser
150
+
151
+ const isQuickOrderEnabled = quickOrderSettings?.quickOrder ?? false
152
+ const attachmentButton = quickOrderSettings?.attachmentButton
153
+ const toastMessages = quickOrderSettings?.toastMessages
154
+ const drawerConfig = quickOrderSettings?.drawer
155
+ const a11yLabels = quickOrderSettings?.accessibilityLabels
156
+ const fileUploadCardConfig = quickOrderSettings?.fileUploadCard
97
157
 
98
158
  useImperativeHandle(ref, () => ({
99
159
  resetSearchInput: () => setSearchQuery(''),
100
160
  }))
101
161
 
162
+ // Map CSV parser error types to FileUploadErrorType
163
+ const mapCSVErrorToFileUploadErrorType = (
164
+ csvErrorType?: string
165
+ ): FileUploadErrorType => {
166
+ if (csvErrorType === 'FILE_ERROR') {
167
+ return FileUploadErrorType.Unreadable
168
+ }
169
+ return FileUploadErrorType.InvalidStructure
170
+ }
171
+
102
172
  const onSearchSelection: SearchProviderContextValue['onSearchSelection'] = (
103
173
  term,
104
174
  path
@@ -108,9 +178,256 @@ const SearchInput = forwardRef<SearchInputRef, SearchInputProps>(
108
178
  setSearchDropdownVisible(false)
109
179
  }
110
180
 
111
- useOnClickOutside(searchRef, () =>
181
+ const handleFileSelect = async (files: File[]) => {
182
+ if (files.length === 0) return
183
+
184
+ setHasFile(true)
185
+ setIsUploadOpen(true)
186
+
187
+ const file = files[0]
188
+ setSelectedFile(file)
189
+
190
+ onClearError()
191
+ setCsvData(null)
192
+ setQuickOrderProducts([])
193
+ setSkusToFetch([])
194
+ setSkuQuantityMap({})
195
+ setIsQuickOrderDrawerOpen(false)
196
+ setNoProductsError(false)
197
+
198
+ const result = await onParseFile(file)
199
+
200
+ if (result && result.data && result.data.length > 0) {
201
+ setCsvData(result)
202
+ }
203
+ }
204
+
205
+ const handleDownloadTemplate = async () => {
206
+ try {
207
+ const csvContent = await onGenerateTemplate()
208
+
209
+ if (csvContent) {
210
+ const blob = new Blob([csvContent], { type: 'text/csv' })
211
+ const url = window.URL.createObjectURL(blob)
212
+ const a = document.createElement('a')
213
+ a.href = url
214
+ a.download = 'template.csv'
215
+ document.body.appendChild(a)
216
+ a.click()
217
+ document.body.removeChild(a)
218
+ window.URL.revokeObjectURL(url)
219
+ }
220
+ } catch (error) {
221
+ console.error('Failed to download template:', error)
222
+ }
223
+ }
224
+
225
+ const handleDismiss = () => {
226
+ setCsvData(null)
227
+ setSelectedFile(null)
228
+ setSkusToFetch([])
229
+ setSkuQuantityMap({})
230
+ setQuickOrderProducts([])
231
+ setFileUploadVisible(false)
232
+ setHasFile(false)
233
+ setIsUploadOpen(false)
234
+ setNoProductsError(false)
235
+ onClearError()
236
+ }
237
+
238
+ const handleSearch = async (_file?: File) => {
239
+ let dataToUse = csvData
240
+
241
+ if (!dataToUse || !dataToUse.data || dataToUse.data.length === 0) {
242
+ const fileToParse = _file || selectedFile
243
+
244
+ if (!fileToParse) {
245
+ pushToast({
246
+ title: toastMessages?.noFileSelected?.title,
247
+ message: toastMessages?.noFileSelected?.message,
248
+ status: 'ERROR',
249
+ icon: <UIIcon name="CircleWavyWarning" width={30} height={30} />,
250
+ })
251
+ return
252
+ }
253
+
254
+ try {
255
+ const parsePromise = onParseFile(fileToParse)
256
+
257
+ const timeoutPromise = new Promise<never>((_, reject) => {
258
+ setTimeout(() => {
259
+ reject(new Error(toastMessages?.fileTimeout?.message))
260
+ }, 30000)
261
+ })
262
+
263
+ const result = (await Promise.race([
264
+ parsePromise,
265
+ timeoutPromise,
266
+ ])) as Awaited<ReturnType<typeof onParseFile>>
267
+
268
+ if (result && result.data && result.data.length > 0) {
269
+ dataToUse = result
270
+ setCsvData(result)
271
+ } else {
272
+ pushToast({
273
+ title: toastMessages?.noDataFound?.title,
274
+ message: toastMessages?.noDataFound?.message,
275
+ status: 'ERROR',
276
+ icon: <UIIcon name="CircleWavyWarning" width={30} height={30} />,
277
+ })
278
+ return
279
+ }
280
+ } catch (error) {
281
+ const errorMessage =
282
+ error instanceof Error
283
+ ? error.message
284
+ : toastMessages?.fileProcessingError?.defaultMessage
285
+ pushToast({
286
+ title: toastMessages?.fileProcessingError?.title,
287
+ message: errorMessage,
288
+ status: 'ERROR',
289
+ icon: <UIIcon name="CircleWavyWarning" width={30} height={30} />,
290
+ })
291
+ return
292
+ }
293
+ }
294
+
295
+ if (!dataToUse || !dataToUse.data || dataToUse.data.length === 0) {
296
+ pushToast({
297
+ title: toastMessages?.noDataAvailable?.title,
298
+ message: toastMessages?.noDataAvailable?.message,
299
+ status: 'ERROR',
300
+ icon: <UIIcon name="CircleWavyWarning" width={30} height={30} />,
301
+ })
302
+ return
303
+ }
304
+
305
+ const payload = {
306
+ fileName: dataToUse.fileName,
307
+ totalRows: dataToUse.totalRows,
308
+ fileSize: dataToUse.fileSize,
309
+ data: dataToUse.data,
310
+ }
311
+ try {
312
+ window.dispatchEvent(
313
+ new CustomEvent('faststore:file-search', { detail: payload })
314
+ )
315
+ } catch {
316
+ // ignore in envs without window
317
+ }
318
+ onFileSearch?.(dataToUse)
319
+
320
+ const map: Record<string, number> = {}
321
+ for (const item of dataToUse.data) {
322
+ const sku = item.sku?.trim()
323
+ if (!sku) continue
324
+ map[sku] = (map[sku] ?? 0) + (item.quantity ?? 1)
325
+ }
326
+ const uniqueSkus = Object.keys(map)
327
+
328
+ if (uniqueSkus.length === 0) {
329
+ pushToast({
330
+ title: toastMessages?.noValidSkus?.title,
331
+ message: toastMessages?.noValidSkus?.message,
332
+ status: 'ERROR',
333
+ icon: <UIIcon name="CircleWavyWarning" width={30} height={30} />,
334
+ })
335
+ return
336
+ }
337
+
338
+ setQuickOrderProducts([])
339
+ setNoProductsError(false)
340
+ setIsLoadingWithDelay(true)
341
+ setSkuQuantityMap(map)
342
+ // Open drawer immediately to show loading skeleton
343
+ setIsQuickOrderDrawerOpen(true)
344
+ setFileUploadVisible(false)
345
+ setSkusToFetch(uniqueSkus)
346
+ }
347
+
348
+ const { products: fetchedProducts, isLoading: isLoadingProducts } =
349
+ useBulkProductsQuery(skusToFetch)
350
+
351
+ useEffect(() => {
352
+ if (skusToFetch.length > 0 && isLoadingProducts) {
353
+ // Clear products and show loading skeleton
354
+ setQuickOrderProducts([])
355
+ setIsLoadingWithDelay(true)
356
+ // Keep drawer open to show loading skeleton
357
+ setIsQuickOrderDrawerOpen(true)
358
+ setFileUploadVisible(false)
359
+ setNoProductsError(false)
360
+ return
361
+ }
362
+
363
+ if (
364
+ !isLoadingProducts &&
365
+ skusToFetch.length > 0 &&
366
+ Object.keys(skuQuantityMap).length > 0 &&
367
+ fetchedProducts.length > 0
368
+ ) {
369
+ // Add artificial delay to test loading state
370
+ setIsLoadingWithDelay(true)
371
+
372
+ const timeoutId = setTimeout(() => {
373
+ const convertedProducts: Product[] = []
374
+
375
+ fetchedProducts.forEach((productData) => {
376
+ if (productData.product && !productData.error) {
377
+ const requestedQuantity =
378
+ skuQuantityMap[productData.sku ?? ''] ?? 1
379
+
380
+ const convertedProduct = convertProductToQuickOrder(
381
+ productData.product,
382
+ requestedQuantity
383
+ )
384
+
385
+ if (convertedProduct) {
386
+ convertedProducts.push(convertedProduct)
387
+ }
388
+ }
389
+ })
390
+
391
+ setQuickOrderProducts(convertedProducts)
392
+ setIsLoadingWithDelay(false)
393
+
394
+ if (convertedProducts.length > 0) {
395
+ setIsQuickOrderDrawerOpen(true)
396
+ setFileUploadVisible(false)
397
+ setNoProductsError(false)
398
+ } else {
399
+ // Keep drawer open to show empty state message
400
+ setQuickOrderProducts([])
401
+ setIsQuickOrderDrawerOpen(true)
402
+ setFileUploadVisible(false)
403
+ setNoProductsError(true)
404
+ }
405
+ }, 2000) // 2 second delay for testing
406
+
407
+ return () => {
408
+ clearTimeout(timeoutId)
409
+ }
410
+ }
411
+
412
+ if (
413
+ !isLoadingProducts &&
414
+ skusToFetch.length > 0 &&
415
+ Object.keys(skuQuantityMap).length > 0 &&
416
+ fetchedProducts.length === 0
417
+ ) {
418
+ // Keep drawer open to show empty state message
419
+ setQuickOrderProducts([])
420
+ setIsQuickOrderDrawerOpen(true)
421
+ setFileUploadVisible(false)
422
+ setNoProductsError(true)
423
+ setIsLoadingWithDelay(false)
424
+ }
425
+ }, [fetchedProducts, skusToFetch, skuQuantityMap, isLoadingProducts])
426
+
427
+ useOnClickOutside(searchRef, () => {
112
428
  setSearchDropdownVisible(customSearchDropdownVisibleCondition ?? false)
113
- )
429
+ setFileUploadVisible(false)
430
+ })
114
431
 
115
432
  const { data, error } = useSuggestions(searchQueryDeferred)
116
433
  const terms = (data?.search.suggestions.terms ?? []).slice(
@@ -122,18 +439,81 @@ const SearchInput = forwardRef<SearchInputRef, SearchInputProps>(
122
439
  MAX_SUGGESTIONS
123
440
  )
124
441
  const isLoading = !error && !data
442
+ const searchId = data?.search.searchId
125
443
 
126
444
  const buttonProps = {
127
445
  onClick: onSearchClick,
128
446
  testId: buttonTestId,
129
447
  }
130
448
 
449
+ const handleAddToCart = useCallback(
450
+ (productsToAdd: Product[]) => {
451
+ productsToAdd.forEach((product: Product) => {
452
+ if (
453
+ product.selectedCount > 0 &&
454
+ product.availability === 'available'
455
+ ) {
456
+ const fetchedProduct = fetchedProducts.find(
457
+ (p) => p.product?.sku === product.id
458
+ )?.product
459
+
460
+ if (fetchedProduct && fetchedProduct.offers?.offers[0]) {
461
+ const offer = fetchedProduct.offers.offers[0]
462
+
463
+ cartStore.addItem({
464
+ itemOffered: {
465
+ sku: fetchedProduct.sku,
466
+ name: fetchedProduct.name,
467
+ unitMultiplier: fetchedProduct.unitMultiplier ?? 1,
468
+ image: fetchedProduct.image,
469
+ brand: fetchedProduct.brand,
470
+ isVariantOf: fetchedProduct.isVariantOf,
471
+ gtin: fetchedProduct.gtin,
472
+ additionalProperty: fetchedProduct.additionalProperty,
473
+ },
474
+ seller: offer.seller,
475
+ quantity: product.selectedCount,
476
+ price: product.price,
477
+ listPrice: offer.listPrice ?? product.price,
478
+ priceWithTaxes: offer.priceWithTaxes ?? product.price,
479
+ listPriceWithTaxes: offer.listPriceWithTaxes ?? product.price,
480
+ })
481
+ }
482
+ }
483
+ })
484
+
485
+ setIsQuickOrderDrawerOpen(false)
486
+ },
487
+ [fetchedProducts]
488
+ )
489
+
490
+ const getCompletedStatusText = useCallback(
491
+ (fileSize: number) => {
492
+ const template = fileUploadCardConfig?.completedStatusTemplate ?? ''
493
+ return template.replace('{fileSize}', (fileSize / 1024).toFixed(1))
494
+ },
495
+ [fileUploadCardConfig?.completedStatusTemplate]
496
+ )
497
+
498
+ const resolvedErrorMessages = useMemo(() => {
499
+ const msgs = fileUploadCardConfig?.errorMessages ?? {}
500
+ const result: Record<string, { title: string; description: string }> = {}
501
+
502
+ for (const [key, val] of Object.entries(msgs)) {
503
+ if (val?.title && val?.description) {
504
+ result[key] = { title: val.title, description: val.description }
505
+ }
506
+ }
507
+
508
+ return result
509
+ }, [fileUploadCardConfig?.errorMessages])
510
+
131
511
  return (
132
512
  <>
133
513
  {hidden ? (
134
514
  <UIIconButton
135
515
  type="submit"
136
- aria-label="Submit Search"
516
+ aria-label={a11yLabels?.searchButtonAriaLabel}
137
517
  icon={<UIIcon name="MagnifyingGlass" />}
138
518
  size="small"
139
519
  {...buttonProps}
@@ -147,11 +527,32 @@ const SearchInput = forwardRef<SearchInputRef, SearchInputProps>(
147
527
  terms={terms}
148
528
  products={products}
149
529
  isLoading={isLoading}
530
+ searchId={searchId}
150
531
  >
151
532
  <UISearchInputField
152
533
  ref={ref}
153
534
  buttonProps={buttonProps}
154
535
  placeholder={placeholder}
536
+ showAttachmentButton={isQuickOrderEnabled}
537
+ attachmentButtonIcon={
538
+ isQuickOrderEnabled && attachmentButton?.icon ? (
539
+ <UIIcon
540
+ name={attachmentButton.icon.icon}
541
+ aria-label={attachmentButton.icon.alt}
542
+ />
543
+ ) : undefined
544
+ }
545
+ attachmentButtonAriaLabel={
546
+ attachmentButton?.ariaLabel ?? a11yLabels?.attachButtonAriaLabel
547
+ }
548
+ attachmentButtonProps={{
549
+ onClick: () => {
550
+ setFileUploadVisible(true)
551
+ },
552
+ 'aria-label':
553
+ attachmentButton?.ariaLabel ??
554
+ a11yLabels?.attachButtonAriaLabel,
555
+ }}
155
556
  onChange={(e: { target: { value: SetStateAction<string> } }) =>
156
557
  setSearchQuery(e.target.value)
157
558
  }
@@ -180,8 +581,94 @@ const SearchInput = forwardRef<SearchInputRef, SearchInputProps>(
180
581
  />
181
582
  </Suspense>
182
583
  )}
584
+ {fileUploadVisible && (
585
+ <FileUploadCard
586
+ title={fileUploadCardConfig?.title}
587
+ fileInputAriaLabel={fileUploadCardConfig?.fileInputAriaLabel}
588
+ dropzoneAriaLabel={fileUploadCardConfig?.dropzoneAriaLabel}
589
+ dropzoneTitle={fileUploadCardConfig?.dropzoneTitle}
590
+ selectFileButtonLabel={
591
+ fileUploadCardConfig?.selectFileButtonLabel
592
+ }
593
+ downloadTemplateButtonLabel={
594
+ fileUploadCardConfig?.downloadTemplateButtonLabel
595
+ }
596
+ removeButtonAriaLabel={
597
+ fileUploadCardConfig?.removeButtonAriaLabel
598
+ }
599
+ searchButtonLabel={fileUploadCardConfig?.searchButtonLabel}
600
+ uploadingStatusText={fileUploadCardConfig?.uploadingStatusText}
601
+ getCompletedStatusText={getCompletedStatusText}
602
+ errorMessages={resolvedErrorMessages}
603
+ accept={fileUploadCardConfig?.acceptedFileTypes}
604
+ isOpen={isUploadOpen || hasFile || fileUploadVisible}
605
+ onDismiss={handleDismiss}
606
+ onFileSelect={handleFileSelect}
607
+ onDownloadTemplate={handleDownloadTemplate}
608
+ formatterFileSize={formatFileSize}
609
+ formatterFileName={formatFileName}
610
+ onSearch={handleSearch}
611
+ isUploading={isCsvProcessing || isLoadingProducts}
612
+ hasError={(!!csvError || noProductsError) && !isLoadingProducts}
613
+ {...((csvError || (noProductsError && !isLoadingProducts)) && {
614
+ errorType: noProductsError
615
+ ? FileUploadErrorType.NoProductsFound
616
+ : mapCSVErrorToFileUploadErrorType(csvError.type),
617
+ errorMessage: noProductsError ? undefined : csvError?.message,
618
+ })}
619
+ />
620
+ )}
183
621
  </UISearchInput>
184
622
  )}
623
+ <QuickOrderDrawer
624
+ isOpen={isQuickOrderDrawerOpen}
625
+ overlayProps={{
626
+ onClick: () => {
627
+ setIsQuickOrderDrawerOpen(false)
628
+ setQuickOrderProducts([])
629
+ setSkusToFetch([])
630
+ setSkuQuantityMap({})
631
+ },
632
+ }}
633
+ providerProps={{
634
+ initialProducts: quickOrderProducts,
635
+ isLoading: isLoadingProducts || isLoadingWithDelay,
636
+ totalRequestedSkus: Object.keys(skuQuantityMap).length || 0,
637
+ onAddToCart: handleAddToCart,
638
+ alertMessages: drawerConfig?.alertMessages,
639
+ }}
640
+ >
641
+ <QuickOrderDrawerHeader
642
+ title={
643
+ selectedFile
644
+ ? formatFileName(selectedFile.name)
645
+ : drawerConfig?.defaultTitle
646
+ }
647
+ onCloseDrawer={() => {
648
+ setIsQuickOrderDrawerOpen(false)
649
+ setQuickOrderProducts([])
650
+ setSkusToFetch([])
651
+ setSkuQuantityMap({})
652
+ }}
653
+ />
654
+ <QuickOrderDrawerProducts
655
+ columns={{
656
+ name: drawerConfig?.columns?.name,
657
+ availability: {
658
+ label: drawerConfig?.columns?.availabilityLabel,
659
+ stockDisplaySettings: 'showAvailability',
660
+ },
661
+ price: drawerConfig?.columns?.price,
662
+ quantity: drawerConfig?.columns?.quantity,
663
+ }}
664
+ formatter={(price) => priceFormatter(price)}
665
+ messages={drawerConfig?.messages}
666
+ />
667
+ <QuickOrderDrawerFooter
668
+ formatter={(price) => priceFormatter(price)}
669
+ labels={drawerConfig?.footer}
670
+ />
671
+ </QuickOrderDrawer>
185
672
  </>
186
673
  )
187
674
  }
@@ -25,6 +25,13 @@ export interface NavbarProps {
25
25
  sort: string
26
26
  quickOrderSettings?: {
27
27
  quickOrder: boolean
28
+ attachmentButton?: {
29
+ icon: {
30
+ icon: string
31
+ alt: string
32
+ }
33
+ ariaLabel: string
34
+ }
28
35
  skuMatrix: {
29
36
  triggerButtonLabel: string
30
37
  columns: {
@@ -38,6 +45,66 @@ export interface NavbarProps {
38
45
  }
39
46
  }
40
47
  }
48
+ drawer?: {
49
+ defaultTitle?: string
50
+ columns?: {
51
+ name?: string
52
+ availabilityLabel?: string
53
+ price?: string
54
+ quantity?: string
55
+ }
56
+ messages?: {
57
+ alertAriaLabel?: string
58
+ tableAriaLabel?: string
59
+ quantityUpdatedTooltip?: string
60
+ quantityUpdatedAriaLabel?: string
61
+ outOfStockLabel?: string
62
+ availableLabel?: string
63
+ selectQuantityAriaLabel?: string
64
+ removeProductAriaLabel?: string
65
+ invalidQuantityTitle?: string
66
+ emptyStateTitle?: string
67
+ emptyStateMessage?: string
68
+ }
69
+ alertMessages?: {
70
+ notFoundAndOutOfStock?: string
71
+ notFound?: string
72
+ outOfStock?: string
73
+ }
74
+ footer?: {
75
+ itemsLabel?: string
76
+ addToCartLabel?: string
77
+ addToCartAriaLabel?: string
78
+ }
79
+ }
80
+ toastMessages?: {
81
+ noFileSelected?: { title?: string; message?: string }
82
+ noDataFound?: { title?: string; message?: string }
83
+ fileProcessingError?: { title?: string; defaultMessage?: string }
84
+ fileTimeout?: { message?: string }
85
+ noDataAvailable?: { title?: string; message?: string }
86
+ noValidSkus?: { title?: string; message?: string }
87
+ }
88
+ accessibilityLabels?: {
89
+ attachButtonAriaLabel?: string
90
+ searchButtonAriaLabel?: string
91
+ }
92
+ fileUploadCard?: {
93
+ title?: string
94
+ fileInputAriaLabel?: string
95
+ dropzoneAriaLabel?: string
96
+ dropzoneTitle?: string
97
+ selectFileButtonLabel?: string
98
+ downloadTemplateButtonLabel?: string
99
+ removeButtonAriaLabel?: string
100
+ searchButtonLabel?: string
101
+ uploadingStatusText?: string
102
+ completedStatusTemplate?: string
103
+ acceptedFileTypes?: string
104
+ errorMessages?: Partial<
105
+ Record<string, { title?: string; description?: string }>
106
+ >
107
+ }
41
108
  }
42
109
  }
43
110
  signInButton: {
@@ -23,6 +23,8 @@
23
23
  @import "@faststore/ui/src/components/organisms/RegionPopover/styles.scss";
24
24
  @import "@faststore/ui/src/components/molecules/SearchAutoComplete/styles.scss";
25
25
  @import "@faststore/ui/src/components/molecules/SearchDropdown/styles.scss";
26
+ @import "@faststore/ui/src/components/molecules/FileUploadCard/styles.scss";
27
+ @import "@faststore/ui/src/components/molecules/FileUploadStatus/styles.scss";
26
28
  @import "@faststore/ui/src/components/molecules/SearchHistory/styles.scss";
27
29
  @import "@faststore/ui/src/components/molecules/SearchInputField/styles.scss";
28
30
  @import "@faststore/ui/src/components/molecules/SearchProducts/styles.scss";
@@ -33,6 +35,7 @@
33
35
  @import "@faststore/ui/src/components/organisms/Navbar/styles.scss";
34
36
  @import "@faststore/ui/src/components/organisms/SlideOver/styles.scss";
35
37
  @import "@faststore/ui/src/components/organisms/SKUMatrix/styles.scss";
38
+ @import "@faststore/ui/src/components/organisms/QuickOrderDrawer/styles.scss";
36
39
 
37
40
  // Sets Navbar height on desktop to avoid CLS issue - Cumulative Layout Shift
38
41
  --fs-navbar-height-desktop: 4.5rem;