storefront-layouts 1.0.3 → 1.0.4

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 (509) hide show
  1. package/dist/components/auth/LoginForm.js +2 -2
  2. package/dist/components/auth/LoginSheet.js +2 -2
  3. package/dist/components/auth/login-form-core.js +3 -3
  4. package/dist/components/auth/login-sheet-header.js +3 -3
  5. package/dist/components/auth/login-sheet-registry.js +2 -2
  6. package/dist/components/auth/login-sheet-themes/booking-agenda.theme.js +1 -1
  7. package/dist/components/auth/login-sheet-themes/booking.theme.js +1 -1
  8. package/dist/components/auth/login-sheet-themes/clothing-minimal.theme.js +1 -1
  9. package/dist/components/auth/login-sheet-themes/clothing.theme.js +1 -1
  10. package/dist/components/auth/login-sheet-themes/electronics-grid.theme.js +1 -1
  11. package/dist/components/auth/login-sheet-themes/electronics.theme.js +1 -1
  12. package/dist/components/auth/login-sheet-themes/food-modern.theme.js +1 -1
  13. package/dist/components/auth/login-sheet-themes/food.theme.js +1 -1
  14. package/dist/components/auth/login-sheet-themes/index.js +9 -9
  15. package/dist/components/auth/login-sheet-themes/motivational-speaker.theme.js +1 -1
  16. package/dist/components/auth/login-sheet-themes/theme-input-baselines.d.ts +2 -2
  17. package/dist/components/auth/login-sheet-themes/theme-input-baselines.d.ts.map +1 -1
  18. package/dist/components/auth/login-sheet-themes/theme-input-baselines.js +2 -2
  19. package/dist/components/auth/login-sheets/StoreLoginSheetShell.d.ts.map +1 -1
  20. package/dist/components/auth/login-sheets/StoreLoginSheetShell.js +6 -6
  21. package/dist/components/auth/use-login-submit.js +3 -3
  22. package/dist/components/cart/InventoryHoldCountdown.js +2 -2
  23. package/dist/components/categories/category-masonry-grid.js +3 -3
  24. package/dist/components/checkout/CheckoutFeeLines.js +1 -1
  25. package/dist/components/checkout/ShippingOptionsPanel.js +3 -3
  26. package/dist/components/learning/CertificateTemplates.js +2 -2
  27. package/dist/components/learning/CertificateViewer.js +3 -3
  28. package/dist/components/learning/MentorshipProgress.d.ts.map +1 -1
  29. package/dist/components/learning/MentorshipProgress.js +4 -4
  30. package/dist/components/product/ProductVariationSelectors.js +1 -1
  31. package/dist/components/rich-text/CategoryDescription.js +2 -2
  32. package/dist/components/rich-text/ProductDescription.js +2 -2
  33. package/dist/components/rich-text/RichTextExcerpt.js +1 -1
  34. package/dist/components/rich-text/SafeRichHtml.d.ts +8 -11
  35. package/dist/components/rich-text/SafeRichHtml.d.ts.map +1 -1
  36. package/dist/components/rich-text/SafeRichHtml.js +3 -5
  37. package/dist/components/shipping/ProductDeliveryInfoSection.d.ts.map +1 -1
  38. package/dist/components/shipping/ProductDeliveryInfoSection.js +7 -4
  39. package/dist/components/shipping/ShippingQuoteAddressForm.js +3 -3
  40. package/dist/components/ui/alert-modal.js +2 -2
  41. package/dist/components/ui/avatar-image.js +1 -1
  42. package/dist/components/ui/badge.js +1 -1
  43. package/dist/components/ui/breadcrumbs.js +1 -1
  44. package/dist/components/ui/button.d.ts +1 -1
  45. package/dist/components/ui/button.js +1 -1
  46. package/dist/components/ui/card.js +1 -1
  47. package/dist/components/ui/category-tree.js +2 -2
  48. package/dist/components/ui/checkout-button.d.ts.map +1 -1
  49. package/dist/components/ui/checkout-button.js +11 -283
  50. package/dist/components/ui/guest-checkout-modal.js +3 -3
  51. package/dist/components/ui/image-skeleton.js +2 -2
  52. package/dist/components/ui/image-with-fallback.d.ts +3 -1
  53. package/dist/components/ui/image-with-fallback.d.ts.map +1 -1
  54. package/dist/components/ui/image-with-fallback.js +55 -139
  55. package/dist/components/ui/input.js +1 -1
  56. package/dist/components/ui/limited-time-offer-badge.js +2 -2
  57. package/dist/components/ui/loading-skeleton-wrapper.js +1 -1
  58. package/dist/components/ui/modal.js +2 -2
  59. package/dist/components/ui/otp-input.js +1 -1
  60. package/dist/components/ui/out-of-stock-overlay.js +1 -1
  61. package/dist/components/ui/page-animate-wrapper.js +2 -2
  62. package/dist/components/ui/page-content-loader.js +2 -2
  63. package/dist/components/ui/page-loader.js +1 -1
  64. package/dist/components/ui/product-card.d.ts.map +1 -1
  65. package/dist/components/ui/product-card.js +17 -17
  66. package/dist/components/ui/product-rating.js +1 -1
  67. package/dist/components/ui/product-stock-badge.js +2 -2
  68. package/dist/components/ui/review-form.js +2 -2
  69. package/dist/components/ui/route-skeleton-loader.js +6 -6
  70. package/dist/components/ui/sheet.d.ts +2 -1
  71. package/dist/components/ui/sheet.d.ts.map +1 -1
  72. package/dist/components/ui/sheet.js +4 -4
  73. package/dist/components/ui/skeleton.js +1 -1
  74. package/dist/components/ui/skeletons/index.js +5 -5
  75. package/dist/components/ui/skeletons/product-grid-skeleton.js +1 -1
  76. package/dist/components/ui/store-logos.d.ts.map +1 -1
  77. package/dist/components/ui/store-logos.js +4 -4
  78. package/dist/components/ui/toast.js +1 -1
  79. package/dist/components/ui/video-player.js +2 -2
  80. package/dist/editor/alignment-schemas/booking.js +1 -1
  81. package/dist/editor/alignment-schemas/clothing-minimal.js +1 -1
  82. package/dist/editor/alignment-schemas/index.js +20 -20
  83. package/dist/editor/alignment-schemas/lazy-loader.js +1 -1
  84. package/dist/editor/alignment-schemas/metadata.js +1 -1
  85. package/dist/editor/alignment-schemas/resolve-canvas-inspector-leaf.js +3 -3
  86. package/dist/editor/blocks/index.js +3 -3
  87. package/dist/editor/blocks/migrate-clothing-minimal.js +3 -3
  88. package/dist/editor/blocks/nav-outline-utils.js +2 -2
  89. package/dist/editor/blocks/registry.js +1 -1
  90. package/dist/editor/document/adapter.js +4 -4
  91. package/dist/editor/document/block-tree.js +1 -1
  92. package/dist/editor/document/index.js +6 -6
  93. package/dist/editor/document/validate.js +1 -1
  94. package/dist/editor/index.js +12 -12
  95. package/dist/editor/layout-content-loader.js +3 -3
  96. package/dist/editor/payaza-form/ArrayItemManager.js +2 -2
  97. package/dist/editor/payaza-form/EditorCanvasPreview.js +5 -5
  98. package/dist/editor/payaza-form/FieldRenderer.js +17 -17
  99. package/dist/editor/payaza-form/IframePreviewMessageBridge.js +3 -3
  100. package/dist/editor/payaza-form/PayazaFormEditor.js +31 -31
  101. package/dist/editor/payaza-form/PayazaFormEditorFullPage.js +2 -2
  102. package/dist/editor/payaza-form/SliderArrayEditor.js +3 -3
  103. package/dist/editor/payaza-form/components/ArrayField.js +1 -1
  104. package/dist/editor/payaza-form/components/BlockStylesInspector.js +1 -1
  105. package/dist/editor/payaza-form/components/BlocksField.js +9 -9
  106. package/dist/editor/payaza-form/components/ButtonField.js +3 -3
  107. package/dist/editor/payaza-form/components/CanvasGranularInspector.js +11 -11
  108. package/dist/editor/payaza-form/components/IconField.js +2 -2
  109. package/dist/editor/payaza-form/components/ImageField.js +1 -1
  110. package/dist/editor/payaza-form/components/NumberField.js +1 -1
  111. package/dist/editor/payaza-form/components/RichTextField.js +2 -2
  112. package/dist/editor/payaza-form/components/SectionField.js +1 -1
  113. package/dist/editor/payaza-form/components/SectionSchemaInspector.js +3 -3
  114. package/dist/editor/payaza-form/components/StarRatingField.js +2 -2
  115. package/dist/editor/payaza-form/components/TextField.js +1 -1
  116. package/dist/editor/payaza-form/data-merger.js +6 -6
  117. package/dist/editor/payaza-form/data-transformer.js +3 -3
  118. package/dist/editor/payaza-form/engine.js +1 -1
  119. package/dist/editor/payaza-form/examples/custom-widgets.example.js +1 -1
  120. package/dist/editor/payaza-form/index.js +8 -8
  121. package/dist/editor/payaza-form/layout-loader.js +2 -2
  122. package/dist/editor/payaza-form/preview-message-handler.js +3 -3
  123. package/dist/editor/payaza-form/schema-bridge.js +3 -3
  124. package/dist/editor/payaza-form/widget-registry.js +1 -1
  125. package/dist/editor/shared/BlockOutlineTree.js +2 -2
  126. package/dist/editor/shared/EditorHeader.js +2 -2
  127. package/dist/editor/shared/EditorNavigator.js +2 -2
  128. package/dist/editor/shared/IframePreview.js +6 -6
  129. package/dist/editor/shared/InlineCanvasPreview.js +8 -8
  130. package/dist/editor/shared/LayoutRenderer.js +1 -1
  131. package/dist/editor/shared/ResizableSidebar.js +1 -1
  132. package/dist/editor/shared/index.js +7 -7
  133. package/dist/hooks/use-analytics.js +3 -3
  134. package/dist/hooks/use-api.js +1 -1
  135. package/dist/hooks/use-cart-api.d.ts.map +1 -1
  136. package/dist/hooks/use-cart-api.js +8 -3
  137. package/dist/hooks/use-catalog-loader.js +3 -3
  138. package/dist/hooks/use-catalog-price-range.d.ts +2 -5
  139. package/dist/hooks/use-catalog-price-range.d.ts.map +1 -1
  140. package/dist/hooks/use-catalog-price-range.js +20 -5
  141. package/dist/hooks/use-category-products.d.ts +8 -0
  142. package/dist/hooks/use-category-products.d.ts.map +1 -0
  143. package/dist/hooks/use-category-products.js +43 -0
  144. package/dist/hooks/use-checkout-fees.d.ts +3 -4
  145. package/dist/hooks/use-checkout-fees.d.ts.map +1 -1
  146. package/dist/hooks/use-checkout-fees.js +1 -1
  147. package/dist/hooks/use-content-ready.js +1 -1
  148. package/dist/hooks/use-featured-products.d.ts +3 -0
  149. package/dist/hooks/use-featured-products.d.ts.map +1 -0
  150. package/dist/hooks/use-featured-products.js +25 -0
  151. package/dist/hooks/use-multi-store-checkout-fees.d.ts +3 -4
  152. package/dist/hooks/use-multi-store-checkout-fees.d.ts.map +1 -1
  153. package/dist/hooks/use-multi-store-checkout-fees.js +1 -1
  154. package/dist/hooks/use-navigation-loading.js +1 -1
  155. package/dist/hooks/use-payaza-checkout.d.ts +1 -1
  156. package/dist/hooks/use-payaza-checkout.d.ts.map +1 -1
  157. package/dist/hooks/use-payaza-checkout.js +9 -3
  158. package/dist/hooks/use-product-brands.d.ts +5 -0
  159. package/dist/hooks/use-product-brands.d.ts.map +1 -0
  160. package/dist/hooks/use-product-brands.js +25 -0
  161. package/dist/hooks/use-product-by-slug.d.ts +7 -0
  162. package/dist/hooks/use-product-by-slug.d.ts.map +1 -0
  163. package/dist/hooks/use-product-by-slug.js +38 -0
  164. package/dist/hooks/use-product-reviews.d.ts +15 -0
  165. package/dist/hooks/use-product-reviews.d.ts.map +1 -0
  166. package/dist/hooks/use-product-reviews.js +75 -0
  167. package/dist/hooks/use-product-variation-selection.d.ts +2 -8
  168. package/dist/hooks/use-product-variation-selection.d.ts.map +1 -1
  169. package/dist/hooks/use-product-variation-selection.js +1 -1
  170. package/dist/hooks/use-products-api.js +3 -3
  171. package/dist/hooks/use-shipping-quote.js +2 -2
  172. package/dist/hooks/use-store-api.js +4 -4
  173. package/dist/hooks/usePreviewSlideSync.js +1 -1
  174. package/dist/index.d.ts +62 -74
  175. package/dist/index.d.ts.map +1 -1
  176. package/dist/index.js +141 -153
  177. package/dist/layouts/booking/components/BookingHomePage.d.ts.map +1 -1
  178. package/dist/layouts/booking/components/BookingHomePage.js +68 -74
  179. package/dist/layouts/booking/components/BookingMultilineHeading.js +1 -1
  180. package/dist/layouts/booking/components/BookingTestimonialCard.js +2 -2
  181. package/dist/layouts/booking/components/BookingTestimonialsEmptyState.js +1 -1
  182. package/dist/layouts/booking/components/booking-footer-defaults.js +2 -2
  183. package/dist/layouts/booking/index.js +8 -8
  184. package/dist/layouts/booking/pages/AboutPage.d.ts +1 -1
  185. package/dist/layouts/booking/pages/AboutPage.d.ts.map +1 -1
  186. package/dist/layouts/booking/pages/AboutPage.js +39 -60
  187. package/dist/layouts/booking/pages/BookPage.d.ts.map +1 -1
  188. package/dist/layouts/booking/pages/BookPage.js +16 -22
  189. package/dist/layouts/booking/pages/CategoriesPage.js +6 -6
  190. package/dist/layouts/booking/pages/CategoryPage.d.ts +1 -1
  191. package/dist/layouts/booking/pages/CategoryPage.d.ts.map +1 -1
  192. package/dist/layouts/booking/pages/CategoryPage.js +17 -26
  193. package/dist/layouts/booking/pages/ContactPage.d.ts +1 -1
  194. package/dist/layouts/booking/pages/ContactPage.d.ts.map +1 -1
  195. package/dist/layouts/booking/pages/ContactPage.js +5 -12
  196. package/dist/layouts/booking/pages/ProductDetailPage.d.ts +1 -1
  197. package/dist/layouts/booking/pages/ProductDetailPage.d.ts.map +1 -1
  198. package/dist/layouts/booking/pages/ProductDetailPage.js +203 -150
  199. package/dist/layouts/booking/pages/ServicesPage.d.ts +1 -1
  200. package/dist/layouts/booking/pages/ServicesPage.d.ts.map +1 -1
  201. package/dist/layouts/booking/pages/ServicesPage.js +11 -31
  202. package/dist/layouts/booking-agenda/components/BookingHomePageAgenda.d.ts.map +1 -1
  203. package/dist/layouts/booking-agenda/components/BookingHomePageAgenda.js +21 -30
  204. package/dist/layouts/booking-agenda/index.js +8 -8
  205. package/dist/layouts/booking-agenda/pages/AboutPage.d.ts +1 -1
  206. package/dist/layouts/booking-agenda/pages/AboutPage.d.ts.map +1 -1
  207. package/dist/layouts/booking-agenda/pages/AboutPage.js +11 -14
  208. package/dist/layouts/booking-agenda/pages/BookPage.d.ts.map +1 -1
  209. package/dist/layouts/booking-agenda/pages/BookPage.js +15 -21
  210. package/dist/layouts/booking-agenda/pages/CategoriesPage.js +5 -5
  211. package/dist/layouts/booking-agenda/pages/CategoryPage.d.ts +1 -1
  212. package/dist/layouts/booking-agenda/pages/CategoryPage.d.ts.map +1 -1
  213. package/dist/layouts/booking-agenda/pages/CategoryPage.js +12 -18
  214. package/dist/layouts/booking-agenda/pages/ContactPage.d.ts +1 -1
  215. package/dist/layouts/booking-agenda/pages/ContactPage.d.ts.map +1 -1
  216. package/dist/layouts/booking-agenda/pages/ContactPage.js +8 -13
  217. package/dist/layouts/booking-agenda/pages/ProductDetailPage.d.ts +1 -1
  218. package/dist/layouts/booking-agenda/pages/ProductDetailPage.d.ts.map +1 -1
  219. package/dist/layouts/booking-agenda/pages/ProductDetailPage.js +202 -149
  220. package/dist/layouts/booking-agenda/pages/ServicesPage.d.ts +1 -1
  221. package/dist/layouts/booking-agenda/pages/ServicesPage.d.ts.map +1 -1
  222. package/dist/layouts/booking-agenda/pages/ServicesPage.js +8 -23
  223. package/dist/layouts/clothing/components/ClothingHomePage.d.ts.map +1 -1
  224. package/dist/layouts/clothing/components/ClothingHomePage.js +199 -136
  225. package/dist/layouts/clothing/index.js +7 -7
  226. package/dist/layouts/clothing/pages/AboutPage.d.ts +1 -1
  227. package/dist/layouts/clothing/pages/AboutPage.d.ts.map +1 -1
  228. package/dist/layouts/clothing/pages/AboutPage.js +19 -33
  229. package/dist/layouts/clothing/pages/CategoriesPage.js +8 -8
  230. package/dist/layouts/clothing/pages/CategoryPage.d.ts +1 -1
  231. package/dist/layouts/clothing/pages/CategoryPage.d.ts.map +1 -1
  232. package/dist/layouts/clothing/pages/CategoryPage.js +15 -41
  233. package/dist/layouts/clothing/pages/ContactPage.d.ts +1 -1
  234. package/dist/layouts/clothing/pages/ContactPage.d.ts.map +1 -1
  235. package/dist/layouts/clothing/pages/ContactPage.js +5 -8
  236. package/dist/layouts/clothing/pages/ProductDetailPage.d.ts +1 -1
  237. package/dist/layouts/clothing/pages/ProductDetailPage.d.ts.map +1 -1
  238. package/dist/layouts/clothing/pages/ProductDetailPage.js +256 -167
  239. package/dist/layouts/clothing/pages/ProductsPage.d.ts +1 -1
  240. package/dist/layouts/clothing/pages/ProductsPage.d.ts.map +1 -1
  241. package/dist/layouts/clothing/pages/ProductsPage.js +125 -59
  242. package/dist/layouts/clothing/payaza-bindings.js +2 -2
  243. package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.d.ts.map +1 -1
  244. package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.js +32 -131
  245. package/dist/layouts/clothing-minimal/components/clothing-minimal-block-render.js +8 -8
  246. package/dist/layouts/clothing-minimal/index.js +7 -7
  247. package/dist/layouts/clothing-minimal/pages/AboutPage.d.ts +1 -1
  248. package/dist/layouts/clothing-minimal/pages/AboutPage.d.ts.map +1 -1
  249. package/dist/layouts/clothing-minimal/pages/AboutPage.js +37 -61
  250. package/dist/layouts/clothing-minimal/pages/CategoriesPage.js +7 -7
  251. package/dist/layouts/clothing-minimal/pages/CategoryPage.d.ts +1 -1
  252. package/dist/layouts/clothing-minimal/pages/CategoryPage.d.ts.map +1 -1
  253. package/dist/layouts/clothing-minimal/pages/CategoryPage.js +13 -18
  254. package/dist/layouts/clothing-minimal/pages/ContactPage.d.ts +1 -1
  255. package/dist/layouts/clothing-minimal/pages/ContactPage.d.ts.map +1 -1
  256. package/dist/layouts/clothing-minimal/pages/ContactPage.js +5 -8
  257. package/dist/layouts/clothing-minimal/pages/ProductDetailPage.d.ts +1 -1
  258. package/dist/layouts/clothing-minimal/pages/ProductDetailPage.d.ts.map +1 -1
  259. package/dist/layouts/clothing-minimal/pages/ProductDetailPage.js +202 -143
  260. package/dist/layouts/clothing-minimal/pages/ProductsPage.d.ts +1 -1
  261. package/dist/layouts/clothing-minimal/pages/ProductsPage.d.ts.map +1 -1
  262. package/dist/layouts/clothing-minimal/pages/ProductsPage.js +126 -57
  263. package/dist/layouts/electronics/components/ElectronicsCategoriesPage.js +7 -7
  264. package/dist/layouts/electronics/components/ElectronicsGridProductCard.js +10 -10
  265. package/dist/layouts/electronics/components/ElectronicsHomePage.d.ts.map +1 -1
  266. package/dist/layouts/electronics/components/ElectronicsHomePage.js +29 -31
  267. package/dist/layouts/electronics/components/ElectronicsPageWrapper.js +4 -4
  268. package/dist/layouts/electronics/components/ElectronicsProductsPage.d.ts.map +1 -1
  269. package/dist/layouts/electronics/components/ElectronicsProductsPage.js +81 -23
  270. package/dist/layouts/electronics/components/ElectronicsStoreFooter.js +2 -2
  271. package/dist/layouts/electronics/components/ElectronicsStoreHeader.js +6 -6
  272. package/dist/layouts/electronics/index.js +18 -18
  273. package/dist/layouts/electronics/pages/AboutPage.d.ts +1 -1
  274. package/dist/layouts/electronics/pages/AboutPage.d.ts.map +1 -1
  275. package/dist/layouts/electronics/pages/AboutPage.js +11 -14
  276. package/dist/layouts/electronics/pages/CategoriesPage.js +1 -1
  277. package/dist/layouts/electronics/pages/CategoryPage.d.ts +1 -1
  278. package/dist/layouts/electronics/pages/CategoryPage.d.ts.map +1 -1
  279. package/dist/layouts/electronics/pages/CategoryPage.js +14 -20
  280. package/dist/layouts/electronics/pages/ContactPage.d.ts +1 -1
  281. package/dist/layouts/electronics/pages/ContactPage.d.ts.map +1 -1
  282. package/dist/layouts/electronics/pages/ContactPage.js +8 -13
  283. package/dist/layouts/electronics/pages/HelpCenterPage.js +1 -1
  284. package/dist/layouts/electronics/pages/PrivacyPolicyPage.js +1 -1
  285. package/dist/layouts/electronics/pages/ProductDetailPage.d.ts +1 -1
  286. package/dist/layouts/electronics/pages/ProductDetailPage.d.ts.map +1 -1
  287. package/dist/layouts/electronics/pages/ProductDetailPage.js +201 -142
  288. package/dist/layouts/electronics/pages/ProductsPage.d.ts +1 -1
  289. package/dist/layouts/electronics/pages/ProductsPage.d.ts.map +1 -1
  290. package/dist/layouts/electronics/pages/ProductsPage.js +119 -49
  291. package/dist/layouts/electronics/pages/TermsPage.js +1 -1
  292. package/dist/layouts/electronics/pages/TrackOrderPage.js +4 -4
  293. package/dist/layouts/electronics-grid/components/ElectronicsGridProductCard.js +10 -10
  294. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.d.ts.map +1 -1
  295. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.js +75 -33
  296. package/dist/layouts/electronics-grid/index.js +14 -14
  297. package/dist/layouts/electronics-grid/pages/AboutPage.d.ts +1 -1
  298. package/dist/layouts/electronics-grid/pages/AboutPage.d.ts.map +1 -1
  299. package/dist/layouts/electronics-grid/pages/AboutPage.js +11 -14
  300. package/dist/layouts/electronics-grid/pages/CategoriesPage.js +1 -1
  301. package/dist/layouts/electronics-grid/pages/CategoryPage.d.ts +1 -1
  302. package/dist/layouts/electronics-grid/pages/CategoryPage.d.ts.map +1 -1
  303. package/dist/layouts/electronics-grid/pages/CategoryPage.js +14 -20
  304. package/dist/layouts/electronics-grid/pages/ContactPage.d.ts +1 -1
  305. package/dist/layouts/electronics-grid/pages/ContactPage.d.ts.map +1 -1
  306. package/dist/layouts/electronics-grid/pages/ContactPage.js +8 -13
  307. package/dist/layouts/electronics-grid/pages/ElectronicsGridCategoriesPage.js +6 -6
  308. package/dist/layouts/electronics-grid/pages/HelpCenterPage.js +1 -1
  309. package/dist/layouts/electronics-grid/pages/PrivacyPolicyPage.js +1 -1
  310. package/dist/layouts/electronics-grid/pages/ProductDetailPage.d.ts +1 -1
  311. package/dist/layouts/electronics-grid/pages/ProductDetailPage.d.ts.map +1 -1
  312. package/dist/layouts/electronics-grid/pages/ProductDetailPage.js +201 -142
  313. package/dist/layouts/electronics-grid/pages/ProductsPage.d.ts +1 -1
  314. package/dist/layouts/electronics-grid/pages/ProductsPage.d.ts.map +1 -1
  315. package/dist/layouts/electronics-grid/pages/ProductsPage.js +121 -52
  316. package/dist/layouts/electronics-grid/pages/TermsPage.js +1 -1
  317. package/dist/layouts/electronics-grid/pages/TrackOrderPage.js +4 -4
  318. package/dist/layouts/food/components/FoodHomePage.d.ts.map +1 -1
  319. package/dist/layouts/food/components/FoodHomePage.js +42 -41
  320. package/dist/layouts/food/index.js +8 -8
  321. package/dist/layouts/food/pages/AboutPage.d.ts +1 -1
  322. package/dist/layouts/food/pages/AboutPage.d.ts.map +1 -1
  323. package/dist/layouts/food/pages/AboutPage.js +44 -45
  324. package/dist/layouts/food/pages/CategoriesPage.js +6 -6
  325. package/dist/layouts/food/pages/CategoryPage.d.ts +1 -1
  326. package/dist/layouts/food/pages/CategoryPage.d.ts.map +1 -1
  327. package/dist/layouts/food/pages/CategoryPage.js +23 -21
  328. package/dist/layouts/food/pages/ContactPage.d.ts +1 -1
  329. package/dist/layouts/food/pages/ContactPage.d.ts.map +1 -1
  330. package/dist/layouts/food/pages/ContactPage.js +5 -7
  331. package/dist/layouts/food/pages/MenuPage.d.ts +1 -1
  332. package/dist/layouts/food/pages/MenuPage.d.ts.map +1 -1
  333. package/dist/layouts/food/pages/MenuPage.js +81 -42
  334. package/dist/layouts/food/pages/ProductDetailPage.d.ts +1 -1
  335. package/dist/layouts/food/pages/ProductDetailPage.d.ts.map +1 -1
  336. package/dist/layouts/food/pages/ProductDetailPage.js +209 -171
  337. package/dist/layouts/food/pages/ProductsPage.d.ts +1 -1
  338. package/dist/layouts/food/pages/ProductsPage.d.ts.map +1 -1
  339. package/dist/layouts/food/pages/ProductsPage.js +130 -45
  340. package/dist/layouts/food-modern/components/FoodHomePageModern.js +10 -10
  341. package/dist/layouts/food-modern/index.js +8 -8
  342. package/dist/layouts/food-modern/pages/AboutPage.d.ts +1 -1
  343. package/dist/layouts/food-modern/pages/AboutPage.d.ts.map +1 -1
  344. package/dist/layouts/food-modern/pages/AboutPage.js +11 -14
  345. package/dist/layouts/food-modern/pages/CategoriesPage.js +5 -5
  346. package/dist/layouts/food-modern/pages/CategoryPage.d.ts +1 -1
  347. package/dist/layouts/food-modern/pages/CategoryPage.d.ts.map +1 -1
  348. package/dist/layouts/food-modern/pages/CategoryPage.js +23 -20
  349. package/dist/layouts/food-modern/pages/ContactPage.d.ts +1 -1
  350. package/dist/layouts/food-modern/pages/ContactPage.d.ts.map +1 -1
  351. package/dist/layouts/food-modern/pages/ContactPage.js +5 -7
  352. package/dist/layouts/food-modern/pages/MenuPage.d.ts +1 -1
  353. package/dist/layouts/food-modern/pages/MenuPage.d.ts.map +1 -1
  354. package/dist/layouts/food-modern/pages/MenuPage.js +81 -46
  355. package/dist/layouts/food-modern/pages/ProductDetailPage.d.ts +1 -1
  356. package/dist/layouts/food-modern/pages/ProductDetailPage.d.ts.map +1 -1
  357. package/dist/layouts/food-modern/pages/ProductDetailPage.js +202 -143
  358. package/dist/layouts/food-modern/pages/ProductsPage.d.ts +1 -1
  359. package/dist/layouts/food-modern/pages/ProductsPage.d.ts.map +1 -1
  360. package/dist/layouts/food-modern/pages/ProductsPage.js +117 -33
  361. package/dist/layouts/motivational-speaker/components/MotivationalHomePage.d.ts.map +1 -1
  362. package/dist/layouts/motivational-speaker/components/MotivationalHomePage.js +32 -23
  363. package/dist/layouts/motivational-speaker/components/MotivationalSpeakerPageWrapper.js +1 -1
  364. package/dist/layouts/motivational-speaker/index.js +9 -9
  365. package/dist/layouts/motivational-speaker/pages/AboutPage.d.ts +1 -1
  366. package/dist/layouts/motivational-speaker/pages/AboutPage.d.ts.map +1 -1
  367. package/dist/layouts/motivational-speaker/pages/AboutPage.js +6 -9
  368. package/dist/layouts/motivational-speaker/pages/CategoryPage.d.ts +1 -1
  369. package/dist/layouts/motivational-speaker/pages/CategoryPage.d.ts.map +1 -1
  370. package/dist/layouts/motivational-speaker/pages/CategoryPage.js +18 -22
  371. package/dist/layouts/motivational-speaker/pages/ContactPage.d.ts +1 -1
  372. package/dist/layouts/motivational-speaker/pages/ContactPage.d.ts.map +1 -1
  373. package/dist/layouts/motivational-speaker/pages/ContactPage.js +9 -13
  374. package/dist/layouts/motivational-speaker/pages/ProductsPage.d.ts +1 -1
  375. package/dist/layouts/motivational-speaker/pages/ProductsPage.d.ts.map +1 -1
  376. package/dist/layouts/motivational-speaker/pages/ProductsPage.js +121 -52
  377. package/dist/layouts/motivational-speaker/pages/ServiceDetailPage.d.ts +1 -1
  378. package/dist/layouts/motivational-speaker/pages/ServiceDetailPage.d.ts.map +1 -1
  379. package/dist/layouts/motivational-speaker/pages/ServiceDetailPage.js +15 -24
  380. package/dist/layouts/motivational-speaker/pages/ServicesPage.d.ts +1 -1
  381. package/dist/layouts/motivational-speaker/pages/ServicesPage.d.ts.map +1 -1
  382. package/dist/layouts/motivational-speaker/pages/ServicesPage.js +8 -23
  383. package/dist/layouts/motivational-speaker/pages/SubscriptionPage.js +7 -7
  384. package/dist/layouts/shared/components/BaseStoreLayout.js +9 -9
  385. package/dist/layouts/shared/components/CartLineQuantityControl.js +1 -1
  386. package/dist/layouts/shared/components/GenericPageWrapper.js +3 -3
  387. package/dist/layouts/shared/components/ProductPriceFilterSection.js +4 -4
  388. package/dist/layouts/shared/components/PromoBanner.d.ts +1 -4
  389. package/dist/layouts/shared/components/PromoBanner.d.ts.map +1 -1
  390. package/dist/layouts/shared/components/PromoBanner.js +12 -8
  391. package/dist/layouts/shared/components/StoreFooter.js +10 -10
  392. package/dist/layouts/shared/components/StoreHeader.js +7 -7
  393. package/dist/layouts/shared/components/TestimonialCard.d.ts.map +1 -1
  394. package/dist/layouts/shared/components/TestimonialCard.js +2 -2
  395. package/dist/layouts/shared/components/headers/BookingAgendaSidebar.js +2 -2
  396. package/dist/layouts/shared/components/headers/ClothingMinimalHeader.js +11 -11
  397. package/dist/layouts/shared/components/headers/FoodModernHeader.js +7 -7
  398. package/dist/layouts/shared/index.js +22 -22
  399. package/dist/layouts/shared/pages/AccountPage.d.ts.map +1 -1
  400. package/dist/layouts/shared/pages/AccountPage.js +101 -27
  401. package/dist/layouts/shared/pages/CartPage.d.ts.map +1 -1
  402. package/dist/layouts/shared/pages/CartPage.js +39 -90
  403. package/dist/layouts/shared/pages/CheckoutPage.d.ts.map +1 -1
  404. package/dist/layouts/shared/pages/CheckoutPage.js +349 -868
  405. package/dist/layouts/shared/pages/CookiePolicyPage.js +1 -1
  406. package/dist/layouts/shared/pages/FeatureDisabledPage.js +1 -1
  407. package/dist/layouts/shared/pages/HelpCenterPage.js +1 -1
  408. package/dist/layouts/shared/pages/MaintenancePage.d.ts.map +1 -1
  409. package/dist/layouts/shared/pages/MaintenancePage.js +2 -3
  410. package/dist/layouts/shared/pages/PortfolioPage.d.ts.map +1 -1
  411. package/dist/layouts/shared/pages/PortfolioPage.js +2 -2
  412. package/dist/layouts/shared/pages/PrivacyPolicyPage.js +1 -1
  413. package/dist/layouts/shared/pages/SizeGuidePage.js +1 -1
  414. package/dist/layouts/shared/pages/StyleGuidePage.js +3 -3
  415. package/dist/layouts/shared/pages/TeamPage.d.ts.map +1 -1
  416. package/dist/layouts/shared/pages/TeamPage.js +1 -1
  417. package/dist/layouts/shared/pages/TermsPage.js +1 -1
  418. package/dist/layouts/shared/pages/TrackOrderPage.js +4 -4
  419. package/dist/layouts/shared/pages/WishlistPage.d.ts.map +1 -1
  420. package/dist/layouts/shared/pages/WishlistPage.js +44 -29
  421. package/dist/layouts/shared/wrappers/BookingAgendaLayout.d.ts.map +1 -1
  422. package/dist/layouts/shared/wrappers/BookingAgendaLayout.js +80 -35
  423. package/dist/layouts/shared/wrappers/ClothingLayout.js +8 -8
  424. package/dist/layouts/shared/wrappers/ClothingMinimalLayout.js +7 -7
  425. package/dist/layouts/shared/wrappers/ElectronicsLayout.js +5 -5
  426. package/dist/layouts/shared/wrappers/FoodModernLayout.js +6 -6
  427. package/dist/layouts/shared/wrappers/MotivationalLayout.js +9 -9
  428. package/dist/layouts/shared/wrappers/StandardLayout.js +8 -8
  429. package/dist/lib/api.d.ts +3 -4
  430. package/dist/lib/api.d.ts.map +1 -1
  431. package/dist/lib/api.js +69 -109
  432. package/dist/lib/auth-context.js +2 -2
  433. package/dist/lib/content-selectors.d.ts +1 -1
  434. package/dist/lib/content-selectors.d.ts.map +1 -1
  435. package/dist/lib/content-selectors.js +8 -0
  436. package/dist/lib/layout-config-hydration.js +2 -2
  437. package/dist/lib/loading-context.d.ts.map +1 -1
  438. package/dist/lib/loading-context.js +11 -21
  439. package/dist/lib/payaza-checkout.d.ts.map +1 -1
  440. package/dist/lib/payaza-checkout.js +2 -4
  441. package/dist/lib/payaza-public-key.d.ts +6 -0
  442. package/dist/lib/payaza-public-key.d.ts.map +1 -0
  443. package/dist/lib/payaza-public-key.js +10 -0
  444. package/dist/lib/rich-html.d.ts +31 -26
  445. package/dist/lib/rich-html.d.ts.map +1 -1
  446. package/dist/lib/rich-html.js +1 -0
  447. package/dist/lib/services/analytics.service.js +1 -1
  448. package/dist/lib/services/auth.service.js +1 -1
  449. package/dist/lib/services/booking.service.js +1 -1
  450. package/dist/lib/services/category.service.js +1 -1
  451. package/dist/lib/services/checkout.service.d.ts +3 -0
  452. package/dist/lib/services/checkout.service.d.ts.map +1 -1
  453. package/dist/lib/services/checkout.service.js +1 -1
  454. package/dist/lib/services/contact.service.js +1 -1
  455. package/dist/lib/services/customer.service.js +1 -1
  456. package/dist/lib/services/fees.service.d.ts +17 -63
  457. package/dist/lib/services/fees.service.d.ts.map +1 -1
  458. package/dist/lib/services/fees.service.js +4 -138
  459. package/dist/lib/services/index.js +13 -13
  460. package/dist/lib/services/location.service.js +1 -1
  461. package/dist/lib/services/order.service.js +1 -1
  462. package/dist/lib/services/payment.service.js +1 -1
  463. package/dist/lib/services/product.service.d.ts +7 -2
  464. package/dist/lib/services/product.service.d.ts.map +1 -1
  465. package/dist/lib/services/product.service.js +13 -1
  466. package/dist/lib/services/promo.service.js +1 -1
  467. package/dist/lib/services/review.service.js +1 -1
  468. package/dist/lib/services/service.service.js +1 -1
  469. package/dist/lib/services/shipping.service.js +1 -1
  470. package/dist/lib/services/store.service.js +1 -1
  471. package/dist/lib/store-config-utils.d.ts +1 -10
  472. package/dist/lib/store-config-utils.d.ts.map +1 -1
  473. package/dist/lib/store-config-utils.js +73 -261
  474. package/dist/lib/store-config.js +1 -1
  475. package/dist/lib/store-context.d.ts +1 -23
  476. package/dist/lib/store-context.d.ts.map +1 -1
  477. package/dist/lib/store-context.js +89 -111
  478. package/dist/lib/store-types.d.ts +9 -91
  479. package/dist/lib/store-types.d.ts.map +1 -1
  480. package/dist/lib/utils/asset-helpers.js +1 -1
  481. package/dist/lib/utils/catalog-price-bounds.d.ts +16 -6
  482. package/dist/lib/utils/catalog-price-bounds.d.ts.map +1 -1
  483. package/dist/lib/utils/catalog-price-bounds.js +58 -14
  484. package/dist/lib/utils/category-tree.d.ts +9 -0
  485. package/dist/lib/utils/category-tree.d.ts.map +1 -1
  486. package/dist/lib/utils/category-tree.js +26 -0
  487. package/dist/lib/utils/editor-preview.d.ts +5 -0
  488. package/dist/lib/utils/editor-preview.d.ts.map +1 -1
  489. package/dist/lib/utils/editor-preview.js +17 -3
  490. package/dist/lib/utils/fee-calculations.d.ts +5 -1
  491. package/dist/lib/utils/fee-calculations.d.ts.map +1 -1
  492. package/dist/lib/utils/fee-calculations.js +28 -31
  493. package/dist/lib/utils/index.d.ts +1 -1
  494. package/dist/lib/utils/index.d.ts.map +1 -1
  495. package/dist/lib/utils/index.js +4 -4
  496. package/dist/lib/utils/product-images.js +1 -1
  497. package/dist/lib/utils/product-share.js +1 -1
  498. package/dist/lib/utils/url-helpers.d.ts +6 -0
  499. package/dist/lib/utils/url-helpers.d.ts.map +1 -1
  500. package/dist/lib/utils/url-helpers.js +20 -4
  501. package/dist/preview/LayoutPreview.js +6 -6
  502. package/dist/preview/PreviewRouter.js +4 -4
  503. package/dist/preview/canvas/PreviewCanvasEnhancer.js +8 -8
  504. package/dist/preview/canvas/preview-flush-await.js +1 -1
  505. package/dist/preview/canvas/preview-isolation.js +1 -1
  506. package/dist/preview/canvas/preview-route.js +2 -2
  507. package/dist/preview/index.js +5 -5
  508. package/dist/styles/index.css +190 -149
  509. package/package.json +31 -43
