payaza-storefront-layouts 1.0.0

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 (629) hide show
  1. package/README.md +108 -0
  2. package/dist/components/learning/CertificateTemplates.d.ts +25 -0
  3. package/dist/components/learning/CertificateTemplates.d.ts.map +1 -0
  4. package/dist/components/learning/CertificateTemplates.js +31 -0
  5. package/dist/components/learning/CertificateViewer.d.ts +11 -0
  6. package/dist/components/learning/CertificateViewer.d.ts.map +1 -0
  7. package/dist/components/learning/CertificateViewer.js +114 -0
  8. package/dist/components/learning/MentorshipProgress.d.ts +18 -0
  9. package/dist/components/learning/MentorshipProgress.d.ts.map +1 -0
  10. package/dist/components/learning/MentorshipProgress.js +19 -0
  11. package/dist/components/ui/address-selector.d.ts +11 -0
  12. package/dist/components/ui/address-selector.d.ts.map +1 -0
  13. package/dist/components/ui/address-selector.js +21 -0
  14. package/dist/components/ui/avatar-image.d.ts +11 -0
  15. package/dist/components/ui/avatar-image.d.ts.map +1 -0
  16. package/dist/components/ui/avatar-image.js +39 -0
  17. package/dist/components/ui/background-patterns.d.ts +27 -0
  18. package/dist/components/ui/background-patterns.d.ts.map +1 -0
  19. package/dist/components/ui/background-patterns.js +5 -0
  20. package/dist/components/ui/badge.d.ts +10 -0
  21. package/dist/components/ui/badge.d.ts.map +1 -0
  22. package/dist/components/ui/badge.js +20 -0
  23. package/dist/components/ui/breadcrumbs.d.ts +11 -0
  24. package/dist/components/ui/breadcrumbs.d.ts.map +1 -0
  25. package/dist/components/ui/breadcrumbs.js +8 -0
  26. package/dist/components/ui/button.d.ts +11 -0
  27. package/dist/components/ui/button.d.ts.map +1 -0
  28. package/dist/components/ui/button.js +33 -0
  29. package/dist/components/ui/card.d.ts +10 -0
  30. package/dist/components/ui/card.d.ts.map +1 -0
  31. package/dist/components/ui/card.js +24 -0
  32. package/dist/components/ui/category-tree.d.ts +16 -0
  33. package/dist/components/ui/category-tree.d.ts.map +1 -0
  34. package/dist/components/ui/category-tree.js +74 -0
  35. package/dist/components/ui/checkout-button.d.ts +11 -0
  36. package/dist/components/ui/checkout-button.d.ts.map +1 -0
  37. package/dist/components/ui/checkout-button.js +174 -0
  38. package/dist/components/ui/guest-checkout-modal.d.ts +19 -0
  39. package/dist/components/ui/guest-checkout-modal.d.ts.map +1 -0
  40. package/dist/components/ui/guest-checkout-modal.js +92 -0
  41. package/dist/components/ui/image-skeleton.d.ts +7 -0
  42. package/dist/components/ui/image-skeleton.d.ts.map +1 -0
  43. package/dist/components/ui/image-skeleton.js +15 -0
  44. package/dist/components/ui/image-with-fallback.d.ts +9 -0
  45. package/dist/components/ui/image-with-fallback.d.ts.map +1 -0
  46. package/dist/components/ui/image-with-fallback.js +203 -0
  47. package/dist/components/ui/input.d.ts +6 -0
  48. package/dist/components/ui/input.d.ts.map +1 -0
  49. package/dist/components/ui/input.js +8 -0
  50. package/dist/components/ui/loading-skeleton-wrapper.d.ts +6 -0
  51. package/dist/components/ui/loading-skeleton-wrapper.d.ts.map +1 -0
  52. package/dist/components/ui/loading-skeleton-wrapper.js +10 -0
  53. package/dist/components/ui/modal.d.ts +11 -0
  54. package/dist/components/ui/modal.d.ts.map +1 -0
  55. package/dist/components/ui/modal.js +26 -0
  56. package/dist/components/ui/otp-input.d.ts +10 -0
  57. package/dist/components/ui/otp-input.d.ts.map +1 -0
  58. package/dist/components/ui/otp-input.js +57 -0
  59. package/dist/components/ui/out-of-stock-overlay.d.ts +8 -0
  60. package/dist/components/ui/out-of-stock-overlay.d.ts.map +1 -0
  61. package/dist/components/ui/out-of-stock-overlay.js +12 -0
  62. package/dist/components/ui/page-animate-wrapper.d.ts +7 -0
  63. package/dist/components/ui/page-animate-wrapper.d.ts.map +1 -0
  64. package/dist/components/ui/page-animate-wrapper.js +16 -0
  65. package/dist/components/ui/page-content-loader.d.ts +13 -0
  66. package/dist/components/ui/page-content-loader.d.ts.map +1 -0
  67. package/dist/components/ui/page-content-loader.js +12 -0
  68. package/dist/components/ui/page-loader.d.ts +20 -0
  69. package/dist/components/ui/page-loader.d.ts.map +1 -0
  70. package/dist/components/ui/page-loader.js +31 -0
  71. package/dist/components/ui/product-card.d.ts +11 -0
  72. package/dist/components/ui/product-card.d.ts.map +1 -0
  73. package/dist/components/ui/product-card.js +95 -0
  74. package/dist/components/ui/product-rating.d.ts +17 -0
  75. package/dist/components/ui/product-rating.d.ts.map +1 -0
  76. package/dist/components/ui/product-rating.js +54 -0
  77. package/dist/components/ui/review-form.d.ts +9 -0
  78. package/dist/components/ui/review-form.d.ts.map +1 -0
  79. package/dist/components/ui/review-form.js +28 -0
  80. package/dist/components/ui/route-skeleton-loader.d.ts +7 -0
  81. package/dist/components/ui/route-skeleton-loader.d.ts.map +1 -0
  82. package/dist/components/ui/route-skeleton-loader.js +75 -0
  83. package/dist/components/ui/sheet.d.ts +12 -0
  84. package/dist/components/ui/sheet.d.ts.map +1 -0
  85. package/dist/components/ui/sheet.js +29 -0
  86. package/dist/components/ui/skeleton.d.ts +3 -0
  87. package/dist/components/ui/skeleton.d.ts.map +1 -0
  88. package/dist/components/ui/skeleton.js +6 -0
  89. package/dist/components/ui/skeletons/category-grid-skeleton.d.ts +6 -0
  90. package/dist/components/ui/skeletons/category-grid-skeleton.d.ts.map +1 -0
  91. package/dist/components/ui/skeletons/category-grid-skeleton.js +16 -0
  92. package/dist/components/ui/skeletons/checkout-skeleton.d.ts +2 -0
  93. package/dist/components/ui/skeletons/checkout-skeleton.d.ts.map +1 -0
  94. package/dist/components/ui/skeletons/checkout-skeleton.js +4 -0
  95. package/dist/components/ui/skeletons/index.d.ts +6 -0
  96. package/dist/components/ui/skeletons/index.d.ts.map +1 -0
  97. package/dist/components/ui/skeletons/index.js +5 -0
  98. package/dist/components/ui/skeletons/page-skeleton.d.ts +2 -0
  99. package/dist/components/ui/skeletons/page-skeleton.d.ts.map +1 -0
  100. package/dist/components/ui/skeletons/page-skeleton.js +4 -0
  101. package/dist/components/ui/skeletons/product-card-skeleton.d.ts +2 -0
  102. package/dist/components/ui/skeletons/product-card-skeleton.d.ts.map +1 -0
  103. package/dist/components/ui/skeletons/product-card-skeleton.js +4 -0
  104. package/dist/components/ui/skeletons/product-detail-skeleton.d.ts +2 -0
  105. package/dist/components/ui/skeletons/product-detail-skeleton.d.ts.map +1 -0
  106. package/dist/components/ui/skeletons/product-detail-skeleton.js +4 -0
  107. package/dist/components/ui/skeletons/product-grid-skeleton.d.ts +7 -0
  108. package/dist/components/ui/skeletons/product-grid-skeleton.d.ts.map +1 -0
  109. package/dist/components/ui/skeletons/product-grid-skeleton.js +12 -0
  110. package/dist/components/ui/store-logos.d.ts +43 -0
  111. package/dist/components/ui/store-logos.d.ts.map +1 -0
  112. package/dist/components/ui/store-logos.js +83 -0
  113. package/dist/components/ui/toast.d.ts +19 -0
  114. package/dist/components/ui/toast.d.ts.map +1 -0
  115. package/dist/components/ui/toast.js +33 -0
  116. package/dist/components/ui/video-player.d.ts +48 -0
  117. package/dist/components/ui/video-player.d.ts.map +1 -0
  118. package/dist/components/ui/video-player.js +96 -0
  119. package/dist/hooks/use-analytics.d.ts +14 -0
  120. package/dist/hooks/use-analytics.d.ts.map +1 -0
  121. package/dist/hooks/use-analytics.js +66 -0
  122. package/dist/hooks/use-api.d.ts +17 -0
  123. package/dist/hooks/use-api.d.ts.map +1 -0
  124. package/dist/hooks/use-api.js +53 -0
  125. package/dist/hooks/use-cart-api.d.ts +17 -0
  126. package/dist/hooks/use-cart-api.d.ts.map +1 -0
  127. package/dist/hooks/use-cart-api.js +134 -0
  128. package/dist/hooks/use-content-ready.d.ts +17 -0
  129. package/dist/hooks/use-content-ready.d.ts.map +1 -0
  130. package/dist/hooks/use-content-ready.js +197 -0
  131. package/dist/hooks/use-navigation-loading.d.ts +4 -0
  132. package/dist/hooks/use-navigation-loading.d.ts.map +1 -0
  133. package/dist/hooks/use-navigation-loading.js +14 -0
  134. package/dist/hooks/use-payaza-checkout.d.ts +14 -0
  135. package/dist/hooks/use-payaza-checkout.d.ts.map +1 -0
  136. package/dist/hooks/use-payaza-checkout.js +56 -0
  137. package/dist/hooks/use-products-api.d.ts +19 -0
  138. package/dist/hooks/use-products-api.d.ts.map +1 -0
  139. package/dist/hooks/use-products-api.js +84 -0
  140. package/dist/hooks/use-store-api.d.ts +12 -0
  141. package/dist/hooks/use-store-api.d.ts.map +1 -0
  142. package/dist/hooks/use-store-api.js +73 -0
  143. package/dist/index.d.ts +116 -0
  144. package/dist/index.d.ts.map +1 -0
  145. package/dist/index.js +126 -0
  146. package/dist/json/booking-agenda.json +18 -0
  147. package/dist/json/booking.json +71 -0
  148. package/dist/json/clothing-minimal.json +26 -0
  149. package/dist/json/clothing.json +169 -0
  150. package/dist/json/electronics-grid.json +18 -0
  151. package/dist/json/electronics.json +50 -0
  152. package/dist/json/food-modern.json +38 -0
  153. package/dist/json/food.json +85 -0
  154. package/dist/json/json-map.d.ts +7 -0
  155. package/dist/json/json-map.d.ts.map +1 -0
  156. package/dist/json/json-map.js +36 -0
  157. package/dist/json/motivational-speaker.json +96 -0
  158. package/dist/layouts/booking/components/BookingHomePage.d.ts +7 -0
  159. package/dist/layouts/booking/components/BookingHomePage.d.ts.map +1 -0
  160. package/dist/layouts/booking/components/BookingHomePage.js +49 -0
  161. package/dist/layouts/booking/index.d.ts +9 -0
  162. package/dist/layouts/booking/index.d.ts.map +1 -0
  163. package/dist/layouts/booking/index.js +9 -0
  164. package/dist/layouts/booking/pages/AboutPage.d.ts +7 -0
  165. package/dist/layouts/booking/pages/AboutPage.d.ts.map +1 -0
  166. package/dist/layouts/booking/pages/AboutPage.js +45 -0
  167. package/dist/layouts/booking/pages/BookPage.d.ts +8 -0
  168. package/dist/layouts/booking/pages/BookPage.d.ts.map +1 -0
  169. package/dist/layouts/booking/pages/BookPage.js +441 -0
  170. package/dist/layouts/booking/pages/CategoriesPage.d.ts +7 -0
  171. package/dist/layouts/booking/pages/CategoriesPage.d.ts.map +1 -0
  172. package/dist/layouts/booking/pages/CategoriesPage.js +162 -0
  173. package/dist/layouts/booking/pages/CategoryPage.d.ts +8 -0
  174. package/dist/layouts/booking/pages/CategoryPage.d.ts.map +1 -0
  175. package/dist/layouts/booking/pages/CategoryPage.js +67 -0
  176. package/dist/layouts/booking/pages/ContactPage.d.ts +7 -0
  177. package/dist/layouts/booking/pages/ContactPage.d.ts.map +1 -0
  178. package/dist/layouts/booking/pages/ContactPage.js +20 -0
  179. package/dist/layouts/booking/pages/ProductDetailPage.d.ts +8 -0
  180. package/dist/layouts/booking/pages/ProductDetailPage.d.ts.map +1 -0
  181. package/dist/layouts/booking/pages/ProductDetailPage.js +502 -0
  182. package/dist/layouts/booking/pages/ServicesPage.d.ts +9 -0
  183. package/dist/layouts/booking/pages/ServicesPage.d.ts.map +1 -0
  184. package/dist/layouts/booking/pages/ServicesPage.js +31 -0
  185. package/dist/layouts/booking-agenda/components/BookingHomePageAgenda.d.ts +7 -0
  186. package/dist/layouts/booking-agenda/components/BookingHomePageAgenda.d.ts.map +1 -0
  187. package/dist/layouts/booking-agenda/components/BookingHomePageAgenda.js +186 -0
  188. package/dist/layouts/booking-agenda/index.d.ts +9 -0
  189. package/dist/layouts/booking-agenda/index.d.ts.map +1 -0
  190. package/dist/layouts/booking-agenda/index.js +9 -0
  191. package/dist/layouts/booking-agenda/pages/AboutPage.d.ts +7 -0
  192. package/dist/layouts/booking-agenda/pages/AboutPage.d.ts.map +1 -0
  193. package/dist/layouts/booking-agenda/pages/AboutPage.js +45 -0
  194. package/dist/layouts/booking-agenda/pages/BookPage.d.ts +8 -0
  195. package/dist/layouts/booking-agenda/pages/BookPage.d.ts.map +1 -0
  196. package/dist/layouts/booking-agenda/pages/BookPage.js +441 -0
  197. package/dist/layouts/booking-agenda/pages/CategoriesPage.d.ts +7 -0
  198. package/dist/layouts/booking-agenda/pages/CategoriesPage.d.ts.map +1 -0
  199. package/dist/layouts/booking-agenda/pages/CategoriesPage.js +162 -0
  200. package/dist/layouts/booking-agenda/pages/CategoryPage.d.ts +8 -0
  201. package/dist/layouts/booking-agenda/pages/CategoryPage.d.ts.map +1 -0
  202. package/dist/layouts/booking-agenda/pages/CategoryPage.js +67 -0
  203. package/dist/layouts/booking-agenda/pages/ContactPage.d.ts +7 -0
  204. package/dist/layouts/booking-agenda/pages/ContactPage.d.ts.map +1 -0
  205. package/dist/layouts/booking-agenda/pages/ContactPage.js +20 -0
  206. package/dist/layouts/booking-agenda/pages/ProductDetailPage.d.ts +8 -0
  207. package/dist/layouts/booking-agenda/pages/ProductDetailPage.d.ts.map +1 -0
  208. package/dist/layouts/booking-agenda/pages/ProductDetailPage.js +502 -0
  209. package/dist/layouts/booking-agenda/pages/ServicesPage.d.ts +9 -0
  210. package/dist/layouts/booking-agenda/pages/ServicesPage.d.ts.map +1 -0
  211. package/dist/layouts/booking-agenda/pages/ServicesPage.js +31 -0
  212. package/dist/layouts/clothing/components/ClothingHomePage.d.ts +7 -0
  213. package/dist/layouts/clothing/components/ClothingHomePage.d.ts.map +1 -0
  214. package/dist/layouts/clothing/components/ClothingHomePage.js +295 -0
  215. package/dist/layouts/clothing/index.d.ts +8 -0
  216. package/dist/layouts/clothing/index.d.ts.map +1 -0
  217. package/dist/layouts/clothing/index.js +8 -0
  218. package/dist/layouts/clothing/pages/AboutPage.d.ts +7 -0
  219. package/dist/layouts/clothing/pages/AboutPage.d.ts.map +1 -0
  220. package/dist/layouts/clothing/pages/AboutPage.js +45 -0
  221. package/dist/layouts/clothing/pages/CategoriesPage.d.ts +7 -0
  222. package/dist/layouts/clothing/pages/CategoriesPage.d.ts.map +1 -0
  223. package/dist/layouts/clothing/pages/CategoriesPage.js +162 -0
  224. package/dist/layouts/clothing/pages/CategoryPage.d.ts +8 -0
  225. package/dist/layouts/clothing/pages/CategoryPage.d.ts.map +1 -0
  226. package/dist/layouts/clothing/pages/CategoryPage.js +67 -0
  227. package/dist/layouts/clothing/pages/ContactPage.d.ts +7 -0
  228. package/dist/layouts/clothing/pages/ContactPage.d.ts.map +1 -0
  229. package/dist/layouts/clothing/pages/ContactPage.js +20 -0
  230. package/dist/layouts/clothing/pages/ProductDetailPage.d.ts +8 -0
  231. package/dist/layouts/clothing/pages/ProductDetailPage.d.ts.map +1 -0
  232. package/dist/layouts/clothing/pages/ProductDetailPage.js +502 -0
  233. package/dist/layouts/clothing/pages/ProductsPage.d.ts +7 -0
  234. package/dist/layouts/clothing/pages/ProductsPage.d.ts.map +1 -0
  235. package/dist/layouts/clothing/pages/ProductsPage.js +297 -0
  236. package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.d.ts +7 -0
  237. package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.d.ts.map +1 -0
  238. package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.js +48 -0
  239. package/dist/layouts/clothing-minimal/index.d.ts +8 -0
  240. package/dist/layouts/clothing-minimal/index.d.ts.map +1 -0
  241. package/dist/layouts/clothing-minimal/index.js +8 -0
  242. package/dist/layouts/clothing-minimal/pages/AboutPage.d.ts +7 -0
  243. package/dist/layouts/clothing-minimal/pages/AboutPage.d.ts.map +1 -0
  244. package/dist/layouts/clothing-minimal/pages/AboutPage.js +45 -0
  245. package/dist/layouts/clothing-minimal/pages/CategoriesPage.d.ts +7 -0
  246. package/dist/layouts/clothing-minimal/pages/CategoriesPage.d.ts.map +1 -0
  247. package/dist/layouts/clothing-minimal/pages/CategoriesPage.js +162 -0
  248. package/dist/layouts/clothing-minimal/pages/CategoryPage.d.ts +8 -0
  249. package/dist/layouts/clothing-minimal/pages/CategoryPage.d.ts.map +1 -0
  250. package/dist/layouts/clothing-minimal/pages/CategoryPage.js +67 -0
  251. package/dist/layouts/clothing-minimal/pages/ContactPage.d.ts +7 -0
  252. package/dist/layouts/clothing-minimal/pages/ContactPage.d.ts.map +1 -0
  253. package/dist/layouts/clothing-minimal/pages/ContactPage.js +20 -0
  254. package/dist/layouts/clothing-minimal/pages/ProductDetailPage.d.ts +8 -0
  255. package/dist/layouts/clothing-minimal/pages/ProductDetailPage.d.ts.map +1 -0
  256. package/dist/layouts/clothing-minimal/pages/ProductDetailPage.js +502 -0
  257. package/dist/layouts/clothing-minimal/pages/ProductsPage.d.ts +7 -0
  258. package/dist/layouts/clothing-minimal/pages/ProductsPage.d.ts.map +1 -0
  259. package/dist/layouts/clothing-minimal/pages/ProductsPage.js +297 -0
  260. package/dist/layouts/electronics/components/ElectronicsCategoriesPage.d.ts +7 -0
  261. package/dist/layouts/electronics/components/ElectronicsCategoriesPage.d.ts.map +1 -0
  262. package/dist/layouts/electronics/components/ElectronicsCategoriesPage.js +34 -0
  263. package/dist/layouts/electronics/components/ElectronicsGridProductCard.d.ts +10 -0
  264. package/dist/layouts/electronics/components/ElectronicsGridProductCard.d.ts.map +1 -0
  265. package/dist/layouts/electronics/components/ElectronicsGridProductCard.js +107 -0
  266. package/dist/layouts/electronics/components/ElectronicsHomePage.d.ts +7 -0
  267. package/dist/layouts/electronics/components/ElectronicsHomePage.d.ts.map +1 -0
  268. package/dist/layouts/electronics/components/ElectronicsHomePage.js +78 -0
  269. package/dist/layouts/electronics/components/ElectronicsPageWrapper.d.ts +8 -0
  270. package/dist/layouts/electronics/components/ElectronicsPageWrapper.d.ts.map +1 -0
  271. package/dist/layouts/electronics/components/ElectronicsPageWrapper.js +10 -0
  272. package/dist/layouts/electronics/components/ElectronicsProductsPage.d.ts +7 -0
  273. package/dist/layouts/electronics/components/ElectronicsProductsPage.d.ts.map +1 -0
  274. package/dist/layouts/electronics/components/ElectronicsProductsPage.js +100 -0
  275. package/dist/layouts/electronics/components/ElectronicsStoreFooter.d.ts +7 -0
  276. package/dist/layouts/electronics/components/ElectronicsStoreFooter.d.ts.map +1 -0
  277. package/dist/layouts/electronics/components/ElectronicsStoreFooter.js +10 -0
  278. package/dist/layouts/electronics/components/ElectronicsStoreHeader.d.ts +7 -0
  279. package/dist/layouts/electronics/components/ElectronicsStoreHeader.d.ts.map +1 -0
  280. package/dist/layouts/electronics/components/ElectronicsStoreHeader.js +27 -0
  281. package/dist/layouts/electronics/index.d.ts +19 -0
  282. package/dist/layouts/electronics/index.d.ts.map +1 -0
  283. package/dist/layouts/electronics/index.js +19 -0
  284. package/dist/layouts/electronics/pages/AboutPage.d.ts +7 -0
  285. package/dist/layouts/electronics/pages/AboutPage.d.ts.map +1 -0
  286. package/dist/layouts/electronics/pages/AboutPage.js +45 -0
  287. package/dist/layouts/electronics/pages/CategoriesPage.d.ts +7 -0
  288. package/dist/layouts/electronics/pages/CategoriesPage.d.ts.map +1 -0
  289. package/dist/layouts/electronics/pages/CategoriesPage.js +6 -0
  290. package/dist/layouts/electronics/pages/CategoryPage.d.ts +8 -0
  291. package/dist/layouts/electronics/pages/CategoryPage.d.ts.map +1 -0
  292. package/dist/layouts/electronics/pages/CategoryPage.js +67 -0
  293. package/dist/layouts/electronics/pages/ContactPage.d.ts +7 -0
  294. package/dist/layouts/electronics/pages/ContactPage.d.ts.map +1 -0
  295. package/dist/layouts/electronics/pages/ContactPage.js +20 -0
  296. package/dist/layouts/electronics/pages/HelpCenterPage.d.ts +7 -0
  297. package/dist/layouts/electronics/pages/HelpCenterPage.d.ts.map +1 -0
  298. package/dist/layouts/electronics/pages/HelpCenterPage.js +55 -0
  299. package/dist/layouts/electronics/pages/PrivacyPolicyPage.d.ts +7 -0
  300. package/dist/layouts/electronics/pages/PrivacyPolicyPage.d.ts.map +1 -0
  301. package/dist/layouts/electronics/pages/PrivacyPolicyPage.js +8 -0
  302. package/dist/layouts/electronics/pages/ProductDetailPage.d.ts +8 -0
  303. package/dist/layouts/electronics/pages/ProductDetailPage.d.ts.map +1 -0
  304. package/dist/layouts/electronics/pages/ProductDetailPage.js +502 -0
  305. package/dist/layouts/electronics/pages/ProductsPage.d.ts +7 -0
  306. package/dist/layouts/electronics/pages/ProductsPage.d.ts.map +1 -0
  307. package/dist/layouts/electronics/pages/ProductsPage.js +297 -0
  308. package/dist/layouts/electronics/pages/ShippingReturnsPage.d.ts +7 -0
  309. package/dist/layouts/electronics/pages/ShippingReturnsPage.d.ts.map +1 -0
  310. package/dist/layouts/electronics/pages/ShippingReturnsPage.js +7 -0
  311. package/dist/layouts/electronics/pages/TermsPage.d.ts +7 -0
  312. package/dist/layouts/electronics/pages/TermsPage.d.ts.map +1 -0
  313. package/dist/layouts/electronics/pages/TermsPage.js +8 -0
  314. package/dist/layouts/electronics/pages/TrackOrderPage.d.ts +7 -0
  315. package/dist/layouts/electronics/pages/TrackOrderPage.d.ts.map +1 -0
  316. package/dist/layouts/electronics/pages/TrackOrderPage.js +371 -0
  317. package/dist/layouts/electronics-grid/components/ElectronicsGridProductCard.d.ts +10 -0
  318. package/dist/layouts/electronics-grid/components/ElectronicsGridProductCard.d.ts.map +1 -0
  319. package/dist/layouts/electronics-grid/components/ElectronicsGridProductCard.js +107 -0
  320. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.d.ts +7 -0
  321. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.d.ts.map +1 -0
  322. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.js +89 -0
  323. package/dist/layouts/electronics-grid/index.d.ts +15 -0
  324. package/dist/layouts/electronics-grid/index.d.ts.map +1 -0
  325. package/dist/layouts/electronics-grid/index.js +15 -0
  326. package/dist/layouts/electronics-grid/pages/AboutPage.d.ts +7 -0
  327. package/dist/layouts/electronics-grid/pages/AboutPage.d.ts.map +1 -0
  328. package/dist/layouts/electronics-grid/pages/AboutPage.js +45 -0
  329. package/dist/layouts/electronics-grid/pages/CategoriesPage.d.ts +7 -0
  330. package/dist/layouts/electronics-grid/pages/CategoriesPage.d.ts.map +1 -0
  331. package/dist/layouts/electronics-grid/pages/CategoriesPage.js +6 -0
  332. package/dist/layouts/electronics-grid/pages/CategoryPage.d.ts +8 -0
  333. package/dist/layouts/electronics-grid/pages/CategoryPage.d.ts.map +1 -0
  334. package/dist/layouts/electronics-grid/pages/CategoryPage.js +67 -0
  335. package/dist/layouts/electronics-grid/pages/ContactPage.d.ts +7 -0
  336. package/dist/layouts/electronics-grid/pages/ContactPage.d.ts.map +1 -0
  337. package/dist/layouts/electronics-grid/pages/ContactPage.js +20 -0
  338. package/dist/layouts/electronics-grid/pages/ElectronicsGridCategoriesPage.d.ts +7 -0
  339. package/dist/layouts/electronics-grid/pages/ElectronicsGridCategoriesPage.d.ts.map +1 -0
  340. package/dist/layouts/electronics-grid/pages/ElectronicsGridCategoriesPage.js +15 -0
  341. package/dist/layouts/electronics-grid/pages/HelpCenterPage.d.ts +7 -0
  342. package/dist/layouts/electronics-grid/pages/HelpCenterPage.d.ts.map +1 -0
  343. package/dist/layouts/electronics-grid/pages/HelpCenterPage.js +55 -0
  344. package/dist/layouts/electronics-grid/pages/PrivacyPolicyPage.d.ts +7 -0
  345. package/dist/layouts/electronics-grid/pages/PrivacyPolicyPage.d.ts.map +1 -0
  346. package/dist/layouts/electronics-grid/pages/PrivacyPolicyPage.js +8 -0
  347. package/dist/layouts/electronics-grid/pages/ProductDetailPage.d.ts +8 -0
  348. package/dist/layouts/electronics-grid/pages/ProductDetailPage.d.ts.map +1 -0
  349. package/dist/layouts/electronics-grid/pages/ProductDetailPage.js +502 -0
  350. package/dist/layouts/electronics-grid/pages/ProductsPage.d.ts +7 -0
  351. package/dist/layouts/electronics-grid/pages/ProductsPage.d.ts.map +1 -0
  352. package/dist/layouts/electronics-grid/pages/ProductsPage.js +297 -0
  353. package/dist/layouts/electronics-grid/pages/ShippingReturnsPage.d.ts +7 -0
  354. package/dist/layouts/electronics-grid/pages/ShippingReturnsPage.d.ts.map +1 -0
  355. package/dist/layouts/electronics-grid/pages/ShippingReturnsPage.js +7 -0
  356. package/dist/layouts/electronics-grid/pages/TermsPage.d.ts +7 -0
  357. package/dist/layouts/electronics-grid/pages/TermsPage.d.ts.map +1 -0
  358. package/dist/layouts/electronics-grid/pages/TermsPage.js +8 -0
  359. package/dist/layouts/electronics-grid/pages/TrackOrderPage.d.ts +7 -0
  360. package/dist/layouts/electronics-grid/pages/TrackOrderPage.d.ts.map +1 -0
  361. package/dist/layouts/electronics-grid/pages/TrackOrderPage.js +371 -0
  362. package/dist/layouts/food/components/FoodHomePage.d.ts +7 -0
  363. package/dist/layouts/food/components/FoodHomePage.d.ts.map +1 -0
  364. package/dist/layouts/food/components/FoodHomePage.js +304 -0
  365. package/dist/layouts/food/index.d.ts +9 -0
  366. package/dist/layouts/food/index.d.ts.map +1 -0
  367. package/dist/layouts/food/index.js +9 -0
  368. package/dist/layouts/food/pages/AboutPage.d.ts +7 -0
  369. package/dist/layouts/food/pages/AboutPage.d.ts.map +1 -0
  370. package/dist/layouts/food/pages/AboutPage.js +45 -0
  371. package/dist/layouts/food/pages/CategoriesPage.d.ts +7 -0
  372. package/dist/layouts/food/pages/CategoriesPage.d.ts.map +1 -0
  373. package/dist/layouts/food/pages/CategoriesPage.js +162 -0
  374. package/dist/layouts/food/pages/CategoryPage.d.ts +8 -0
  375. package/dist/layouts/food/pages/CategoryPage.d.ts.map +1 -0
  376. package/dist/layouts/food/pages/CategoryPage.js +67 -0
  377. package/dist/layouts/food/pages/ContactPage.d.ts +7 -0
  378. package/dist/layouts/food/pages/ContactPage.d.ts.map +1 -0
  379. package/dist/layouts/food/pages/ContactPage.js +20 -0
  380. package/dist/layouts/food/pages/MenuPage.d.ts +8 -0
  381. package/dist/layouts/food/pages/MenuPage.d.ts.map +1 -0
  382. package/dist/layouts/food/pages/MenuPage.js +75 -0
  383. package/dist/layouts/food/pages/ProductDetailPage.d.ts +8 -0
  384. package/dist/layouts/food/pages/ProductDetailPage.d.ts.map +1 -0
  385. package/dist/layouts/food/pages/ProductDetailPage.js +502 -0
  386. package/dist/layouts/food/pages/ProductsPage.d.ts +7 -0
  387. package/dist/layouts/food/pages/ProductsPage.d.ts.map +1 -0
  388. package/dist/layouts/food/pages/ProductsPage.js +297 -0
  389. package/dist/layouts/food-modern/components/FoodHomePageModern.d.ts +7 -0
  390. package/dist/layouts/food-modern/components/FoodHomePageModern.d.ts.map +1 -0
  391. package/dist/layouts/food-modern/components/FoodHomePageModern.js +118 -0
  392. package/dist/layouts/food-modern/index.d.ts +9 -0
  393. package/dist/layouts/food-modern/index.d.ts.map +1 -0
  394. package/dist/layouts/food-modern/index.js +9 -0
  395. package/dist/layouts/food-modern/pages/AboutPage.d.ts +7 -0
  396. package/dist/layouts/food-modern/pages/AboutPage.d.ts.map +1 -0
  397. package/dist/layouts/food-modern/pages/AboutPage.js +45 -0
  398. package/dist/layouts/food-modern/pages/CategoriesPage.d.ts +7 -0
  399. package/dist/layouts/food-modern/pages/CategoriesPage.d.ts.map +1 -0
  400. package/dist/layouts/food-modern/pages/CategoriesPage.js +162 -0
  401. package/dist/layouts/food-modern/pages/CategoryPage.d.ts +8 -0
  402. package/dist/layouts/food-modern/pages/CategoryPage.d.ts.map +1 -0
  403. package/dist/layouts/food-modern/pages/CategoryPage.js +67 -0
  404. package/dist/layouts/food-modern/pages/ContactPage.d.ts +7 -0
  405. package/dist/layouts/food-modern/pages/ContactPage.d.ts.map +1 -0
  406. package/dist/layouts/food-modern/pages/ContactPage.js +20 -0
  407. package/dist/layouts/food-modern/pages/MenuPage.d.ts +8 -0
  408. package/dist/layouts/food-modern/pages/MenuPage.d.ts.map +1 -0
  409. package/dist/layouts/food-modern/pages/MenuPage.js +75 -0
  410. package/dist/layouts/food-modern/pages/ProductDetailPage.d.ts +8 -0
  411. package/dist/layouts/food-modern/pages/ProductDetailPage.d.ts.map +1 -0
  412. package/dist/layouts/food-modern/pages/ProductDetailPage.js +502 -0
  413. package/dist/layouts/food-modern/pages/ProductsPage.d.ts +7 -0
  414. package/dist/layouts/food-modern/pages/ProductsPage.d.ts.map +1 -0
  415. package/dist/layouts/food-modern/pages/ProductsPage.js +297 -0
  416. package/dist/layouts/motivational-speaker/components/MotivationalHomePage.d.ts +7 -0
  417. package/dist/layouts/motivational-speaker/components/MotivationalHomePage.d.ts.map +1 -0
  418. package/dist/layouts/motivational-speaker/components/MotivationalHomePage.js +115 -0
  419. package/dist/layouts/motivational-speaker/components/MotivationalPageWrapper.d.ts +8 -0
  420. package/dist/layouts/motivational-speaker/components/MotivationalPageWrapper.d.ts.map +1 -0
  421. package/dist/layouts/motivational-speaker/components/MotivationalPageWrapper.js +10 -0
  422. package/dist/layouts/motivational-speaker/index.d.ts +10 -0
  423. package/dist/layouts/motivational-speaker/index.d.ts.map +1 -0
  424. package/dist/layouts/motivational-speaker/index.js +10 -0
  425. package/dist/layouts/motivational-speaker/pages/AboutPage.d.ts +7 -0
  426. package/dist/layouts/motivational-speaker/pages/AboutPage.d.ts.map +1 -0
  427. package/dist/layouts/motivational-speaker/pages/AboutPage.js +45 -0
  428. package/dist/layouts/motivational-speaker/pages/CategoryPage.d.ts +8 -0
  429. package/dist/layouts/motivational-speaker/pages/CategoryPage.d.ts.map +1 -0
  430. package/dist/layouts/motivational-speaker/pages/CategoryPage.js +67 -0
  431. package/dist/layouts/motivational-speaker/pages/ContactPage.d.ts +7 -0
  432. package/dist/layouts/motivational-speaker/pages/ContactPage.d.ts.map +1 -0
  433. package/dist/layouts/motivational-speaker/pages/ContactPage.js +20 -0
  434. package/dist/layouts/motivational-speaker/pages/ProductsPage.d.ts +7 -0
  435. package/dist/layouts/motivational-speaker/pages/ProductsPage.d.ts.map +1 -0
  436. package/dist/layouts/motivational-speaker/pages/ProductsPage.js +297 -0
  437. package/dist/layouts/motivational-speaker/pages/ServiceDetailPage.d.ts +8 -0
  438. package/dist/layouts/motivational-speaker/pages/ServiceDetailPage.d.ts.map +1 -0
  439. package/dist/layouts/motivational-speaker/pages/ServiceDetailPage.js +144 -0
  440. package/dist/layouts/motivational-speaker/pages/ServicesPage.d.ts +9 -0
  441. package/dist/layouts/motivational-speaker/pages/ServicesPage.d.ts.map +1 -0
  442. package/dist/layouts/motivational-speaker/pages/ServicesPage.js +31 -0
  443. package/dist/layouts/motivational-speaker/pages/SubscriptionPage.d.ts +7 -0
  444. package/dist/layouts/motivational-speaker/pages/SubscriptionPage.d.ts.map +1 -0
  445. package/dist/layouts/motivational-speaker/pages/SubscriptionPage.js +136 -0
  446. package/dist/layouts/shared/components/BaseStoreLayout.d.ts +8 -0
  447. package/dist/layouts/shared/components/BaseStoreLayout.d.ts.map +1 -0
  448. package/dist/layouts/shared/components/BaseStoreLayout.js +59 -0
  449. package/dist/layouts/shared/components/GenericPageWrapper.d.ts +8 -0
  450. package/dist/layouts/shared/components/GenericPageWrapper.d.ts.map +1 -0
  451. package/dist/layouts/shared/components/GenericPageWrapper.js +19 -0
  452. package/dist/layouts/shared/components/PromoBanner.d.ts +9 -0
  453. package/dist/layouts/shared/components/PromoBanner.d.ts.map +1 -0
  454. package/dist/layouts/shared/components/PromoBanner.js +14 -0
  455. package/dist/layouts/shared/components/StoreFooter.d.ts +7 -0
  456. package/dist/layouts/shared/components/StoreFooter.d.ts.map +1 -0
  457. package/dist/layouts/shared/components/StoreFooter.js +147 -0
  458. package/dist/layouts/shared/components/StoreHeader.d.ts +8 -0
  459. package/dist/layouts/shared/components/StoreHeader.d.ts.map +1 -0
  460. package/dist/layouts/shared/components/StoreHeader.js +87 -0
  461. package/dist/layouts/shared/components/TestimonialCard.d.ts +8 -0
  462. package/dist/layouts/shared/components/TestimonialCard.d.ts.map +1 -0
  463. package/dist/layouts/shared/components/TestimonialCard.js +10 -0
  464. package/dist/layouts/shared/index.d.ts +23 -0
  465. package/dist/layouts/shared/index.d.ts.map +1 -0
  466. package/dist/layouts/shared/index.js +23 -0
  467. package/dist/layouts/shared/pages/AccountPage.d.ts +7 -0
  468. package/dist/layouts/shared/pages/AccountPage.d.ts.map +1 -0
  469. package/dist/layouts/shared/pages/AccountPage.js +605 -0
  470. package/dist/layouts/shared/pages/CartPage.d.ts +7 -0
  471. package/dist/layouts/shared/pages/CartPage.d.ts.map +1 -0
  472. package/dist/layouts/shared/pages/CartPage.js +83 -0
  473. package/dist/layouts/shared/pages/CheckoutPage.d.ts +7 -0
  474. package/dist/layouts/shared/pages/CheckoutPage.d.ts.map +1 -0
  475. package/dist/layouts/shared/pages/CheckoutPage.js +860 -0
  476. package/dist/layouts/shared/pages/CookiePolicyPage.d.ts +7 -0
  477. package/dist/layouts/shared/pages/CookiePolicyPage.d.ts.map +1 -0
  478. package/dist/layouts/shared/pages/CookiePolicyPage.js +8 -0
  479. package/dist/layouts/shared/pages/FeatureDisabledPage.d.ts +9 -0
  480. package/dist/layouts/shared/pages/FeatureDisabledPage.d.ts.map +1 -0
  481. package/dist/layouts/shared/pages/FeatureDisabledPage.js +8 -0
  482. package/dist/layouts/shared/pages/HelpCenterPage.d.ts +7 -0
  483. package/dist/layouts/shared/pages/HelpCenterPage.d.ts.map +1 -0
  484. package/dist/layouts/shared/pages/HelpCenterPage.js +55 -0
  485. package/dist/layouts/shared/pages/MaintenancePage.d.ts +7 -0
  486. package/dist/layouts/shared/pages/MaintenancePage.d.ts.map +1 -0
  487. package/dist/layouts/shared/pages/MaintenancePage.js +44 -0
  488. package/dist/layouts/shared/pages/PortfolioPage.d.ts +7 -0
  489. package/dist/layouts/shared/pages/PortfolioPage.d.ts.map +1 -0
  490. package/dist/layouts/shared/pages/PortfolioPage.js +130 -0
  491. package/dist/layouts/shared/pages/PrivacyPolicyPage.d.ts +7 -0
  492. package/dist/layouts/shared/pages/PrivacyPolicyPage.d.ts.map +1 -0
  493. package/dist/layouts/shared/pages/PrivacyPolicyPage.js +8 -0
  494. package/dist/layouts/shared/pages/ShippingReturnsPage.d.ts +7 -0
  495. package/dist/layouts/shared/pages/ShippingReturnsPage.d.ts.map +1 -0
  496. package/dist/layouts/shared/pages/ShippingReturnsPage.js +7 -0
  497. package/dist/layouts/shared/pages/SizeGuidePage.d.ts +7 -0
  498. package/dist/layouts/shared/pages/SizeGuidePage.d.ts.map +1 -0
  499. package/dist/layouts/shared/pages/SizeGuidePage.js +10 -0
  500. package/dist/layouts/shared/pages/StyleGuidePage.d.ts +7 -0
  501. package/dist/layouts/shared/pages/StyleGuidePage.d.ts.map +1 -0
  502. package/dist/layouts/shared/pages/StyleGuidePage.js +126 -0
  503. package/dist/layouts/shared/pages/TeamPage.d.ts +7 -0
  504. package/dist/layouts/shared/pages/TeamPage.d.ts.map +1 -0
  505. package/dist/layouts/shared/pages/TeamPage.js +39 -0
  506. package/dist/layouts/shared/pages/TermsPage.d.ts +7 -0
  507. package/dist/layouts/shared/pages/TermsPage.d.ts.map +1 -0
  508. package/dist/layouts/shared/pages/TermsPage.js +8 -0
  509. package/dist/layouts/shared/pages/TrackOrderPage.d.ts +7 -0
  510. package/dist/layouts/shared/pages/TrackOrderPage.d.ts.map +1 -0
  511. package/dist/layouts/shared/pages/TrackOrderPage.js +371 -0
  512. package/dist/layouts/shared/pages/WishlistPage.d.ts +7 -0
  513. package/dist/layouts/shared/pages/WishlistPage.d.ts.map +1 -0
  514. package/dist/layouts/shared/pages/WishlistPage.js +162 -0
  515. package/dist/lib/api.d.ts +8 -0
  516. package/dist/lib/api.d.ts.map +1 -0
  517. package/dist/lib/api.js +109 -0
  518. package/dist/lib/auth-context.d.ts +30 -0
  519. package/dist/lib/auth-context.d.ts.map +1 -0
  520. package/dist/lib/auth-context.js +207 -0
  521. package/dist/lib/content-selectors.d.ts +21 -0
  522. package/dist/lib/content-selectors.d.ts.map +1 -0
  523. package/dist/lib/content-selectors.js +75 -0
  524. package/dist/lib/countries.d.ts +11 -0
  525. package/dist/lib/countries.d.ts.map +1 -0
  526. package/dist/lib/countries.js +252 -0
  527. package/dist/lib/currency-symbols.d.ts +36 -0
  528. package/dist/lib/currency-symbols.d.ts.map +1 -0
  529. package/dist/lib/currency-symbols.js +153 -0
  530. package/dist/lib/guest-user.d.ts +27 -0
  531. package/dist/lib/guest-user.d.ts.map +1 -0
  532. package/dist/lib/guest-user.js +71 -0
  533. package/dist/lib/loading-context.d.ts +19 -0
  534. package/dist/lib/loading-context.d.ts.map +1 -0
  535. package/dist/lib/loading-context.js +197 -0
  536. package/dist/lib/mock-stores.d.ts +22 -0
  537. package/dist/lib/mock-stores.d.ts.map +1 -0
  538. package/dist/lib/mock-stores.js +2099 -0
  539. package/dist/lib/payaza-checkout.d.ts +167 -0
  540. package/dist/lib/payaza-checkout.d.ts.map +1 -0
  541. package/dist/lib/payaza-checkout.js +455 -0
  542. package/dist/lib/services/analytics.service.d.ts +58 -0
  543. package/dist/lib/services/analytics.service.d.ts.map +1 -0
  544. package/dist/lib/services/analytics.service.js +182 -0
  545. package/dist/lib/services/auth.service.d.ts +63 -0
  546. package/dist/lib/services/auth.service.d.ts.map +1 -0
  547. package/dist/lib/services/auth.service.js +101 -0
  548. package/dist/lib/services/booking.service.d.ts +53 -0
  549. package/dist/lib/services/booking.service.d.ts.map +1 -0
  550. package/dist/lib/services/booking.service.js +52 -0
  551. package/dist/lib/services/cart.service.d.ts +37 -0
  552. package/dist/lib/services/cart.service.d.ts.map +1 -0
  553. package/dist/lib/services/cart.service.js +55 -0
  554. package/dist/lib/services/category.service.d.ts +21 -0
  555. package/dist/lib/services/category.service.d.ts.map +1 -0
  556. package/dist/lib/services/category.service.js +41 -0
  557. package/dist/lib/services/checkout.service.d.ts +79 -0
  558. package/dist/lib/services/checkout.service.d.ts.map +1 -0
  559. package/dist/lib/services/checkout.service.js +37 -0
  560. package/dist/lib/services/customer.service.d.ts +52 -0
  561. package/dist/lib/services/customer.service.d.ts.map +1 -0
  562. package/dist/lib/services/customer.service.js +64 -0
  563. package/dist/lib/services/fees.service.d.ts +23 -0
  564. package/dist/lib/services/fees.service.d.ts.map +1 -0
  565. package/dist/lib/services/fees.service.js +13 -0
  566. package/dist/lib/services/index.d.ts +19 -0
  567. package/dist/lib/services/index.d.ts.map +1 -0
  568. package/dist/lib/services/index.js +18 -0
  569. package/dist/lib/services/order.service.d.ts +107 -0
  570. package/dist/lib/services/order.service.d.ts.map +1 -0
  571. package/dist/lib/services/order.service.js +82 -0
  572. package/dist/lib/services/payment.service.d.ts +51 -0
  573. package/dist/lib/services/payment.service.d.ts.map +1 -0
  574. package/dist/lib/services/payment.service.js +105 -0
  575. package/dist/lib/services/product.service.d.ts +90 -0
  576. package/dist/lib/services/product.service.d.ts.map +1 -0
  577. package/dist/lib/services/product.service.js +86 -0
  578. package/dist/lib/services/promo.service.d.ts +31 -0
  579. package/dist/lib/services/promo.service.d.ts.map +1 -0
  580. package/dist/lib/services/promo.service.js +29 -0
  581. package/dist/lib/services/review.service.d.ts +47 -0
  582. package/dist/lib/services/review.service.d.ts.map +1 -0
  583. package/dist/lib/services/review.service.js +54 -0
  584. package/dist/lib/services/service.service.d.ts +55 -0
  585. package/dist/lib/services/service.service.d.ts.map +1 -0
  586. package/dist/lib/services/service.service.js +37 -0
  587. package/dist/lib/services/shipping.service.d.ts +44 -0
  588. package/dist/lib/services/shipping.service.d.ts.map +1 -0
  589. package/dist/lib/services/shipping.service.js +23 -0
  590. package/dist/lib/services/store.service.d.ts +87 -0
  591. package/dist/lib/services/store.service.d.ts.map +1 -0
  592. package/dist/lib/services/store.service.js +41 -0
  593. package/dist/lib/services/wishlist.service.d.ts +30 -0
  594. package/dist/lib/services/wishlist.service.d.ts.map +1 -0
  595. package/dist/lib/services/wishlist.service.js +53 -0
  596. package/dist/lib/store-config-utils.d.ts +41 -0
  597. package/dist/lib/store-config-utils.d.ts.map +1 -0
  598. package/dist/lib/store-config-utils.js +1535 -0
  599. package/dist/lib/store-config.d.ts +3 -0
  600. package/dist/lib/store-config.d.ts.map +1 -0
  601. package/dist/lib/store-config.js +2 -0
  602. package/dist/lib/store-context.d.ts +39 -0
  603. package/dist/lib/store-context.d.ts.map +1 -0
  604. package/dist/lib/store-context.js +803 -0
  605. package/dist/lib/store-types.d.ts +663 -0
  606. package/dist/lib/store-types.d.ts.map +1 -0
  607. package/dist/lib/store-types.js +1 -0
  608. package/dist/lib/utils/asset-helpers.d.ts +102 -0
  609. package/dist/lib/utils/asset-helpers.d.ts.map +1 -0
  610. package/dist/lib/utils/asset-helpers.js +395 -0
  611. package/dist/lib/utils/category-tree.d.ts +25 -0
  612. package/dist/lib/utils/category-tree.d.ts.map +1 -0
  613. package/dist/lib/utils/category-tree.js +85 -0
  614. package/dist/lib/utils/demo-detection.d.ts +23 -0
  615. package/dist/lib/utils/demo-detection.d.ts.map +1 -0
  616. package/dist/lib/utils/demo-detection.js +36 -0
  617. package/dist/lib/utils/fee-calculations.d.ts +35 -0
  618. package/dist/lib/utils/fee-calculations.d.ts.map +1 -0
  619. package/dist/lib/utils/fee-calculations.js +64 -0
  620. package/dist/lib/utils/index.d.ts +37 -0
  621. package/dist/lib/utils/index.d.ts.map +1 -0
  622. package/dist/lib/utils/index.js +160 -0
  623. package/dist/lib/utils/url-helpers.d.ts +30 -0
  624. package/dist/lib/utils/url-helpers.d.ts.map +1 -0
  625. package/dist/lib/utils/url-helpers.js +56 -0
  626. package/dist/lib/utils/video-helpers.d.ts +32 -0
  627. package/dist/lib/utils/video-helpers.d.ts.map +1 -0
  628. package/dist/lib/utils/video-helpers.js +210 -0
  629. package/package.json +92 -0