@@ -1,39 +1,30 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { shareProductLink } from '../../../lib/utils/product-share.js';
4
- import { Button } from '../../../components/ui/button.js';
5
- import { Breadcrumbs } from '../../../components/ui/breadcrumbs.js';
6
- import { Modal } from '../../../components/ui/modal.js';
7
- import { ShoppingCart, Heart, Star, ThumbsUp, User, Minus, Plus, Share2 } from 'lucide-react';
3
+ import { useProductBySlug } from '../../../hooks/use-product-by-slug';
4
+ import { useProductReviews } from '../../../hooks/use-product-reviews';
5
+ import { Button } from '../../../components/ui/button';
6
+ import { Breadcrumbs } from '../../../components/ui/breadcrumbs';
7
+ import { Modal } from '../../../components/ui/modal';
8
+ import { ShoppingCart, Heart, Star, CheckCircle, ThumbsUp, User, Minus, Plus, Ruler, Share2, Info } from 'lucide-react';
8
9
  import { useState, useMemo, useEffect } from 'react';
9
- import { useStore } from '../../../lib/store-context.js';
10
- import { useToast } from '../../../components/ui/toast.js';
10
+ import { useStore } from '../../../lib/store-context';
11
+ import { useToast } from '../../../components/ui/toast';
11
12
  import { useRouter } from 'next/navigation';
12
- import { useAuth } from '../../../lib/auth-context.js';
13
- import { useAnalytics } from '../../../hooks/use-analytics.js';
14
- import { trackStorefrontEvent } from '../../../lib/mixpanel.js';
15
- import { customerService } from '../../../lib/services/customer.service.js';
16
- import { GuestCheckoutModal } from '../../../components/ui/guest-checkout-modal.js';
17
- import { getGuestUserInfo, saveGuestUserInfo } from '../../../lib/guest-user.js';
18
- import { ProductCard } from '../../../components/ui/product-card.js';
13
+ import { useAuth } from '../../../lib/auth-context';
14
+ import { useAnalytics } from '../../../hooks/use-analytics';
15
+ import { customerService } from '../../../lib/services/customer.service';
16
+ import { GuestCheckoutModal } from '../../../components/ui/guest-checkout-modal';
17
+ import { getGuestUserInfo, saveGuestUserInfo } from '../../../lib/guest-user';
18
+ import { ProductCard } from '../../../components/ui/product-card';
19
19
  import Image from 'next/image';
20
- import { ImageWithFallback } from '../../../components/ui/image-with-fallback.js';
21
- import { ButtonLoader } from '../../../components/ui/page-loader.js';
22
- import { extractImageUrls } from '../../../lib/store-config-utils.js';
23
- import { OutOfStockOverlay } from '../../../components/ui/out-of-stock-overlay.js';
24
- import { ProductStockBadge } from '../../../components/ui/product-stock-badge.js';
25
- import { LimitedTimeOfferBadge } from '../../../components/ui/limited-time-offer-badge.js';
26
- import { getProductStockInfo, getMaxPurchasableQuantity, formatStockLimitMessage } from '../../../lib/inventory-utils.js';
27
- import { cn, formatCurrency, isEditorPreviewMode, resolveProductBySlugForDisplay, resolveStoreProductsForDisplay, } from '../../../lib/utils/index.js';
28
- import { useShippingQuote } from '../../../hooks/use-shipping-quote.js';
29
- import { ProductDeliveryInfoSection } from '../../../components/shipping/ProductDeliveryInfoSection.js';
30
- import { isAutomatedShippingEnabled } from '../../../lib/shipping-settings.util.js';
31
- import { enrichShippingQuoteAddress } from '../../../lib/shipping-address.util.js';
32
- import { useProductVariationSelection } from '../../../hooks/use-product-variation-selection.js';
33
- import { ProductVariationSelectors } from '../../../components/product/ProductVariationSelectors.js';
34
- import { findMatchingVariation, resolveVariantPrice, resolveVariantSKU, resolveVariantStockProduct, resolveVariantImageUrls, buildCartLineProduct, } from '../../../lib/product-variation-utils.js';
35
- import { guardCheckoutAvailable, isCheckoutDisabled } from '../../../lib/checkout-availability.js';
36
- import { formatDateSafe } from '../../../utils/date.js';
20
+ import { ImageWithFallback } from '../../../components/ui/image-with-fallback';
21
+ import { ButtonLoader } from '../../../components/ui/page-loader';
22
+ import { extractImageUrls } from '../../../lib/store-config-utils';
23
+ import { OutOfStockOverlay } from '../../../components/ui/out-of-stock-overlay';
24
+ import { cn, formatCurrency, filterActiveProducts, isEditorPreviewMode, resolvePdpProduct } from '../../../lib/utils';
25
+ import { shippingService } from '../../../lib/services/shipping.service';
26
+ import { ProductDeliveryInfoSection } from '../../../components/shipping/ProductDeliveryInfoSection';
27
+ import { formatDateSafe } from '../../../utils/date';
37
28
  // Helper function to format date