@@ -0,0 +1,1535 @@
1
+ import { getStoreConfig } from './store-config';
2
+ import { shouldUseAPI, getBaseStoreSlug } from './utils/demo-detection';
3
+ import { storeService } from './services/store.service';
4
+ import { categoryService } from './services/category.service';
5
+ import { productService } from './services/product.service';
6
+ import { serviceService } from './services/service.service';
7
+ import { normalizePrice } from './utils';
8
+ // Simple ID generator fallback (doesn't require uuid package)
9
+ function generateId() {
10
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
11
+ return crypto.randomUUID();
12
+ }
13
+ // Fallback for environments without crypto.randomUUID
14
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
15
+ }
16
+ /**
17
+ * Comprehensive function to extract and validate image URLs from any format
18
+ * Handles: strings, objects, arrays, JSON-encoded, comma-separated, fragmented JSON
19
+ * @param input - Can be string, object, array, or any combination
20
+ * @returns Array of valid absolute image URLs
21
+ */
22
+ export function extractImageUrls(input) {
23
+ if (!input) {
24
+ return [];
25
+ }
26
+ // Handle arrays
27
+ if (Array.isArray(input)) {
28
+ if (input.length === 0) {
29
+ return [];
30
+ }
31
+ // Check if array contains objects with url property
32
+ const firstItem = input[0];
33
+ if (firstItem && typeof firstItem === 'object' && firstItem !== null && 'url' in firstItem) {
34
+ // Array of objects: [{url: "...", isPrimary: true}, ...]
35
+ return input
36
+ .map((item) => extractImageUrls(item)) // Recursively extract from each object
37
+ .flat()
38
+ .filter((url) => url.length > 0);
39
+ }
40
+ // Check if array contains fragmented JSON strings (TypeORM simple-array issue)
41
+ if (typeof firstItem === 'string' && firstItem.trim().startsWith('[') && firstItem.includes('"url"')) {
42
+ try {
43
+ // Reconstruct fragmented JSON
44
+ const reconstructedJson = input.join('');
45
+ const parsed = JSON.parse(reconstructedJson);
46
+ return extractImageUrls(parsed); // Recursively process parsed result
47
+ }
48
+ catch {
49
+ // If reconstruction fails, treat as string array
50
+ }
51
+ }
52
+ // Array of strings: ["url1", "url2", ...]
53
+ return input
54
+ .map((item) => extractImageUrls(item)) // Recursively extract from each item
55
+ .flat()
56
+ .filter((url) => url.length > 0);
57
+ }
58
+ // Handle objects
59
+ if (typeof input === 'object' && input !== null) {
60
+ // Object with url property: {url: "...", isPrimary: true}
61
+ if ('url' in input && typeof input.url === 'string') {
62
+ const url = validateAndConvertUrl(input.url);
63
+ return url ? [url] : [];
64
+ }
65
+ // Stringified object: '{"url":"..."}'
66
+ if (typeof input === 'object' && Object.keys(input).length === 0) {
67
+ return [];
68
+ }
69
+ // Try to find url in nested structure
70
+ for (const key of ['url', 'image', 'src', 'imageUrl', 'image_url']) {
71
+ if (key in input && typeof input[key] === 'string') {
72
+ const url = validateAndConvertUrl(input[key]);
73
+ if (url)
74
+ return [url];
75
+ }
76
+ }
77
+ return [];
78
+ }
79
+ // Handle strings
80
+ if (typeof input === 'string') {
81
+ const trimmed = input.trim();
82
+ if (trimmed.length === 0) {
83
+ return [];
84
+ }
85
+ // Check if it's JSON-encoded
86
+ if ((trimmed.startsWith('[') || trimmed.startsWith('{')) && (trimmed.includes('"url"') || trimmed.includes('"image"'))) {
87
+ try {
88
+ const parsed = JSON.parse(trimmed);
89
+ return extractImageUrls(parsed); // Recursively process parsed result
90
+ }
91
+ catch {
92
+ // Not valid JSON, continue as string
93
+ }
94
+ }
95
+ // Check if it's comma-separated URLs
96
+ if (trimmed.includes(',') && (trimmed.includes('http://') || trimmed.includes('https://') || trimmed.includes('r2.dev'))) {
97
+ return trimmed
98
+ .split(',')
99
+ .map((s) => s.trim())
100
+ .map((url) => validateAndConvertUrl(url))
101
+ .filter((url) => url.length > 0);
102
+ }
103
+ // Single URL string
104
+ const url = validateAndConvertUrl(trimmed);
105
+ return url ? [url] : [];
106
+ }
107
+ return [];
108
+ }
109
+ /**
110
+ * Validates a URL string (CDN URLs from Cloudflare Object Storage are used as-is)
111
+ * @param url - URL string to validate
112
+ * @returns Valid URL string or empty string
113
+ */
114
+ function validateAndConvertUrl(url) {
115
+ if (!url || typeof url !== 'string') {
116
+ return '';
117
+ }
118
+ const trimmed = url.trim();
119
+ if (trimmed.length === 0) {
120
+ return '';
121
+ }
122
+ // URLs from Cloudflare Object Storage (CDN) are already absolute - use as-is
123
+ // Only validate that it's a non-empty string
124
+ return trimmed;
125
+ }
126
+ /**
127
+ * Validates a single image URL string
128
+ * @param url - URL to validate
129
+ * @returns Valid URL string or empty string
130
+ */
131
+ function validateImageUrl(url) {
132
+ if (!url) {
133
+ return '';
134
+ }
135
+ // Handle string URLs
136
+ if (typeof url === 'string') {
137
+ const trimmed = url.trim();
138
+ return trimmed.length > 0 ? trimmed : '';
139
+ }
140
+ // Handle number (convert to string)
141
+ if (typeof url === 'number') {
142
+ return String(url).trim();
143
+ }
144
+ // Handle object with url property (nested structures)
145
+ if (typeof url === 'object' && url !== null) {
146
+ // Try common URL property names
147
+ for (const key of ['url', 'src', 'image', 'imageUrl', 'image_url', 'value']) {
148
+ if (key in url && url[key]) {
149
+ const extracted = validateImageUrl(url[key]);
150
+ if (extracted)
151
+ return extracted;
152
+ }
153
+ }
154
+ }
155
+ return '';
156
+ }
157
+ /**
158
+ * Product-specific image extraction function
159
+ * Comprehensive function that handles all image storage formats
160
+ * URLs are used as-is from CDN (Cloudflare Object Storage)
161
+ * @param images - Can be:
162
+ * - Array of objects: [{url: string}, ...] or [{url: {url: string}}, ...]
163
+ * - Array of strings: ["url1", "url2"]
164
+ * - Single object: {url: string}
165
+ * - Single string: "url"
166
+ * - JSON string: '{"url":"..."}' or '[{"url":"..."}]'
167
+ * - null/undefined
168
+ * @returns Array of valid URL strings
169
+ */
170
+ function extractProductImageUrls(images) {
171
+ // Handle null/undefined
172
+ if (!images) {
173
+ return [];
174
+ }
175
+ // Handle JSON strings (parsed or unparsed)
176
+ if (typeof images === 'string') {
177
+ const trimmed = images.trim();
178
+ if (trimmed.length === 0) {
179
+ return [];
180
+ }
181
+ // Try to parse as JSON (handles both single and double-stringified)
182
+ if ((trimmed.startsWith('[') || trimmed.startsWith('{') || trimmed.startsWith('"')) && (trimmed.includes('"url"') || trimmed.includes('"image"'))) {
183
+ try {
184
+ let parsed = JSON.parse(trimmed);
185
+ // Check if result is still a string (double-stringified)
186
+ if (typeof parsed === 'string') {
187
+ try {
188
+ parsed = JSON.parse(parsed);
189
+ }
190
+ catch (e) {
191
+ // Not double-stringified, continue as string URL
192
+ }
193
+ }
194
+ // Recursively process the parsed result
195
+ return extractProductImageUrls(parsed);
196
+ }
197
+ catch (e) {
198
+ // Not valid JSON, continue as string URL
199
+ }
200
+ }
201
+ // Check if it's comma-separated URLs
202
+ if (trimmed.includes(',') && (trimmed.includes('http://') || trimmed.includes('https://') || trimmed.includes('r2.dev') || trimmed.includes('pub-'))) {
203
+ return trimmed
204
+ .split(',')
205
+ .map((url) => validateImageUrl(url))
206
+ .filter((url) => url.length > 0);
207
+ }
208
+ // Single URL string
209
+ const url = validateImageUrl(trimmed);
210
+ return url ? [url] : [];
211
+ }
212
+ // Handle arrays - this is the most common case
213
+ if (Array.isArray(images)) {
214
+ if (images.length === 0) {
215
+ return [];
216
+ }
217
+ const firstItem = images[0];
218
+ // Case 1: Array of objects with url property: [{url: "...", isPrimary: true}, ...]
219
+ // This is what backend normalizeProductImages returns
220
+ // Also handles nested: [{url: {url: "..."}}]
221
+ if (firstItem && typeof firstItem === 'object' && firstItem !== null) {
222
+ const result = [];
223
+ for (const item of images) {
224
+ if (!item)
225
+ continue;
226
+ // Handle object items
227
+ if (typeof item === 'object' && item !== null) {
228
+ // Check for direct url property
229
+ if ('url' in item) {
230
+ const url = validateImageUrl(item.url);
231
+ if (url) {
232
+ result.push(url);
233
+ continue;
234
+ }
235
+ }
236
+ // Check for other common property names
237
+ for (const key of ['src', 'image', 'imageUrl', 'image_url', 'value']) {
238
+ if (key in item) {
239
+ const url = validateImageUrl(item[key]);
240
+ if (url) {
241
+ result.push(url);
242
+ break;
243
+ }
244
+ }
245
+ }
246
+ }
247
+ // Handle string items in mixed arrays
248
+ else if (typeof item === 'string') {
249
+ const url = validateImageUrl(item);
250
+ if (url) {
251
+ result.push(url);
252
+ }
253
+ }
254
+ }
255
+ if (result.length > 0) {
256
+ return result;
257
+ }
258
+ }
259
+ // Case 2: Array of string URLs: ["url1", "url2", ...]
260
+ if (typeof firstItem === 'string') {
261
+ return images
262
+ .map((item) => validateImageUrl(item))
263
+ .filter((url) => url.length > 0);
264
+ }
265
+ // Case 3: Array of mixed types - try to extract from each
266
+ const result = [];
267
+ for (const item of images) {
268
+ const url = validateImageUrl(item);
269
+ if (url) {
270
+ result.push(url);
271
+ }
272
+ }
273
+ return result;
274
+ }
275
+ // Handle single object with url property
276
+ if (typeof images === 'object' && images !== null && !Array.isArray(images)) {
277
+ // Check for direct url property
278
+ if ('url' in images) {
279
+ const url = validateImageUrl(images.url);
280
+ if (url) {
281
+ return [url];
282
+ }
283
+ }
284
+ // Check for other common property names
285
+ for (const key of ['src', 'image', 'imageUrl', 'image_url', 'value']) {
286
+ if (key in images) {
287
+ const url = validateImageUrl(images[key]);
288
+ if (url) {
289
+ return [url];
290
+ }
291
+ }
292
+ }
293
+ }
294
+ return [];
295
+ }
296
+ /**
297
+ * Converts a relative URL to an absolute URL using the API base URL
298
+ * @param url - The URL to convert (can be relative like /uploads/... or already absolute)
299
+ * @returns Absolute URL string
300
+ * @deprecated Use validateAndConvertUrl instead for better validation
301
+ */
302
+ function convertToAbsoluteUrl(url) {
303
+ return validateAndConvertUrl(url);
304
+ }
305
+ /**
306
+ * Valid StoreLayoutType values
307
+ */
308
+ const VALID_LAYOUTS = [
309
+ 'food',
310
+ 'food-modern',
311
+ 'clothing',
312
+ 'clothing-minimal',
313
+ 'booking',
314
+ 'booking-agenda',
315
+ 'electronics',
316
+ 'electronics-grid',
317
+ ];
318
+ /**
319
+ * Maps API layout string to StoreLayoutType
320
+ * Falls back to 'food' if layout is invalid or missing
321
+ */
322
+ function mapLayoutToStoreLayoutType(layout) {
323
+ if (!layout) {
324
+ return 'food'; // Default fallback
325
+ }
326
+ // Check if layout is a valid StoreLayoutType
327
+ if (VALID_LAYOUTS.includes(layout)) {
328
+ return layout;
329
+ }
330
+ // Try to match by prefix for flexibility
331
+ const normalizedLayout = layout.toLowerCase();
332
+ for (const validLayout of VALID_LAYOUTS) {
333
+ if (normalizedLayout.startsWith(validLayout) || validLayout.startsWith(normalizedLayout)) {
334
+ return validLayout;
335
+ }
336
+ }
337
+ // Default fallback
338
+ return 'food';
339
+ }
340
+ /**
341
+ * Category-specific image extraction function
342
+ * Handles all category image storage formats independently
343
+ * @param image - Can be:
344
+ * - String URL: "https://..."
345
+ * - Object: {url: "https://..."}
346
+ * - Array: ["https://..."] or [{url: "https://..."}]
347
+ * - JSON string: '{"url":"..."}' or '"https://..."'
348
+ * - null/undefined
349
+ * @returns Single valid URL string or undefined
350
+ */
351
+ function extractCategoryImageUrl(image) {
352
+ if (!image) {
353
+ return undefined;
354
+ }
355
+ // Handle string URLs
356
+ if (typeof image === 'string') {
357
+ const trimmed = image.trim();
358
+ if (trimmed.length === 0) {
359
+ return undefined;
360
+ }
361
+ // Try to parse as JSON
362
+ if ((trimmed.startsWith('[') || trimmed.startsWith('{')) && (trimmed.includes('"url"') || trimmed.includes('"image"'))) {
363
+ try {
364
+ const parsed = JSON.parse(trimmed);
365
+ return extractCategoryImageUrl(parsed);
366
+ }
367
+ catch {
368
+ // Not valid JSON, continue as string URL
369
+ }
370
+ }
371
+ // Validate and return single URL string
372
+ const url = validateImageUrl(trimmed);
373
+ return url || undefined;
374
+ }
375
+ // Handle arrays - take first valid URL
376
+ if (Array.isArray(image)) {
377
+ if (image.length === 0) {
378
+ return undefined;
379
+ }
380
+ // Try to extract from first item
381
+ for (const item of image) {
382
+ const url = extractCategoryImageUrl(item);
383
+ if (url) {
384
+ return url;
385
+ }
386
+ }
387
+ return undefined;
388
+ }
389
+ // Handle objects
390
+ if (typeof image === 'object' && image !== null) {
391
+ // Check for direct url property
392
+ if ('url' in image) {
393
+ const url = validateImageUrl(image.url);
394
+ if (url) {
395
+ return url;
396
+ }
397
+ }
398
+ // Check for other common property names
399
+ for (const key of ['src', 'image', 'imageUrl', 'image_url', 'value']) {
400
+ if (key in image) {
401
+ const url = validateImageUrl(image[key]);
402
+ if (url) {
403
+ return url;
404
+ }
405
+ }
406
+ }
407
+ }
408
+ return undefined;
409
+ }
410
+ /**
411
+ * Transforms API Category to StoreCategory format
412
+ * Uses dedicated category image extraction function for independent validation
413
+ */
414
+ export function transformCategoryToStoreCategory(apiCategory) {
415
+ // Use category-specific image extraction function
416
+ // This ensures independent validation for category images
417
+ const imageUrl = extractCategoryImageUrl(apiCategory.image);
418
+ return {
419
+ id: apiCategory.id,
420
+ name: apiCategory.name,
421
+ slug: apiCategory.slug,
422
+ description: apiCategory.description,
423
+ image: imageUrl,
424
+ parentId: apiCategory.parentId,
425
+ };
426
+ }
427
+ /**
428
+ * Transforms API Product to StoreProduct format
429
+ * Calculates inStock based on trackInventory and inventory data
430
+ */
431
+ export function transformProductToStoreProduct(apiProduct) {
432
+ // Calculate inStock
433
+ let inStock = true; // Default to true
434
+ if (apiProduct.trackInventory === true) {
435
+ // If tracking inventory, check if any inventory item has quantity > 0
436
+ if (apiProduct.inventory && Array.isArray(apiProduct.inventory)) {
437
+ inStock = apiProduct.inventory.some((inv) => (inv.quantity || 0) > 0);
438
+ }
439
+ else {
440
+ // If inventory data is unavailable but tracking is enabled, default to false for safety
441
+ inStock = false;
442
+ }
443
+ }
444
+ else {
445
+ // If not tracking inventory, always in stock
446
+ inStock = true;
447
+ }
448
+ // Convert price to number (API may return string from decimal type)
449
+ const price = normalizePrice(apiProduct.price);
450
+ // Convert compareAtPrice to number if it exists
451
+ const compareAtPrice = apiProduct.compareAtPrice
452
+ ? normalizePrice(apiProduct.compareAtPrice)
453
+ : undefined;
454
+ // Use product-specific image extraction function
455
+ // Backend returns: [{url: string, isPrimary?: boolean}]
456
+ // Frontend needs: string[] (array of URL strings)
457
+ let images = extractProductImageUrls(apiProduct.images);
458
+ // Ensure all extracted URLs are valid (non-empty strings)
459
+ images = images.filter((url) => url && typeof url === 'string' && url.trim().length > 0);
460
+ // Enhanced logging for debugging image extraction issues
461
+ if (images.length === 0 && apiProduct.images) {
462
+ console.warn('[transformProductToStoreProduct] WARNING: No images extracted!', {
463
+ productId: apiProduct.id,
464
+ productName: apiProduct.name,
465
+ inputImages: apiProduct.images,
466
+ inputType: typeof apiProduct.images,
467
+ inputIsArray: Array.isArray(apiProduct.images),
468
+ inputLength: Array.isArray(apiProduct.images) ? apiProduct.images.length : 'N/A',
469
+ inputStringified: typeof apiProduct.images === 'string' ? apiProduct.images.substring(0, 200) : JSON.stringify(apiProduct.images || []).substring(0, 200)
470
+ });
471
+ // Try fallback extraction using the general extractImageUrls function
472
+ const fallbackImages = extractImageUrls(apiProduct.images);
473
+ if (fallbackImages.length > 0) {
474
+ console.log('[transformProductToStoreProduct] Fallback extraction succeeded:', {
475
+ productId: apiProduct.id,
476
+ extractedCount: fallbackImages.length
477
+ });
478
+ images = fallbackImages.filter((url) => url && typeof url === 'string' && url.trim().length > 0);
479
+ }
480
+ }
481
+ else if (images.length > 0) {
482
+ // Log successful extraction in development
483
+ if (process.env.NODE_ENV === 'development') {
484
+ console.log('[transformProductToStoreProduct] Successfully extracted images:', {
485
+ productId: apiProduct.id,
486
+ productName: apiProduct.name,
487
+ imageCount: images.length,
488
+ firstImage: images[0]?.substring(0, 100)
489
+ });
490
+ }
491
+ }
492
+ // Convert rating to number, handling undefined, null, or string values
493
+ let rating;
494
+ if (apiProduct.rating !== undefined && apiProduct.rating !== null) {
495
+ if (typeof apiProduct.rating === 'number') {
496
+ rating = apiProduct.rating;
497
+ }
498
+ else if (typeof apiProduct.rating === 'string') {
499
+ const parsed = parseFloat(apiProduct.rating);
500
+ rating = isNaN(parsed) ? undefined : parsed;
501
+ }
502
+ else {
503
+ rating = undefined;
504
+ }
505
+ }
506
+ // Generate SKU from slug or name if not provided
507
+ const generateSKU = (product) => {
508
+ // Try to get SKU from metadata first
509
+ if (product.metadata?.sku) {
510
+ return String(product.metadata.sku);
511
+ }
512
+ // Check if any variation has a SKU (use the first one found)
513
+ if (product.variations && product.variations.length > 0) {
514
+ const variationWithSKU = product.variations.find((v) => v.sku);
515
+ if (variationWithSKU?.sku) {
516
+ return String(variationWithSKU.sku);
517
+ }
518
+ }
519
+ // Generate SKU from slug (uppercase, remove hyphens, take first 8-12 chars)
520
+ if (product.slug) {
521
+ const slugSKU = product.slug.toUpperCase().replace(/[^A-Z0-9]/g, '').substring(0, 12);
522
+ return slugSKU.length >= 6 ? slugSKU : slugSKU.padEnd(8, 'X');
523
+ }
524
+ // Fallback: generate from name (uppercase, alphanumeric only, first 8-12 chars)
525
+ const nameSKU = product.name
526
+ .toUpperCase()
527
+ .replace(/[^A-Z0-9]/g, '')
528
+ .substring(0, 12);
529
+ return nameSKU.length >= 6 ? nameSKU : nameSKU.padEnd(8, 'X');
530
+ };
531
+ // Extract reviewCount from API product (added by backend)
532
+ const reviewCount = apiProduct.reviewCount !== undefined
533
+ ? Number(apiProduct.reviewCount)
534
+ : undefined;
535
+ return {
536
+ id: apiProduct.id,
537
+ name: apiProduct.name,
538
+ slug: apiProduct.slug,
539
+ description: apiProduct.description || '',
540
+ price,
541
+ compareAtPrice,
542
+ images,
543
+ categoryId: apiProduct.categoryId || '',
544
+ inStock,
545
+ rating,
546
+ reviewCount,
547
+ sku: generateSKU(apiProduct),
548
+ currency: apiProduct.currency || 'USD',
549
+ variants: apiProduct.variations?.map((variation) => ({
550
+ id: variation.id || variation.name || '',
551
+ name: variation.name || '',
552
+ value: variation.value || '',
553
+ price: variation.price
554
+ ? (typeof variation.price === 'string'
555
+ ? parseFloat(variation.price)
556
+ : Number(variation.price))
557
+ : undefined,
558
+ sku: variation.sku,
559
+ })),
560
+ specifications: apiProduct.brand ? { brand: apiProduct.brand } : undefined,
561
+ isActive: apiProduct.isActive,
562
+ status: apiProduct.status,
563
+ };
564
+ }
565
+ /**
566
+ * Transforms API Service to StoreService format
567
+ */
568
+ export function transformServiceToStoreService(apiService) {
569
+ // Convert price to number (API may return string from decimal type)
570
+ const price = normalizePrice(apiService.price);
571
+ // Extract image from images array or use image field
572
+ let image;
573
+ if (apiService.image) {
574
+ image = apiService.image;
575
+ }
576
+ else if (apiService.images) {
577
+ const imageUrls = extractImageUrls(apiService.images);
578
+ image = imageUrls.length > 0 ? imageUrls[0] : undefined;
579
+ }
580
+ // Convert availability to StoreService format
581
+ let availability;
582
+ if (apiService.availability) {
583
+ if (Array.isArray(apiService.availability)) {
584
+ availability = apiService.availability.map((avail) => ({
585
+ day: avail.day || '',
586
+ slots: avail.slots || [],
587
+ }));
588
+ }
589
+ else if (typeof apiService.availability === 'object') {
590
+ // Handle object format - convert to array format
591
+ const availObj = apiService.availability;
592
+ if (availObj.days && Array.isArray(availObj.days)) {
593
+ availability = availObj.days.map((day) => ({
594
+ day,
595
+ slots: availObj.timeSlots || [],
596
+ }));
597
+ }
598
+ else if (availObj.day) {
599
+ availability = [{
600
+ day: availObj.day,
601
+ slots: availObj.slots || [],
602
+ }];
603
+ }
604
+ }
605
+ }
606
+ // Extract provider info if available (providerId exists but provider relation may not be loaded)
607
+ const provider = apiService.providerId ? {
608
+ id: apiService.providerId,
609
+ name: apiService.provider?.name || 'Service Provider',
610
+ avatar: apiService.provider?.avatar,
611
+ rating: apiService.provider?.rating,
612
+ } : undefined;
613
+ return {
614
+ id: apiService.id,
615
+ name: apiService.name,
616
+ slug: apiService.slug,
617
+ description: apiService.description || '',
618
+ price,
619
+ currency: apiService.currency,
620
+ duration: apiService.duration || 0,
621
+ categoryId: apiService.categoryId || '',
622
+ image,
623
+ provider,
624
+ availability,
625
+ isActive: apiService.isActive,
626
+ status: apiService.status,
627
+ };
628
+ }
629
+ /**
630
+ * Transforms API StoreResponse to StoreConfig format
631
+ */
632
+ function transformStoreResponseToConfig(apiStore) {
633
+ const layout = mapLayoutToStoreLayoutType(apiStore.layout);
634
+ // Debug logging for layoutConfig
635
+ console.log('[transformStoreResponseToConfig] Received apiStore.layoutConfig:', {
636
+ exists: !!apiStore.layoutConfig,
637
+ type: typeof apiStore.layoutConfig,
638
+ hasSections: !!apiStore.layoutConfig?.sections,
639
+ hasHeroSliders: !!apiStore.layoutConfig?.sections?.hero?.sliders,
640
+ sliderCount: apiStore.layoutConfig?.sections?.hero?.sliders?.length || 0,
641
+ });
642
+ // Build contactInfo from various sources
643
+ let contactInfo = apiStore.contactInfo || {
644
+ email: apiStore.contactEmail,
645
+ phone: apiStore.contactPhone,
646
+ address: apiStore.address,
647
+ };
648
+ // If contactInfo exists but doesn't have an address, merge Store's address if available
649
+ if (contactInfo && !contactInfo.address && apiStore.address) {
650
+ contactInfo = {
651
+ ...contactInfo,
652
+ address: apiStore.address,
653
+ };
654
+ }
655
+ const transformedLayoutConfig = transformLayoutConfig(apiStore.layoutConfig, apiStore.slug);
656
+ console.log('[transformStoreResponseToConfig] Transformed layoutConfig:', {
657
+ exists: !!transformedLayoutConfig,
658
+ hasSections: !!transformedLayoutConfig?.sections,
659
+ hasHeroSliders: !!transformedLayoutConfig?.sections?.hero?.sliders,
660
+ sliderCount: transformedLayoutConfig?.sections?.hero?.sliders?.length || 0,
661
+ });
662
+ return {
663
+ id: apiStore.id,
664
+ slug: apiStore.slug,
665
+ name: apiStore.name,
666
+ description: apiStore.description || '',
667
+ type: layout,
668
+ layout: layout,
669
+ branding: {
670
+ primaryColor: apiStore.branding?.primaryColor || '#000000',
671
+ secondaryColor: apiStore.branding?.secondaryColor,
672
+ accentColor: apiStore.branding?.secondaryColor || apiStore.branding?.primaryColor || '#000000',
673
+ logo: (apiStore.branding?.logo || apiStore.logo) ? convertToAbsoluteUrl(apiStore.branding?.logo || apiStore.logo || '') : undefined,
674
+ },
675
+ navigation: {
676
+ main: [],
677
+ footer: [],
678
+ },
679
+ features: {
680
+ cart: true,
681
+ wishlist: true,
682
+ reviews: true,
683
+ search: true,
684
+ filters: true,
685
+ booking: layout.startsWith('booking'),
686
+ delivery: true,
687
+ },
688
+ products: [],
689
+ categories: [],
690
+ settings: {
691
+ currency: apiStore.settings?.currency || 'USD',
692
+ taxRate: apiStore.settings?.taxRate, // Deprecated: kept for backward compatibility
693
+ vat: apiStore.settings?.vat,
694
+ serviceCharge: apiStore.settings?.serviceCharge,
695
+ },
696
+ contactInfo: (contactInfo.email || contactInfo.phone || contactInfo.address) ? contactInfo : undefined,
697
+ layoutConfig: transformedLayoutConfig, // Transform layoutConfig to match frontend structure
698
+ // Extract puckData from configuration if it exists
699
+ puckData: apiStore.configuration?.puck_configuration?.puckData || undefined,
700
+ };
701
+ }
702
+ /**
703
+ * Transforms backend layoutContent structure to frontend layoutConfig structure
704
+ * Backend uses assignedAssets/assignedText, frontend expects sections structure
705
+ */
706
+ function transformLayoutConfig(layoutContent, storeSlug) {
707
+ if (!layoutContent || typeof layoutContent !== 'object') {
708
+ console.log('[transformLayoutConfig] No layoutContent provided or invalid');
709
+ return undefined;
710
+ }
711
+ // If it already has the sections structure, return as-is but ensure assignedAssets/assignedText are preserved
712
+ if (layoutContent.sections) {
713
+ console.log('[transformLayoutConfig] Sections structure found, returning as-is');
714
+ console.log('[transformLayoutConfig] Sections found:', {
715
+ hero: !!layoutContent.sections.hero,
716
+ heroSliders: layoutContent.sections?.hero?.sliders?.length || 0,
717
+ categories: !!layoutContent.sections.categories,
718
+ featuredProducts: !!layoutContent.sections.featuredProducts,
719
+ marketing: !!layoutContent.sections.marketing,
720
+ marketingEditorial: !!layoutContent.sections.marketing?.editorial,
721
+ marketingPromoBanner: !!layoutContent.sections.marketing?.promoBanner,
722
+ marketingNewsletter: !!layoutContent.sections.marketing?.newsletter,
723
+ hasAssignedAssets: !!layoutContent.assignedAssets,
724
+ hasAssignedText: !!layoutContent.assignedText,
725
+ });
726
+ // Return the entire structure as-is - all sections are already in the correct format
727
+ // Ensure assignedAssets and assignedText are preserved for backward compatibility
728
+ return {
729
+ ...layoutContent,
730
+ assignedAssets: layoutContent.assignedAssets || {},
731
+ assignedText: layoutContent.assignedText || {},
732
+ };
733
+ }
734
+ // Transform from assignedAssets/assignedText structure to sections structure
735
+ const assignedAssets = layoutContent.assignedAssets || {};
736
+ const assignedText = layoutContent.assignedText || {};
737
+ // Build sections structure
738
+ const sections = {};
739
+ // Marketing section - migrate from old format to structured format
740
+ if (layoutContent.sections?.marketing) {
741
+ // New structure already exists - preserve it exactly as-is from database
742
+ console.log('[transformLayoutConfig] Found sections.marketing, preserving structure');
743
+ console.log('[transformLayoutConfig] Marketing sections:', {
744
+ hasEditorial: !!layoutContent.sections.marketing.editorial,
745
+ hasPromoBanner: !!layoutContent.sections.marketing.promoBanner,
746
+ hasNewsletter: !!layoutContent.sections.marketing.newsletter,
747
+ });
748
+ sections.marketing = {
749
+ show: layoutContent.sections.marketing.show !== false,
750
+ showNewsletter: layoutContent.sections.marketing.showNewsletter !== false,
751
+ showPromoBanner: layoutContent.sections.marketing.showPromoBanner !== false,
752
+ // Preserve all marketing subsections exactly as stored
753
+ editorial: layoutContent.sections.marketing.editorial,
754
+ promoBanner: layoutContent.sections.marketing.promoBanner,
755
+ newsletter: layoutContent.sections.marketing.newsletter,
756
+ shopTheLook: layoutContent.sections.marketing.shopTheLook,
757
+ chefRecommendations: layoutContent.sections.marketing.chefRecommendations,
758
+ };
759
+ }
760
+ else {
761
+ // Migrate from old format
762
+ const marketing = {
763
+ show: true,
764
+ showNewsletter: false,
765
+ showPromoBanner: false,
766
+ };
767
+ // Editorial section (lookbook)
768
+ if (assignedAssets.lookbook_main || assignedText['lookbook_main:section_header']) {
769
+ marketing.editorial = {
770
+ show: true,
771
+ label: assignedText['lookbook_main:section_header'] || 'EDITORIAL',
772
+ title: (assignedText['lookbook_main:main_caption'] && assignedText['lookbook_main:main_caption'].length < 50)
773
+ ? assignedText['lookbook_main:main_caption']
774
+ : 'Redefining Modern\nElegance',
775
+ description: assignedText['lookbook_main:main_caption']?.length >= 50
776
+ ? assignedText['lookbook_main:main_caption']
777
+ : assignedText['lookbook_detail:detail_caption'] || assignedText['lookbook_main:main_caption'] || 'Explore our latest editorial featuring timeless pieces crafted for the contemporary wardrobe. From essential basics to statement outwear, find your signature look.',
778
+ image: assignedAssets.lookbook_main,
779
+ detailImage: assignedAssets.lookbook_detail,
780
+ primaryButtonText: 'View Lookbook',
781
+ primaryButtonLink: '/style-guide',
782
+ secondaryButtonText: 'Read Our Story',
783
+ secondaryButtonLink: '/about',
784
+ };
785
+ }
786
+ // Promo banner
787
+ // Check for sale_banner (electronics-grid), promo_banner_image, seasonal_promo_banner, or promo_title text
788
+ const hasPromoBanner = assignedAssets.sale_banner ||
789
+ assignedAssets.promo_banner_image ||
790
+ assignedAssets.seasonal_promo_banner ||
791
+ assignedText['promo_banner_title'] ||
792
+ assignedText['promo_title'] ||
793
+ assignedText['sale_banner:banner_title'];
794
+ if (hasPromoBanner) {
795
+ // Get banner image - prioritize sale_banner for electronics-grid
796
+ const bannerImage = assignedAssets.sale_banner ||
797
+ assignedAssets.promo_banner_image ||
798
+ assignedAssets.seasonal_promo_banner;
799
+ // Get banner text - check sale_banner textElements first, then other sources
800
+ const bannerTitle = assignedText['sale_banner:banner_title'] ||
801
+ assignedText['promo_banner_title'] ||
802
+ assignedText['promo_title'] ||
803
+ assignedText['promo_headline'];
804
+ const bannerSubtitle = assignedText['sale_banner:banner_subtitle'] ||
805
+ assignedText['promo_banner_subtitle'] ||
806
+ assignedText['promo_subtext'] ||
807
+ assignedText['promo_subhead'];
808
+ const bannerButtonText = assignedText['sale_banner:cta_button'] ||
809
+ assignedText['promo_banner_button'] ||
810
+ assignedText['promo_cta'] ||
811
+ assignedText['cta_text'];
812
+ const bannerButtonLink = assignedText['promo_banner_link'] ||
813
+ assignedText['sale_banner:button_link'] ||
814
+ '/products';
815
+ marketing.showPromoBanner = true;
816
+ marketing.promoBanner = {
817
+ show: true,
818
+ image: bannerImage,
819
+ title: bannerTitle,
820
+ subtitle: bannerSubtitle,
821
+ buttonText: bannerButtonText,
822
+ buttonLink: bannerButtonLink,
823
+ };
824
+ }
825
+ // Newsletter
826
+ if (assignedText['newsletter_title'] || assignedText['footer_newsletter_title']) {
827
+ marketing.showNewsletter = true;
828
+ marketing.newsletter = {
829
+ show: true,
830
+ title: assignedText['newsletter_title'] || assignedText['footer_newsletter_title'],
831
+ subtitle: assignedText['newsletter_subtitle'] || assignedText['footer_newsletter_subtitle'],
832
+ button: assignedText['newsletter_button'] || assignedText['footer_newsletter_button'],
833
+ placeholder: assignedText['newsletter_placeholder'],
834
+ disclaimer: assignedText['newsletter_disclaimer'],
835
+ };
836
+ }
837
+ // Shop the look (clothing-minimal)
838
+ if (assignedAssets.shop_the_look_image || assignedText['shop_the_look:section_title']) {
839
+ marketing.shopTheLook = {
840
+ show: true,
841
+ image: assignedAssets.shop_the_look_image,
842
+ title: assignedText['shop_the_look:section_title'] || assignedText['section_title'],
843
+ description: assignedText['shop_the_look:look_desc'] || assignedText['look_desc'],
844
+ products: [], // Will be populated from product data
845
+ };
846
+ }
847
+ // Chef recommendations (food layout)
848
+ if (assignedText['chef_recommendations_title'] || assignedAssets.chef_image) {
849
+ marketing.chefRecommendations = {
850
+ show: true,
851
+ title: assignedText['chef_recommendations_title'] || 'Chef\'s Recommendations',
852
+ description: assignedText['chef_recommendations_description'],
853
+ items: [], // Will be populated from menu item data
854
+ };
855
+ }
856
+ if (Object.keys(marketing).length > 3) { // More than just show, showNewsletter, showPromoBanner
857
+ sections.marketing = marketing;
858
+ }
859
+ }
860
+ // Hero section - migrate old format to new slider structure
861
+ if (layoutContent.sections?.hero?.sliders && Array.isArray(layoutContent.sections.hero.sliders)) {
862
+ // New structure already exists - preserve it exactly as-is from database
863
+ // This ensures the slider structure with images, text, and buttons is not modified
864
+ console.log('[transformLayoutConfig] Found sections.hero.sliders, preserving structure');
865
+ console.log('[transformLayoutConfig] Sliders count:', layoutContent.sections.hero.sliders.length);
866
+ // Log each slider for debugging
867
+ layoutContent.sections.hero.sliders.forEach((slider, index) => {
868
+ console.log(`[transformLayoutConfig] Slider ${index + 1}:`, {
869
+ id: slider.id,
870
+ hasImage: !!slider.image,
871
+ imageUrl: slider.image ? (slider.image.substring(0, 50) + '...') : 'missing',
872
+ hasTitle: !!slider.title,
873
+ title: slider.title || 'missing',
874
+ primaryButtonText: slider.primaryButton?.text || 'empty',
875
+ secondaryButtonText: slider.secondaryButton?.text || 'empty',
876
+ });
877
+ });
878
+ sections.hero = {
879
+ ...layoutContent.sections.hero,
880
+ show: layoutContent.sections.hero.show !== false,
881
+ showCTA: layoutContent.sections.hero.showCTA !== false,
882
+ showSecondaryCTA: layoutContent.sections.hero.showSecondaryCTA !== false,
883
+ autoPlay: layoutContent.sections.hero.autoPlay !== false,
884
+ showBadges: layoutContent.sections.hero.showBadges !== false,
885
+ // Preserve sliders array exactly as stored - don't transform or modify
886
+ sliders: layoutContent.sections.hero.sliders,
887
+ };
888
+ }
889
+ else if (assignedAssets.hero_slide_1 || assignedAssets.hero_slide_2 || assignedAssets.hero_slide_3) {
890
+ // Old format detected - migrate to new structure
891
+ const sliders = [];
892
+ // Build sliders array from old format (support up to 10 slides for future growth)
893
+ for (let i = 1; i <= 10; i++) {
894
+ const slideKey = `hero_slide_${i}`;
895
+ const imageUrl = assignedAssets[slideKey];
896
+ if (imageUrl) {
897
+ // Determine store slug for default links (use passed parameter or fallback)
898
+ const defaultProductsLink = storeSlug ? `/${storeSlug}/products` : '/products';
899
+ const defaultCategoriesLink = storeSlug ? `/${storeSlug}/categories` : '/categories';
900
+ const slider = {
901
+ id: slideKey,
902
+ image: imageUrl,
903
+ order: i,
904
+ };
905
+ // Map old text keys to new structure
906
+ // Support multiple key variations for backward compatibility
907
+ const badgeKey = `${slideKey}:badge`;
908
+ const headingKey = `${slideKey}:heading`;
909
+ const titleKey = `${slideKey}:title`;
910
+ const subheadingKey = `${slideKey}:subheading`;
911
+ const descriptionKey = `${slideKey}:description`;
912
+ const btnLabelKey = `${slideKey}:btn_label`;
913
+ const primaryButtonKey = `${slideKey}:primaryButton`;
914
+ const secondaryBtnKey = `${slideKey}:secondary_btn`;
915
+ const secondaryButtonKey = `${slideKey}:secondaryButton`;
916
+ const highlightKey = `${slideKey}:highlight`; // Food layout specific
917
+ if (assignedText[badgeKey]) {
918
+ slider.badge = assignedText[badgeKey];
919
+ }
920
+ slider.title = assignedText[headingKey] || assignedText[titleKey] || '';
921
+ if (assignedText[subheadingKey] || assignedText[descriptionKey]) {
922
+ slider.description = assignedText[subheadingKey] || assignedText[descriptionKey];
923
+ }
924
+ // Food layout specific: highlight field
925
+ if (assignedText[highlightKey]) {
926
+ slider.highlight = assignedText[highlightKey];
927
+ }
928
+ // Primary button - handle both string and object formats
929
+ const primaryButtonText = assignedText[btnLabelKey] || assignedText[primaryButtonKey];
930
+ if (primaryButtonText) {
931
+ // Check if it's already an object (from new format migration)
932
+ if (typeof primaryButtonText === 'object' && primaryButtonText !== null) {
933
+ slider.primaryButton = primaryButtonText;
934
+ }
935
+ else {
936
+ slider.primaryButton = {
937
+ text: String(primaryButtonText),
938
+ link: defaultProductsLink,
939
+ };
940
+ }
941
+ }
942
+ // Secondary button - handle both string and object formats
943
+ const secondaryButtonText = assignedText[secondaryBtnKey] || assignedText[secondaryButtonKey];
944
+ if (secondaryButtonText) {
945
+ // Check if it's already an object (from new format migration)
946
+ if (typeof secondaryButtonText === 'object' && secondaryButtonText !== null) {
947
+ slider.secondaryButton = secondaryButtonText;
948
+ }
949
+ else {
950
+ slider.secondaryButton = {
951
+ text: String(secondaryButtonText),
952
+ link: defaultCategoriesLink,
953
+ };
954
+ }
955
+ }
956
+ sliders.push(slider);
957
+ }
958
+ }
959
+ // Only create hero section if we have at least one slider
960
+ if (sliders.length > 0) {
961
+ sections.hero = {
962
+ show: true,
963
+ showCTA: true,
964
+ showSecondaryCTA: true,
965
+ autoPlay: true,
966
+ showBadges: true,
967
+ sliders: sliders,
968
+ };
969
+ }
970
+ }
971
+ else if (assignedAssets.hero_bg || assignedAssets.hero_image || assignedAssets.hero_split_image || assignedAssets.hero_video) {
972
+ // Single image/video hero (non-slider layouts)
973
+ sections.hero = {
974
+ show: true,
975
+ showCTA: true,
976
+ showSecondaryCTA: true,
977
+ autoPlay: false,
978
+ showBadges: true,
979
+ };
980
+ }
981
+ // Categories section - migrate from old format to structured format
982
+ if (layoutContent.sections?.categories) {
983
+ // New structure already exists - use it
984
+ sections.categories = {
985
+ show: layoutContent.sections.categories.show !== false,
986
+ showViewAll: layoutContent.sections.categories.showViewAll !== false,
987
+ limit: layoutContent.sections.categories.limit || 4,
988
+ title: layoutContent.sections.categories.title,
989
+ subtitle: layoutContent.sections.categories.subtitle,
990
+ viewAll: layoutContent.sections.categories.viewAll,
991
+ };
992
+ }
993
+ else {
994
+ // Migrate from old format
995
+ sections.categories = {
996
+ show: true,
997
+ showViewAll: true,
998
+ limit: 4,
999
+ title: assignedText['categories_title'] || assignedText['sections.categories.title'],
1000
+ subtitle: assignedText['categories_subtitle'] || assignedText['sections.categories.subtitle'],
1001
+ viewAll: assignedText['categories_view_all'] || assignedText['sections.categories.viewAll'] || 'View All Categories',
1002
+ };
1003
+ }
1004
+ // Featured products section - migrate from old format to structured format
1005
+ if (layoutContent.sections?.featuredProducts) {
1006
+ // New structure already exists - use it
1007
+ sections.featuredProducts = {
1008
+ show: layoutContent.sections.featuredProducts.show !== false,
1009
+ title: layoutContent.sections.featuredProducts.title,
1010
+ subtitle: layoutContent.sections.featuredProducts.subtitle,
1011
+ showViewAll: layoutContent.sections.featuredProducts.showViewAll !== false,
1012
+ viewAll: layoutContent.sections.featuredProducts.viewAll,
1013
+ showAddToCart: layoutContent.sections.featuredProducts.showAddToCart !== false,
1014
+ showWishlist: layoutContent.sections.featuredProducts.showWishlist !== false,
1015
+ showRatings: layoutContent.sections.featuredProducts.showRatings !== false,
1016
+ emptyState: layoutContent.sections.featuredProducts.emptyState,
1017
+ };
1018
+ }
1019
+ else {
1020
+ // Migrate from old format
1021
+ sections.featuredProducts = {
1022
+ show: true,
1023
+ title: assignedText['featured_products_title'] || assignedText['trending_title'] || assignedText['sections.featuredProducts.title'] || 'Trending Now',
1024
+ subtitle: assignedText['featured_products_subtitle'] || assignedText['sections.featuredProducts.subtitle'],
1025
+ showViewAll: true,
1026
+ viewAll: assignedText['featured_products_view_all'] || assignedText['sections.featuredProducts.viewAll'] || 'View All Products',
1027
+ showAddToCart: true,
1028
+ showWishlist: true,
1029
+ showRatings: true,
1030
+ emptyState: assignedText['featured_products_empty'] || assignedText['sections.featuredProducts.emptyState'],
1031
+ };
1032
+ }
1033
+ // Testimonials section - migrate from old format to structured format
1034
+ if (layoutContent.sections?.testimonials) {
1035
+ const testimonialsData = layoutContent.sections.testimonials;
1036
+ sections.testimonials = {
1037
+ show: testimonialsData.show !== false,
1038
+ title: testimonialsData.title,
1039
+ subtitle: testimonialsData.subtitle,
1040
+ // Support both new items array and old single quote format
1041
+ items: testimonialsData.items && Array.isArray(testimonialsData.items)
1042
+ ? testimonialsData.items.map((item) => ({
1043
+ id: item.id || generateId(),
1044
+ name: item.name || 'Customer',
1045
+ role: item.role || 'Customer',
1046
+ image: item.image || '',
1047
+ quote: item.quote || '',
1048
+ rating: typeof item.rating === 'number' ? item.rating : 5,
1049
+ order: typeof item.order === 'number' ? item.order : 0,
1050
+ })).sort((a, b) => a.order - b.order)
1051
+ : testimonialsData.quote
1052
+ ? [{
1053
+ id: generateId(),
1054
+ name: testimonialsData.author || 'Customer',
1055
+ role: testimonialsData.role || 'Customer',
1056
+ image: '',
1057
+ quote: testimonialsData.quote,
1058
+ rating: 5,
1059
+ order: 0,
1060
+ }]
1061
+ : [],
1062
+ // Keep backward compatibility with old single quote format
1063
+ quote: testimonialsData.quote,
1064
+ author: testimonialsData.author,
1065
+ role: testimonialsData.role,
1066
+ };
1067
+ }
1068
+ else if (assignedText['testimonial_quote'] || assignedText['testimonials_title']) {
1069
+ sections.testimonials = {
1070
+ show: true,
1071
+ title: assignedText['testimonials_title'] || assignedText['sections.testimonials.title'],
1072
+ subtitle: assignedText['testimonials_subtitle'] || assignedText['sections.testimonials.subtitle'],
1073
+ items: assignedText['testimonial_quote'] ? [{
1074
+ id: generateId(),
1075
+ name: assignedText['testimonial_author'] || 'Customer',
1076
+ role: assignedText['testimonial_role'] || 'Customer',
1077
+ image: '',
1078
+ quote: assignedText['testimonial_quote'],
1079
+ rating: 5,
1080
+ order: 0,
1081
+ }] : [],
1082
+ // Keep backward compatibility
1083
+ quote: assignedText['testimonial_quote'],
1084
+ author: assignedText['testimonial_author'],
1085
+ role: assignedText['testimonial_role'],
1086
+ };
1087
+ }
1088
+ // Story section - new structured format
1089
+ if (layoutContent.sections?.story) {
1090
+ sections.story = {
1091
+ show: layoutContent.sections.story.show !== false,
1092
+ label: layoutContent.sections.story.label,
1093
+ title: layoutContent.sections.story.title || '',
1094
+ description: layoutContent.sections.story.description || '',
1095
+ image: layoutContent.sections.story.image,
1096
+ signature: layoutContent.sections.story.signature,
1097
+ };
1098
+ }
1099
+ // PromoBanner section - new structured format (directly in sections, not just in marketing)
1100
+ if (layoutContent.sections?.promoBanner) {
1101
+ sections.promoBanner = {
1102
+ show: layoutContent.sections.promoBanner.show !== false,
1103
+ image: layoutContent.sections.promoBanner.image,
1104
+ title: layoutContent.sections.promoBanner.title || '',
1105
+ subtitle: layoutContent.sections.promoBanner.subtitle,
1106
+ buttonText: layoutContent.sections.promoBanner.buttonText,
1107
+ buttonLink: layoutContent.sections.promoBanner.buttonLink,
1108
+ };
1109
+ }
1110
+ // Team section - migrate from old format to structured format
1111
+ if (layoutContent.sections?.team) {
1112
+ sections.team = {
1113
+ show: layoutContent.sections.team.show !== false,
1114
+ title: layoutContent.sections.team.title,
1115
+ description: layoutContent.sections.team.description,
1116
+ showViewAll: layoutContent.sections.team.showViewAll !== false,
1117
+ viewAll: layoutContent.sections.team.viewAll,
1118
+ items: layoutContent.sections.team.items && Array.isArray(layoutContent.sections.team.items)
1119
+ ? layoutContent.sections.team.items.map((item) => ({
1120
+ id: item.id || generateId(),
1121
+ name: item.name || 'Team Member',
1122
+ role: item.role || 'Specialist',
1123
+ image: item.image || item.photo || '',
1124
+ rating: item.rating,
1125
+ reviews: item.reviews,
1126
+ }))
1127
+ : [],
1128
+ };
1129
+ }
1130
+ else if (assignedText['team_section_title'] || assignedText['team_title']) {
1131
+ sections.team = {
1132
+ show: true,
1133
+ title: assignedText['team_section_title'] || assignedText['team_title'] || assignedText['sections.team.title'],
1134
+ description: assignedText['team_section_subtitle'] || assignedText['team_description'] || assignedText['team_desc'] || assignedText['sections.team.description'],
1135
+ showViewAll: true,
1136
+ viewAll: assignedText['team_view_all'] || assignedText['sections.team.viewAll'] || 'View All Team',
1137
+ items: [],
1138
+ };
1139
+ }
1140
+ // Services section - migrate from old format to structured format (for booking layouts)
1141
+ if (layoutContent.sections?.services) {
1142
+ sections.services = {
1143
+ show: layoutContent.sections.services.show !== false,
1144
+ title: layoutContent.sections.services.title,
1145
+ subtitle: layoutContent.sections.services.subtitle,
1146
+ showViewAll: layoutContent.sections.services.showViewAll !== false,
1147
+ viewAll: layoutContent.sections.services.viewAll,
1148
+ limit: layoutContent.sections.services.limit,
1149
+ };
1150
+ }
1151
+ else if (assignedText['services_section_title'] || assignedText['services_title']) {
1152
+ sections.services = {
1153
+ show: true,
1154
+ title: assignedText['services_section_title'] || assignedText['services_title'] || assignedText['sections.services.title'],
1155
+ subtitle: assignedText['services_section_subtitle'] || assignedText['services_subtitle'] || assignedText['sections.services.subtitle'],
1156
+ showViewAll: true,
1157
+ viewAll: assignedText['services_view_all'] || assignedText['sections.services.viewAll'] || 'View All Services',
1158
+ limit: 5,
1159
+ };
1160
+ }
1161
+ // Process section - migrate from old format to structured format (for booking layouts)
1162
+ if (layoutContent.sections?.process) {
1163
+ sections.process = {
1164
+ show: layoutContent.sections.process.show !== false,
1165
+ title: layoutContent.sections.process.title,
1166
+ subtitle: layoutContent.sections.process.subtitle,
1167
+ steps: layoutContent.sections.process.steps,
1168
+ };
1169
+ }
1170
+ else if (assignedText['process_title'] || assignedText['how_it_works_title']) {
1171
+ sections.process = {
1172
+ show: true,
1173
+ title: assignedText['process_title'] || assignedText['how_it_works_title'] || assignedText['sections.process.title'] || 'How it Works',
1174
+ subtitle: assignedText['process_subtitle'] || assignedText['how_it_works_subtitle'] || assignedText['sections.process.subtitle'],
1175
+ steps: [], // Will be populated from layout-specific process steps if available
1176
+ };
1177
+ }
1178
+ // Transform assignedText to structured text config
1179
+ const textConfig = {
1180
+ hero: {
1181
+ badge: assignedText['hero_badge'],
1182
+ title: assignedText['hero_title'],
1183
+ subtitle: assignedText['hero_subtitle'],
1184
+ primaryButton: assignedText['hero_primary_button'] || assignedText['hero_btn_label'] || assignedText['book_btn'],
1185
+ secondaryButton: assignedText['hero_secondary_button'] || assignedText['view_services_btn'],
1186
+ // Support multi-slide heroes
1187
+ slides: assignedText['hero_slide_1:heading'] ? [
1188
+ {
1189
+ badge: assignedText['hero_slide_1:badge'] || assignedText['hero_badge'],
1190
+ title: assignedText['hero_slide_1:heading'] || assignedText['hero_title'],
1191
+ description: assignedText['hero_slide_1:subheading'] || assignedText['hero_subtitle'],
1192
+ primaryButton: assignedText['hero_slide_1:btn_label'] || assignedText['hero_primary_button'],
1193
+ secondaryButton: assignedText['hero_slide_1:secondary_btn'] || assignedText['hero_secondary_button'],
1194
+ },
1195
+ assignedText['hero_slide_2:heading'] ? {
1196
+ badge: assignedText['hero_slide_2:badge'],
1197
+ title: assignedText['hero_slide_2:heading'],
1198
+ description: assignedText['hero_slide_2:subheading'],
1199
+ primaryButton: assignedText['hero_slide_2:btn_label'],
1200
+ secondaryButton: assignedText['hero_slide_2:secondary_btn'],
1201
+ } : undefined,
1202
+ assignedText['hero_slide_3:heading'] ? {
1203
+ badge: assignedText['hero_slide_3:badge'],
1204
+ title: assignedText['hero_slide_3:heading'],
1205
+ description: assignedText['hero_slide_3:subheading'],
1206
+ primaryButton: assignedText['hero_slide_3:btn_label'],
1207
+ secondaryButton: assignedText['hero_slide_3:secondary_btn'],
1208
+ } : undefined,
1209
+ ].filter(Boolean) : undefined,
1210
+ },
1211
+ sections: {
1212
+ categories: {
1213
+ title: assignedText['categories_title'],
1214
+ subtitle: assignedText['categories_subtitle'],
1215
+ viewAll: assignedText['categories_view_all'],
1216
+ },
1217
+ services: {
1218
+ title: assignedText['services_section_title'],
1219
+ subtitle: assignedText['services_section_subtitle'],
1220
+ listTitle: assignedText['services_list_title'],
1221
+ listCount: assignedText['services_list_count'],
1222
+ },
1223
+ testimonials: {
1224
+ quote: assignedText['testimonial_quote'],
1225
+ author: assignedText['testimonial_author'],
1226
+ role: assignedText['testimonial_role'],
1227
+ title: assignedText['testimonials_title'],
1228
+ subtitle: assignedText['testimonials_subtitle'],
1229
+ },
1230
+ cta: {
1231
+ title: assignedText['cta_title'],
1232
+ description: assignedText['cta_description'],
1233
+ },
1234
+ promo: {
1235
+ badge: assignedText['promo_badge'],
1236
+ title: assignedText['promo_title'],
1237
+ description: assignedText['promo_desc'],
1238
+ },
1239
+ experts: {
1240
+ title: assignedText['experts_section_title'],
1241
+ viewAll: assignedText['experts_view_all'],
1242
+ },
1243
+ featuredProducts: {
1244
+ title: assignedText['featured_products_title'] || assignedText['trending_title'] || assignedText['hero_slide_2:heading'],
1245
+ subtitle: assignedText['featured_products_subtitle'],
1246
+ viewAll: assignedText['featured_products_view_all'],
1247
+ emptyState: assignedText['featured_products_empty'],
1248
+ },
1249
+ marketing: {
1250
+ newsletter: {
1251
+ title: assignedText['newsletter_title'] || assignedText['footer_newsletter_title'],
1252
+ subtitle: assignedText['newsletter_subtitle'] || assignedText['footer_newsletter_subtitle'],
1253
+ button: assignedText['newsletter_button'] || assignedText['footer_newsletter_button'],
1254
+ placeholder: assignedText['newsletter_placeholder'],
1255
+ disclaimer: assignedText['newsletter_disclaimer'],
1256
+ },
1257
+ promoBanner: {
1258
+ title: assignedText['promo_banner_title'] || assignedText['promo_title'],
1259
+ subtitle: assignedText['promo_banner_subtitle'] || assignedText['promo_subtext'],
1260
+ button: assignedText['promo_banner_button'] || assignedText['promo_cta'],
1261
+ },
1262
+ },
1263
+ team: {
1264
+ title: assignedText['team_section_title'] || assignedText['team_title'],
1265
+ subtitle: assignedText['team_section_subtitle'] || assignedText['team_description'] || assignedText['team_desc'],
1266
+ viewAll: assignedText['team_view_all'],
1267
+ },
1268
+ process: {
1269
+ title: assignedText['process_title'],
1270
+ subtitle: assignedText['process_subtitle'],
1271
+ },
1272
+ },
1273
+ common: {
1274
+ shopNow: assignedText['common_shop_now'],
1275
+ viewAll: assignedText['common_view_all'],
1276
+ addToCart: assignedText['common_add_to_cart'],
1277
+ buyNow: assignedText['common_buy_now'],
1278
+ learnMore: assignedText['common_learn_more'],
1279
+ readMore: assignedText['common_read_more'],
1280
+ seeMore: assignedText['common_see_more'],
1281
+ discover: assignedText['common_discover'],
1282
+ explore: assignedText['common_explore'],
1283
+ new: assignedText['common_new'],
1284
+ trending: assignedText['common_trending'],
1285
+ limited: assignedText['common_limited'],
1286
+ sale: assignedText['common_sale'],
1287
+ outOfStock: assignedText['common_out_of_stock'],
1288
+ inStock: assignedText['common_in_stock'],
1289
+ selectSize: assignedText['common_select_size'],
1290
+ selectColor: assignedText['common_select_color'],
1291
+ quantity: assignedText['common_quantity'],
1292
+ reviews: assignedText['common_reviews'],
1293
+ writeReview: assignedText['common_write_review'],
1294
+ customerReviews: assignedText['common_customer_reviews'],
1295
+ noReviews: assignedText['common_no_reviews'],
1296
+ search: assignedText['common_search'],
1297
+ searchPlaceholder: assignedText['common_search_placeholder'],
1298
+ cart: assignedText['common_cart'],
1299
+ wishlist: assignedText['common_wishlist'],
1300
+ account: assignedText['common_account'],
1301
+ login: assignedText['common_login'],
1302
+ logout: assignedText['common_logout'],
1303
+ signup: assignedText['common_signup'],
1304
+ checkout: assignedText['common_checkout'],
1305
+ continueShopping: assignedText['common_continue_shopping'],
1306
+ proceedToCheckout: assignedText['common_proceed_to_checkout'],
1307
+ },
1308
+ footer: {
1309
+ newsletter: {
1310
+ title: assignedText['footer_newsletter_title'],
1311
+ subtitle: assignedText['footer_newsletter_subtitle'],
1312
+ button: assignedText['footer_newsletter_button'],
1313
+ placeholder: assignedText['footer_newsletter_placeholder'],
1314
+ disclaimer: assignedText['footer_newsletter_disclaimer'],
1315
+ },
1316
+ copyright: assignedText['footer_copyright'],
1317
+ links: {
1318
+ about: assignedText['footer_link_about'],
1319
+ contact: assignedText['footer_link_contact'],
1320
+ privacy: assignedText['footer_link_privacy'],
1321
+ terms: assignedText['footer_link_terms'],
1322
+ shipping: assignedText['footer_link_shipping'],
1323
+ faq: assignedText['footer_link_faq'],
1324
+ },
1325
+ },
1326
+ header: {
1327
+ searchPlaceholder: assignedText['header_search_placeholder'],
1328
+ cartEmpty: assignedText['header_cart_empty'],
1329
+ wishlistEmpty: assignedText['header_wishlist_empty'],
1330
+ accountMenu: {
1331
+ profile: assignedText['header_account_profile'],
1332
+ orders: assignedText['header_account_orders'],
1333
+ wishlist: assignedText['header_account_wishlist'],
1334
+ logout: assignedText['header_account_logout'],
1335
+ },
1336
+ },
1337
+ booking: {
1338
+ pageTitle: assignedText['booking_page_title'],
1339
+ pageSubtitle: assignedText['booking_page_subtitle'],
1340
+ bookAppointment: assignedText['booking_book_appointment'] || assignedText['book_btn'],
1341
+ viewServices: assignedText['booking_view_services'] || assignedText['view_services_btn'],
1342
+ selectDate: assignedText['booking_select_date'],
1343
+ selectService: assignedText['booking_select_service'],
1344
+ selectTime: assignedText['booking_select_time'],
1345
+ confirmBooking: assignedText['booking_confirm'],
1346
+ completePayment: assignedText['booking_complete_payment'],
1347
+ bookingConfirmed: assignedText['booking_confirmed'],
1348
+ limitedAvailability: assignedText['booking_limited_availability'],
1349
+ availableServices: assignedText['booking_available_services'] || assignedText['services_list_title'],
1350
+ showingResults: assignedText['booking_showing_results'] || assignedText['services_list_count'],
1351
+ filters: assignedText['booking_filters'],
1352
+ providers: assignedText['booking_providers'],
1353
+ },
1354
+ food: {
1355
+ reserveTable: assignedText['food_reserveTable'] || assignedText['food_reserve_table'],
1356
+ viewMenu: assignedText['food_viewMenu'] || assignedText['food_view_menu'],
1357
+ chefRecommendations: assignedText['food_chefRecommendations'] || assignedText['food_chef_recommendations'],
1358
+ ourPhilosophy: assignedText['food_ourPhilosophy'] || assignedText['food_our_philosophy'],
1359
+ meetChef: assignedText['food_meetChef'] || assignedText['food_meet_chef'],
1360
+ menuCategories: assignedText['food_menuCategories'] || assignedText['food_menu_categories'],
1361
+ },
1362
+ electronics: {
1363
+ newArrivals: assignedText['electronics_new_arrivals'],
1364
+ techSpecs: assignedText['electronics_tech_specs'],
1365
+ compare: assignedText['electronics_compare'],
1366
+ addToCompare: assignedText['electronics_add_to_compare'],
1367
+ removeFromCompare: assignedText['electronics_remove_from_compare'],
1368
+ brands: assignedText['electronics_brands'],
1369
+ },
1370
+ };
1371
+ // Remove undefined values to keep the config clean
1372
+ const cleanTextConfig = JSON.parse(JSON.stringify(textConfig, (key, value) => {
1373
+ if (value === undefined || (typeof value === 'object' && value !== null && Object.keys(value).length === 0)) {
1374
+ return undefined;
1375
+ }
1376
+ return value;
1377
+ }));
1378
+ // Transform theme colors if provided
1379
+ let themeColors;
1380
+ if (layoutContent.themeColors && typeof layoutContent.themeColors === 'object') {
1381
+ themeColors = {
1382
+ background: layoutContent.themeColors.background || undefined,
1383
+ text: layoutContent.themeColors.text || undefined,
1384
+ border: layoutContent.themeColors.border || undefined,
1385
+ gradient: layoutContent.themeColors.gradient || undefined,
1386
+ accent: layoutContent.themeColors.accent || undefined,
1387
+ layoutSpecific: layoutContent.themeColors.layoutSpecific || undefined,
1388
+ };
1389
+ // Remove undefined categories
1390
+ if (Object.values(themeColors).every(v => v === undefined)) {
1391
+ themeColors = undefined;
1392
+ }
1393
+ }
1394
+ // Also set hero at top level for backward compatibility (if sections.hero exists)
1395
+ const hero = sections?.hero ? {
1396
+ show: sections.hero.show !== false,
1397
+ showCTA: sections.hero.showCTA !== false,
1398
+ showSecondaryCTA: sections.hero.showSecondaryCTA !== false,
1399
+ autoPlay: sections.hero.autoPlay !== false,
1400
+ showBadges: sections.hero.showBadges !== false,
1401
+ sliders: sections.hero.sliders,
1402
+ } : undefined;
1403
+ return {
1404
+ hero, // Top-level hero for backward compatibility
1405
+ sections,
1406
+ assignedAssets,
1407
+ assignedText, // Preserve assignedText for direct access via getTextContent()
1408
+ assetRequirements: layoutContent.assetRequirements,
1409
+ text: Object.keys(cleanTextConfig).length > 0 ? cleanTextConfig : undefined,
1410
+ themeColors,
1411
+ version: layoutContent.version, // Preserve version for layout version checking
1412
+ };
1413
+ }
1414
+ /**
1415
+ * Async function to get store configuration
1416
+ * - For demo stores: uses mock data from mock-stores
1417
+ * - For real stores: fetches from API and transforms to StoreConfig
1418
+ * - Returns null storeConfig if store not found (for 404 handling)
1419
+ * - Returns maintenanceMode flag when store exists but is not published/active
1420
+ */
1421
+ export async function getStoreConfigAsync(storeSlug) {
1422
+ try {
1423
+ console.log(`[StoreConfig] Loading store config for slug: ${storeSlug}`);
1424
+ if (shouldUseAPI(storeSlug)) {
1425
+ // Use API for non-demo stores
1426
+ const baseSlug = getBaseStoreSlug(storeSlug);
1427
+ console.log(`[StoreConfig] Using API for store. Base slug: ${baseSlug}`);
1428
+ const { store: apiStore, maintenanceMode } = await storeService.getStoreBySlug(baseSlug);
1429
+ console.log(`[StoreConfig] Store loaded from API: ${apiStore.name} (ID: ${apiStore.id})`);
1430
+ const storeConfig = transformStoreResponseToConfig(apiStore);
1431
+ // Fetch categories, products, and services in parallel
1432
+ const [categoriesResult, productsResult, servicesResult] = await Promise.allSettled([
1433
+ // Fetch categories (backend Category entity doesn't have isActive field, so include all)
1434
+ categoryService.getCategories(apiStore.id).then((apiCategories) => apiCategories.map(transformCategoryToStoreCategory)),
1435
+ // Fetch products (backend already filters for isActive: true)
1436
+ productService
1437
+ .getProducts({
1438
+ storeId: apiStore.id,
1439
+ limit: 1000, // Fetch a large number to get all products for the store config
1440
+ })
1441
+ .then((response) => response.data.map(transformProductToStoreProduct)),
1442
+ // Fetch services (backend already filters for isActive: true)
1443
+ serviceService
1444
+ .getServices(apiStore.id)
1445
+ .then((apiServices) => apiServices.map(transformServiceToStoreService)),
1446
+ ]);
1447
+ // Extract results with graceful degradation
1448
+ const categories = categoriesResult.status === 'fulfilled' ? categoriesResult.value : [];
1449
+ const products = productsResult.status === 'fulfilled' ? productsResult.value : [];
1450
+ const services = servicesResult.status === 'fulfilled' ? servicesResult.value : [];
1451
+ // Log errors if any occurred
1452
+ if (categoriesResult.status === 'rejected') {
1453
+ console.error('[StoreConfig] Failed to fetch categories:', categoriesResult.reason);
1454
+ console.error('[StoreConfig] Category error details:', {
1455
+ message: categoriesResult.reason?.message,
1456
+ status: categoriesResult.reason?.status,
1457
+ response: categoriesResult.reason?.response?.data,
1458
+ });
1459
+ }
1460
+ else {
1461
+ console.log(`[StoreConfig] Successfully fetched ${categories.length} categories for store ${apiStore.id} (${apiStore.slug})`);
1462
+ if (categories.length === 0) {
1463
+ console.warn(`[StoreConfig] WARNING: No categories found for store ${apiStore.id}. This may indicate missing data in the database.`);
1464
+ }
1465
+ }
1466
+ if (productsResult.status === 'rejected') {
1467
+ console.error('[StoreConfig] Failed to fetch products:', productsResult.reason);
1468
+ console.error('[StoreConfig] Product error details:', {
1469
+ message: productsResult.reason?.message,
1470
+ status: productsResult.reason?.status,
1471
+ response: productsResult.reason?.response?.data,
1472
+ });
1473
+ }
1474
+ else {
1475
+ console.log(`[StoreConfig] Successfully fetched ${products.length} products for store ${apiStore.id} (${apiStore.slug})`);
1476
+ if (products.length === 0) {
1477
+ console.warn(`[StoreConfig] WARNING: No products found for store ${apiStore.id}. This may indicate missing data in the database.`);
1478
+ }
1479
+ }
1480
+ if (servicesResult.status === 'rejected') {
1481
+ console.error('[StoreConfig] Failed to fetch services:', servicesResult.reason);
1482
+ console.error('[StoreConfig] Service error details:', {
1483
+ message: servicesResult.reason?.message,
1484
+ status: servicesResult.reason?.status,
1485
+ response: servicesResult.reason?.response?.data,
1486
+ });
1487
+ }
1488
+ else {
1489
+ console.log(`[StoreConfig] Successfully fetched ${services.length} services for store ${apiStore.id} (${apiStore.slug})`);
1490
+ if (services.length === 0) {
1491
+ console.warn(`[StoreConfig] WARNING: No services found for store ${apiStore.id}. This may indicate missing data in the database.`);
1492
+ }
1493
+ }
1494
+ // Populate categories, products, and services in storeConfig
1495
+ storeConfig.categories = categories;
1496
+ storeConfig.products = products;
1497
+ storeConfig.services = services;
1498
+ console.log(`[StoreConfig] Final storeConfig populated with ${categories.length} categories, ${products.length} products, and ${services.length} services`);
1499
+ return {
1500
+ storeConfig,
1501
+ maintenanceMode: maintenanceMode || false,
1502
+ };
1503
+ }
1504
+ else {
1505
+ // Use mock data for demo stores (always active and published)
1506
+ const baseSlug = getBaseStoreSlug(storeSlug);
1507
+ console.log(`[StoreConfig] Using mock data for demo store. Base slug: ${baseSlug}`);
1508
+ const storeConfig = getStoreConfig(baseSlug);
1509
+ if (storeConfig) {
1510
+ console.log(`[StoreConfig] Mock store loaded: ${storeConfig.name} with ${storeConfig.categories?.length || 0} categories and ${storeConfig.products?.length || 0} products`);
1511
+ }
1512
+ return {
1513
+ storeConfig,
1514
+ maintenanceMode: false, // Demo stores are always available
1515
+ };
1516
+ }
1517
+ }
1518
+ catch (error) {
1519
+ // Check if it's a 404 (store not found) vs other error
1520
+ const isNotFound = error?.status === 404 || error?.response?.status === 404;
1521
+ if (isNotFound) {
1522
+ // Store truly doesn't exist
1523
+ return {
1524
+ storeConfig: null,
1525
+ maintenanceMode: false,
1526
+ };
1527
+ }
1528
+ // Other API errors - log and return null
1529
+ console.error('Failed to fetch store config:', error);
1530
+ return {
1531
+ storeConfig: null,
1532
+ maintenanceMode: false,
1533
+ };
1534
+ }
1535
+ }