38
29
  const formatDate = (dateString) => {
39
30
  return formatDateSafe(dateString, '—', { year: 'numeric', month: 'long', day: 'numeric' });
@@ -55,45 +46,52 @@ function StarRating({ rating, size = 'md', className = '' }) {
55
46
  return (_jsxs("div", { className: `relative inline-block ${sizeClasses[size]}`, children: [_jsx(Star, { className: `w-full h-full absolute inset-0 text-gray-200 fill-gray-200` }), isHalf && (_jsx("div", { className: "absolute inset-0", style: { clipPath: 'inset(0 50% 0 0)' }, children: _jsx(Star, { className: `w-full h-full text-gray-900 fill-gray-900` }) })), isFull && (_jsx(Star, { className: `w-full h-full absolute inset-0 text-gray-900 fill-gray-900` }))] }, i));
56
47
  }) }));
57
48
  }
58
- import { ProductDescription } from '../../../components/rich-text/ProductDescription.js';
59
49
  function ReviewCard({ review }) {
60
- return (_jsxs("div", { className: "border-b border-gray-100 pb-8 last:border-b-0 last:pb-0", children: [_jsx("div", { className: "flex items-start justify-between mb-4", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("div", { className: "w-12 h-12 rounded-full bg-gradient-to-br from-gray-200 to-gray-300 flex items-center justify-center flex-shrink-0 ring-2 ring-white shadow-sm overflow-hidden", children: [review.userAvatar ? (_jsx(Image, { src: review.userAvatar, alt: review.userName, fill: true, className: "w-full h-full object-cover", unoptimized: true })) : null, _jsx(User, { className: "h-6 w-6 text-gray-600", style: { display: review.userAvatar ? 'none' : 'flex' } })] }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2 mb-1", children: [_jsx("span", { className: "font-semibold text-gray-900", children: review.userName }), review.verified && (_jsx("span", { className: "text-xs bg-blue-50 text-blue-700 px-2.5 py-1 rounded-full font-medium border border-blue-100", children: "Verified Purchase" }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(StarRating, { rating: review.rating, size: "sm" }), _jsx("span", { className: "text-xs text-gray-500", children: formatDate(review.date) })] })] })] }) }), review.title && (_jsx("h4", { className: "font-semibold text-gray-900 mb-3 text-lg", children: review.title })), _jsx("p", { className: "text-gray-700 leading-relaxed mb-4", children: review.comment }), review.images && review.images.length > 0 && (_jsx("div", { className: "flex gap-2 mb-4", children: review.images.map((img, idx) => (_jsx("div", { className: "relative w-20 h-20 rounded-lg overflow-hidden border border-gray-200", children: _jsx(Image, { src: img, alt: `${review.userName}'s review image ${idx + 1}`, fill: true, className: "object-cover", unoptimized: true }) }, idx))) })), review.helpful !== undefined && (_jsx("div", { className: "flex items-center gap-4", children: _jsxs("button", { className: "flex items-center gap-1.5 text-xs text-gray-600 hover:text-gray-900 transition-colors font-medium", children: [_jsx(ThumbsUp, { className: "h-4 w-4" }), _jsxs("span", { children: ["Helpful (", review.helpful, ")"] })] }) }))] }));
50
+ return (_jsxs("div", { className: "border-b border-gray-100 pb-8 last:border-b-0 last:pb-0", children: [_jsx("div", { className: "flex items-start justify-between mb-4", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("div", { className: "w-12 h-12 rounded-full bg-gradient-to-br from-gray-200 to-gray-300 flex items-center justify-center flex-shrink-0 ring-2 ring-white shadow-sm overflow-hidden", children: [review.userAvatar ? (_jsx(Image, { src: review.userAvatar, alt: review.userName, fill: true, className: "w-full h-full object-cover" })) : null, _jsx(User, { className: "h-6 w-6 text-gray-600", style: { display: review.userAvatar ? 'none' : 'flex' } })] }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2 mb-1", children: [_jsx("span", { className: "font-semibold text-gray-900", children: review.userName }), review.verified && (_jsx("span", { className: "text-xs bg-blue-50 text-blue-700 px-2.5 py-1 rounded-full font-medium border border-blue-100", children: "Verified Purchase" }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(StarRating, { rating: review.rating, size: "sm" }), _jsx("span", { className: "text-xs text-gray-500", children: formatDate(review.date) })] })] })] }) }), review.title && (_jsx("h4", { className: "font-semibold text-gray-900 mb-3 text-lg", children: review.title })), _jsx("p", { className: "text-gray-700 leading-relaxed mb-4", children: review.comment }), review.images && review.images.length > 0 && (_jsx("div", { className: "flex gap-2 mb-4", children: review.images.map((img, idx) => (_jsx("div", { className: "relative w-20 h-20 rounded-lg overflow-hidden border border-gray-200", children: _jsx(Image, { src: img, alt: `${review.userName}'s review image ${idx + 1}`, fill: true, className: "object-cover" }) }, idx))) })), review.helpful !== undefined && (_jsx("div", { className: "flex items-center gap-4", children: _jsxs("button", { className: "flex items-center gap-1.5 text-xs text-gray-600 hover:text-gray-900 transition-colors font-medium", children: [_jsx(ThumbsUp, { className: "h-4 w-4" }), _jsxs("span", { children: ["Helpful (", review.helpful, ")"] })] }) }))] }));
61
51
  }
62
- export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, productSlug }) {
52
+ export function ProductDetailPage({ storeConfig: initialConfig, productSlug }) {
63
53
  const { store, addToCart, isCartLoading, toggleWishlist, isInWishlist, isWishlistLoading, setBuyNowItem } = useStore();
64
54
  const storeConfig = store || initialConfig;
65
- const isPreview = isEditorPreviewMode(storeConfig);
66
- const products = resolveStoreProductsForDisplay(storeConfig.products, isPreview);
67
- const product = resolveProductBySlugForDisplay(storeConfig.products, productSlug, isPreview);
68
- const { optionGroups, selectedAttributes, setAttribute, selectedColor, selectedSize, matchingVariation, hasVariations, hasSelectedOptions, } = useProductVariationSelection(product?.variants);
55
+ const products = filterActiveProducts(storeConfig.products || []);
56
+ const initialProduct = resolvePdpProduct(initialConfig.products, storeConfig.products, productSlug, isEditorPreviewMode(storeConfig));
57
+ const { product, relatedProducts: apiRelatedProducts, isLoading: isLoadingProduct } = useProductBySlug(storeConfig.id, productSlug, initialProduct);
69
58
  const { addToast } = useToast();
70
59
  const router = useRouter();
71
- const { isAuthenticated } = useAuth();
60
+ const { isAuthenticated, openLogin } = useAuth();
72
61
  const { trackEvent } = useAnalytics();
73
62
  const productDetailConfig = storeConfig.layoutConfig?.pages?.productDetail;
63
+ const { reviews, isSubmitting: isSubmittingReview, submitReview, } = useProductReviews(product?.id);
74
64
  // Related products logic
75
- const relatedProducts = useMemo(() => {
65
+ const fallbackRelatedProducts = useMemo(() => {
76
66
  if (!product)
77
67
  return [];
78
68
  return products
79
69
  .filter(p => p.categoryId === product.categoryId && p.id !== product.id)
80
70
  .slice(0, 4);
81
71
  }, [product, products]);
72
+ const relatedProducts = apiRelatedProducts.length > 0 ? apiRelatedProducts : fallbackRelatedProducts;
82
73
  const handleShare = async () => {
83
- if (!product)
84
- return;
85
- try {
86
- const result = await shareProductLink({
87
- storeSlug: storeConfig.slug,
88
- productSlug: product.slug,
89
- productName: product.name,
90
- });
91
- addToast(result === 'shared' ? 'Product shared!' : 'Link copied to clipboard!', 'success');
74
+ if (typeof navigator !== 'undefined' && navigator.share) {
75
+ try {
76
+ await navigator.share({
77
+ title: product?.name,
78
+ text: product?.description,
79
+ url: window.location.href,
80
+ });
81
+ }
82
+ catch (error) {
83
+ console.log('Error sharing:', error);
84
+ }
92
85
  }
93
- catch (error) {
94
- if (error instanceof Error && error.name === 'AbortError')
95
- return;
96
- addToast('Failed to copy link', 'error');
86
+ else {
87
+ // Fallback to copy to clipboard
88
+ try {
89
+ await navigator.clipboard.writeText(window.location.href);
90
+ addToast('Link copied to clipboard!', 'success');
91
+ }
92
+ catch (err) {
93
+ addToast('Failed to copy link', 'error');
94
+ }
97
95
  }
98
96
  };
99
97
  const handleQuickView = (p) => {
@@ -118,6 +116,9 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
118
116
  addToast('Failed to update wishlist', 'error');
119
117
  }
120
118
  };
119
+ // Extract color and size variants
120
+ const colorVariants = product?.variants?.filter(v => v.name === 'Color') || [];
121
+ const sizeVariants = product?.variants?.filter(v => v.name === 'Size') || [];
121
122
  // Initialize state with defaults
122
123
  const [selectedImage, setSelectedImage] = useState(0);
123
124
  // Ensure selectedImage is within bounds when images change
@@ -128,37 +129,68 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
128
129
  return () => clearTimeout(timer);
129
130
  }
130
131
  }, [product, selectedImage]);
132
+ const [selectedColor, setSelectedColor] = useState(colorVariants.length > 0 ? colorVariants[0].value : null);
133
+ const [selectedSize, setSelectedSize] = useState(sizeVariants.length > 0 ? sizeVariants[0].value : null);
131
134
  const [quantity, setQuantity] = useState(1);
132
135
  const [showAllReviews, setShowAllReviews] = useState(false);
133
136
  const [isReviewModalOpen, setIsReviewModalOpen] = useState(false);
134
137
  const [newReview, setNewReview] = useState({ rating: 5, title: '', comment: '' });
135
138
  const [showGuestModal, setShowGuestModal] = useState(false);
136
139
  const [isBuyNowLoading, setIsBuyNowLoading] = useState(false);
137
- // Shipping calculation (ShipBubble-ready address fields)
138
- const currency = product?.currency || storeConfig.settings?.currency || 'USD';
139
- const { address: shippingAddress, updateAddress: updateShippingAddress, methods: shippingMethods, isCalculating: isCalculatingShipping, error: shippingError, freeShippingEligible, freeShippingThreshold, } = useShippingQuote({
140
- storeId: storeConfig.id,
141
- productId: product?.id || '',
142
- productPrice: resolveVariantPrice({ price: product?.price ?? 0 }, matchingVariation),
143
- currency,
144
- quantity,
145
- enabled: Boolean(product) && isAutomatedShippingEnabled(storeConfig),
140
+ // Shipping calculation state
141
+ const [shippingAddress, setShippingAddress] = useState({
142
+ country: '',
143
+ city: '',
144
+ zipCode: '',
146
145
  });
147
146
  const [savedAddresses, setSavedAddresses] = useState([]);
148
- const handleSubmitReview = (e) => {
147
+ const [isCountryDropdownOpen, setIsCountryDropdownOpen] = useState(false);
148
+ const [isCityDropdownOpen, setIsCityDropdownOpen] = useState(false);
149
+ const [shippingMethods, setShippingMethods] = useState([]);
150
+ const [isCalculatingShipping, setIsCalculatingShipping] = useState(false);
151
+ const [shippingError, setShippingError] = useState(null);
152
+ const [freeShippingEligible, setFreeShippingEligible] = useState(false);
153
+ const [freeShippingThreshold, setFreeShippingThreshold] = useState(undefined);
154
+ const handleSubmitReview = async (e) => {
149
155
  e.preventDefault();
150
- // In a real app, this would submit to API
151
- addToast('Review submitted successfully!', 'success');
152
- setIsReviewModalOpen(false);
153
- setNewReview({ rating: 5, title: '', comment: '' });
156
+ if (!product?.id)
157
+ return;
158
+ if (!isAuthenticated) {
159
+ setIsReviewModalOpen(false);
160
+ openLogin({
161
+ onSuccess: () => setIsReviewModalOpen(true),
162
+ });
163
+ addToast('Sign in to submit your review', 'info');
164
+ return;
165
+ }
166
+ const title = newReview.title.trim();
167
+ const comment = newReview.comment.trim();
168
+ if (!title && !comment) {
169
+ addToast('Please add a review title or comment', 'error');
170
+ return;
171
+ }
172
+ try {
173
+ await submitReview({
174
+ rating: newReview.rating,
175
+ title,
176
+ comment,
177
+ });
178
+ addToast('Review submitted successfully!', 'success');
179
+ setIsReviewModalOpen(false);
180
+ setNewReview({ rating: 5, title: '', comment: '' });
181
+ }
182
+ catch (error) {
183
+ addToast(error instanceof Error ? error.message : 'Failed to submit review', 'error');
184
+ }
154
185
  };
186
+ if (isLoadingProduct) {
187
+ return _jsx("div", { className: "min-h-screen bg-white flex items-center justify-center p-8", children: "Loading product..." });
188
+ }
155
189
  if (!product) {
156
190
  return (_jsx("div", { className: "min-h-screen bg-white flex items-center justify-center p-8", children: _jsxs("div", { className: "text-center", children: [_jsx("h1", { className: "text-2xl font-bold mb-2", children: "Product Not Found" }), _jsx("p", { className: "text-gray-600 mb-4", children: "The product you're looking for doesn't exist." })] }) }));
157
191
  }
158
192
  // Use SKU for display, fallback to generated SKU from slug if not available
159
- const displayPrice = resolveVariantPrice(product, matchingVariation);
160
- const displaySKU = resolveVariantSKU(product, matchingVariation);
161
- const stockProduct = resolveVariantStockProduct(product, matchingVariation);
193
+ const displaySKU = product.sku || product.slug?.toUpperCase().replace(/-/g, '').substring(0, 12).padEnd(8, 'X') || 'N/A';
162
194
  // Build category breadcrumb path with all parent categories
163
195
  const buildCategoryPath = (categoryId) => {
164
196
  if (!categoryId)
@@ -193,9 +225,6 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
193
225
  // but handle edge cases where it might still be in object format
194
226
  // Use the comprehensive extraction utility from store-config-utils for consistency
195
227
  const productImages = (() => {
196
- const variantImages = resolveVariantImageUrls(matchingVariation);
197
- if (variantImages.length > 0)
198
- return variantImages;
199
228
  // Debug: Log the raw product.images to understand its format
200
229
  if (process.env.NODE_ENV === 'development') {
201
230
  console.log('[ProductDetailPage] Raw product.images:', {
@@ -231,10 +260,8 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
231
260
  }
232
261
  return extracted;
233
262
  })();
263
+ // For gallery, use actual images only (don't duplicate to fill 5 slots)
234
264
  const displayImages = productImages.slice(0, 5);
235
- useEffect(() => {
236
- setSelectedImage(0);
237
- }, [matchingVariation?.id, productImages[0]]);
238
265
  const hasMoreImages = productImages.length > 5;
239
266
  // Debug logging for images (can be removed in production)
240
267
  if (process.env.NODE_ENV === 'development') {
@@ -271,17 +298,18 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
271
298
  'Navy': '#1E3A8A',
272
299
  'Beige': '#F5F5DC',
273
300
  };
274
- // Get reviews
275
- const reviews = product.reviews || [];
301
+ // Reviews loaded from API (product payload does not include review rows)
276
302
  const displayedReviews = showAllReviews ? reviews : reviews.slice(0, 3);
277
303
  const hasMoreReviews = reviews.length > 3;
304
+ const reviewCount = Math.max(Number(product.reviewCount) || 0, reviews.length);
305
+ const averageRating = reviews.length > 0
306
+ ? reviews.reduce((sum, review) => sum + review.rating, 0) / reviews.length
307
+ : Number(product.rating) || 0;
278
308
  // Out of stock check
279
- const stockInfo = getProductStockInfo(stockProduct);
280
- const isOutOfStock = !stockInfo.canPurchase;
281
- const maxPurchasableQty = getMaxPurchasableQuantity({ ...product, ...stockProduct });
309
+ const isOutOfStock = !product.inStock;
282
310
  // Calculate rating distribution
283
311
  const ratingDistribution = [5, 4, 3, 2, 1].map(rating => {
284
- const count = reviews.filter(r => r.rating === rating).length;
312
+ const count = reviews.filter(r => Math.round(r.rating) === rating).length;
285
313
  return {
286
314
  rating,
287
315
  count,
@@ -290,44 +318,31 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
290
318
  });
291
319
  const handleAddToCart = () => {
292
320
  if (isOutOfStock) {
293
- addToast(formatStockLimitMessage(product.name, stockInfo.availableStock ?? 0), 'error');
294
- return;
295
- }
296
- if (hasVariations && hasSelectedOptions && !matchingVariation) {
297
- addToast('Please select all product options', 'error');
321
+ addToast('This product is currently out of stock', 'error');
298
322
  return;
299
323
  }
300
324
  // Find the matching variation UUID based on selected attributes
301
325
  // Note: StoreProduct uses 'variants' not 'variations'
302
- let variationId = matchingVariation?.id;
303
- if (!variationId && product.variants && product.variants.length > 0) {
304
- const resolved = findMatchingVariation(product.variants, {
305
- ...(selectedColor ? { color: selectedColor } : {}),
306
- ...(selectedSize ? { size: selectedSize } : {}),
307
- ...selectedAttributes,
326
+ let variationId;
327
+ if (product.variants && Array.isArray(product.variants) && product.variants.length > 0) {
328
+ const matchingVariation = product.variants.find((variation) => {
329
+ const attrs = variation.attributes || {};
330
+ const colorMatch = !selectedColor || attrs.color === selectedColor;
331
+ const sizeMatch = !selectedSize || attrs.size === selectedSize;
332
+ return colorMatch && sizeMatch;
308
333
  });
309
- variationId = resolved?.id;
334
+ variationId = matchingVariation?.id;
310
335
  }
311
336
  // Fallback to composite string for backward compatibility if no variation found
312
337
  const variantId = variationId || (selectedColor || selectedSize
313
338
  ? [selectedColor, selectedSize].filter(Boolean).join(' / ')
314
339
  : undefined);
315
- const resolvedVariation = variationId ? product.variants?.find(v => v.id === variationId) : matchingVariation;
316
- const variantName = resolvedVariation?.value || Object.values(resolvedVariation?.attributes || {}).filter(Boolean).join(' / ') || undefined;
317
- const unitPrice = resolvedVariation?.price ?? product.price;
318
- addToCart(product, quantity, { variantId, variantName, unitPrice });
340
+ addToCart(product, quantity, variantId);
319
341
  addToast(`${product.name} added to cart`, 'success');
320
342
  };
321
343
  const handleBuyNow = async () => {
322
344
  if (isOutOfStock) {
323
- addToast(formatStockLimitMessage(product.name, stockInfo.availableStock ?? 0), 'error');
324
- return;
325
- }
326
- if (hasVariations && hasSelectedOptions && !matchingVariation) {
327
- addToast('Please select all product options', 'error');
328
- return;
329
- }
330
- if (!guardCheckoutAvailable(storeConfig, addToast)) {
345
+ addToast('This product is currently out of stock', 'error');
331
346
  return;
332
347
  }
333
348
  if (isBuyNowLoading || isCartLoading) {
@@ -337,19 +352,17 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
337
352
  try {
338
353
  // Find the matching variation UUID based on selected attributes
339
354
  // Note: StoreProduct uses 'variants' not 'variations'
340
- let variationId = matchingVariation?.id;
355
+ let variationId;
341
356
  let variantName;
342
- if (!variationId && product.variants && product.variants.length > 0) {
343
- const resolved = findMatchingVariation(product.variants, {
344
- ...(selectedColor ? { color: selectedColor } : {}),
345
- ...(selectedSize ? { size: selectedSize } : {}),
346
- ...selectedAttributes,
357
+ if (product.variants && Array.isArray(product.variants) && product.variants.length > 0) {
358
+ const matchingVariation = product.variants.find((variation) => {
359
+ const attrs = variation.attributes || {};
360
+ const colorMatch = !selectedColor || attrs.color === selectedColor;
361
+ const sizeMatch = !selectedSize || attrs.size === selectedSize;
362
+ return colorMatch && sizeMatch;
347
363
  });
348
- variationId = resolved?.id;
349
- variantName = resolved?.value || Object.values(resolved?.attributes || {}).filter(Boolean).join(' / ');
350
- }
351
- else if (matchingVariation) {
352
- variantName = matchingVariation.value || Object.values(matchingVariation.attributes || {}).filter(Boolean).join(' / ');
364
+ variationId = matchingVariation?.id;
365
+ variantName = matchingVariation?.name || matchingVariation?.value;
353
366
  }
354
367
  // Fallback to composite string for backward compatibility if no variation found
355
368
  const variantId = variationId || (selectedColor || selectedSize
@@ -363,8 +376,8 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
363
376
  quantity,
364
377
  variantId,
365
378
  variantName: variantName || variantId,
366
- price: (variationId ? product.variants?.find(v => v.id === variationId)?.price : matchingVariation?.price) ?? product.price,
367
- product: buildCartLineProduct(product, variationId ? product.variants?.find(v => v.id === variationId) : matchingVariation)
379
+ price: product.price,
380
+ product
368
381
  };
369
382
  // Set buy now item and navigate directly to checkout
370
383
  setBuyNowItem(buyNowItem);
@@ -386,6 +399,44 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
386
399
  // Note: This is now only used for other flows, not buy now
387
400
  // Buy now now redirects to checkout page
388
401
  };
402
+ // Calculate shipping when address is provided
403
+ const calculateShipping = async () => {
404
+ if (!product || !shippingAddress.country || !shippingAddress.city) {
405
+ setShippingError('Please provide country and city to calculate shipping');
406
+ return;
407
+ }
408
+ setIsCalculatingShipping(true);
409
+ setShippingError(null);
410
+ try {
411
+ const currency = product.currency || storeConfig.settings?.currency || 'USD';
412
+ const subtotal = product.price * quantity;
413
+ const result = await shippingService.calculateShipping({
414
+ storeId: storeConfig.id,
415
+ address: {
416
+ country: shippingAddress.country,
417
+ city: shippingAddress.city,
418
+ zipCode: shippingAddress.zipCode,
419
+ },
420
+ items: [{
421
+ productId: product.id,
422
+ quantity: quantity,
423
+ }],
424
+ subtotal: subtotal,
425
+ currency: currency,
426
+ });
427
+ setShippingMethods(result.methods || []);
428
+ setFreeShippingEligible(result.freeShippingEligible || false);
429
+ setFreeShippingThreshold(result.freeShippingThreshold);
430
+ }
431
+ catch (error) {
432
+ console.error('Shipping calculation error:', error);
433
+ setShippingError(error.message || 'Failed to calculate shipping. Please try again.');
434
+ setShippingMethods([]);
435
+ }
436
+ finally {
437
+ setIsCalculatingShipping(false);
438
+ }
439
+ };
389
440
  // Load saved addresses for authenticated users and auto-populate shipping address
390
441
  useEffect(() => {
391
442
  const loadAddresses = async () => {
@@ -393,28 +444,39 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
393
444
  try {
394
445
  const addresses = await customerService.getAddresses();
395
446
  setSavedAddresses(addresses);
447
+ // Auto-populate with default address or first address if available
396
448
  if (addresses.length > 0) {
397
- const defaultAddress = addresses.find((a) => a.isDefault) || addresses[0];
449
+ const defaultAddress = addresses.find(a => a.isDefault) || addresses[0];
398
450
  if (defaultAddress) {
399
- updateShippingAddress(enrichShippingQuoteAddress({
451
+ setShippingAddress({
400
452
  country: defaultAddress.country || '',
401
453
  city: defaultAddress.city || '',
402
454
  zipCode: defaultAddress.zipCode || '',
403
- street: defaultAddress.address1 || '',
404
- state: defaultAddress.state || '',
405
- phone: defaultAddress.phone || '',
406
- }));
455
+ });
407
456
  }
408
457
  }
409
458
  }
410
459
  catch (error) {
411
460
  console.error('Failed to load addresses:', error);
461
+ // Don't show error toast - addresses are optional
462
+ // Users can still manually enter shipping address
412
463
  }
413
464
  }
414
465
  };
415
466
  loadAddresses();
416
467
  // eslint-disable-next-line react-hooks/exhaustive-deps
417
468
  }, [isAuthenticated]);
469
+ // Auto-calculate shipping when address fields are filled (debounced)
470
+ useEffect(() => {
471
+ if (!shippingAddress.country || !shippingAddress.city || !product) {
472
+ return;
473
+ }
474
+ const timer = setTimeout(() => {
475
+ calculateShipping();
476
+ }, 500); // Debounce 500ms
477
+ return () => clearTimeout(timer);
478
+ // eslint-disable-next-line react-hooks/exhaustive-deps
479
+ }, [shippingAddress.country, shippingAddress.city, shippingAddress.zipCode, quantity, product?.id, product?.price]);
418
480
  // Track product view
419
481
  useEffect(() => {
420
482
  if (product && storeConfig?.id) {
@@ -427,29 +489,26 @@ export function ClothingMinimalProductDetailPage({ storeConfig: initialConfig, p
427
489
  price: product.price,
428
490
  },
429
491
  });
430
- trackStorefrontEvent('Product_viewed', {
431
- storeId: storeConfig.id,
432
- storeSlug: storeConfig.slug,
433
- productId: product.id,
434
- productName: product.name,
435
- categoryId: product.categoryId,
436
- price: product.price,
437
- });
438
492
  }
439
493
  }, [product?.id, storeConfig?.id, trackEvent]);
440
- return (_jsxs("div", { className: "min-h-screen bg-white", children: [_jsxs("div", { "data-content-ready": true, "data-section": "productInfo", "data-payaza-section-key": "productInfo", "data-payaza-page": "productDetail", className: "container mx-auto px-4 sm:px-6 lg:px-8 py-8 lg:py-12 max-w-7xl", children: [_jsx("div", { className: "mb-6", children: _jsx(Breadcrumbs, { items: breadcrumbItems }) }), _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-16 mb-20", children: [_jsxs("div", { className: "relative lg:sticky lg:top-24 self-start z-0", children: [_jsxs("div", { className: "relative aspect-square bg-gray-50 rounded-xl overflow-hidden mb-4 border border-gray-100 shadow-sm group", children: [_jsx(ImageWithFallback, { "data-product-image": true, src: displayImages[selectedImage] || displayImages[0] || productImages[0], alt: product.name, className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", isOutOfStock && "grayscale"), skeletonAspectRatio: "square" }), isOutOfStock && (_jsx(OutOfStockOverlay, { badgePosition: "center" }))] }), displayImages.length > 0 && (_jsxs("div", { className: "grid grid-cols-5 gap-2", children: [displayImages.map((image, index) => (_jsx("button", { onClick: () => setSelectedImage(Math.min(index, displayImages.length - 1)), className: `aspect-square rounded-lg overflow-hidden border-2 transition-all ${selectedImage === index
494
+ return (_jsxs("div", { className: "min-h-screen bg-white", children: [_jsxs("div", { "data-content-ready": true, className: "container mx-auto px-4 sm:px-6 lg:px-8 py-8 lg:py-12 max-w-7xl", children: [_jsx("div", { className: "mb-6", children: _jsx(Breadcrumbs, { items: breadcrumbItems }) }), _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-16 mb-20", children: [_jsxs("div", { className: "relative lg:sticky lg:top-24 self-start z-0", children: [_jsxs("div", { className: "relative aspect-square bg-gray-50 rounded-xl overflow-hidden mb-4 border border-gray-100 shadow-sm group", children: [_jsx(ImageWithFallback, { "data-product-image": true, src: displayImages[selectedImage] || displayImages[0] || productImages[0], alt: product.name, className: cn("w-full h-full object-cover transition-transform duration-300 group-hover:scale-105", isOutOfStock && "grayscale"), skeletonAspectRatio: "square" }), isOutOfStock && (_jsx(OutOfStockOverlay, { badgePosition: "center" }))] }), displayImages.length > 0 && (_jsxs("div", { className: "grid grid-cols-5 gap-2", children: [displayImages.map((image, index) => (_jsx("button", { onClick: () => setSelectedImage(Math.min(index, displayImages.length - 1)), className: `aspect-square rounded-lg overflow-hidden border-2 transition-all ${selectedImage === index
441
495
  ? 'border-gray-900 ring-2 ring-gray-900 ring-offset-2'
442
496
  : 'border-gray-200 hover:border-gray-300'}`, children: _jsx(ImageWithFallback, { src: image, alt: `${product.name} view ${index + 1}`, className: cn("w-full h-full object-cover", isOutOfStock && "grayscale"), skeletonAspectRatio: "square" }) }, index))), hasMoreImages && (_jsxs("div", { className: "aspect-square rounded-lg border-2 border-gray-200 bg-gray-50 flex items-center justify-center text-xs text-gray-500 font-medium", children: ["+", productImages.length - 5, " more"] }))] }))] }), _jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("span", { className: "text-sm font-semibold text-gray-700 uppercase tracking-wide", children: (() => {
443
497
  const brandMatch = product.name.match(/\b(Reebok|Nike|Adidas|Puma|New Balance|Vans|Converse)\b/i);
444
498
  return brandMatch ? brandMatch[1] : storeConfig.name;
445
- })() }), _jsx("button", { onClick: handleShare, className: "text-gray-400 hover:text-gray-900 transition-colors p-2 rounded-full hover:bg-gray-100", title: "Share this product", children: _jsx(Share2, { className: "h-5 w-5" }) })] }), _jsx("h1", { "data-product-name": true, className: "text-3xl sm:text-4xl lg:text-5xl font-bold text-gray-900 mb-3 leading-tight tracking-tight", children: product.name }), _jsxs("p", { className: "text-sm text-gray-500 mb-6 font-mono", children: ["SKU: ", displaySKU] }), _jsxs("div", { className: "mb-4 flex items-center gap-2", children: [_jsx(ProductStockBadge, { product: stockProduct }), _jsx(LimitedTimeOfferBadge, { product: product })] }), _jsxs("div", { className: "mb-8", children: [_jsxs("div", { className: "flex items-baseline gap-4", children: [_jsx("span", { "data-product-price": true, className: "text-4xl lg:text-5xl font-bold text-gray-900", children: formatCurrency(matchingVariation?.price ?? product.price, product.currency || 'USD') }), (matchingVariation?.compareAtPrice ?? product.compareAtPrice) != null &&
446
- (matchingVariation?.compareAtPrice ?? product.compareAtPrice) >
447
- (matchingVariation?.price ?? product.price) && (_jsx("span", { className: "text-2xl text-gray-500 line-through", children: formatCurrency(matchingVariation?.compareAtPrice ?? product.compareAtPrice, product.currency || 'USD') }))] }), (matchingVariation?.compareAtPrice ?? product.compareAtPrice) != null &&
448
- (matchingVariation?.compareAtPrice ?? product.compareAtPrice) >
449
- (matchingVariation?.price ?? product.price) && (_jsxs("span", { className: "inline-block mt-2 bg-red-100 text-red-700 text-xs font-bold px-2 py-1 rounded", children: ["SAVE", " ", Math.round((((matchingVariation?.compareAtPrice ?? product.compareAtPrice) -
450
- (matchingVariation?.price ?? product.price)) /
451
- (matchingVariation?.compareAtPrice ?? product.compareAtPrice)) *
452
- 100), "%"] }))] }), _jsx(ProductVariationSelectors, { optionGroups: optionGroups, selectedAttributes: selectedAttributes, onSelectAttribute: setAttribute, storeSlug: storeConfig.slug, colorSwatches: colorSwatches, variants: product.variants }), _jsxs("div", { className: "flex flex-col gap-4 mb-8", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: "Quantity" }), _jsxs("div", { className: "flex items-center border border-gray-300 rounded-lg", children: [_jsx("button", { className: "p-3 text-gray-600 hover:bg-gray-100 rounded-l-lg disabled:opacity-50", onClick: () => setQuantity(Math.max(1, quantity - 1)), disabled: quantity <= 1, children: _jsx(Minus, { className: "h-4 w-4" }) }), _jsx("span", { className: "w-12 text-center font-semibold text-gray-900", children: quantity }), _jsx("button", { className: "p-3 text-gray-600 hover:bg-gray-100 rounded-r-lg", onClick: () => setQuantity(Math.min(maxPurchasableQty ?? quantity + 1, quantity + 1)), children: _jsx(Plus, { className: "h-4 w-4" }) })] })] }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-3 mt-2", children: [productDetailConfig?.showAddToCart !== false && (_jsx(Button, { "data-add-to-cart": true, size: "xl", onClick: handleAddToCart, disabled: isCartLoading || isOutOfStock, className: "w-full sm:flex-1 bg-white border-2 border-gray-900 text-gray-900 hover:bg-gray-50 rounded-full min-h-14 text-base font-bold shadow-sm transition-all disabled:opacity-50 disabled:cursor-not-allowed", children: isCartLoading ? (_jsxs(_Fragment, { children: [_jsx(ButtonLoader, { className: "mr-2" }), "Adding..."] })) : (_jsxs(_Fragment, { children: [_jsx(ShoppingCart, { className: "h-5 w-5 mr-2" }), "Add to Cart"] })) })), productDetailConfig?.showAddToCart !== false && (_jsx(Button, { size: "xl", onClick: handleBuyNow, disabled: isOutOfStock || isBuyNowLoading || isCartLoading || isCheckoutDisabled(storeConfig), className: "w-full sm:flex-1 bg-gray-900 hover:bg-gray-800 text-white rounded-full min-h-14 text-base font-bold shadow-lg hover:shadow-xl transition-all disabled:opacity-50 disabled:cursor-not-allowed", children: isBuyNowLoading || isCartLoading ? (_jsxs(_Fragment, { children: [_jsx(ButtonLoader, { className: "mr-2" }), "Adding..."] })) : ('Buy Now') })), storeConfig.features.wishlist && productDetailConfig?.showWishlist !== false && (_jsx(Button, { variant: "outline", size: "xl", onClick: handleWishlistClick, disabled: isWishlistLoading || !product, className: cn("h-14 w-14 rounded-full border-2 transition-all disabled:opacity-50 disabled:cursor-not-allowed", product && isInWishlist(product.id)
499
+ })() }), _jsx("button", { onClick: handleShare, className: "text-gray-400 hover:text-gray-900 transition-colors p-2 rounded-full hover:bg-gray-100", title: "Share this product", children: _jsx(Share2, { className: "h-5 w-5" }) })] }), _jsx("h1", { "data-product-name": true, className: "text-3xl sm:text-4xl lg:text-5xl font-bold text-gray-900 mb-3 leading-tight tracking-tight", children: product.name }), _jsxs("p", { className: "text-sm text-gray-500 mb-6 font-mono", children: ["SKU: ", displaySKU] }), _jsx("div", { className: "mb-4 flex items-center gap-2", children: product.inStock ? (_jsxs("span", { className: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800", children: [_jsx(CheckCircle, { className: "w-3 h-3 mr-1" }), "In Stock"] })) : (_jsxs("span", { className: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800", children: [_jsx(Info, { className: "w-3 h-3 mr-1" }), "Out of Stock"] })) }), _jsxs("div", { className: "mb-8", children: [_jsxs("div", { className: "flex items-baseline gap-4", children: [_jsx("span", { "data-product-price": true, className: "text-4xl lg:text-5xl font-bold text-gray-900", children: formatCurrency(product.price, product.currency || 'USD') }), product.compareAtPrice && (_jsx("span", { className: "text-2xl text-gray-500 line-through", children: formatCurrency(product.compareAtPrice, product.currency || 'USD') }))] }), product.compareAtPrice && (_jsxs("span", { className: "inline-block mt-2 bg-red-100 text-red-700 text-xs font-bold px-2 py-1 rounded", children: ["SAVE ", Math.round(((product.compareAtPrice - product.price) / product.compareAtPrice) * 100), "%"] }))] }), colorVariants.length > 0 && (_jsxs("div", { className: "mb-8", children: [_jsxs("div", { className: "flex items-center gap-2 mb-4", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: "Color:" }), _jsx("span", { className: "text-sm text-gray-600 capitalize", children: selectedColor || colorVariants[0]?.value })] }), _jsx("div", { className: "flex gap-3", children: colorVariants.map((variant) => {
500
+ const colorValue = variant.value;
501
+ const swatchColor = colorSwatches[colorValue] || '#CCCCCC';
502
+ const isSelected = selectedColor === colorValue;
503
+ return (_jsx("button", { onClick: () => setSelectedColor(colorValue), className: `relative w-12 h-12 rounded-full border-2 transition-all ${isSelected
504
+ ? 'border-gray-900 ring-2 ring-gray-900 ring-offset-2 scale-105'
505
+ : 'border-gray-200 hover:border-gray-300'}`, style: { backgroundColor: swatchColor }, title: colorValue, children: isSelected && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx(CheckCircle, { className: `h-5 w-5 ${['White', 'Beige', 'Yellow'].includes(colorValue) ? 'text-gray-900' : 'text-white'} drop-shadow-sm` }) })) }, variant.id));
506
+ }) })] })), sizeVariants.length > 0 && (_jsxs("div", { className: "mb-8", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: "Size:" }), _jsx("span", { className: "text-sm text-gray-600", children: selectedSize || 'Select Size' })] }), productDetailConfig?.showSizeGuide !== false && (_jsxs("a", { href: `/${storeConfig.slug}/size-guide`, target: "_blank", rel: "noopener noreferrer", className: "flex items-center gap-1.5 text-xs font-medium text-gray-600 hover:text-gray-900 underline decoration-gray-400 underline-offset-4", children: [_jsx(Ruler, { className: "h-3.5 w-3.5" }), " Size guide"] }))] }), _jsx("div", { className: "grid grid-cols-4 sm:grid-cols-5 gap-2.5", children: sizeVariants.map((variant) => {
507
+ const isSelected = selectedSize === variant.value;
508
+ return (_jsx("button", { onClick: () => setSelectedSize(variant.value), className: `px-4 py-3 rounded-lg border-2 text-sm font-semibold transition-all ${isSelected
509
+ ? 'bg-gray-900 text-white border-gray-900 shadow-md transform -translate-y-0.5'
510
+ : 'bg-white text-gray-700 border-gray-200 hover:border-gray-300 hover:bg-gray-50'}`, children: variant.value }, variant.id));
511
+ }) })] })), _jsxs("div", { className: "flex flex-col gap-4 mb-8", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: "Quantity" }), _jsxs("div", { className: "flex items-center border border-gray-300 rounded-lg", children: [_jsx("button", { className: "p-3 text-gray-600 hover:bg-gray-100 rounded-l-lg disabled:opacity-50", onClick: () => setQuantity(Math.max(1, quantity - 1)), disabled: quantity <= 1, children: _jsx(Minus, { className: "h-4 w-4" }) }), _jsx("span", { className: "w-12 text-center font-semibold text-gray-900", children: quantity }), _jsx("button", { className: "p-3 text-gray-600 hover:bg-gray-100 rounded-r-lg", onClick: () => setQuantity(quantity + 1), children: _jsx(Plus, { className: "h-4 w-4" }) })] })] }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-3 mt-2", children: [productDetailConfig?.showAddToCart !== false && (_jsx(Button, { "data-add-to-cart": true, size: "lg", onClick: handleAddToCart, disabled: isCartLoading || isOutOfStock, className: "flex-1 bg-white border-2 border-gray-900 text-gray-900 hover:bg-gray-50 rounded-full h-14 text-base font-bold shadow-sm transition-all disabled:opacity-50 disabled:cursor-not-allowed", children: isCartLoading ? (_jsxs(_Fragment, { children: [_jsx(ButtonLoader, { className: "mr-2" }), "Adding..."] })) : (_jsxs(_Fragment, { children: [_jsx(ShoppingCart, { className: "h-5 w-5 mr-2" }), "Add to Cart"] })) })), productDetailConfig?.showAddToCart !== false && (_jsx(Button, { size: "lg", onClick: handleBuyNow, disabled: isOutOfStock || isBuyNowLoading || isCartLoading, className: "flex-1 bg-gray-900 hover:bg-gray-800 text-white rounded-full h-14 text-base font-bold shadow-lg hover:shadow-xl transition-all disabled:opacity-50 disabled:cursor-not-allowed", children: isBuyNowLoading || isCartLoading ? (_jsxs(_Fragment, { children: [_jsx(ButtonLoader, { className: "mr-2" }), "Adding..."] })) : ('Buy Now') })), storeConfig.features.wishlist && productDetailConfig?.showWishlist !== false && (_jsx(Button, { variant: "outline", size: "lg", onClick: handleWishlistClick, disabled: isWishlistLoading || !product, className: cn("h-14 w-14 rounded-full border-2 transition-all disabled:opacity-50 disabled:cursor-not-allowed", product && isInWishlist(product.id)
453
512
  ? "border-red-500 bg-red-50 text-red-500 hover:bg-red-100"
454
- : "border-gray-200 hover:border-gray-300 hover:bg-gray-50"), children: isWishlistLoading ? (_jsx(ButtonLoader, { className: "h-5 w-5" })) : (_jsx(Heart, { className: cn("h-5 w-5", product && isInWishlist(product.id) && "fill-current") })) }))] })] }), _jsx(ProductDeliveryInfoSection, { storeConfig: storeConfig, currency: currency, productCurrency: product.currency, productPrice: displayPrice, quantity: quantity, shippingAddress: shippingAddress, updateShippingAddress: updateShippingAddress, shippingMethods: shippingMethods, isCalculatingShipping: isCalculatingShipping, shippingError: shippingError, freeShippingEligible: freeShippingEligible, freeShippingThreshold: freeShippingThreshold, onToast: (message, type) => addToast(message, type) }), _jsx(ProductDescription, { description: product.description }), product.specifications && Object.keys(product.specifications).length > 0 && (_jsxs("div", { className: "mb-8", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900 mb-4", children: "Specifications" }), _jsx("dl", { className: "grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-4", children: Object.entries(product.specifications).map(([key, value]) => (_jsxs("div", { className: "flex flex-col p-3 bg-gray-50 rounded-lg", children: [_jsx("dt", { className: "text-xs text-gray-500 font-medium uppercase tracking-wider mb-1", children: key }), _jsx("dd", { className: "text-sm font-bold text-gray-900", children: value })] }, key))) })] }))] })] }), productDetailConfig?.showReviews !== false && (_jsx("div", { className: "mt-20 pt-16 border-t border-gray-200", children: _jsxs("div", { className: "max-w-4xl", children: [_jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-6 mb-10", children: [_jsxs("div", { className: "flex-1", children: [_jsx("h2", { className: "text-2xl lg:text-3xl font-bold text-gray-900 mb-4", children: "Customer Reviews" }), product.reviewCount && product.reviewCount > 0 && product.rating && product.rating > 0 ? (_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(StarRating, { rating: typeof product.rating === 'number' ? product.rating : Number(product.rating) || 0, size: "lg" }), _jsx("span", { className: "text-2xl font-bold text-gray-900", children: Number(product.rating).toFixed(1) }), _jsx("span", { className: "text-lg text-gray-500", children: "out of 5" })] }), _jsx("span", { className: "text-gray-300", children: "|" }), _jsxs("span", { className: "text-lg text-gray-600", children: [product.reviewCount, " ", product.reviewCount === 1 ? 'review' : 'reviews'] })] })) : (_jsx("div", { className: "text-gray-500", children: _jsx("p", { className: "text-base", children: "Be the first to review this product" }) }))] }), _jsx(Button, { onClick: () => setIsReviewModalOpen(true), className: "rounded-full shrink-0 bg-gray-900 hover:bg-gray-800 text-white", children: product.reviewCount && product.reviewCount > 0 ? 'Write a Review' : 'Be the First to Review' })] }), ratingDistribution.some(r => r.count > 0) && (_jsxs("div", { className: "mb-10 p-6 bg-gray-50 rounded-xl border border-gray-100", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-5", children: "Rating Breakdown" }), _jsx("div", { className: "space-y-3", children: ratingDistribution.map(({ rating, count, percentage }) => (_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-1.5 w-20", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: rating }), _jsx(Star, { className: "h-4 w-4 fill-gray-900 text-gray-900" })] }), _jsx("div", { className: "flex-1 h-2.5 bg-gray-200 rounded-full overflow-hidden", children: _jsx("div", { className: "h-full bg-gradient-to-r from-gray-700 to-gray-900 rounded-full transition-all duration-500", style: { width: `${percentage}%` } }) }), _jsx("span", { className: "text-sm font-medium text-gray-700 w-12 text-right", children: count })] }, rating))) })] })), reviews.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "space-y-6", children: displayedReviews.map((review) => (_jsx(ReviewCard, { review: review }, review.id))) }), hasMoreReviews && !showAllReviews && (_jsx("div", { className: "mt-8 text-center", children: _jsxs(Button, { variant: "outline", onClick: () => setShowAllReviews(true), className: "px-8 rounded-full h-12 border-gray-300", children: ["Show All ", reviews.length, " Reviews"] }) }))] })) : (_jsxs("div", { className: "text-center py-12 bg-gray-50 rounded-xl border border-dashed border-gray-300", children: [_jsx("div", { className: "inline-flex items-center justify-center w-12 h-12 rounded-full bg-white shadow-sm mb-4", children: _jsx(Star, { className: "h-6 w-6 text-gray-400" }) }), _jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: "No Reviews Yet" }), _jsx("p", { className: "text-gray-500 max-w-sm mx-auto mb-6", children: "Be the first to review this product and help other customers make informed decisions." }), _jsx(Button, { onClick: () => setIsReviewModalOpen(true), className: "bg-gray-900 hover:bg-gray-800 text-white", children: "Write the First Review" })] }))] }) })), productDetailConfig?.showRelatedProducts !== false && relatedProducts.length > 0 && (_jsxs("div", { "data-section": "relatedProducts", "data-payaza-section-key": "relatedProducts", "data-payaza-page": "productDetail", className: "mt-20 pt-16 border-t border-gray-200", children: [_jsx("h2", { className: "text-2xl lg:text-3xl font-bold text-gray-900 mb-8", children: "You Might Also Like" }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6", children: relatedProducts.map((relatedProduct) => (_jsx("div", { className: "h-[400px]", children: _jsx(ProductCard, { product: relatedProduct, storeSlug: storeConfig.slug, onAddToCart: (p) => addToCart(p, 1), onQuickView: handleQuickView, className: "h-full" }) }, relatedProduct.id))) })] }))] }), _jsx(Modal, { isOpen: isReviewModalOpen, onClose: () => setIsReviewModalOpen(false), title: "Write a Review", children: _jsxs("form", { onSubmit: handleSubmitReview, className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Rating" }), _jsxs("div", { className: "flex items-center gap-1", children: [[1, 2, 3, 4, 5].map((star) => (_jsxs("div", { className: "relative group", children: [_jsx("button", { type: "button", onClick: () => setNewReview({ ...newReview, rating: star - 0.5 }), className: "absolute top-0 left-0 w-1/2 h-full z-20 focus:outline-none", title: `${star - 0.5} stars` }), _jsx("button", { type: "button", onClick: () => setNewReview({ ...newReview, rating: star }), className: "absolute top-0 right-0 w-1/2 h-full z-20 focus:outline-none", title: `${star} stars` }), _jsxs("div", { className: "relative pointer-events-none transition-transform group-hover:scale-110", children: [_jsx(Star, { className: "h-8 w-8 text-gray-200 fill-gray-200" }), newReview.rating >= star - 0.5 && (_jsx("div", { className: "absolute inset-0 overflow-hidden", style: { width: newReview.rating === star - 0.5 ? '50%' : '100%' }, children: _jsx(Star, { className: "h-8 w-8 text-gray-900 fill-gray-900" }) }))] })] }, star))), _jsx("span", { className: "ml-3 text-lg font-medium text-gray-900 w-12", children: newReview.rating })] })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "title", className: "block text-sm font-medium text-gray-700 mb-1", children: "Review Title" }), _jsx("input", { type: "text", id: "title", required: true, className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-black", placeholder: "Summarize your thoughts", value: newReview.title, onChange: (e) => setNewReview({ ...newReview, title: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "comment", className: "block text-sm font-medium text-gray-700 mb-1", children: "Review" }), _jsx("textarea", { id: "comment", required: true, rows: 4, className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-black", placeholder: "What did you like or dislike?", value: newReview.comment, onChange: (e) => setNewReview({ ...newReview, comment: e.target.value }) })] }), _jsxs("div", { className: "pt-4 flex justify-end gap-3", children: [_jsx(Button, { type: "button", variant: "outline", onClick: () => setIsReviewModalOpen(false), children: "Cancel" }), _jsx(Button, { type: "submit", className: "bg-black text-white hover:bg-gray-800", children: "Submit Review" })] })] }) }), _jsx(GuestCheckoutModal, { isOpen: showGuestModal, onClose: () => setShowGuestModal(false), onSubmit: handleGuestInfoSubmit, initialData: getGuestUserInfo() || undefined })] }));
513
+ : "border-gray-200 hover:border-gray-300 hover:bg-gray-50"), children: isWishlistLoading ? (_jsx(ButtonLoader, { className: "h-5 w-5" })) : (_jsx(Heart, { className: cn("h-5 w-5", product && isInWishlist(product.id) && "fill-current") })) }))] })] }), _jsx(ProductDeliveryInfoSection, { storeConfig: storeConfig, currency: storeConfig.settings?.currency || 'USD', productCurrency: product.currency, productPrice: product.price, quantity: quantity, shippingAddress: shippingAddress, updateShippingAddress: (patch) => setShippingAddress((prev) => ({ ...prev, ...patch })), shippingMethods: shippingMethods, isCalculatingShipping: isCalculatingShipping, shippingError: shippingError, freeShippingEligible: freeShippingEligible, freeShippingThreshold: freeShippingThreshold, onToast: addToast }), product.description && (_jsxs("div", { className: "mb-8", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900 mb-3", children: "Description" }), _jsxs("div", { className: "prose prose-sm max-w-none text-gray-600 leading-relaxed", children: [_jsx("p", { children: product.description }), _jsxs("ul", { className: "list-disc pl-5 space-y-1 mt-2", children: [_jsx("li", { children: "Premium quality material" }), _jsx("li", { children: "Comfortable fit for all-day wear" }), _jsx("li", { children: "Durable stitching and finish" })] })] })] })), product.specifications && Object.keys(product.specifications).length > 0 && (_jsxs("div", { className: "mb-8", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900 mb-4", children: "Specifications" }), _jsx("dl", { className: "grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-4", children: Object.entries(product.specifications).map(([key, value]) => (_jsxs("div", { className: "flex flex-col p-3 bg-gray-50 rounded-lg", children: [_jsx("dt", { className: "text-xs text-gray-500 font-medium uppercase tracking-wider mb-1", children: key }), _jsx("dd", { className: "text-sm font-bold text-gray-900", children: value })] }, key))) })] }))] })] }), productDetailConfig?.showReviews !== false && (_jsx("div", { className: "mt-20 pt-16 border-t border-gray-200", children: _jsxs("div", { className: "max-w-4xl", children: [_jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-6 mb-10", children: [_jsxs("div", { className: "flex-1", children: [_jsx("h2", { className: "text-2xl lg:text-3xl font-bold text-gray-900 mb-4", children: "Customer Reviews" }), product.reviewCount && product.reviewCount > 0 && product.rating && product.rating > 0 ? (_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(StarRating, { rating: typeof product.rating === 'number' ? product.rating : Number(product.rating) || 0, size: "lg" }), _jsx("span", { className: "text-2xl font-bold text-gray-900", children: Number(product.rating).toFixed(1) }), _jsx("span", { className: "text-lg text-gray-500", children: "out of 5" })] }), _jsx("span", { className: "text-gray-300", children: "|" }), _jsxs("span", { className: "text-lg text-gray-600", children: [product.reviewCount, " ", product.reviewCount === 1 ? 'review' : 'reviews'] })] })) : (_jsx("div", { className: "text-gray-500", children: _jsx("p", { className: "text-base", children: "Be the first to review this product" }) }))] }), _jsx(Button, { onClick: () => setIsReviewModalOpen(true), className: "rounded-full shrink-0 bg-gray-900 hover:bg-gray-800 text-white", children: product.reviewCount && product.reviewCount > 0 ? 'Write a Review' : 'Be the First to Review' })] }), ratingDistribution.some(r => r.count > 0) && (_jsxs("div", { className: "mb-10 p-6 bg-gray-50 rounded-xl border border-gray-100", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-5", children: "Rating Breakdown" }), _jsx("div", { className: "space-y-3", children: ratingDistribution.map(({ rating, count, percentage }) => (_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-1.5 w-20", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: rating }), _jsx(Star, { className: "h-4 w-4 fill-gray-900 text-gray-900" })] }), _jsx("div", { className: "flex-1 h-2.5 bg-gray-200 rounded-full overflow-hidden", children: _jsx("div", { className: "h-full bg-gradient-to-r from-gray-700 to-gray-900 rounded-full transition-all duration-500", style: { width: `${percentage}%` } }) }), _jsx("span", { className: "text-sm font-medium text-gray-700 w-12 text-right", children: count })] }, rating))) })] })), reviews.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "space-y-6", children: displayedReviews.map((review) => (_jsx(ReviewCard, { review: review }, review.id))) }), hasMoreReviews && !showAllReviews && (_jsx("div", { className: "mt-8 text-center", children: _jsxs(Button, { variant: "outline", onClick: () => setShowAllReviews(true), className: "px-8 rounded-full h-12 border-gray-300", children: ["Show All ", reviews.length, " Reviews"] }) }))] })) : (_jsxs("div", { className: "text-center py-12 bg-gray-50 rounded-xl border border-dashed border-gray-300", children: [_jsx("div", { className: "inline-flex items-center justify-center w-12 h-12 rounded-full bg-white shadow-sm mb-4", children: _jsx(Star, { className: "h-6 w-6 text-gray-400" }) }), _jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: "No Reviews Yet" }), _jsx("p", { className: "text-gray-500 max-w-sm mx-auto mb-6", children: "Be the first to review this product and help other customers make informed decisions." }), _jsx(Button, { onClick: () => setIsReviewModalOpen(true), className: "bg-gray-900 hover:bg-gray-800 text-white", children: "Write the First Review" })] }))] }) })), productDetailConfig?.showRelatedProducts !== false && relatedProducts.length > 0 && (_jsxs("div", { className: "mt-20 pt-16 border-t border-gray-200", children: [_jsx("h2", { className: "text-2xl lg:text-3xl font-bold text-gray-900 mb-8", children: "You Might Also Like" }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6", children: relatedProducts.map((relatedProduct) => (_jsx("div", { className: "h-[400px]", children: _jsx(ProductCard, { product: relatedProduct, storeSlug: storeConfig.slug, onAddToCart: (p) => addToCart(p, 1), onQuickView: handleQuickView, className: "h-full" }) }, relatedProduct.id))) })] }))] }), _jsx(Modal, { isOpen: isReviewModalOpen, onClose: () => setIsReviewModalOpen(false), title: "Write a Review", children: _jsxs("form", { onSubmit: handleSubmitReview, className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Rating" }), _jsxs("div", { className: "flex items-center gap-1", children: [[1, 2, 3, 4, 5].map((star) => (_jsxs("div", { className: "relative group", children: [_jsx("button", { type: "button", onClick: () => setNewReview({ ...newReview, rating: star - 0.5 }), className: "absolute top-0 left-0 w-1/2 h-full z-20 focus:outline-none", title: `${star - 0.5} stars` }), _jsx("button", { type: "button", onClick: () => setNewReview({ ...newReview, rating: star }), className: "absolute top-0 right-0 w-1/2 h-full z-20 focus:outline-none", title: `${star} stars` }), _jsxs("div", { className: "relative pointer-events-none transition-transform group-hover:scale-110", children: [_jsx(Star, { className: "h-8 w-8 text-gray-200 fill-gray-200" }), newReview.rating >= star - 0.5 && (_jsx("div", { className: "absolute inset-0 overflow-hidden", style: { width: newReview.rating === star - 0.5 ? '50%' : '100%' }, children: _jsx(Star, { className: "h-8 w-8 text-gray-900 fill-gray-900" }) }))] })] }, star))), _jsx("span", { className: "ml-3 text-lg font-medium text-gray-900 w-12", children: newReview.rating })] })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "title", className: "block text-sm font-medium text-gray-700 mb-1", children: "Review Title" }), _jsx("input", { type: "text", id: "title", required: true, className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-black", placeholder: "Summarize your thoughts", value: newReview.title, onChange: (e) => setNewReview({ ...newReview, title: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "comment", className: "block text-sm font-medium text-gray-700 mb-1", children: "Review" }), _jsx("textarea", { id: "comment", required: true, rows: 4, className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-black", placeholder: "What did you like or dislike?", value: newReview.comment, onChange: (e) => setNewReview({ ...newReview, comment: e.target.value }) })] }), _jsxs("div", { className: "pt-4 flex justify-end gap-3", children: [_jsx(Button, { type: "button", variant: "outline", onClick: () => setIsReviewModalOpen(false), children: "Cancel" }), _jsx(Button, { type: "submit", className: "bg-black text-white hover:bg-gray-800", children: "Submit Review" })] })] }) }), _jsx(GuestCheckoutModal, { isOpen: showGuestModal, onClose: () => setShowGuestModal(false), onSubmit: handleGuestInfoSubmit, initialData: getGuestUserInfo() || undefined })] }));
455
514
  }
@@ -2,6 +2,6 @@ import { StoreConfig } from '../../../lib/store-types';
2
2
  interface ProductsPageProps {
3
3
  storeConfig: StoreConfig;
4
4
  }
5
- export declare function ClothingMinimalProductsPage(props: ProductsPageProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare function ProductsPage(props: ProductsPageProps): import("react/jsx-runtime").JSX.Element;
6
6
  export {};
7
7
  //# sourceMappingURL=ProductsPage.d.ts.map