@salla.sa/twilight-theme-engine 1.0.129 → 1.0.131

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 (280) hide show
  1. package/dist/{AddToCartForm-I2SZGGZK.js → AddToCartForm-S73TIRFL.js} +3 -3
  2. package/dist/{AddToCartForm-I2SZGGZK.js.map → AddToCartForm-S73TIRFL.js.map} +1 -1
  3. package/dist/{BlogAuthorPage-JHZHLSIA.js → BlogAuthorPage-ISOONUBI.js} +19 -18
  4. package/dist/BlogAuthorPage-ISOONUBI.js.map +1 -0
  5. package/dist/{BlogCategoryPage-F4264MQG.js → BlogCategoryPage-3CEQWDB7.js} +19 -18
  6. package/dist/BlogCategoryPage-3CEQWDB7.js.map +1 -0
  7. package/dist/{BlogPage-3TELFUFM.js → BlogPage-AYYUM3GY.js} +17 -16
  8. package/dist/BlogPage-AYYUM3GY.js.map +1 -0
  9. package/dist/{BlogSinglePage-QBADHXXZ.js → BlogSinglePage-NH7RZVLA.js} +17 -16
  10. package/dist/BlogSinglePage-NH7RZVLA.js.map +1 -0
  11. package/dist/{BlogTagPage-WEP37KDY.js → BlogTagPage-LONJWWDW.js} +19 -18
  12. package/dist/BlogTagPage-LONJWWDW.js.map +1 -0
  13. package/dist/{BrandsPage-EENWKAIY.js → BrandsPage-DTV4FJBP.js} +18 -17
  14. package/dist/BrandsPage-DTV4FJBP.js.map +1 -0
  15. package/dist/{Breadcrumb-A2CNX5VU.js → Breadcrumb-JCEPGH5A.js} +17 -16
  16. package/dist/Breadcrumb-JCEPGH5A.js.map +1 -0
  17. package/dist/{CartItem-X7UB2GZG.js → CartItem-NTIU45BB.js} +17 -16
  18. package/dist/CartItem-NTIU45BB.js.map +1 -0
  19. package/dist/{CartSummary-EEJ3JO6E.js → CartSummary-GETYV24Q.js} +17 -16
  20. package/dist/CartSummary-GETYV24Q.js.map +1 -0
  21. package/dist/{Copyright-VGOFMMIR.js → Copyright-W7RY445F.js} +3 -3
  22. package/dist/{Copyright-VGOFMMIR.js.map → Copyright-W7RY445F.js.map} +1 -1
  23. package/dist/{CustomerLayout-2E6ENXOH.js → CustomerLayout-P5QZJDMR.js} +17 -16
  24. package/dist/CustomerLayout-P5QZJDMR.js.map +1 -0
  25. package/dist/{Footer-5L3YKKPB.js → Footer-GANB36WN.js} +4 -4
  26. package/dist/{Footer-5L3YKKPB.js.map → Footer-GANB36WN.js.map} +1 -1
  27. package/dist/{Header-KMURB263.js → Header-IZ3UWIEO.js} +8 -8
  28. package/dist/{Header-KMURB263.js.map → Header-IZ3UWIEO.js.map} +1 -1
  29. package/dist/{LiveEditorBar-DOSRO35J.js → LiveEditorBar-4AWOAJYX.js} +58 -9
  30. package/dist/LiveEditorBar-4AWOAJYX.js.map +1 -0
  31. package/dist/{LoyaltyPage-WI2SL6SR.js → LoyaltyPage-BNJO3BTK.js} +17 -16
  32. package/dist/LoyaltyPage-BNJO3BTK.js.map +1 -0
  33. package/dist/{LoyaltyPointsPage-RKGFGLL4.js → LoyaltyPointsPage-2OGOGII3.js} +6 -6
  34. package/dist/{LoyaltyPointsPage-RKGFGLL4.js.map → LoyaltyPointsPage-2OGOGII3.js.map} +1 -1
  35. package/dist/{MainMenu-VFI4SRRS.js → MainMenu-56OTUHET.js} +5 -5
  36. package/dist/{MainMenu-VFI4SRRS.js.map → MainMenu-56OTUHET.js.map} +1 -1
  37. package/dist/MaintenancePage-A7CNHM7B.js +7 -0
  38. package/dist/{MaintenancePage-7Y4QA5LD.js.map → MaintenancePage-A7CNHM7B.js.map} +1 -1
  39. package/dist/{MasterLayout-AZSOVNPR.js → MasterLayout-DWXUEODB.js} +17 -16
  40. package/dist/{MasterLayout-AZSOVNPR.js.map → MasterLayout-DWXUEODB.js.map} +1 -1
  41. package/dist/{MobileMenu-PRND3T3Z.js → MobileMenu-JJA7PHVS.js} +18 -17
  42. package/dist/MobileMenu-JJA7PHVS.js.map +1 -0
  43. package/dist/{NotificationsPage-VPCF5TNJ.js → NotificationsPage-L57HNZRC.js} +17 -16
  44. package/dist/NotificationsPage-L57HNZRC.js.map +1 -0
  45. package/dist/{OrderSinglePage-BIPGDSSI.js → OrderSinglePage-5FWWZ4TJ.js} +18 -17
  46. package/dist/OrderSinglePage-5FWWZ4TJ.js.map +1 -0
  47. package/dist/{OrdersPage-DTI5CYHH.js → OrdersPage-AE674QJO.js} +17 -16
  48. package/dist/OrdersPage-AE674QJO.js.map +1 -0
  49. package/dist/{PageSingle-VUKTKJKB.js → PageSingle-N5G42IIX.js} +3 -3
  50. package/dist/{PageSingle-VUKTKJKB.js.map → PageSingle-N5G42IIX.js.map} +1 -1
  51. package/dist/{ProductDetails-CUSUV3YF.js → ProductDetails-FWN3T7H7.js} +4 -4
  52. package/dist/{ProductDetails-CUSUV3YF.js.map → ProductDetails-FWN3T7H7.js.map} +1 -1
  53. package/dist/{ProfilePage-APTF4ZI3.js → ProfilePage-BXZJY55Z.js} +17 -16
  54. package/dist/ProfilePage-BXZJY55Z.js.map +1 -0
  55. package/dist/{ReviewsPage-Q5UUELM5.js → ReviewsPage-A7OXTEXY.js} +3 -3
  56. package/dist/{ReviewsPage-Q5UUELM5.js.map → ReviewsPage-A7OXTEXY.js.map} +1 -1
  57. package/dist/{SeoCartWidget-7BLWJVZ7.js → SeoCartWidget-N3MOUSW7.js} +17 -16
  58. package/dist/SeoCartWidget-N3MOUSW7.js.map +1 -0
  59. package/dist/{SettingsPage-I6STBZ2M.js → SettingsPage-DFHGU5OH.js} +17 -16
  60. package/dist/SettingsPage-DFHGU5OH.js.map +1 -0
  61. package/dist/{StoreClosedNotification-PNOFS2B5.js → StoreClosedNotification-GNSQYWDS.js} +18 -17
  62. package/dist/{StoreClosedNotification-PNOFS2B5.js.map → StoreClosedNotification-GNSQYWDS.js.map} +1 -1
  63. package/dist/{TestimonialsPage-S64KZKPY.js → TestimonialsPage-26OBKQAG.js} +3 -3
  64. package/dist/{TestimonialsPage-S64KZKPY.js.map → TestimonialsPage-26OBKQAG.js.map} +1 -1
  65. package/dist/{ThankYouPage-VGNCUZTV.js → ThankYouPage-7C3OC6P5.js} +17 -16
  66. package/dist/ThankYouPage-7C3OC6P5.js.map +1 -0
  67. package/dist/{WalletPage-MIXW2MTQ.js → WalletPage-RA354UQQ.js} +18 -17
  68. package/dist/WalletPage-RA354UQQ.js.map +1 -0
  69. package/dist/{WishlistPage-RVWSOXRC.js → WishlistPage-NTJW33VF.js} +19 -18
  70. package/dist/WishlistPage-NTJW33VF.js.map +1 -0
  71. package/dist/api/advertisement.js +2 -2
  72. package/dist/api/apps.js +2 -2
  73. package/dist/api/blog.js +3 -3
  74. package/dist/api/brands.js +3 -3
  75. package/dist/api/cart.js +3 -3
  76. package/dist/api/category.js +3 -3
  77. package/dist/api/client.js +1 -1
  78. package/dist/api/home.js +2 -2
  79. package/dist/api/loyalty.js +3 -3
  80. package/dist/api/menu.js +2 -2
  81. package/dist/api/notification.js +2 -2
  82. package/dist/api/order.js +3 -3
  83. package/dist/api/page.js +3 -3
  84. package/dist/api/product.js +3 -3
  85. package/dist/api/profile.js +1 -1
  86. package/dist/api/store.d.ts +8 -0
  87. package/dist/api/store.d.ts.map +1 -1
  88. package/dist/api/store.js +3 -2
  89. package/dist/api/translations.js +2 -2
  90. package/dist/api/user.js +2 -2
  91. package/dist/api/wallet.js +2 -2
  92. package/dist/api/wishlist.js +4 -4
  93. package/dist/{chunk-QPKK4LPK.js → chunk-2Z7XKCT3.js} +23 -4
  94. package/dist/chunk-2Z7XKCT3.js.map +1 -0
  95. package/dist/{chunk-KQEBYXYB.js → chunk-3CNXPHJE.js} +4 -69
  96. package/dist/chunk-3CNXPHJE.js.map +1 -0
  97. package/dist/{chunk-XX4L34QI.js → chunk-3FXRE7JW.js} +6 -6
  98. package/dist/{chunk-XX4L34QI.js.map → chunk-3FXRE7JW.js.map} +1 -1
  99. package/dist/{chunk-2SCIGF3L.js → chunk-4YYB4AUZ.js} +4 -4
  100. package/dist/{chunk-2SCIGF3L.js.map → chunk-4YYB4AUZ.js.map} +1 -1
  101. package/dist/{chunk-L75KAYY5.js → chunk-5LOWNXWH.js} +12 -11
  102. package/dist/chunk-5LOWNXWH.js.map +1 -0
  103. package/dist/{chunk-2M5BICJK.js → chunk-67XC4WLH.js} +4 -4
  104. package/dist/{chunk-2M5BICJK.js.map → chunk-67XC4WLH.js.map} +1 -1
  105. package/dist/{chunk-OOSLYT2L.js → chunk-6A42EQCV.js} +7 -7
  106. package/dist/{chunk-OOSLYT2L.js.map → chunk-6A42EQCV.js.map} +1 -1
  107. package/dist/{chunk-FFIONN5M.js → chunk-6S2SIUOD.js} +7 -7
  108. package/dist/{chunk-FFIONN5M.js.map → chunk-6S2SIUOD.js.map} +1 -1
  109. package/dist/{chunk-763YWRXT.js → chunk-77Z3U5JT.js} +3 -3
  110. package/dist/{chunk-763YWRXT.js.map → chunk-77Z3U5JT.js.map} +1 -1
  111. package/dist/{chunk-EMOLTV77.js → chunk-B3EKF5HJ.js} +4 -4
  112. package/dist/{chunk-EMOLTV77.js.map → chunk-B3EKF5HJ.js.map} +1 -1
  113. package/dist/{chunk-NOVJ3US5.js → chunk-CBYM3JIG.js} +3 -3
  114. package/dist/{chunk-NOVJ3US5.js.map → chunk-CBYM3JIG.js.map} +1 -1
  115. package/dist/{chunk-J5DGBS7Q.js → chunk-CKH6WBMA.js} +71 -7
  116. package/dist/chunk-CKH6WBMA.js.map +1 -0
  117. package/dist/{chunk-ASTCQSK6.js → chunk-CR3EY7K7.js} +3 -3
  118. package/dist/{chunk-ASTCQSK6.js.map → chunk-CR3EY7K7.js.map} +1 -1
  119. package/dist/{chunk-RPRZYRPX.js → chunk-DJHYJ2VY.js} +4 -4
  120. package/dist/{chunk-RPRZYRPX.js.map → chunk-DJHYJ2VY.js.map} +1 -1
  121. package/dist/{chunk-WOMGFBX5.js → chunk-DSJE2TS2.js} +4 -4
  122. package/dist/{chunk-WOMGFBX5.js.map → chunk-DSJE2TS2.js.map} +1 -1
  123. package/dist/{chunk-ZWOD67SV.js → chunk-EAKEYWYL.js} +3 -3
  124. package/dist/{chunk-ZWOD67SV.js.map → chunk-EAKEYWYL.js.map} +1 -1
  125. package/dist/{chunk-V4HOZSIW.js → chunk-ECMFNYPW.js} +3 -3
  126. package/dist/{chunk-V4HOZSIW.js.map → chunk-ECMFNYPW.js.map} +1 -1
  127. package/dist/chunk-FID76MUV.js +73 -0
  128. package/dist/chunk-FID76MUV.js.map +1 -0
  129. package/dist/{chunk-DEDX3AIO.js → chunk-FU52JCUN.js} +7 -7
  130. package/dist/{chunk-DEDX3AIO.js.map → chunk-FU52JCUN.js.map} +1 -1
  131. package/dist/{chunk-FBOWKMPX.js → chunk-GHACVKKD.js} +19 -18
  132. package/dist/chunk-GHACVKKD.js.map +1 -0
  133. package/dist/{chunk-FHAHE46U.js → chunk-H2QBHOF2.js} +2 -2
  134. package/dist/{chunk-FHAHE46U.js.map → chunk-H2QBHOF2.js.map} +1 -1
  135. package/dist/{chunk-RDMEIF2O.js → chunk-HCCSVECA.js} +4 -4
  136. package/dist/{chunk-RDMEIF2O.js.map → chunk-HCCSVECA.js.map} +1 -1
  137. package/dist/chunk-IXHM24Z4.js +28 -0
  138. package/dist/chunk-IXHM24Z4.js.map +1 -0
  139. package/dist/{chunk-VWZG5QKQ.js → chunk-J2OPSCWD.js} +3 -3
  140. package/dist/{chunk-VWZG5QKQ.js.map → chunk-J2OPSCWD.js.map} +1 -1
  141. package/dist/{chunk-QRFYOEZY.js → chunk-KSGBNVBQ.js} +3 -3
  142. package/dist/{chunk-QRFYOEZY.js.map → chunk-KSGBNVBQ.js.map} +1 -1
  143. package/dist/{chunk-AT3IL55G.js → chunk-MYW5QYWO.js} +3 -3
  144. package/dist/{chunk-AT3IL55G.js.map → chunk-MYW5QYWO.js.map} +1 -1
  145. package/dist/{chunk-6VBXPDXM.js → chunk-ONK7RUTK.js} +3 -3
  146. package/dist/{chunk-6VBXPDXM.js.map → chunk-ONK7RUTK.js.map} +1 -1
  147. package/dist/{chunk-747V3UL5.js → chunk-OSIFK62D.js} +3 -3
  148. package/dist/{chunk-747V3UL5.js.map → chunk-OSIFK62D.js.map} +1 -1
  149. package/dist/{chunk-6I2J6V3S.js → chunk-QT5YXTED.js} +3 -3
  150. package/dist/{chunk-6I2J6V3S.js.map → chunk-QT5YXTED.js.map} +1 -1
  151. package/dist/{chunk-D7IP4MVJ.js → chunk-R4CQNOSV.js} +27 -12
  152. package/dist/chunk-R4CQNOSV.js.map +1 -0
  153. package/dist/{chunk-PTSJOV2E.js → chunk-R5AR7QRY.js} +4 -4
  154. package/dist/{chunk-PTSJOV2E.js.map → chunk-R5AR7QRY.js.map} +1 -1
  155. package/dist/{chunk-G74DWDSJ.js → chunk-RHMJ6VR7.js} +3 -3
  156. package/dist/{chunk-G74DWDSJ.js.map → chunk-RHMJ6VR7.js.map} +1 -1
  157. package/dist/{chunk-OQTBHL5T.js → chunk-SOQN5WKL.js} +3 -3
  158. package/dist/{chunk-OQTBHL5T.js.map → chunk-SOQN5WKL.js.map} +1 -1
  159. package/dist/{chunk-3TKG3ORJ.js → chunk-TUW2BXB3.js} +6 -6
  160. package/dist/{chunk-3TKG3ORJ.js.map → chunk-TUW2BXB3.js.map} +1 -1
  161. package/dist/{chunk-OYPE6432.js → chunk-USDRQPA3.js} +5 -3
  162. package/dist/chunk-USDRQPA3.js.map +1 -0
  163. package/dist/{chunk-WQJT663R.js → chunk-VRLPOATQ.js} +3 -3
  164. package/dist/{chunk-WQJT663R.js.map → chunk-VRLPOATQ.js.map} +1 -1
  165. package/dist/{chunk-IWBUTY3D.js → chunk-W4OJM7BD.js} +4 -4
  166. package/dist/{chunk-IWBUTY3D.js.map → chunk-W4OJM7BD.js.map} +1 -1
  167. package/dist/chunk-WW6B37EO.js +14 -0
  168. package/dist/{chunk-DEZVFNN2.js.map → chunk-WW6B37EO.js.map} +1 -1
  169. package/dist/{chunk-GJFWNFMU.js → chunk-XDPKYHQJ.js} +3 -3
  170. package/dist/{chunk-GJFWNFMU.js.map → chunk-XDPKYHQJ.js.map} +1 -1
  171. package/dist/{chunk-ECY5POOK.js → chunk-XH36I3IM.js} +3 -3
  172. package/dist/{chunk-ECY5POOK.js.map → chunk-XH36I3IM.js.map} +1 -1
  173. package/dist/{chunk-F5H7QF2T.js → chunk-Y22HI53V.js} +4 -4
  174. package/dist/{chunk-F5H7QF2T.js.map → chunk-Y22HI53V.js.map} +1 -1
  175. package/dist/{chunk-EPTYC5H3.js → chunk-YOJTLXNS.js} +4 -4
  176. package/dist/{chunk-EPTYC5H3.js.map → chunk-YOJTLXNS.js.map} +1 -1
  177. package/dist/{chunk-OJ7YQEW7.js → chunk-Z4MMMPKI.js} +4 -4
  178. package/dist/{chunk-OJ7YQEW7.js.map → chunk-Z4MMMPKI.js.map} +1 -1
  179. package/dist/{chunk-CLZRX5TX.js → chunk-ZGU7B5F4.js} +3 -3
  180. package/dist/{chunk-CLZRX5TX.js.map → chunk-ZGU7B5F4.js.map} +1 -1
  181. package/dist/components/cart/index.js +1 -1
  182. package/dist/components/common/index.js +1 -1
  183. package/dist/components/drawer/index.js +15 -14
  184. package/dist/components/home/index.js +19 -18
  185. package/dist/components/layout/index.js +4 -4
  186. package/dist/components/live-editor/LiveEditorBar.d.ts.map +1 -1
  187. package/dist/components/live-editor/frame.d.ts +2 -0
  188. package/dist/components/live-editor/frame.d.ts.map +1 -1
  189. package/dist/components/live-editor/moves.d.ts +14 -0
  190. package/dist/components/live-editor/moves.d.ts.map +1 -0
  191. package/dist/components/product/index.js +16 -15
  192. package/dist/components/store/MaintenancePage.d.ts +3 -2
  193. package/dist/components/store/MaintenancePage.d.ts.map +1 -1
  194. package/dist/components/store/index.js +17 -16
  195. package/dist/dev/editor/index.js +1 -1
  196. package/dist/dev/index.js +1 -1
  197. package/dist/{document-class-7JZLKPFE.js → document-class-ZHPKTBSI.js} +13 -12
  198. package/dist/{document-class-7JZLKPFE.js.map → document-class-ZHPKTBSI.js.map} +1 -1
  199. package/dist/hooks/index.js +15 -14
  200. package/dist/hooks/useGtm.js +15 -14
  201. package/dist/hooks/useMoney.js +15 -14
  202. package/dist/hooks/useStore.js +15 -14
  203. package/dist/hooks/useUser.js +3 -3
  204. package/dist/index.js +15 -14
  205. package/dist/index.js.map +1 -1
  206. package/dist/{navigation-IUHYIHIQ.js → navigation-7DJCQ7MJ.js} +5 -5
  207. package/dist/{navigation-IUHYIHIQ.js.map → navigation-7DJCQ7MJ.js.map} +1 -1
  208. package/dist/{navigation-L77QYQHZ.js → navigation-HC3IK4P7.js} +4 -4
  209. package/dist/{navigation-L77QYQHZ.js.map → navigation-HC3IK4P7.js.map} +1 -1
  210. package/dist/{not-found-YVGX5ST2.js → not-found-ANC6EGYO.js} +18 -17
  211. package/dist/not-found-ANC6EGYO.js.map +1 -0
  212. package/dist/providers/NavigationProvider.d.ts +2 -0
  213. package/dist/providers/NavigationProvider.d.ts.map +1 -1
  214. package/dist/providers/index.js +15 -14
  215. package/dist/routes/account/orders.js +4 -4
  216. package/dist/routes/account.js +13 -13
  217. package/dist/routes/blog.js +8 -8
  218. package/dist/routes/brands.js +4 -4
  219. package/dist/routes/cart.js +24 -22
  220. package/dist/routes/cart.js.map +1 -1
  221. package/dist/routes/home/HomePage.d.ts.map +1 -1
  222. package/dist/routes/home.js +21 -19
  223. package/dist/routes/index.js +3 -3
  224. package/dist/routes/loyalty.js +5 -5
  225. package/dist/routes/page.js +4 -4
  226. package/dist/routes/product-listing.js +21 -20
  227. package/dist/routes/product-listing.js.map +1 -1
  228. package/dist/routes/product.js +19 -18
  229. package/dist/routes/product.js.map +1 -1
  230. package/dist/routes/seo-redirects.js +3 -3
  231. package/dist/routes/testimonials.js +2 -2
  232. package/dist/routes/thank-you.js +4 -4
  233. package/dist/skeleton.js +21 -19
  234. package/dist/{store-lookup-F66OF7JS.js → store-lookup-5SPFTCPN.js} +8 -8
  235. package/dist/{store-lookup-F66OF7JS.js.map → store-lookup-5SPFTCPN.js.map} +1 -1
  236. package/dist/tanstack.js +13 -12
  237. package/dist/tanstack.js.map +1 -1
  238. package/dist/types/twilight.d.ts +4 -2
  239. package/dist/types/twilight.d.ts.map +1 -1
  240. package/dist/utils/index.js +2 -2
  241. package/dist/utils/maintenance.d.ts +13 -0
  242. package/dist/utils/maintenance.d.ts.map +1 -1
  243. package/package.json +1 -1
  244. package/tailwind/components/live-editor/LiveEditorBar.tsx.txt +80 -8
  245. package/tailwind/components/live-editor/frame.ts.txt +1 -1
  246. package/tailwind/components/live-editor/moves.ts.txt +38 -0
  247. package/tailwind/components/store/MaintenancePage.tsx.txt +116 -6
  248. package/tailwind/routes/home/HomePage.tsx.txt +32 -6
  249. package/dist/BlogAuthorPage-JHZHLSIA.js.map +0 -1
  250. package/dist/BlogCategoryPage-F4264MQG.js.map +0 -1
  251. package/dist/BlogPage-3TELFUFM.js.map +0 -1
  252. package/dist/BlogSinglePage-QBADHXXZ.js.map +0 -1
  253. package/dist/BlogTagPage-WEP37KDY.js.map +0 -1
  254. package/dist/BrandsPage-EENWKAIY.js.map +0 -1
  255. package/dist/Breadcrumb-A2CNX5VU.js.map +0 -1
  256. package/dist/CartItem-X7UB2GZG.js.map +0 -1
  257. package/dist/CartSummary-EEJ3JO6E.js.map +0 -1
  258. package/dist/CustomerLayout-2E6ENXOH.js.map +0 -1
  259. package/dist/LiveEditorBar-DOSRO35J.js.map +0 -1
  260. package/dist/LoyaltyPage-WI2SL6SR.js.map +0 -1
  261. package/dist/MaintenancePage-7Y4QA5LD.js +0 -7
  262. package/dist/MobileMenu-PRND3T3Z.js.map +0 -1
  263. package/dist/NotificationsPage-VPCF5TNJ.js.map +0 -1
  264. package/dist/OrderSinglePage-BIPGDSSI.js.map +0 -1
  265. package/dist/OrdersPage-DTI5CYHH.js.map +0 -1
  266. package/dist/ProfilePage-APTF4ZI3.js.map +0 -1
  267. package/dist/SeoCartWidget-7BLWJVZ7.js.map +0 -1
  268. package/dist/SettingsPage-I6STBZ2M.js.map +0 -1
  269. package/dist/ThankYouPage-VGNCUZTV.js.map +0 -1
  270. package/dist/WalletPage-MIXW2MTQ.js.map +0 -1
  271. package/dist/WishlistPage-RVWSOXRC.js.map +0 -1
  272. package/dist/chunk-D7IP4MVJ.js.map +0 -1
  273. package/dist/chunk-DEZVFNN2.js +0 -14
  274. package/dist/chunk-FBOWKMPX.js.map +0 -1
  275. package/dist/chunk-J5DGBS7Q.js.map +0 -1
  276. package/dist/chunk-KQEBYXYB.js.map +0 -1
  277. package/dist/chunk-L75KAYY5.js.map +0 -1
  278. package/dist/chunk-OYPE6432.js.map +0 -1
  279. package/dist/chunk-QPKK4LPK.js.map +0 -1
  280. package/dist/not-found-YVGX5ST2.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/routes/seo-redirects.ts"],"names":[],"mappings":";;;;;AAcA,eAAsB,wBAAwB,GAAA,EAAkD;AAC9F,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,SAAS,CAAA,CAAA,EAAI,MAAM,WAAW,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AACrD;AAOA,eAAsB,4BACpB,GAAA,GAA+C,EAAE,MAAA,EAAQ,IAAG,EAC5C;AAChB,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,QAAA,CAAS,CAAA,CAAA,EAAI,MAAM,CAAA,8BAAA,CAAgC,CAAA;AAC3D;AAGA,eAAsB,qBACpB,GAAA,GAA+C,EAAE,MAAA,EAAQ,IAAG,EAC5C;AAChB,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,QAAA,CAAS,CAAA,CAAA,EAAI,MAAM,CAAA,eAAA,CAAiB,CAAA;AAC5C;AAGA,eAAsB,sBAAsB,GAAA,EAKzB;AAEjB,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,CAAO,MAAA,GAAS,IAAI,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,CAAA,GAAK,EAAA;AAC7D,EAAA,MAAM,QAAA,CAAS,CAAA,EAAG,MAAM,CAAA,SAAA,EAAY,IAAI,IAAI,CAAA,EAAG,GAAA,CAAI,MAAA,IAAU,EAAE,CAAA,CAAA,EAAI,EAAE,UAAA,EAAY,KAAK,CAAA;AACxF;AAGA,eAAsB,6BAA6B,GAAA,EAIhC;AACjB,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,CAAO,MAAA,GAAS,IAAI,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,CAAA,GAAK,EAAA;AAC7D,EAAA,MAAM,KAAA,GAAQ,IAAI,eAAA,CAAgB,GAAA,CAAI,MAAM,CAAA;AAC5C,EAAA,KAAA,CAAM,OAAO,QAAQ,CAAA;AACrB,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,EAAS;AAC5B,EAAA,MAAM,QAAA,CAAS,CAAA,EAAG,MAAM,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,EAAG,IAAA,GAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA,EAAI;AAAA,IACjF,UAAA,EAAY;AAAA,GACb,CAAA;AACH;AAUO,SAAS,cAAA,GAAuB;AACrC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,oBAAA,EAAqB;AAErB,IAAA,MAAA,CAAO,QAAA,CAAS,QAAQ,MAAA,CAAO,QAAA,CAAS,KAAK,OAAA,CAAQ,8BAAA,EAAgC,EAAE,CAAC,CAAA;AAAA,EAC1F,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,OAAO,IAAA;AACT","file":"chunk-NOVJ3US5.js","sourcesContent":["import { useEffect } from 'react';\nimport { redirect } from '../providers/NavigationProvider';\nimport { FALLBACK_LOCALE } from '../providers/locale-constants';\nimport { clearAuthTokenCookie } from '../utils/cookies';\n\nexport interface SlugBrandParams {\n /** SEO slug segment (ignored — only here to match the route pattern). */\n slug: string;\n /** Brand numeric ID to redirect to. */\n id: string;\n /** Active locale from the `/$locale` parent layout (e.g. `'ar'`, `'en'`). */\n locale?: string;\n}\n\nexport async function slugBrandRedirectLoader(ctx: { params: SlugBrandParams }): Promise<never> {\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n throw redirect(`/${locale}/brands/${ctx.params.id}`);\n}\n\nexport interface PendingOrdersRedirectParams {\n /** Active locale from the `/$locale` parent layout (e.g. `'ar'`, `'en'`). */\n locale?: string;\n}\n\nexport async function pendingOrdersRedirectLoader(\n ctx: { params: PendingOrdersRedirectParams } = { params: {} }\n): Promise<never> {\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n throw redirect(`/${locale}/account/orders?status=pending`);\n}\n\n/** `/account/rating`: the loyalty \"rate your orders\" link. Twig Raed has no rating page and sends it to the orders list. */\nexport async function ratingRedirectLoader(\n ctx: { params: PendingOrdersRedirectParams } = { params: {} }\n): Promise<never> {\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n throw redirect(`/${locale}/account/orders`);\n}\n\n/** A Twig customer URL (`/profile`, `/orders`, …) kept working as its `/account/…` page. */\nexport async function accountRedirectLoader(ctx: {\n params: PendingOrdersRedirectParams;\n page: string;\n /** The incoming query string (`?status=pending`), kept on the account page. */\n search?: string;\n}): Promise<never> {\n // No locale in the URL stays without one: the locale layout adds it only where the store has several.\n const prefix = ctx.params.locale ? `/${ctx.params.locale}` : '';\n throw redirect(`${prefix}/account/${ctx.page}${ctx.search ?? ''}`, { statusCode: 301 });\n}\n\n/** `/latest-products`, `/most-sales-products` and `/offers` now live at `/products?source=`. */\nexport async function productsSourceRedirectLoader(ctx: {\n params: PendingOrdersRedirectParams;\n source: 'latest' | 'sales' | 'offers';\n search?: string;\n}): Promise<never> {\n const prefix = ctx.params.locale ? `/${ctx.params.locale}` : '';\n const query = new URLSearchParams(ctx.search);\n query.delete('source');\n const rest = query.toString();\n throw redirect(`${prefix}/products?source=${ctx.source}${rest ? `&${rest}` : ''}`, {\n statusCode: 301,\n });\n}\n\n/**\n * `/logout` — where the SDK sends the browser once `salla.auth.logout()` has run\n * (`salla.url.get('logout?from=…')`). The Twig storefront serves that URL server-side. Here\n * it renders nothing and, in the browser, removes the theme's own `token` cookie (the SDK's\n * `cookie.clearAll()` leaves it) and then does a full navigation home. It has to be a\n * component, not a loader redirect: a loader runs during server rendering, where the cookie\n * can't be cleared, so the redirect would leave the visitor signed in on the next request.\n */\nexport function LogoutRedirect(): null {\n useEffect(() => {\n clearAuthTokenCookie();\n // `/{store base}/{locale}/logout?from=…` → `/{store base}/{locale}`\n window.location.replace(window.location.href.replace(/\\/logout\\/?(\\?[^#]*)?(#.*)?$/, ''));\n }, []);\n return null;\n}\n"]}
1
+ {"version":3,"sources":["../src/routes/seo-redirects.ts"],"names":[],"mappings":";;;;;AAcA,eAAsB,wBAAwB,GAAA,EAAkD;AAC9F,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,SAAS,CAAA,CAAA,EAAI,MAAM,WAAW,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AACrD;AAOA,eAAsB,4BACpB,GAAA,GAA+C,EAAE,MAAA,EAAQ,IAAG,EAC5C;AAChB,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,QAAA,CAAS,CAAA,CAAA,EAAI,MAAM,CAAA,8BAAA,CAAgC,CAAA;AAC3D;AAGA,eAAsB,qBACpB,GAAA,GAA+C,EAAE,MAAA,EAAQ,IAAG,EAC5C;AAChB,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,QAAA,CAAS,CAAA,CAAA,EAAI,MAAM,CAAA,eAAA,CAAiB,CAAA;AAC5C;AAGA,eAAsB,sBAAsB,GAAA,EAKzB;AAEjB,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,CAAO,MAAA,GAAS,IAAI,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,CAAA,GAAK,EAAA;AAC7D,EAAA,MAAM,QAAA,CAAS,CAAA,EAAG,MAAM,CAAA,SAAA,EAAY,IAAI,IAAI,CAAA,EAAG,GAAA,CAAI,MAAA,IAAU,EAAE,CAAA,CAAA,EAAI,EAAE,UAAA,EAAY,KAAK,CAAA;AACxF;AAGA,eAAsB,6BAA6B,GAAA,EAIhC;AACjB,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,CAAO,MAAA,GAAS,IAAI,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,CAAA,GAAK,EAAA;AAC7D,EAAA,MAAM,KAAA,GAAQ,IAAI,eAAA,CAAgB,GAAA,CAAI,MAAM,CAAA;AAC5C,EAAA,KAAA,CAAM,OAAO,QAAQ,CAAA;AACrB,EAAA,MAAM,IAAA,GAAO,MAAM,QAAA,EAAS;AAC5B,EAAA,MAAM,QAAA,CAAS,CAAA,EAAG,MAAM,CAAA,iBAAA,EAAoB,GAAA,CAAI,MAAM,CAAA,EAAG,IAAA,GAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA,EAAI;AAAA,IACjF,UAAA,EAAY;AAAA,GACb,CAAA;AACH;AAUO,SAAS,cAAA,GAAuB;AACrC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,oBAAA,EAAqB;AAErB,IAAA,MAAA,CAAO,QAAA,CAAS,QAAQ,MAAA,CAAO,QAAA,CAAS,KAAK,OAAA,CAAQ,8BAAA,EAAgC,EAAE,CAAC,CAAA;AAAA,EAC1F,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,OAAO,IAAA;AACT","file":"chunk-CBYM3JIG.js","sourcesContent":["import { useEffect } from 'react';\nimport { redirect } from '../providers/NavigationProvider';\nimport { FALLBACK_LOCALE } from '../providers/locale-constants';\nimport { clearAuthTokenCookie } from '../utils/cookies';\n\nexport interface SlugBrandParams {\n /** SEO slug segment (ignored — only here to match the route pattern). */\n slug: string;\n /** Brand numeric ID to redirect to. */\n id: string;\n /** Active locale from the `/$locale` parent layout (e.g. `'ar'`, `'en'`). */\n locale?: string;\n}\n\nexport async function slugBrandRedirectLoader(ctx: { params: SlugBrandParams }): Promise<never> {\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n throw redirect(`/${locale}/brands/${ctx.params.id}`);\n}\n\nexport interface PendingOrdersRedirectParams {\n /** Active locale from the `/$locale` parent layout (e.g. `'ar'`, `'en'`). */\n locale?: string;\n}\n\nexport async function pendingOrdersRedirectLoader(\n ctx: { params: PendingOrdersRedirectParams } = { params: {} }\n): Promise<never> {\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n throw redirect(`/${locale}/account/orders?status=pending`);\n}\n\n/** `/account/rating`: the loyalty \"rate your orders\" link. Twig Raed has no rating page and sends it to the orders list. */\nexport async function ratingRedirectLoader(\n ctx: { params: PendingOrdersRedirectParams } = { params: {} }\n): Promise<never> {\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n throw redirect(`/${locale}/account/orders`);\n}\n\n/** A Twig customer URL (`/profile`, `/orders`, …) kept working as its `/account/…` page. */\nexport async function accountRedirectLoader(ctx: {\n params: PendingOrdersRedirectParams;\n page: string;\n /** The incoming query string (`?status=pending`), kept on the account page. */\n search?: string;\n}): Promise<never> {\n // No locale in the URL stays without one: the locale layout adds it only where the store has several.\n const prefix = ctx.params.locale ? `/${ctx.params.locale}` : '';\n throw redirect(`${prefix}/account/${ctx.page}${ctx.search ?? ''}`, { statusCode: 301 });\n}\n\n/** `/latest-products`, `/most-sales-products` and `/offers` now live at `/products?source=`. */\nexport async function productsSourceRedirectLoader(ctx: {\n params: PendingOrdersRedirectParams;\n source: 'latest' | 'sales' | 'offers';\n search?: string;\n}): Promise<never> {\n const prefix = ctx.params.locale ? `/${ctx.params.locale}` : '';\n const query = new URLSearchParams(ctx.search);\n query.delete('source');\n const rest = query.toString();\n throw redirect(`${prefix}/products?source=${ctx.source}${rest ? `&${rest}` : ''}`, {\n statusCode: 301,\n });\n}\n\n/**\n * `/logout` — where the SDK sends the browser once `salla.auth.logout()` has run\n * (`salla.url.get('logout?from=…')`). The Twig storefront serves that URL server-side. Here\n * it renders nothing and, in the browser, removes the theme's own `token` cookie (the SDK's\n * `cookie.clearAll()` leaves it) and then does a full navigation home. It has to be a\n * component, not a loader redirect: a loader runs during server rendering, where the cookie\n * can't be cleared, so the redirect would leave the visitor signed in on the next request.\n */\nexport function LogoutRedirect(): null {\n useEffect(() => {\n clearAuthTokenCookie();\n // `/{store base}/{locale}/logout?from=…` → `/{store base}/{locale}`\n window.location.replace(window.location.href.replace(/\\/logout\\/?(\\?[^#]*)?(#.*)?$/, ''));\n }, []);\n return null;\n}\n"]}
@@ -1,8 +1,9 @@
1
1
  import { useTranslation } from './chunk-TYNZ5B2B.js';
2
2
  import { getTwilightContext } from './chunk-7VNVCHID.js';
3
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
 
5
5
  var THUMB_URL = "https://cdn.assets.salla.network/prod/stores/images/construction-01.png";
6
+ var LAUNCHING_THUMB_URL = "https://cdn.assets.salla.network/prod/stores/images/under-construction.png";
6
7
  var SOCIAL_ICONS = [
7
8
  ["twitter", "sicon-x"],
8
9
  ["snapchat", "sicon-snapchat"],
@@ -11,6 +12,12 @@ var SOCIAL_ICONS = [
11
12
  ["facebook", "sicon-facebook"],
12
13
  ["instagram", "sicon-instagram"]
13
14
  ];
15
+ function socialLinks(store) {
16
+ return SOCIAL_ICONS.flatMap(([key, icon]) => {
17
+ const href = store?.social?.[key];
18
+ return href ? [{ key, icon, href }] : [];
19
+ });
20
+ }
14
21
  var STYLE = `
15
22
  .s-maintenance{display:flex;flex-direction:column;align-items:center;width:100%;height:100vh;height:100dvh;overflow-y:auto;color:#a3a3a3;background:#fff;filter:grayscale(100%);box-sizing:border-box}
16
23
  .s-maintenance *{box-sizing:border-box}
@@ -45,10 +52,7 @@ var STYLE = `
45
52
  function Contacts({ store, arabic }) {
46
53
  const { t } = useTranslation();
47
54
  const mobile = store?.contacts?.mobile;
48
- const socials = SOCIAL_ICONS.flatMap(([key, icon]) => {
49
- const href = store?.social?.[key];
50
- return href ? [{ key, icon, href }] : [];
51
- });
55
+ const socials = socialLinks(store);
52
56
  if (!mobile && socials.length === 0) return null;
53
57
  return /* @__PURE__ */ jsxs("ul", { className: "mt-contact-list", children: [
54
58
  mobile && /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("a", { href: `tel:${mobile}`, className: "mt-contact--btn", children: [
@@ -60,12 +64,72 @@ function Contacts({ store, arabic }) {
60
64
  socials.map(({ key, icon, href }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noreferrer", "aria-label": key, children: /* @__PURE__ */ jsx("i", { className: icon, "aria-hidden": "true" }) }) }, key))
61
65
  ] });
62
66
  }
67
+ var LAUNCHING_STYLE = `
68
+ .s-launching{display:flex;flex-direction:column;align-items:center;width:100%;height:100vh;height:100dvh;overflow-y:auto;color:#a3a3a3;background:#fff;text-align:center;box-sizing:border-box}
69
+ .s-launching *{box-sizing:border-box}
70
+ .s-launching .ls-panel{display:flex;flex-direction:column;align-items:center;width:100%;max-width:1200px;margin:auto 0;padding:40px 15px 100px;animation:revealMtBlock 1.5s forwards}
71
+ .s-launching .ls-logo{display:block;max-width:70px;margin:0 0 60px}
72
+ .s-launching .ls-thumb{display:block;width:100%;max-width:250px}
73
+ .s-launching h1{font-size:3.125rem;line-height:1;margin:20px 0;color:#000}
74
+ .s-launching .ls-content p{margin:0;white-space:pre-line}
75
+ .s-launching .ls-footer{position:fixed;inset-inline:0;bottom:0;display:flex;align-items:center;justify-content:space-between;padding:0 25px;color:#000;background:#fbfbfb}
76
+ .s-launching .ls-contacts{display:flex;align-items:center}
77
+ .s-launching .ls-contacts h2{margin:1em 0;font-size:1rem;color:#7d7d7d}
78
+ .s-launching .ls-contacts h2::after{content:"|";margin:0 10px;font-weight:700;color:#dbdbdb}
79
+ .s-launching .ls-contacts ul{display:flex;list-style:none;margin:0;padding:0}
80
+ .s-launching .ls-contacts li{padding:0 10px}
81
+ .s-launching .ls-contacts a{display:inline-flex;align-items:center;gap:5px;color:#000;text-decoration:none}
82
+ .s-launching .ls-footer-logo{display:block;max-width:30px}
83
+ @media (max-width:1024px){.s-launching h1{font-size:1.5625rem}}
84
+ @media (max-width:767px){.s-launching .ls-contacts a span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}
85
+ @keyframes revealMtBlock{from{opacity:0;transform:translateY(50%)}to{opacity:1;transform:translateY(0)}}
86
+ `;
87
+ function LaunchingContacts({ store, arabic }) {
88
+ const { t } = useTranslation();
89
+ const mobile = store?.contacts?.mobile;
90
+ const socials = socialLinks(store);
91
+ if (!mobile && socials.length === 0) return null;
92
+ return /* @__PURE__ */ jsxs("footer", { className: "ls-footer", children: [
93
+ /* @__PURE__ */ jsxs("div", { className: "ls-contacts", children: [
94
+ /* @__PURE__ */ jsx("h2", { children: t("common.elements.contact_us", {
95
+ defaultValue: arabic ? "\u062A\u0648\u0627\u0635\u0644 \u0645\u0639\u0646\u0627" : "Contact us"
96
+ }) }),
97
+ /* @__PURE__ */ jsxs("ul", { children: [
98
+ mobile && /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("a", { href: `tel:${mobile}`, children: [
99
+ /* @__PURE__ */ jsx("i", { className: "sicon-phone", "aria-hidden": "true" }),
100
+ /* @__PURE__ */ jsx("span", { dir: "ltr", children: mobile })
101
+ ] }) }),
102
+ socials.map(({ key, icon, href }) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noreferrer", "aria-label": key, children: /* @__PURE__ */ jsx("i", { className: icon, "aria-hidden": "true" }) }) }, key))
103
+ ] })
104
+ ] }),
105
+ store?.logo && /* @__PURE__ */ jsx("img", { className: "ls-footer-logo", src: store.logo, alt: "" })
106
+ ] });
107
+ }
108
+ function LaunchingSoon({ store, arabic }) {
109
+ const { t } = useTranslation();
110
+ const logoAlt = store?.name || t("common.elements.store_logo", { defaultValue: arabic ? "\u0634\u0639\u0627\u0631 \u0627\u0644\u0645\u062A\u062C\u0631" : "Store logo" });
111
+ return /* @__PURE__ */ jsxs("div", { className: "s-launching", "data-testid": "store-launching-soon-page", children: [
112
+ /* @__PURE__ */ jsx("style", { children: LAUNCHING_STYLE }),
113
+ /* @__PURE__ */ jsxs("section", { className: "ls-panel", children: [
114
+ store?.logo && /* @__PURE__ */ jsx("img", { className: "ls-logo", src: store.logo, alt: logoAlt }),
115
+ /* @__PURE__ */ jsx("img", { className: "ls-thumb", src: LAUNCHING_THUMB_URL, alt: "" }),
116
+ /* @__PURE__ */ jsx("h1", { children: t("pages.launching_soon.title", {
117
+ defaultValue: arabic ? "\u062A\u0631\u0642\u064E\u0651\u0628 \u0625\u0637\u0644\u0627\u0642 \u0627\u0644\u0645\u062A\u062C\u0631" : "The store is launching soon"
118
+ }) }),
119
+ /* @__PURE__ */ jsx("div", { className: "ls-content", children: /* @__PURE__ */ jsx("p", { children: t("pages.launching_soon.message", {
120
+ defaultValue: arabic ? "\u0646\u0639\u0645\u0644 \u0639\u0644\u0649 \u0648\u0636\u0639 \u0627\u0644\u0644\u0645\u0633\u0627\u062A \u0627\u0644\u0623\u062E\u064A\u0631\u0629 \u0644\u0646\u0642\u062F\u0645 \u0644\u0643 \u062A\u062C\u0631\u0628\u0629 \u062A\u0633\u0648\u0642 \u0645\u062A\u0643\u0627\u0645\u0644\u0629\u060C \u0642\u0631\u064A\u0628\u064B\u0627!" : "We're putting the finishing touches on a complete shopping experience for you. Coming soon!"
121
+ }) }) })
122
+ ] }),
123
+ /* @__PURE__ */ jsx(LaunchingContacts, { store, arabic })
124
+ ] });
125
+ }
63
126
  function MaintenancePage() {
64
127
  const { settings, locale } = getTwilightContext();
65
128
  const { t } = useTranslation();
66
129
  const store = settings.store;
67
130
  const details = settings.maintenance_details;
68
131
  const arabic = locale.startsWith("ar");
132
+ if (settings.launched === false) return /* @__PURE__ */ jsx(LaunchingSoon, { store, arabic });
69
133
  const title = details?.title || t("pages.maintenance.title", {
70
134
  defaultValue: arabic ? "\u0627\u0644\u0645\u062A\u062C\u0631 \u0642\u064A\u062F \u0627\u0644\u0635\u064A\u0627\u0646\u0629" : "Store under maintenance"
71
135
  });
@@ -104,5 +168,5 @@ function MaintenancePage() {
104
168
  }
105
169
 
106
170
  export { MaintenancePage };
107
- //# sourceMappingURL=chunk-J5DGBS7Q.js.map
108
- //# sourceMappingURL=chunk-J5DGBS7Q.js.map
171
+ //# sourceMappingURL=chunk-CKH6WBMA.js.map
172
+ //# sourceMappingURL=chunk-CKH6WBMA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/store/MaintenancePage.tsx"],"names":[],"mappings":"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","file":"chunk-CKH6WBMA.js","sourcesContent":["import { getTwilightContext } from '../../twilight/context';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport type { Store, StoreSocial } from '../../types';\n\nconst THUMB_URL = 'https://cdn.assets.salla.network/prod/stores/images/construction-01.png';\nconst LAUNCHING_THUMB_URL =\n 'https://cdn.assets.salla.network/prod/stores/images/under-construction.png';\n\n/** Social networks the page links to, in the old page's order, with their Salla icon class. */\nconst SOCIAL_ICONS: [keyof StoreSocial, string][] = [\n ['twitter', 'sicon-x'],\n ['snapchat', 'sicon-snapchat'],\n ['youtube', 'sicon-youtube'],\n ['tiktok', 'sicon-tiktok'],\n ['facebook', 'sicon-facebook'],\n ['instagram', 'sicon-instagram'],\n];\n\n/** The store's social links the page shows, each with its icon class. */\nfunction socialLinks(store: Store | undefined) {\n return SOCIAL_ICONS.flatMap(([key, icon]) => {\n const href = store?.social?.[key];\n return href ? [{ key, icon, href }] : [];\n });\n}\n\n// The platform's maintenance page (Store `pages/maintenance.blade.php` + `_maintenance.scss`),\n// trimmed to what it renders: greyscale, logo + title beside the message, contacts under a\n// rule, the illustration alongside; stacked and centred under 1024px.\n//\n// The page is its own scroll container, the viewport tall, because app-shell themes lock\n// `html, body { overflow: hidden }` and scroll only their main element, which this page\n// replaces. Centring is by auto margins, not `justify-content`, so content taller than the\n// viewport starts at the top instead of being clipped at both ends.\nconst STYLE = `\n.s-maintenance{display:flex;flex-direction:column;align-items:center;width:100%;height:100vh;height:100dvh;overflow-y:auto;color:#a3a3a3;background:#fff;filter:grayscale(100%);box-sizing:border-box}\n.s-maintenance *{box-sizing:border-box}\n.s-maintenance .mt-container{width:100%;max-width:1200px;margin:auto 0;padding:0 15px}\n.s-maintenance .mt-panel{display:flex;flex-direction:row;align-items:center;justify-content:space-between;width:100%}\n.s-maintenance .mt-message{width:100%;padding-inline-start:80px;animation:revealMtBlock 1.5s forwards}\n.s-maintenance .mt-title{display:flex;align-items:center;margin:0 0 20px}\n.s-maintenance .mt-logo{display:block;flex-shrink:0;width:80px;height:80px;margin-inline-end:20px;border-radius:50%;overflow:hidden;box-shadow:0 0 5px rgb(0 0 0 / 10%)}\n.s-maintenance .mt-logo img{display:block;width:100%;height:100%;object-fit:cover}\n.s-maintenance .mt-title h1{font-size:2.25rem;line-height:1;margin:0;color:#666}\n.s-maintenance .mt-content p{margin:0;white-space:pre-line}\n.s-maintenance .mt-contact-list{display:inline-block;list-style:none;width:100%;max-width:500px;margin:20px 0 0;padding:20px 0 0;border-top:1px solid #eee}\n.s-maintenance .mt-contact-list li{display:inline-block;margin-inline-end:10px}\n.s-maintenance .mt-contact-list a{display:inline-flex;align-items:center;padding:5px;color:rgb(102 102 102 / 80%);text-decoration:none;font-size:1.25rem}\n.s-maintenance .mt-contact-list a:hover{color:#666}\n.s-maintenance .mt-contact--btn{padding:3px 20px 5px;border-radius:20px;color:#fff!important;background:rgb(102 102 102 / 80%);font-size:1rem!important}\n.s-maintenance .mt-contact--btn:hover{background:#666}\n.s-maintenance .mt-contact--btn i{margin-inline-end:10px}\n.s-maintenance .thumb{width:100%;animation:revealMtBlock 1.5s .1s forwards;opacity:0}\n.s-maintenance .thumb img{display:block;width:100%;max-width:450px;margin:0 auto}\n@media (max-width:1024px){\n.s-maintenance{padding:40px 0 10px}\n.s-maintenance .mt-panel{flex-direction:column}\n.s-maintenance .mt-message{order:2;text-align:center;padding:0;margin:50px 0 0}\n.s-maintenance .mt-title{flex-direction:column;margin-bottom:30px}\n.s-maintenance .mt-logo{margin:0 0 10px}\n.s-maintenance .mt-title h1{font-size:1.5rem}\n}\n@media (max-width:640px){.s-maintenance .thumb img{width:80%}}\n@keyframes revealMtBlock{from{opacity:0;transform:translateY(50%)}to{opacity:1;transform:translateY(0)}}\n`;\n\n/** The phone button and social links under the message; nothing when the store lists none. */\nfunction Contacts({ store, arabic }: { store: Store | undefined; arabic: boolean }) {\n const { t } = useTranslation();\n const mobile = store?.contacts?.mobile;\n const socials = socialLinks(store);\n if (!mobile && socials.length === 0) return null;\n\n return (\n <ul className=\"mt-contact-list\">\n {mobile && (\n <li>\n <a href={`tel:${mobile}`} className=\"mt-contact--btn\">\n <i className=\"sicon-phone\" aria-hidden=\"true\" />\n {t('common.elements.contact_us', {\n defaultValue: arabic ? 'تواصل معنا' : 'Contact us',\n })}\n </a>\n </li>\n )}\n {socials.map(({ key, icon, href }) => (\n <li key={key}>\n <a href={href} target=\"_blank\" rel=\"noreferrer\" aria-label={key}>\n <i className={icon} aria-hidden=\"true\" />\n </a>\n </li>\n ))}\n </ul>\n );\n}\n\n// The platform's page for a store that has not launched yet (Store\n// `pages/construction.blade.php` + the `construction` rules of `_maintenance.scss`): in\n// colour, logo over the illustration over the title, centred, contacts in a bar along the\n// bottom. Its own scroll container, as the maintenance page above is.\nconst LAUNCHING_STYLE = `\n.s-launching{display:flex;flex-direction:column;align-items:center;width:100%;height:100vh;height:100dvh;overflow-y:auto;color:#a3a3a3;background:#fff;text-align:center;box-sizing:border-box}\n.s-launching *{box-sizing:border-box}\n.s-launching .ls-panel{display:flex;flex-direction:column;align-items:center;width:100%;max-width:1200px;margin:auto 0;padding:40px 15px 100px;animation:revealMtBlock 1.5s forwards}\n.s-launching .ls-logo{display:block;max-width:70px;margin:0 0 60px}\n.s-launching .ls-thumb{display:block;width:100%;max-width:250px}\n.s-launching h1{font-size:3.125rem;line-height:1;margin:20px 0;color:#000}\n.s-launching .ls-content p{margin:0;white-space:pre-line}\n.s-launching .ls-footer{position:fixed;inset-inline:0;bottom:0;display:flex;align-items:center;justify-content:space-between;padding:0 25px;color:#000;background:#fbfbfb}\n.s-launching .ls-contacts{display:flex;align-items:center}\n.s-launching .ls-contacts h2{margin:1em 0;font-size:1rem;color:#7d7d7d}\n.s-launching .ls-contacts h2::after{content:\"|\";margin:0 10px;font-weight:700;color:#dbdbdb}\n.s-launching .ls-contacts ul{display:flex;list-style:none;margin:0;padding:0}\n.s-launching .ls-contacts li{padding:0 10px}\n.s-launching .ls-contacts a{display:inline-flex;align-items:center;gap:5px;color:#000;text-decoration:none}\n.s-launching .ls-footer-logo{display:block;max-width:30px}\n@media (max-width:1024px){.s-launching h1{font-size:1.5625rem}}\n@media (max-width:767px){.s-launching .ls-contacts a span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}\n@keyframes revealMtBlock{from{opacity:0;transform:translateY(50%)}to{opacity:1;transform:translateY(0)}}\n`;\n\n/** The bar along the bottom with the phone and social links; nothing when the store lists none. */\nfunction LaunchingContacts({ store, arabic }: { store: Store | undefined; arabic: boolean }) {\n const { t } = useTranslation();\n const mobile = store?.contacts?.mobile;\n const socials = socialLinks(store);\n if (!mobile && socials.length === 0) return null;\n\n return (\n <footer className=\"ls-footer\">\n <div className=\"ls-contacts\">\n <h2>\n {t('common.elements.contact_us', {\n defaultValue: arabic ? 'تواصل معنا' : 'Contact us',\n })}\n </h2>\n <ul>\n {mobile && (\n <li>\n <a href={`tel:${mobile}`}>\n <i className=\"sicon-phone\" aria-hidden=\"true\" />\n <span dir=\"ltr\">{mobile}</span>\n </a>\n </li>\n )}\n {socials.map(({ key, icon, href }) => (\n <li key={key}>\n <a href={href} target=\"_blank\" rel=\"noreferrer\" aria-label={key}>\n <i className={icon} aria-hidden=\"true\" />\n </a>\n </li>\n ))}\n </ul>\n </div>\n {store?.logo && <img className=\"ls-footer-logo\" src={store.logo} alt=\"\" />}\n </footer>\n );\n}\n\n/**\n * The page a customer sees while the store has not launched yet. Its wording is the\n * platform's own, not `maintenance_details`: for an unlaunched store that holds the\n * merchant's \"finish launching\" notice, addressed to the merchant.\n */\nfunction LaunchingSoon({ store, arabic }: { store: Store | undefined; arabic: boolean }) {\n const { t } = useTranslation();\n const logoAlt =\n store?.name ||\n t('common.elements.store_logo', { defaultValue: arabic ? 'شعار المتجر' : 'Store logo' });\n\n return (\n <div className=\"s-launching\" data-testid=\"store-launching-soon-page\">\n <style>{LAUNCHING_STYLE}</style>\n <section className=\"ls-panel\">\n {store?.logo && <img className=\"ls-logo\" src={store.logo} alt={logoAlt} />}\n <img className=\"ls-thumb\" src={LAUNCHING_THUMB_URL} alt=\"\" />\n <h1>\n {t('pages.launching_soon.title', {\n defaultValue: arabic ? 'ترقَّب إطلاق المتجر' : 'The store is launching soon',\n })}\n </h1>\n <div className=\"ls-content\">\n <p>\n {t('pages.launching_soon.message', {\n defaultValue: arabic\n ? 'نعمل على وضع اللمسات الأخيرة لنقدم لك تجربة تسوق متكاملة، قريبًا!'\n : \"We're putting the finishing touches on a complete shopping experience for you. Coming soon!\",\n })}\n </p>\n </div>\n </section>\n <LaunchingContacts store={store} arabic={arabic} />\n </div>\n );\n}\n\n/**\n * The page a customer sees while the store is closed: the platform's maintenance page,\n * fed by the settings' `maintenance_details` (the merchant's title and message) and the\n * store's contacts; or, while the store has not launched yet (`settings.launched` is\n * `false`), the platform's launching-soon page. Rendered by `TwilightProvider` in place\n * of the layout; see `rootBeforeLoad` for who sees it.\n */\nexport function MaintenancePage() {\n const { settings, locale } = getTwilightContext();\n const { t } = useTranslation();\n const store = settings.store;\n const details = settings.maintenance_details;\n const arabic = locale.startsWith('ar');\n\n if (settings.launched === false) return <LaunchingSoon store={store} arabic={arabic} />;\n\n const title =\n details?.title ||\n t('pages.maintenance.title', {\n defaultValue: arabic ? 'المتجر قيد الصيانة' : 'Store under maintenance',\n });\n\n return (\n <div className=\"s-maintenance\" data-testid=\"store-maintenance-page\">\n <style>{STYLE}</style>\n <div className=\"mt-container\">\n <section className=\"mt-panel\">\n <div className=\"mt-message\">\n <div className=\"mt-title\">\n {store?.logo && (\n <span className=\"mt-logo\">\n <img\n src={store.logo}\n alt={\n store.name ||\n t('common.elements.store_logo', {\n defaultValue: arabic ? 'شعار المتجر' : 'Store logo',\n })\n }\n />\n </span>\n )}\n <h1>{title}</h1>\n </div>\n <div className=\"mt-content\">\n {details?.message ? (\n // The merchant's own wording: a plain string the dashboard caps at 200 characters.\n <p>{details.message}</p>\n ) : (\n <>\n <p>\n {t('pages.maintenance.message', {\n defaultValue: arabic\n ? 'عذرا عزيزي العميل، المتجر حاليا قيد الصيانة و سنعاود العمل خلال فترة وجيزة'\n : 'Sorry, the store is under maintenance and will be back shortly.',\n })}\n </p>\n <p>\n {t('pages.maintenance.thanks', {\n defaultValue: arabic ? 'شكرا لتفهمكم' : 'Thank you for your understanding.',\n })}\n </p>\n </>\n )}\n </div>\n <Contacts store={store} arabic={arabic} />\n </div>\n <div className=\"thumb\">\n <img src={THUMB_URL} alt=\"\" />\n </div>\n </section>\n </div>\n </div>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { api } from './chunk-OQTBHL5T.js';
1
+ import { api } from './chunk-SOQN5WKL.js';
2
2
  import { getTwilightContext } from './chunk-7VNVCHID.js';
3
3
  import { queryOptions } from '@tanstack/react-query';
4
4
 
@@ -23,5 +23,5 @@ var menu = {
23
23
  };
24
24
 
25
25
  export { menu };
26
- //# sourceMappingURL=chunk-ASTCQSK6.js.map
27
- //# sourceMappingURL=chunk-ASTCQSK6.js.map
26
+ //# sourceMappingURL=chunk-CR3EY7K7.js.map
27
+ //# sourceMappingURL=chunk-CR3EY7K7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/menu.ts"],"names":[],"mappings":";;;;AAKO,IAAM,IAAA,GAAO;AAAA,EAClB,QAAQ,YAAiC;AACvC,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,kBAAA,EAAmB;AACtC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,kBAAA,EAAqB,MAAM,CAAA,CAAE,CAAA,CAAE,IAAA,EAA2B;AACzF,IAAA,OAAO,QAAQ,EAAC;AAAA,EAClB,CAAA;AAAA,EAEA,QAAQ,YAAiC;AACvC,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,kBAAA,EAAmB;AACtC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,kBAAA,EAAqB,MAAM,CAAA,CAAE,CAAA,CAAE,IAAA,EAA2B;AACzF,IAAA,OAAO,QAAQ,EAAC;AAAA,EAClB,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,MACN,YAAA,CAAa;AAAA,MACX,UAAU,CAAC,OAAA,EAAS,QAAA,EAAU,kBAAA,GAAqB,MAAM,CAAA;AAAA,MACzD,OAAA,EAAS,MAAM,IAAA,CAAK,MAAA,EAAO;AAAA,MAC3B,SAAA,EAAW,IAAI,EAAA,GAAK;AAAA,KACrB;AAAA;AAEP","file":"chunk-ASTCQSK6.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api } from './client';\nimport { getTwilightContext } from '../twilight/context';\nimport type { MenuItem } from '../types';\n\nexport const menu = {\n header: async (): Promise<MenuItem[]> => {\n const { locale } = getTwilightContext();\n const { data } = await api.get(`menus/header?lang=${locale}`).json<{ data: MenuItem[] }>();\n return data || [];\n },\n\n footer: async (): Promise<MenuItem[]> => {\n const { locale } = getTwilightContext();\n const { data } = await api.get(`menus/footer?lang=${locale}`).json<{ data: MenuItem[] }>();\n return data || [];\n },\n\n queries: {\n header: () =>\n queryOptions({\n queryKey: ['menus', 'header', getTwilightContext().locale],\n queryFn: () => menu.header(),\n staleTime: 5 * 60 * 1000,\n }),\n },\n};\n"]}
1
+ {"version":3,"sources":["../src/api/menu.ts"],"names":[],"mappings":";;;;AAKO,IAAM,IAAA,GAAO;AAAA,EAClB,QAAQ,YAAiC;AACvC,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,kBAAA,EAAmB;AACtC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,kBAAA,EAAqB,MAAM,CAAA,CAAE,CAAA,CAAE,IAAA,EAA2B;AACzF,IAAA,OAAO,QAAQ,EAAC;AAAA,EAClB,CAAA;AAAA,EAEA,QAAQ,YAAiC;AACvC,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,kBAAA,EAAmB;AACtC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,kBAAA,EAAqB,MAAM,CAAA,CAAE,CAAA,CAAE,IAAA,EAA2B;AACzF,IAAA,OAAO,QAAQ,EAAC;AAAA,EAClB,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,MACN,YAAA,CAAa;AAAA,MACX,UAAU,CAAC,OAAA,EAAS,QAAA,EAAU,kBAAA,GAAqB,MAAM,CAAA;AAAA,MACzD,OAAA,EAAS,MAAM,IAAA,CAAK,MAAA,EAAO;AAAA,MAC3B,SAAA,EAAW,IAAI,EAAA,GAAK;AAAA,KACrB;AAAA;AAEP","file":"chunk-CR3EY7K7.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api } from './client';\nimport { getTwilightContext } from '../twilight/context';\nimport type { MenuItem } from '../types';\n\nexport const menu = {\n header: async (): Promise<MenuItem[]> => {\n const { locale } = getTwilightContext();\n const { data } = await api.get(`menus/header?lang=${locale}`).json<{ data: MenuItem[] }>();\n return data || [];\n },\n\n footer: async (): Promise<MenuItem[]> => {\n const { locale } = getTwilightContext();\n const { data } = await api.get(`menus/footer?lang=${locale}`).json<{ data: MenuItem[] }>();\n return data || [];\n },\n\n queries: {\n header: () =>\n queryOptions({\n queryKey: ['menus', 'header', getTwilightContext().locale],\n queryFn: () => menu.header(),\n staleTime: 5 * 60 * 1000,\n }),\n },\n};\n"]}
@@ -1,5 +1,5 @@
1
- import { orThrow } from './chunk-QPKK4LPK.js';
2
- import { getActiveScope, api } from './chunk-OQTBHL5T.js';
1
+ import { orThrow } from './chunk-2Z7XKCT3.js';
2
+ import { getActiveScope, api } from './chunk-SOQN5WKL.js';
3
3
  import { getTwilightContext } from './chunk-7VNVCHID.js';
4
4
  import { defaultShouldDehydrateQuery, queryOptions } from '@tanstack/react-query';
5
5
 
@@ -194,5 +194,5 @@ var product = {
194
194
  };
195
195
 
196
196
  export { getProductPreview, isProductPreviewQuery, parseNextPageToken, product, productDetailQueryKey, productPreviewQueryKey, rememberProductPreview, shouldDehydrateQuery };
197
- //# sourceMappingURL=chunk-RPRZYRPX.js.map
198
- //# sourceMappingURL=chunk-RPRZYRPX.js.map
197
+ //# sourceMappingURL=chunk-DJHYJ2VY.js.map
198
+ //# sourceMappingURL=chunk-DJHYJ2VY.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/product.ts"],"names":["product"],"mappings":"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","file":"chunk-RPRZYRPX.js","sourcesContent":["import { queryOptions, defaultShouldDehydrateQuery } from '@tanstack/react-query';\nimport { api, getActiveScope } from './client';\nimport type { Product } from '../types';\nimport type { Pagination, PaginatedResult } from './types';\nimport { orThrow } from '../providers/NavigationProvider';\nimport { getTwilightContext } from '../twilight/context';\nimport type { ActiveScope } from '../utils/cookies';\n\n// ===== Filter Types =====\n\nexport interface FilterValue {\n key?: string;\n count?: number;\n value?: string;\n from?: number | '*';\n to?: number | '*';\n}\n\nexport interface Filter {\n key?: string;\n label?: string;\n type?: string;\n values?: FilterValue[];\n max?: number;\n min?: number;\n}\n\n// ===== Product List Types =====\n\nexport type ProductsListSource =\n | 'brands'\n | 'categories'\n | 'json'\n | 'landing-page'\n | 'latest'\n | 'offers'\n | 'recently'\n | 'related'\n | 'selected'\n | 'tags'\n | 'top-rated'\n | 'wishlist'\n | 'search'\n | 'sales'\n | 'reorder'\n | 'best_selling';\n\nexport interface ProductsListParams {\n /** Source type (wishlist, latest, brands, etc.) */\n source: ProductsListSource;\n /**\n * The ids the source reads, as an array: category, brand, tag or product ids\n * (`sourceValue: [708738657]`). Sent as `source_value[]`.\n */\n sourceValue?: string | number | number[] | null;\n /** The search words when `source` is `'search'`. Sent as `keyword`; other sources ignore it. */\n keyword?: string;\n /** Page number for offset-based pagination */\n page?: number;\n /** Cursor for cursor-based pagination (from previous response) */\n cursor?: string | null;\n /** Items per page (default: 15) */\n perPage?: number;\n /** Sort option */\n sort?: string;\n /** Enable filters on the response */\n filterable?: boolean;\n /** Applied `<salla-filters>` selection (the `salla-filters::changed` payload). */\n filters?: ProductListFilters;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n}\n\n/** One `<salla-filters>` value: a scalar, a list, or a nested `{ sub-key: value }` (variants). */\nexport type ProductListFilterValue =\n string | number | Array<string | number> | { [key: string]: ProductListFilterValue };\n\n/** A `<salla-filters>` selection, i.e. the `salla-filters::changed` payload. */\nexport type ProductListFilters = Record<string, ProductListFilterValue>;\n\nexport type ProductsListResult = PaginatedResult<Product> & {\n filters?: Filter[];\n};\n\nexport interface ProductsListResponse {\n data: Product[];\n cursor?: Pagination;\n filters?: Filter[];\n}\n\n// ===== List-card preview cache =====\n// List payloads are a subset of details (one `image`, no `options` / `images[]`).\n// They live on a separate query key so they can paint a sheet/quick-view without\n// being treated as a successful `products/{id}/details` fetch.\n\nfunction queryClientOrNull() {\n try {\n const queryClient = getTwilightContext().queryClient;\n return queryClient && typeof queryClient.setQueryData === 'function' ? queryClient : null;\n } catch {\n return null;\n }\n}\n\nexport function productPreviewQueryKey(id: string) {\n return ['products', 'preview', String(id), { scope: getActiveScope() }] as const;\n}\n\nexport function productDetailQueryKey(id: string) {\n return ['products', 'detail', id, { scope: getActiveScope() }] as const;\n}\n\n/** True when this query is a list-card stand-in — skip it when dehydrating SSR. */\nexport function isProductPreviewQuery(query: { queryKey: readonly unknown[] }): boolean {\n return query.queryKey[0] === 'products' && query.queryKey[1] === 'preview';\n}\n\n/**\n * Default dehydrate policy (success) plus pending SSR-stream queries, minus\n * list-card stand-ins. Replacing the default wholesale would ship error states.\n */\nexport function shouldDehydrateQuery(\n query: Parameters<typeof defaultShouldDehydrateQuery>[0]\n): boolean {\n return (\n !isProductPreviewQuery(query) &&\n (defaultShouldDehydrateQuery(query) || query.state.status === 'pending')\n );\n}\n\n/**\n * Remember a list/card product so `product.queries.detail(id)` can use it as\n * `placeholderData` while details load. No-op if details for this id are already\n * cached. Themes that fetch products outside `product.list` should call this.\n */\nexport function rememberProductPreview(product: Product): void {\n const queryClient = queryClientOrNull();\n if (!queryClient || product?.id == null) return;\n const id = String(product.id);\n if (queryClient.getQueryState(productDetailQueryKey(id))?.status === 'success') return;\n queryClient.setQueryData(productPreviewQueryKey(id), product);\n}\n\nfunction scopeFromQueryKey(queryKey: readonly unknown[]): ActiveScope | null | undefined {\n const last = queryKey[queryKey.length - 1];\n if (last == null || typeof last !== 'object' || !('scope' in last)) return undefined;\n return (last as { scope: ActiveScope | null }).scope;\n}\n\nfunction isSameScope(a: ActiveScope | null | undefined, b: ActiveScope | null): boolean {\n if (a === undefined) return false;\n if (a === b) return true;\n if (a == null || b == null) return a == null && b == null;\n return (\n a.id === b.id &&\n a.type === b.type &&\n a.allocation_id === b.allocation_id &&\n a.allocation_type === b.allocation_type\n );\n}\n\nconst LIST_QUERY_PREFIXES = [\n ['products', 'list'],\n ['wishlist', 'list'],\n] as const;\n\n/**\n * Rebuild the scoped preview index from hydrated list/wishlist queries (SSR\n * dehydrate drops preview keys). Subsequent lookups hit `productPreviewQueryKey`.\n */\nfunction findProductInScopedLists(\n queryClient: NonNullable<ReturnType<typeof queryClientOrNull>>,\n id: string\n): Product | undefined {\n const scope = getActiveScope();\n let found: Product | undefined;\n for (const prefix of LIST_QUERY_PREFIXES) {\n for (const [queryKey, data] of queryClient.getQueriesData<ProductsListResult>({\n queryKey: prefix,\n })) {\n if (!isSameScope(scopeFromQueryKey(queryKey), scope)) continue;\n for (const item of data?.items ?? []) {\n if (item?.id == null) continue;\n rememberProductPreview(item);\n if (!found && String(item.id) === id) found = item;\n }\n }\n }\n return found;\n}\n\n/**\n * List-card product for `placeholderData`. Prefers the preview key; if that was\n * dropped on SSR dehydrate, rebuilds it from the current-scope list/wishlist.\n */\nexport function getProductPreview(id: string): Product | undefined {\n const queryClient = queryClientOrNull();\n if (!queryClient) return undefined;\n const key = String(id);\n return (\n queryClient.getQueryData(productPreviewQueryKey(key)) ??\n findProductInScopedLists(queryClient, key)\n );\n}\n\nfunction rememberProductPreviews(items: Product[]): void {\n for (const item of items) rememberProductPreview(item);\n}\n\n/**\n * Search sends its words as `keyword` (a `sourceValue` string is still read there, as before);\n * every other source sends its ids as `source_value[]`, which the API requires as an array.\n */\nfunction appendSourceParams(\n searchParams: URLSearchParams,\n { source, sourceValue, keyword }: Pick<ProductsListParams, 'source' | 'sourceValue' | 'keyword'>\n): void {\n if (source === 'search') {\n const words = keyword ?? sourceValue;\n if (words !== undefined) searchParams.set('keyword', String(words));\n } else if (Array.isArray(sourceValue)) {\n sourceValue.forEach((val) => searchParams.append('source_value[]', String(val)));\n } else if (sourceValue !== undefined) {\n searchParams.append('source_value[]', String(sourceValue));\n }\n}\n\n/**\n * Sends an applied filter selection the way the SDK's `<salla-products-list>` does:\n * `filters[key]=v`, `filters[key][]=v` or `filters[key][sub]=v`.\n */\nfunction appendFilterParams(\n searchParams: URLSearchParams,\n filters?: Record<string, ProductListFilterValue>,\n parentKey = 'filters'\n): void {\n if (!filters) return;\n for (const [key, value] of Object.entries(filters)) {\n const fullKey = `${parentKey}[${key}]`;\n if (Array.isArray(value)) {\n value.forEach((item) => searchParams.append(`${fullKey}[]`, String(item)));\n } else if (value !== null && typeof value === 'object') {\n appendFilterParams(searchParams, value, fullKey);\n } else if (value !== undefined && value !== null) {\n searchParams.append(fullKey, String(value));\n }\n }\n}\n\n/** A `category_id` filter replaces the page's category as the list source (as in the SDK). */\nfunction categoryFilterIds(filters?: ProductListFilters): number[] | null {\n const raw = filters?.category_id;\n if (raw === undefined || raw === null) return null;\n const ids = Array.isArray(raw) ? raw : typeof raw === 'object' ? Object.values(raw) : [raw];\n return ids.map(Number);\n}\n\n// ===== Pagination =====\n\n/**\n * The API's own `cursor.next` (the previous page's response) is usually a\n * bare opaque cursor token, but for sources that don't support true\n * cursor-based pagination (observed: `source=offers`) it's instead a full\n * next-page URL carrying its own `page=N` — and no `cursor=` param at all.\n *\n * Passing that whole URL straight through as `list()`'s own `cursor` used to\n * smuggle its embedded `source` / `per_page` / `sort` into the request on\n * top of the ones `list()` already sets unconditionally, producing a\n * doubled query string (`source=offers&source=offers&...`) the API can't\n * paginate from correctly — every subsequent scroll re-fetched the exact\n * same first page instead of advancing. Pulling just the `page` number back\n * out here, the same way an actual `cursor=` is already pulled out, keeps\n * `list()`'s request to the one copy of each param it's supposed to have.\n */\nexport function parseNextPageToken(nextUrl: string | null | undefined): {\n cursor?: string;\n page?: number;\n} {\n if (!nextUrl) return {};\n\n const cursorMatch = nextUrl.match(/[?&]cursor=([^&]+)/);\n if (cursorMatch) return { cursor: decodeURIComponent(cursorMatch[1]) };\n\n const pageMatch = nextUrl.match(/[?&]page=([^&]+)/);\n if (pageMatch) {\n const page = Number(decodeURIComponent(pageMatch[1]));\n if (Number.isFinite(page)) return { page };\n }\n\n // Neither pattern matched: not a URL at all, just the bare opaque token itself.\n return { cursor: nextUrl };\n}\n\n// ===== API Functions =====\n\nexport const product = {\n find: async (id: string): Promise<Product> => {\n const endpoint = `products/${id}/details?with[]=images&with[]=category&with[]=rating&with[]=notify_availability&with[]=tags&with[]=brand&with[]=options&with[]=skus&with[]=skus_availability&with[]=included_products&with[]=bundle&with[]=sold_quantity`;\n const { data } = await api.get(endpoint).json<{ data: Product }>();\n return data;\n },\n\n findOrThrow: (id: string): Promise<Product> => orThrow(product.find(id)),\n\n /** A tag's name. The list endpoint returns every product for an unknown tag; this one answers 410. */\n tag: async (id: string): Promise<{ id: number; name: string }> => {\n const { tag } = await api\n .get(`products/tags/${id}`)\n .json<{ tag: { id: number; name: string } }>();\n return tag;\n },\n\n /**\n * Fetch products list with pagination support\n * Used by native ProductsList component for SSR loaders\n *\n * API pattern: GET /products?source=wishlist&page=1\n */\n list: async (params: ProductsListParams): Promise<ProductsListResult> => {\n const {\n source,\n sourceValue,\n keyword,\n page,\n cursor,\n perPage = 16,\n sort,\n filterable,\n filters,\n signal,\n } = params;\n\n // Build URL with query parameters\n const searchParams = new URLSearchParams();\n searchParams.set('source', source);\n // Only send page when explicitly provided — cursor-based callers omit it entirely\n if (page !== undefined) searchParams.set('page', String(page));\n searchParams.set('per_page', String(perPage));\n\n appendSourceParams(searchParams, {\n source,\n sourceValue: (source === 'categories' && categoryFilterIds(filters)) || sourceValue,\n keyword,\n });\n appendFilterParams(searchParams, filters);\n\n // Add filterable parameter\n if (filterable !== undefined) {\n searchParams.set('filterable', filterable ? '1' : '0');\n }\n\n // Add sort parameter\n if (sort) {\n searchParams.set('sort', sort);\n }\n\n // Add cursor for cursor-based pagination\n if (cursor) {\n searchParams.set('cursor', cursor);\n }\n\n // Make the request\n const options: Record<string, unknown> = {};\n if (signal) options.signal = signal;\n\n const response = await api\n .get(`products?${searchParams.toString()}`, options as any)\n .json<ProductsListResponse>();\n\n const items = response.data ?? [];\n rememberProductPreviews(items);\n\n return {\n items,\n next: response.cursor?.next ?? null,\n filters: response.filters,\n };\n },\n\n queries: {\n detail: (id: string) =>\n queryOptions({\n // Stock and availability are resolved per branch allocation — same as the list.\n queryKey: productDetailQueryKey(id),\n queryFn: () => product.find(id),\n // List-card product, if one was remembered. Not written as the detail\n // cache entry — `queryFn` still hits products/{id}/details.\n placeholderData: () => getProductPreview(id),\n }),\n tag: (id: string) =>\n queryOptions({\n queryKey: ['products', 'tag', id],\n queryFn: () => product.tag(id),\n }),\n list: (params: Omit<ProductsListParams, 'signal'>) =>\n queryOptions({\n // Scope (branch) varies product availability — key must include it.\n queryKey: ['products', 'list', params, { scope: getActiveScope() }],\n queryFn: ({ signal }) => product.list({ ...params, signal }),\n }),\n },\n};\n"]}
1
+ {"version":3,"sources":["../src/api/product.ts"],"names":["product"],"mappings":"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","file":"chunk-DJHYJ2VY.js","sourcesContent":["import { queryOptions, defaultShouldDehydrateQuery } from '@tanstack/react-query';\nimport { api, getActiveScope } from './client';\nimport type { Product } from '../types';\nimport type { Pagination, PaginatedResult } from './types';\nimport { orThrow } from '../providers/NavigationProvider';\nimport { getTwilightContext } from '../twilight/context';\nimport type { ActiveScope } from '../utils/cookies';\n\n// ===== Filter Types =====\n\nexport interface FilterValue {\n key?: string;\n count?: number;\n value?: string;\n from?: number | '*';\n to?: number | '*';\n}\n\nexport interface Filter {\n key?: string;\n label?: string;\n type?: string;\n values?: FilterValue[];\n max?: number;\n min?: number;\n}\n\n// ===== Product List Types =====\n\nexport type ProductsListSource =\n | 'brands'\n | 'categories'\n | 'json'\n | 'landing-page'\n | 'latest'\n | 'offers'\n | 'recently'\n | 'related'\n | 'selected'\n | 'tags'\n | 'top-rated'\n | 'wishlist'\n | 'search'\n | 'sales'\n | 'reorder'\n | 'best_selling';\n\nexport interface ProductsListParams {\n /** Source type (wishlist, latest, brands, etc.) */\n source: ProductsListSource;\n /**\n * The ids the source reads, as an array: category, brand, tag or product ids\n * (`sourceValue: [708738657]`). Sent as `source_value[]`.\n */\n sourceValue?: string | number | number[] | null;\n /** The search words when `source` is `'search'`. Sent as `keyword`; other sources ignore it. */\n keyword?: string;\n /** Page number for offset-based pagination */\n page?: number;\n /** Cursor for cursor-based pagination (from previous response) */\n cursor?: string | null;\n /** Items per page (default: 15) */\n perPage?: number;\n /** Sort option */\n sort?: string;\n /** Enable filters on the response */\n filterable?: boolean;\n /** Applied `<salla-filters>` selection (the `salla-filters::changed` payload). */\n filters?: ProductListFilters;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n}\n\n/** One `<salla-filters>` value: a scalar, a list, or a nested `{ sub-key: value }` (variants). */\nexport type ProductListFilterValue =\n string | number | Array<string | number> | { [key: string]: ProductListFilterValue };\n\n/** A `<salla-filters>` selection, i.e. the `salla-filters::changed` payload. */\nexport type ProductListFilters = Record<string, ProductListFilterValue>;\n\nexport type ProductsListResult = PaginatedResult<Product> & {\n filters?: Filter[];\n};\n\nexport interface ProductsListResponse {\n data: Product[];\n cursor?: Pagination;\n filters?: Filter[];\n}\n\n// ===== List-card preview cache =====\n// List payloads are a subset of details (one `image`, no `options` / `images[]`).\n// They live on a separate query key so they can paint a sheet/quick-view without\n// being treated as a successful `products/{id}/details` fetch.\n\nfunction queryClientOrNull() {\n try {\n const queryClient = getTwilightContext().queryClient;\n return queryClient && typeof queryClient.setQueryData === 'function' ? queryClient : null;\n } catch {\n return null;\n }\n}\n\nexport function productPreviewQueryKey(id: string) {\n return ['products', 'preview', String(id), { scope: getActiveScope() }] as const;\n}\n\nexport function productDetailQueryKey(id: string) {\n return ['products', 'detail', id, { scope: getActiveScope() }] as const;\n}\n\n/** True when this query is a list-card stand-in — skip it when dehydrating SSR. */\nexport function isProductPreviewQuery(query: { queryKey: readonly unknown[] }): boolean {\n return query.queryKey[0] === 'products' && query.queryKey[1] === 'preview';\n}\n\n/**\n * Default dehydrate policy (success) plus pending SSR-stream queries, minus\n * list-card stand-ins. Replacing the default wholesale would ship error states.\n */\nexport function shouldDehydrateQuery(\n query: Parameters<typeof defaultShouldDehydrateQuery>[0]\n): boolean {\n return (\n !isProductPreviewQuery(query) &&\n (defaultShouldDehydrateQuery(query) || query.state.status === 'pending')\n );\n}\n\n/**\n * Remember a list/card product so `product.queries.detail(id)` can use it as\n * `placeholderData` while details load. No-op if details for this id are already\n * cached. Themes that fetch products outside `product.list` should call this.\n */\nexport function rememberProductPreview(product: Product): void {\n const queryClient = queryClientOrNull();\n if (!queryClient || product?.id == null) return;\n const id = String(product.id);\n if (queryClient.getQueryState(productDetailQueryKey(id))?.status === 'success') return;\n queryClient.setQueryData(productPreviewQueryKey(id), product);\n}\n\nfunction scopeFromQueryKey(queryKey: readonly unknown[]): ActiveScope | null | undefined {\n const last = queryKey[queryKey.length - 1];\n if (last == null || typeof last !== 'object' || !('scope' in last)) return undefined;\n return (last as { scope: ActiveScope | null }).scope;\n}\n\nfunction isSameScope(a: ActiveScope | null | undefined, b: ActiveScope | null): boolean {\n if (a === undefined) return false;\n if (a === b) return true;\n if (a == null || b == null) return a == null && b == null;\n return (\n a.id === b.id &&\n a.type === b.type &&\n a.allocation_id === b.allocation_id &&\n a.allocation_type === b.allocation_type\n );\n}\n\nconst LIST_QUERY_PREFIXES = [\n ['products', 'list'],\n ['wishlist', 'list'],\n] as const;\n\n/**\n * Rebuild the scoped preview index from hydrated list/wishlist queries (SSR\n * dehydrate drops preview keys). Subsequent lookups hit `productPreviewQueryKey`.\n */\nfunction findProductInScopedLists(\n queryClient: NonNullable<ReturnType<typeof queryClientOrNull>>,\n id: string\n): Product | undefined {\n const scope = getActiveScope();\n let found: Product | undefined;\n for (const prefix of LIST_QUERY_PREFIXES) {\n for (const [queryKey, data] of queryClient.getQueriesData<ProductsListResult>({\n queryKey: prefix,\n })) {\n if (!isSameScope(scopeFromQueryKey(queryKey), scope)) continue;\n for (const item of data?.items ?? []) {\n if (item?.id == null) continue;\n rememberProductPreview(item);\n if (!found && String(item.id) === id) found = item;\n }\n }\n }\n return found;\n}\n\n/**\n * List-card product for `placeholderData`. Prefers the preview key; if that was\n * dropped on SSR dehydrate, rebuilds it from the current-scope list/wishlist.\n */\nexport function getProductPreview(id: string): Product | undefined {\n const queryClient = queryClientOrNull();\n if (!queryClient) return undefined;\n const key = String(id);\n return (\n queryClient.getQueryData(productPreviewQueryKey(key)) ??\n findProductInScopedLists(queryClient, key)\n );\n}\n\nfunction rememberProductPreviews(items: Product[]): void {\n for (const item of items) rememberProductPreview(item);\n}\n\n/**\n * Search sends its words as `keyword` (a `sourceValue` string is still read there, as before);\n * every other source sends its ids as `source_value[]`, which the API requires as an array.\n */\nfunction appendSourceParams(\n searchParams: URLSearchParams,\n { source, sourceValue, keyword }: Pick<ProductsListParams, 'source' | 'sourceValue' | 'keyword'>\n): void {\n if (source === 'search') {\n const words = keyword ?? sourceValue;\n if (words !== undefined) searchParams.set('keyword', String(words));\n } else if (Array.isArray(sourceValue)) {\n sourceValue.forEach((val) => searchParams.append('source_value[]', String(val)));\n } else if (sourceValue !== undefined) {\n searchParams.append('source_value[]', String(sourceValue));\n }\n}\n\n/**\n * Sends an applied filter selection the way the SDK's `<salla-products-list>` does:\n * `filters[key]=v`, `filters[key][]=v` or `filters[key][sub]=v`.\n */\nfunction appendFilterParams(\n searchParams: URLSearchParams,\n filters?: Record<string, ProductListFilterValue>,\n parentKey = 'filters'\n): void {\n if (!filters) return;\n for (const [key, value] of Object.entries(filters)) {\n const fullKey = `${parentKey}[${key}]`;\n if (Array.isArray(value)) {\n value.forEach((item) => searchParams.append(`${fullKey}[]`, String(item)));\n } else if (value !== null && typeof value === 'object') {\n appendFilterParams(searchParams, value, fullKey);\n } else if (value !== undefined && value !== null) {\n searchParams.append(fullKey, String(value));\n }\n }\n}\n\n/** A `category_id` filter replaces the page's category as the list source (as in the SDK). */\nfunction categoryFilterIds(filters?: ProductListFilters): number[] | null {\n const raw = filters?.category_id;\n if (raw === undefined || raw === null) return null;\n const ids = Array.isArray(raw) ? raw : typeof raw === 'object' ? Object.values(raw) : [raw];\n return ids.map(Number);\n}\n\n// ===== Pagination =====\n\n/**\n * The API's own `cursor.next` (the previous page's response) is usually a\n * bare opaque cursor token, but for sources that don't support true\n * cursor-based pagination (observed: `source=offers`) it's instead a full\n * next-page URL carrying its own `page=N` — and no `cursor=` param at all.\n *\n * Passing that whole URL straight through as `list()`'s own `cursor` used to\n * smuggle its embedded `source` / `per_page` / `sort` into the request on\n * top of the ones `list()` already sets unconditionally, producing a\n * doubled query string (`source=offers&source=offers&...`) the API can't\n * paginate from correctly — every subsequent scroll re-fetched the exact\n * same first page instead of advancing. Pulling just the `page` number back\n * out here, the same way an actual `cursor=` is already pulled out, keeps\n * `list()`'s request to the one copy of each param it's supposed to have.\n */\nexport function parseNextPageToken(nextUrl: string | null | undefined): {\n cursor?: string;\n page?: number;\n} {\n if (!nextUrl) return {};\n\n const cursorMatch = nextUrl.match(/[?&]cursor=([^&]+)/);\n if (cursorMatch) return { cursor: decodeURIComponent(cursorMatch[1]) };\n\n const pageMatch = nextUrl.match(/[?&]page=([^&]+)/);\n if (pageMatch) {\n const page = Number(decodeURIComponent(pageMatch[1]));\n if (Number.isFinite(page)) return { page };\n }\n\n // Neither pattern matched: not a URL at all, just the bare opaque token itself.\n return { cursor: nextUrl };\n}\n\n// ===== API Functions =====\n\nexport const product = {\n find: async (id: string): Promise<Product> => {\n const endpoint = `products/${id}/details?with[]=images&with[]=category&with[]=rating&with[]=notify_availability&with[]=tags&with[]=brand&with[]=options&with[]=skus&with[]=skus_availability&with[]=included_products&with[]=bundle&with[]=sold_quantity`;\n const { data } = await api.get(endpoint).json<{ data: Product }>();\n return data;\n },\n\n findOrThrow: (id: string): Promise<Product> => orThrow(product.find(id)),\n\n /** A tag's name. The list endpoint returns every product for an unknown tag; this one answers 410. */\n tag: async (id: string): Promise<{ id: number; name: string }> => {\n const { tag } = await api\n .get(`products/tags/${id}`)\n .json<{ tag: { id: number; name: string } }>();\n return tag;\n },\n\n /**\n * Fetch products list with pagination support\n * Used by native ProductsList component for SSR loaders\n *\n * API pattern: GET /products?source=wishlist&page=1\n */\n list: async (params: ProductsListParams): Promise<ProductsListResult> => {\n const {\n source,\n sourceValue,\n keyword,\n page,\n cursor,\n perPage = 16,\n sort,\n filterable,\n filters,\n signal,\n } = params;\n\n // Build URL with query parameters\n const searchParams = new URLSearchParams();\n searchParams.set('source', source);\n // Only send page when explicitly provided — cursor-based callers omit it entirely\n if (page !== undefined) searchParams.set('page', String(page));\n searchParams.set('per_page', String(perPage));\n\n appendSourceParams(searchParams, {\n source,\n sourceValue: (source === 'categories' && categoryFilterIds(filters)) || sourceValue,\n keyword,\n });\n appendFilterParams(searchParams, filters);\n\n // Add filterable parameter\n if (filterable !== undefined) {\n searchParams.set('filterable', filterable ? '1' : '0');\n }\n\n // Add sort parameter\n if (sort) {\n searchParams.set('sort', sort);\n }\n\n // Add cursor for cursor-based pagination\n if (cursor) {\n searchParams.set('cursor', cursor);\n }\n\n // Make the request\n const options: Record<string, unknown> = {};\n if (signal) options.signal = signal;\n\n const response = await api\n .get(`products?${searchParams.toString()}`, options as any)\n .json<ProductsListResponse>();\n\n const items = response.data ?? [];\n rememberProductPreviews(items);\n\n return {\n items,\n next: response.cursor?.next ?? null,\n filters: response.filters,\n };\n },\n\n queries: {\n detail: (id: string) =>\n queryOptions({\n // Stock and availability are resolved per branch allocation — same as the list.\n queryKey: productDetailQueryKey(id),\n queryFn: () => product.find(id),\n // List-card product, if one was remembered. Not written as the detail\n // cache entry — `queryFn` still hits products/{id}/details.\n placeholderData: () => getProductPreview(id),\n }),\n tag: (id: string) =>\n queryOptions({\n queryKey: ['products', 'tag', id],\n queryFn: () => product.tag(id),\n }),\n list: (params: Omit<ProductsListParams, 'signal'>) =>\n queryOptions({\n // Scope (branch) varies product availability — key must include it.\n queryKey: ['products', 'list', params, { scope: getActiveScope() }],\n queryFn: ({ signal }) => product.list({ ...params, signal }),\n }),\n },\n};\n"]}
@@ -1,6 +1,6 @@
1
- import { useDate } from './chunk-FBOWKMPX.js';
1
+ import { useDate } from './chunk-GHACVKKD.js';
2
2
  import { useTranslation } from './chunk-TYNZ5B2B.js';
3
- import { Image } from './chunk-AT3IL55G.js';
3
+ import { Image } from './chunk-MYW5QYWO.js';
4
4
  import { Link } from './chunk-AXW67SY7.js';
5
5
  import { jsxs, jsx } from 'react/jsx-runtime';
6
6
 
@@ -61,5 +61,5 @@ function BlogListLayout({
61
61
  }
62
62
 
63
63
  export { BlogArticleCard, BlogListLayout };
64
- //# sourceMappingURL=chunk-WOMGFBX5.js.map
65
- //# sourceMappingURL=chunk-WOMGFBX5.js.map
64
+ //# sourceMappingURL=chunk-DSJE2TS2.js.map
65
+ //# sourceMappingURL=chunk-DSJE2TS2.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/routes/blog/components.tsx"],"names":[],"mappings":"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","file":"chunk-WOMGFBX5.js","sourcesContent":["import type { ReactNode } from 'react';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { useDate } from '../../hooks';\nimport { Image, Link } from '../../components/common';\nimport type { BlogCategory, ArticleSummary } from './types';\n\nexport function BlogCategoriesSidebar({ categories }: { categories: BlogCategory[] }) {\n const { t } = useTranslation();\n\n if (!categories.length) return null;\n\n return (\n <nav aria-label=\"Sidebar\" className=\"hidden lg:block lg:sticky shrink-0 top-24 col-span-2\">\n <h2 className=\"font-bold mb-3\">{t('pages.blog_categories.categories')}</h2>\n <ul>\n {categories.map((category) => (\n <li key={category.id} className={category.is_current ? 'text-primary' : ''}>\n <Link className=\"py-3 block text-sm hover:text-primary\" to={category.url}>\n {category.name}\n </Link>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n\nexport function BlogArticleCard({\n article,\n showAuthor = false,\n}: {\n article: ArticleSummary;\n showAuthor?: boolean;\n}) {\n const { format: formatDate } = useDate();\n\n return (\n <div className=\"list-block post-entry relative h-full transition-shadow duration-500 bg-white hover:shadow-default rounded-lg justify-around overflow-hidden flex flex-col\">\n <Link\n to={article.url}\n className=\"post-entry__image relative overflow-hidden hover:opacity-90 w-full h-56 bg-border-color flex items-center justify-center\"\n >\n {article.image && (\n <Image\n className=\"h-full w-full object-cover\"\n src={article.image}\n alt={article.name}\n aspectRatio=\"16/9\"\n />\n )}\n </Link>\n <div className=\"flex-1 px-5 pt-5 pb-7\">\n <div className=\"mb-2.5 text-gray-500 rounded-md inline-flex text-sm rtl:space-x-reverse space-x-5\">\n <div className=\"flex items-center\">\n <i className=\"sicon-calendar-date rtl:ml-1 ltr:mr-1\"></i>\n <span>{formatDate(article.created_at)}</span>\n </div>\n {showAuthor && article.author && (\n <Link to={article.author.url} className=\"flex items-center hover:text-dark\">\n <i className=\"sicon-user rtl:ml-1 ltr:mr-1\"></i>\n <span>{article.author.name}</span>\n </Link>\n )}\n </div>\n <h3 className=\"post-entry__title text-sm font-bold text-gray-800 leading-6 mb-2.5\">\n <Link to={article.url}>{article.name}</Link>\n </h3>\n <p className=\"text-sm text-gray-500 leading-6 mb-2.5\">{article.description}</p>\n </div>\n </div>\n );\n}\n\nexport function BlogListLayout({\n categories,\n children,\n}: {\n categories: BlogCategory[];\n children: ReactNode;\n}) {\n return (\n <div className=\"grid grid-cols-1 lg:grid-cols-8 gap-8\">\n <BlogCategoriesSidebar categories={categories} />\n <div className=\"main-content lg:col-span-6\">{children}</div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/routes/blog/components.tsx"],"names":[],"mappings":"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","file":"chunk-DSJE2TS2.js","sourcesContent":["import type { ReactNode } from 'react';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { useDate } from '../../hooks';\nimport { Image, Link } from '../../components/common';\nimport type { BlogCategory, ArticleSummary } from './types';\n\nexport function BlogCategoriesSidebar({ categories }: { categories: BlogCategory[] }) {\n const { t } = useTranslation();\n\n if (!categories.length) return null;\n\n return (\n <nav aria-label=\"Sidebar\" className=\"hidden lg:block lg:sticky shrink-0 top-24 col-span-2\">\n <h2 className=\"font-bold mb-3\">{t('pages.blog_categories.categories')}</h2>\n <ul>\n {categories.map((category) => (\n <li key={category.id} className={category.is_current ? 'text-primary' : ''}>\n <Link className=\"py-3 block text-sm hover:text-primary\" to={category.url}>\n {category.name}\n </Link>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n\nexport function BlogArticleCard({\n article,\n showAuthor = false,\n}: {\n article: ArticleSummary;\n showAuthor?: boolean;\n}) {\n const { format: formatDate } = useDate();\n\n return (\n <div className=\"list-block post-entry relative h-full transition-shadow duration-500 bg-white hover:shadow-default rounded-lg justify-around overflow-hidden flex flex-col\">\n <Link\n to={article.url}\n className=\"post-entry__image relative overflow-hidden hover:opacity-90 w-full h-56 bg-border-color flex items-center justify-center\"\n >\n {article.image && (\n <Image\n className=\"h-full w-full object-cover\"\n src={article.image}\n alt={article.name}\n aspectRatio=\"16/9\"\n />\n )}\n </Link>\n <div className=\"flex-1 px-5 pt-5 pb-7\">\n <div className=\"mb-2.5 text-gray-500 rounded-md inline-flex text-sm rtl:space-x-reverse space-x-5\">\n <div className=\"flex items-center\">\n <i className=\"sicon-calendar-date rtl:ml-1 ltr:mr-1\"></i>\n <span>{formatDate(article.created_at)}</span>\n </div>\n {showAuthor && article.author && (\n <Link to={article.author.url} className=\"flex items-center hover:text-dark\">\n <i className=\"sicon-user rtl:ml-1 ltr:mr-1\"></i>\n <span>{article.author.name}</span>\n </Link>\n )}\n </div>\n <h3 className=\"post-entry__title text-sm font-bold text-gray-800 leading-6 mb-2.5\">\n <Link to={article.url}>{article.name}</Link>\n </h3>\n <p className=\"text-sm text-gray-500 leading-6 mb-2.5\">{article.description}</p>\n </div>\n </div>\n );\n}\n\nexport function BlogListLayout({\n categories,\n children,\n}: {\n categories: BlogCategory[];\n children: ReactNode;\n}) {\n return (\n <div className=\"grid grid-cols-1 lg:grid-cols-8 gap-8\">\n <BlogCategoriesSidebar categories={categories} />\n <div className=\"main-content lg:col-span-6\">{children}</div>\n </div>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { getActiveCurrency } from './chunk-OQTBHL5T.js';
1
+ import { getActiveCurrency } from './chunk-SOQN5WKL.js';
2
2
  import { whenSallaLoaded } from './chunk-GYXUYHKO.js';
3
3
  import { getTwilightContext } from './chunk-7VNVCHID.js';
4
4
 
@@ -36,5 +36,5 @@ function dispatchProductViewed(product) {
36
36
  }
37
37
 
38
38
  export { dispatchProductViewed, dispatchRouteChanged };
39
- //# sourceMappingURL=chunk-ZWOD67SV.js.map
40
- //# sourceMappingURL=chunk-ZWOD67SV.js.map
39
+ //# sourceMappingURL=chunk-EAKEYWYL.js.map
40
+ //# sourceMappingURL=chunk-EAKEYWYL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/sdk-events.ts"],"names":[],"mappings":";;;;;AA6BO,SAAS,oBAAA,GAA6B;AAC3C,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAEnC,EAAA,MAAM,QAAQ,MAAA,CAAO,KAAA;AACrB,EAAA,IAAI,CAAC,KAAA,EAAO,KAAA,EAAO,QAAA,EAAU;AAE7B,EAAA,MAAM,MAAM,kBAAA,EAAmB;AAC/B,EAAA,KAAA,CAAM,MAAM,QAAA,CAAS,gBAAA,EAAkB,GAAA,CAAI,IAAA,IAAQ,EAAE,CAAA;AACvD;AAMO,SAAS,sBAAsB,OAAA,EAAwB;AAC5D,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,IAAK,CAAA;AACvC,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,EAAO,GAAA,IAAO,EAAA;AACpC,EAAA,MAAM,OAAA,GAAU;AAAA,IACd,IAAI,OAAA,CAAQ,EAAA;AAAA,IACZ,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,UAAA,EAAY,OAAA,CAAQ,QAAA,GAAW,CAAC,EAAE,EAAA,EAAI,OAAA,CAAQ,QAAA,CAAS,EAAA,EAAI,MAAM,OAAA,CAAQ,QAAA,CAAS,IAAA,EAAM,IAAI,EAAC;AAAA,IAC7F,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAU,IAAA,IAAQ,EAAA;AAAA,IACpC,KAAA;AAAA,IACA,QAAA,EAAU,CAAA;AAAA,IACV,OAAA,EAAS,EAAA;AAAA,IACT,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,IAAA,IAAQ,EAAA;AAAA,IAC9B,KAAA;AAAA,IACA,QAAA,EAAU,iBAAA,CAAkB,OAAA,CAAQ,QAAQ,CAAA;AAAA,IAC5C,GAAA,EAAK,QAAQ,GAAA,IAAO,EAAA;AAAA,IACpB,KAAA,EAAO,KAAA;AAAA,IACP,KAAK,OAAA,CAAQ,GAAA;AAAA,IACb,SAAA,EAAW;AAAA,GACb;AAEA,EAAA,eAAA;AAAA,IACE,CAAC,GAAA,KAAQ,KAAK,GAAA,CAAI,SAAQ,CAAE,IAAA,CAAK,MAAM,GAAA,CAAI,MAAM,QAAA,CAAS,gBAAA,EAAkB,CAAC,OAAO,CAAC,CAAC;AAAA,GACxF;AACF","file":"chunk-ZWOD67SV.js","sourcesContent":["import { getTwilightContext } from '../twilight/context';\nimport type { PageContext } from '../twilight/context';\nimport type { Product } from '../types';\nimport { getActiveCurrency } from '../api/client';\nimport { whenSallaLoaded } from './sdk-helpers';\n\n/**\n * Payload dispatched via `salla.event.dispatch('route::changed', payload)`\n * after each client-side navigation completes.\n *\n * The page config fields are spread at root level. When the matched route\n * has no page data (e.g., 404, error boundary), an empty object is dispatched.\n *\n * @example\n * ```ts\n * salla.event.on('route::changed', (page: RouteChangedEvent) => {\n * console.log(page.slug, page.title, page.id);\n * });\n * ```\n */\nexport type RouteChangedEvent = PageContext;\n\n/**\n * Dispatch the `route::changed` Salla SDK event with the current page config.\n *\n * Framework-agnostic — reads from the twilight context store which is\n * populated by whichever framework adapter is active (TanStack, Next.js, etc.).\n * Each adapter should call this after navigation resolves.\n */\nexport function dispatchRouteChanged(): void {\n if (typeof window === 'undefined') return;\n\n const salla = window.salla;\n if (!salla?.event?.dispatch) return;\n\n const ctx = getTwilightContext();\n salla.event.dispatch('route::changed', ctx.page ?? {});\n}\n\n/**\n * Dispatch `Product Viewed`, which Twig's product page hands the SDK through `salla.init`'s\n * `events`: store analytics, pixels and apps that remember viewed products listen for it.\n */\nexport function dispatchProductViewed(product: Product): void {\n if (typeof window === 'undefined') return;\n const price = Number(product.price) || 0;\n const image = product.image?.url ?? '';\n const payload = {\n id: product.id,\n name: product.name,\n categories: product.category ? [{ id: product.category.id, name: product.category.name }] : [],\n category: product.category?.name ?? '',\n price,\n quantity: 1,\n variant: '',\n brand: product.brand?.name ?? '',\n image,\n currency: getActiveCurrency(product.currency),\n sku: product.sku ?? '',\n value: price,\n url: product.url,\n image_url: image,\n };\n // After init: analytics drops events until `salla.init` has merged the store's `jitsu` list.\n whenSallaLoaded(\n (sdk) => void sdk.onReady().then(() => sdk.event.dispatch('Product Viewed', [payload]))\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/sdk-events.ts"],"names":[],"mappings":";;;;;AA6BO,SAAS,oBAAA,GAA6B;AAC3C,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAEnC,EAAA,MAAM,QAAQ,MAAA,CAAO,KAAA;AACrB,EAAA,IAAI,CAAC,KAAA,EAAO,KAAA,EAAO,QAAA,EAAU;AAE7B,EAAA,MAAM,MAAM,kBAAA,EAAmB;AAC/B,EAAA,KAAA,CAAM,MAAM,QAAA,CAAS,gBAAA,EAAkB,GAAA,CAAI,IAAA,IAAQ,EAAE,CAAA;AACvD;AAMO,SAAS,sBAAsB,OAAA,EAAwB;AAC5D,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,IAAK,CAAA;AACvC,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,EAAO,GAAA,IAAO,EAAA;AACpC,EAAA,MAAM,OAAA,GAAU;AAAA,IACd,IAAI,OAAA,CAAQ,EAAA;AAAA,IACZ,MAAM,OAAA,CAAQ,IAAA;AAAA,IACd,UAAA,EAAY,OAAA,CAAQ,QAAA,GAAW,CAAC,EAAE,EAAA,EAAI,OAAA,CAAQ,QAAA,CAAS,EAAA,EAAI,MAAM,OAAA,CAAQ,QAAA,CAAS,IAAA,EAAM,IAAI,EAAC;AAAA,IAC7F,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAU,IAAA,IAAQ,EAAA;AAAA,IACpC,KAAA;AAAA,IACA,QAAA,EAAU,CAAA;AAAA,IACV,OAAA,EAAS,EAAA;AAAA,IACT,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,IAAA,IAAQ,EAAA;AAAA,IAC9B,KAAA;AAAA,IACA,QAAA,EAAU,iBAAA,CAAkB,OAAA,CAAQ,QAAQ,CAAA;AAAA,IAC5C,GAAA,EAAK,QAAQ,GAAA,IAAO,EAAA;AAAA,IACpB,KAAA,EAAO,KAAA;AAAA,IACP,KAAK,OAAA,CAAQ,GAAA;AAAA,IACb,SAAA,EAAW;AAAA,GACb;AAEA,EAAA,eAAA;AAAA,IACE,CAAC,GAAA,KAAQ,KAAK,GAAA,CAAI,SAAQ,CAAE,IAAA,CAAK,MAAM,GAAA,CAAI,MAAM,QAAA,CAAS,gBAAA,EAAkB,CAAC,OAAO,CAAC,CAAC;AAAA,GACxF;AACF","file":"chunk-EAKEYWYL.js","sourcesContent":["import { getTwilightContext } from '../twilight/context';\nimport type { PageContext } from '../twilight/context';\nimport type { Product } from '../types';\nimport { getActiveCurrency } from '../api/client';\nimport { whenSallaLoaded } from './sdk-helpers';\n\n/**\n * Payload dispatched via `salla.event.dispatch('route::changed', payload)`\n * after each client-side navigation completes.\n *\n * The page config fields are spread at root level. When the matched route\n * has no page data (e.g., 404, error boundary), an empty object is dispatched.\n *\n * @example\n * ```ts\n * salla.event.on('route::changed', (page: RouteChangedEvent) => {\n * console.log(page.slug, page.title, page.id);\n * });\n * ```\n */\nexport type RouteChangedEvent = PageContext;\n\n/**\n * Dispatch the `route::changed` Salla SDK event with the current page config.\n *\n * Framework-agnostic — reads from the twilight context store which is\n * populated by whichever framework adapter is active (TanStack, Next.js, etc.).\n * Each adapter should call this after navigation resolves.\n */\nexport function dispatchRouteChanged(): void {\n if (typeof window === 'undefined') return;\n\n const salla = window.salla;\n if (!salla?.event?.dispatch) return;\n\n const ctx = getTwilightContext();\n salla.event.dispatch('route::changed', ctx.page ?? {});\n}\n\n/**\n * Dispatch `Product Viewed`, which Twig's product page hands the SDK through `salla.init`'s\n * `events`: store analytics, pixels and apps that remember viewed products listen for it.\n */\nexport function dispatchProductViewed(product: Product): void {\n if (typeof window === 'undefined') return;\n const price = Number(product.price) || 0;\n const image = product.image?.url ?? '';\n const payload = {\n id: product.id,\n name: product.name,\n categories: product.category ? [{ id: product.category.id, name: product.category.name }] : [],\n category: product.category?.name ?? '',\n price,\n quantity: 1,\n variant: '',\n brand: product.brand?.name ?? '',\n image,\n currency: getActiveCurrency(product.currency),\n sku: product.sku ?? '',\n value: price,\n url: product.url,\n image_url: image,\n };\n // After init: analytics drops events until `salla.init` has merged the store's `jitsu` list.\n whenSallaLoaded(\n (sdk) => void sdk.onReady().then(() => sdk.event.dispatch('Product Viewed', [payload]))\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { api } from './chunk-OQTBHL5T.js';
1
+ import { api } from './chunk-SOQN5WKL.js';
2
2
  import { queryOptions } from '@tanstack/react-query';
3
3
 
4
4
  var notification = {
@@ -24,5 +24,5 @@ var notification = {
24
24
  };
25
25
 
26
26
  export { notification };
27
- //# sourceMappingURL=chunk-V4HOZSIW.js.map
28
- //# sourceMappingURL=chunk-V4HOZSIW.js.map
27
+ //# sourceMappingURL=chunk-ECMFNYPW.js.map
28
+ //# sourceMappingURL=chunk-ECMFNYPW.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/notification.ts"],"names":[],"mappings":";;;AAcO,IAAM,YAAA,GAAe;AAAA,EAC1B,MAAM,YAAgD;AACpD,IAAA,MAAM,WAAW,MAAM,GAAA,CACpB,GAAA,CAAI,eAAe,EACnB,IAAA,EAAmF;AACtF,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,QAAA,CAAS,IAAA,IAAQ,EAAC;AAAA,MACxB,QAAQ,QAAA,CAAS;AAAA,KACnB;AAAA,EACF,CAAA;AAAA,EAEA,UAAA,EAAY,OAAO,EAAA,KAA8B;AAC/C,IAAA,MAAM,IAAI,GAAA,CAAI,CAAA,cAAA,EAAiB,EAAE,CAAA,KAAA,CAAO,EAAE,IAAA,EAAK;AAAA,EACjD,CAAA;AAAA,EAEA,eAAe,YAA2B;AACxC,IAAA,MAAM,GAAA,CAAI,GAAA,CAAI,wBAAwB,CAAA,CAAE,IAAA,EAAK;AAAA,EAC/C,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,MACJ,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,eAAA,EAAiB,MAAM,CAAA;AAAA,MAClC,OAAA,EAAS,MAAM,YAAA,CAAa,IAAA;AAAK,KAClC;AAAA;AAEP","file":"chunk-V4HOZSIW.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api } from './client';\nimport type { Notification } from '../routes/account/notifications/types';\n\nexport interface NotificationsListResponse {\n data: Notification[];\n cursor: {\n current: number;\n previous: number | null;\n next: number | null;\n count: number;\n };\n}\n\nexport const notification = {\n list: async (): Promise<NotificationsListResponse> => {\n const response = await api\n .get('notifications')\n .json<{ data: Notification[] | null; cursor: NotificationsListResponse['cursor'] }>();\n return {\n data: response.data ?? [],\n cursor: response.cursor,\n };\n },\n\n markAsRead: async (id: number): Promise<void> => {\n await api.put(`notifications/${id}/read`).json();\n },\n\n markAllAsRead: async (): Promise<void> => {\n await api.put('notifications/read-all').json();\n },\n\n queries: {\n list: () =>\n queryOptions({\n queryKey: ['notifications', 'list'],\n queryFn: () => notification.list(),\n }),\n },\n};\n"]}
1
+ {"version":3,"sources":["../src/api/notification.ts"],"names":[],"mappings":";;;AAcO,IAAM,YAAA,GAAe;AAAA,EAC1B,MAAM,YAAgD;AACpD,IAAA,MAAM,WAAW,MAAM,GAAA,CACpB,GAAA,CAAI,eAAe,EACnB,IAAA,EAAmF;AACtF,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,QAAA,CAAS,IAAA,IAAQ,EAAC;AAAA,MACxB,QAAQ,QAAA,CAAS;AAAA,KACnB;AAAA,EACF,CAAA;AAAA,EAEA,UAAA,EAAY,OAAO,EAAA,KAA8B;AAC/C,IAAA,MAAM,IAAI,GAAA,CAAI,CAAA,cAAA,EAAiB,EAAE,CAAA,KAAA,CAAO,EAAE,IAAA,EAAK;AAAA,EACjD,CAAA;AAAA,EAEA,eAAe,YAA2B;AACxC,IAAA,MAAM,GAAA,CAAI,GAAA,CAAI,wBAAwB,CAAA,CAAE,IAAA,EAAK;AAAA,EAC/C,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,MACJ,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,eAAA,EAAiB,MAAM,CAAA;AAAA,MAClC,OAAA,EAAS,MAAM,YAAA,CAAa,IAAA;AAAK,KAClC;AAAA;AAEP","file":"chunk-ECMFNYPW.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api } from './client';\nimport type { Notification } from '../routes/account/notifications/types';\n\nexport interface NotificationsListResponse {\n data: Notification[];\n cursor: {\n current: number;\n previous: number | null;\n next: number | null;\n count: number;\n };\n}\n\nexport const notification = {\n list: async (): Promise<NotificationsListResponse> => {\n const response = await api\n .get('notifications')\n .json<{ data: Notification[] | null; cursor: NotificationsListResponse['cursor'] }>();\n return {\n data: response.data ?? [],\n cursor: response.cursor,\n };\n },\n\n markAsRead: async (id: number): Promise<void> => {\n await api.put(`notifications/${id}/read`).json();\n },\n\n markAllAsRead: async (): Promise<void> => {\n await api.put('notifications/read-all').json();\n },\n\n queries: {\n list: () =>\n queryOptions({\n queryKey: ['notifications', 'list'],\n queryFn: () => notification.list(),\n }),\n },\n};\n"]}
@@ -0,0 +1,73 @@
1
+ import { extractTokenFromCookies } from './chunk-FHU2MXZA.js';
2
+
3
+ // src/utils/maintenance.ts
4
+ var VIEW_AS_OWNER_COOKIE_NAME = "salla_view_as";
5
+ var OWNER_SOURCES = ["dashboard", "portal"];
6
+ function storeIdOf(settings) {
7
+ const id = settings?.store?.id;
8
+ return id == null ? null : String(id);
9
+ }
10
+ function ownerLinkMatches(href, settings) {
11
+ const storeId = storeIdOf(settings);
12
+ if (!storeId) return false;
13
+ let params;
14
+ try {
15
+ params = new URL(href, "http://localhost").searchParams;
16
+ } catch {
17
+ return false;
18
+ }
19
+ const source = params.get("utm_source");
20
+ return source != null && OWNER_SOURCES.includes(source) && params.get("identifier") === storeId;
21
+ }
22
+ function ownerCookieMatches(cookieHeader, settings) {
23
+ const storeId = storeIdOf(settings);
24
+ return !!storeId && extractTokenFromCookies(cookieHeader, VIEW_AS_OWNER_COOKIE_NAME) === storeId;
25
+ }
26
+ function showsMaintenancePage(settings, viewAsOwner) {
27
+ return settings?.maintenance === true && !viewAsOwner && settings.theme?.mode !== "preview";
28
+ }
29
+ var MAINTENANCE_EVIDENCE_HEADER = "x-twilight-maintenance";
30
+ function maintenanceEvidence(settings) {
31
+ const evidence = {};
32
+ if (!settings) return evidence;
33
+ for (const [key, read] of EVIDENCE) {
34
+ const value = read(settings);
35
+ if (value != null && value !== "") evidence[key] = String(value);
36
+ }
37
+ return evidence;
38
+ }
39
+ var EVIDENCE = [
40
+ ["store", (s) => s.store?.id],
41
+ ["scope", (s) => s.store?.scope?.id],
42
+ ["requested-scope", (s) => s.requestedScopeId],
43
+ ["mode", (s) => s.theme?.mode],
44
+ ["request-id", (s) => s.answer?.requestId],
45
+ ["trace", (s) => s.answer?.traceId],
46
+ ["cache", (s) => s.answer?.cacheStatus],
47
+ ["age", (s) => s.answer?.age]
48
+ ];
49
+ function maintenanceEvidenceHeader(evidence) {
50
+ return Object.entries(evidence).map(([key, value]) => `${key}=${value.replace(/[^\x21-\x7e]/g, "")}`).join("; ");
51
+ }
52
+ var DASHBOARD_URL = "https://s.salla.sa";
53
+ var MAINTENANCE_SETTINGS_URL = `${DASHBOARD_URL}/channel/settings?legacy=0#maintenance-mode`;
54
+ function isNotLaunchedNotice(details) {
55
+ return details?.button_url?.replace(/\/+$/, "") === DASHBOARD_URL;
56
+ }
57
+ function withOwnerMaintenanceButton(settings, buttonTitle) {
58
+ const details = settings.maintenance_details;
59
+ if (settings.maintenance !== true || details?.button_title) return settings;
60
+ return {
61
+ ...settings,
62
+ maintenance_details: {
63
+ ...details,
64
+ button_title: buttonTitle,
65
+ button_full_title: buttonTitle,
66
+ button_url: MAINTENANCE_SETTINGS_URL
67
+ }
68
+ };
69
+ }
70
+
71
+ export { MAINTENANCE_EVIDENCE_HEADER, VIEW_AS_OWNER_COOKIE_NAME, isNotLaunchedNotice, maintenanceEvidence, maintenanceEvidenceHeader, ownerCookieMatches, ownerLinkMatches, showsMaintenancePage, withOwnerMaintenanceButton };
72
+ //# sourceMappingURL=chunk-FID76MUV.js.map
73
+ //# sourceMappingURL=chunk-FID76MUV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/maintenance.ts"],"names":[],"mappings":";;;AAgBO,IAAM,yBAAA,GAA4B;AAEzC,IAAM,aAAA,GAAgB,CAAC,WAAA,EAAa,QAAQ,CAAA;AAG5C,SAAS,UAAU,QAAA,EAA0D;AAC3E,EAAA,MAAM,EAAA,GAAK,UAAU,KAAA,EAAO,EAAA;AAC5B,EAAA,OAAO,EAAA,IAAM,IAAA,GAAO,IAAA,GAAO,MAAA,CAAO,EAAE,CAAA;AACtC;AAOO,SAAS,gBAAA,CAAiB,MAAc,QAAA,EAAoD;AACjG,EAAA,MAAM,OAAA,GAAU,UAAU,QAAQ,CAAA;AAClC,EAAA,IAAI,CAAC,SAAS,OAAO,KAAA;AACrB,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAI,GAAA,CAAI,IAAA,EAAM,kBAAkB,CAAA,CAAE,YAAA;AAAA,EAC7C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,GAAA,CAAI,YAAY,CAAA;AACtC,EAAA,OAAO,MAAA,IAAU,QAAQ,aAAA,CAAc,QAAA,CAAS,MAAM,CAAA,IAAK,MAAA,CAAO,GAAA,CAAI,YAAY,CAAA,KAAM,OAAA;AAC1F;AAGO,SAAS,kBAAA,CACd,cACA,QAAA,EACS;AACT,EAAA,MAAM,OAAA,GAAU,UAAU,QAAQ,CAAA;AAClC,EAAA,OAAO,CAAC,CAAC,OAAA,IAAW,uBAAA,CAAwB,YAAA,EAAc,yBAAyB,CAAA,KAAM,OAAA;AAC3F;AASO,SAAS,oBAAA,CACd,UACA,WAAA,EACS;AACT,EAAA,OAAO,UAAU,WAAA,KAAgB,IAAA,IAAQ,CAAC,WAAA,IAAe,QAAA,CAAS,OAAO,IAAA,KAAS,SAAA;AACpF;AAWO,IAAM,2BAAA,GAA8B;AAMpC,SAAS,oBACd,QAAA,EACwB;AACxB,EAAA,MAAM,WAAmC,EAAC;AAC1C,EAAA,IAAI,CAAC,UAAU,OAAO,QAAA;AACtB,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,IAAI,CAAA,IAAK,QAAA,EAAU;AAClC,IAAA,MAAM,KAAA,GAAQ,KAAK,QAAQ,CAAA;AAC3B,IAAA,IAAI,KAAA,IAAS,QAAQ,KAAA,KAAU,EAAA,WAAa,GAAG,CAAA,GAAI,OAAO,KAAK,CAAA;AAAA,EACjE;AACA,EAAA,OAAO,QAAA;AACT;AAEA,IAAM,QAAA,GAA4D;AAAA,EAChE,CAAC,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AAAA,EAC5B,CAAC,OAAA,EAAS,CAAC,MAAM,CAAA,CAAE,KAAA,EAAO,OAAO,EAAE,CAAA;AAAA,EACnC,CAAC,iBAAA,EAAmB,CAAC,CAAA,KAAM,EAAE,gBAAgB,CAAA;AAAA,EAC7C,CAAC,MAAA,EAAQ,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,IAAI,CAAA;AAAA,EAC7B,CAAC,YAAA,EAAc,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,SAAS,CAAA;AAAA,EACzC,CAAC,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,OAAO,CAAA;AAAA,EAClC,CAAC,OAAA,EAAS,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,WAAW,CAAA;AAAA,EACtC,CAAC,KAAA,EAAO,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,GAAG;AAC9B,CAAA;AAGO,SAAS,0BAA0B,QAAA,EAA0C;AAClF,EAAA,OAAO,MAAA,CAAO,QAAQ,QAAQ,CAAA,CAC3B,IAAI,CAAC,CAAC,KAAK,KAAK,CAAA,KAAM,GAAG,GAAG,CAAA,CAAA,EAAI,MAAM,OAAA,CAAQ,eAAA,EAAiB,EAAE,CAAC,CAAA,CAAE,CAAA,CACpE,IAAA,CAAK,IAAI,CAAA;AACd;AAKA,IAAM,aAAA,GAAgB,oBAAA;AAGf,IAAM,wBAAA,GAA2B,GAAG,aAAa,CAAA,2CAAA,CAAA;AAcjD,SAAS,oBAAoB,OAAA,EAAyD;AAC3F,EAAA,OAAO,OAAA,EAAS,UAAA,EAAY,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,KAAM,aAAA;AACtD;AAUO,SAAS,0BAAA,CAEd,UAAa,WAAA,EAAwB;AACrC,EAAA,MAAM,UAAU,QAAA,CAAS,mBAAA;AACzB,EAAA,IAAI,QAAA,CAAS,WAAA,KAAgB,IAAA,IAAQ,OAAA,EAAS,cAAc,OAAO,QAAA;AACnE,EAAA,OAAO;AAAA,IACL,GAAG,QAAA;AAAA,IACH,mBAAA,EAAqB;AAAA,MACnB,GAAG,OAAA;AAAA,MACH,YAAA,EAAc,WAAA;AAAA,MACd,iBAAA,EAAmB,WAAA;AAAA,MACnB,UAAA,EAAY;AAAA;AACd,GACF;AACF","file":"chunk-FID76MUV.js","sourcesContent":["import type { StoreContext } from '../api/store';\nimport type { MaintenanceDetails } from '../types';\nimport { extractTokenFromCookies } from './cookies';\n\n/**\n * Remembers that this browser is the merchant looking at their own closed store.\n *\n * The dashboard's \"view store\" link carries `?utm_source=dashboard&identifier=<store id>`\n * (`portal` for the partners portal). Twig's backend checks that once, keeps\n * `view-as: owner` in the PHP session and lets every later request through; this\n * cookie is that session entry. No `max-age`: a session cookie, as the PHP session\n * was, so closing the browser ends the owner view.\n *\n * The value is the store id the bypass was granted for, checked against the store\n * the settings answer about, so one store's cookie opens no other store.\n */\nexport const VIEW_AS_OWNER_COOKIE_NAME = 'salla_view_as';\n\nconst OWNER_SOURCES = ['dashboard', 'portal'];\n\n/** The id as the URL and the cookie spell it, or null when the settings name none. */\nfunction storeIdOf(settings: StoreContext | null | undefined): string | null {\n const id = settings?.store?.id;\n return id == null ? null : String(id);\n}\n\n/**\n * Whether `href` is the dashboard's link into the merchant's own store:\n * `utm_source` is `dashboard` or `portal`, and `identifier` is this store's id.\n * The backend's own rule, translated.\n */\nexport function ownerLinkMatches(href: string, settings: StoreContext | null | undefined): boolean {\n const storeId = storeIdOf(settings);\n if (!storeId) return false;\n let params: URLSearchParams;\n try {\n params = new URL(href, 'http://localhost').searchParams;\n } catch {\n return false;\n }\n const source = params.get('utm_source');\n return source != null && OWNER_SOURCES.includes(source) && params.get('identifier') === storeId;\n}\n\n/** Whether the cookie remembers an owner view of this store. */\nexport function ownerCookieMatches(\n cookieHeader: string | null,\n settings: StoreContext | null | undefined\n): boolean {\n const storeId = storeIdOf(settings);\n return !!storeId && extractTokenFromCookies(cookieHeader, VIEW_AS_OWNER_COOKIE_NAME) === storeId;\n}\n\n/**\n * Whether this visitor gets the maintenance page instead of the store.\n *\n * True only when the settings say the store is closed and nothing lets the visitor\n * through: neither an owner view (the link or the cookie) nor the theme editor's\n * preview, which the backend also always lets in.\n */\nexport function showsMaintenancePage(\n settings: StoreContext | null | undefined,\n viewAsOwner: boolean\n): boolean {\n return settings?.maintenance === true && !viewAsOwner && settings.theme?.mode !== 'preview';\n}\n\n/**\n * The response header a maintenance 503 carries saying which settings decided it.\n *\n * Theme workers write no logs, and the dispatcher's line for a 5xx records the\n * answer's own `x-trace-id` and this header, so the evidence travels on the answer.\n * The backend sets `maintenance` from store-wide state alone (closed, not launched,\n * or the market in maintenance), so `request-id` and `trace` find the settings\n * request it logged, and `cache`/`age` say whether this was a cached copy of one.\n */\nexport const MAINTENANCE_EVIDENCE_HEADER = 'x-twilight-maintenance';\n\n/**\n * What the maintenance decision rested on, as `key=value` pairs. Ids and the API's\n * own header values only: nothing a visitor typed, nothing that identifies them.\n */\nexport function maintenanceEvidence(\n settings: StoreContext | null | undefined\n): Record<string, string> {\n const evidence: Record<string, string> = {};\n if (!settings) return evidence;\n for (const [key, read] of EVIDENCE) {\n const value = read(settings);\n if (value != null && value !== '') evidence[key] = String(value);\n }\n return evidence;\n}\n\nconst EVIDENCE: [string, (settings: StoreContext) => unknown][] = [\n ['store', (s) => s.store?.id],\n ['scope', (s) => s.store?.scope?.id],\n ['requested-scope', (s) => s.requestedScopeId],\n ['mode', (s) => s.theme?.mode],\n ['request-id', (s) => s.answer?.requestId],\n ['trace', (s) => s.answer?.traceId],\n ['cache', (s) => s.answer?.cacheStatus],\n ['age', (s) => s.answer?.age],\n];\n\n/** {@link maintenanceEvidence} as one header value: `store=1; scope=2; cache=HIT`. */\nexport function maintenanceEvidenceHeader(evidence: Record<string, string>): string {\n return Object.entries(evidence)\n .map(([key, value]) => `${key}=${value.replace(/[^\\x21-\\x7e]/g, '')}`)\n .join('; ');\n}\n\n// todo:: drop both once the backend sends `dashboard_url` (or the filled `button_*`) in the\n// settings; until then this mirrors `config('salla.app.dashboard_url')` and the path Twig's\n// `StoreStatusAlertWidget` appends for the owner.\nconst DASHBOARD_URL = 'https://s.salla.sa';\n\n/** The dashboard page where the merchant turns maintenance mode off, as the backend links it. */\nexport const MAINTENANCE_SETTINGS_URL = `${DASHBOARD_URL}/channel/settings?legacy=0#maintenance-mode`;\n\n/**\n * Whether the notice is the one the backend sends for a store that has not launched yet.\n *\n * The settings carry no `launched` flag: a store whose `store::launched` setting is `0`\n * gets `maintenance: true` and `StoreStatusAlertWidget::getData(true)`, the merchant's\n * \"finish launching\" notice, whose button goes to the dashboard's root, and it goes\n * there for every visitor. A closed store's notice links nowhere for a customer and to\n * {@link MAINTENANCE_SETTINGS_URL} for the owner, so the bare dashboard URL tells them\n * apart, as Twig's `CheckStoreStatus` does by rendering `construction` instead of\n * `maintenance`.\n */\n// todo:: read the backend's own flag once the settings send one.\nexport function isNotLaunchedNotice(details: MaintenanceDetails | null | undefined): boolean {\n return details?.button_url?.replace(/\\/+$/, '') === DASHBOARD_URL;\n}\n\n/**\n * The button on the SDK's merchant maintenance bar. The API fills the `button_*`\n * fields only inside Twig's owner session, which the engine's settings request has\n * none of, so the SDK, handed the settings as they are, draws an empty button. The\n * SDK renders only in the store view, so `maintenance: true` there means the owner\n * (or the preview, where the SDK mounts no bar): the three fields get what Twig's\n * owner branch gives them. The merchant's own title and message stay as they are.\n */\nexport function withOwnerMaintenanceButton<\n T extends Pick<StoreContext, 'maintenance' | 'maintenance_details'>,\n>(settings: T, buttonTitle: string): T {\n const details = settings.maintenance_details;\n if (settings.maintenance !== true || details?.button_title) return settings;\n return {\n ...settings,\n maintenance_details: {\n ...details,\n button_title: buttonTitle,\n button_full_title: buttonTitle,\n button_url: MAINTENANCE_SETTINGS_URL,\n },\n };\n}\n"]}
@@ -1,21 +1,21 @@
1
1
  import { lazy } from 'react';
2
2
 
3
3
  // src/components/layout/lazy.ts
4
- var LazyHeader = lazy(() => import('./Header-KMURB263.js').then((m) => ({ default: m.Header })));
5
- var LazyFooter = lazy(() => import('./Footer-5L3YKKPB.js').then((m) => ({ default: m.Footer })));
4
+ var LazyHeader = lazy(() => import('./Header-IZ3UWIEO.js').then((m) => ({ default: m.Header })));
5
+ var LazyFooter = lazy(() => import('./Footer-GANB36WN.js').then((m) => ({ default: m.Footer })));
6
6
  var LazyCopyright = lazy(
7
- () => import('./Copyright-VGOFMMIR.js').then((m) => ({ default: m.Copyright }))
7
+ () => import('./Copyright-W7RY445F.js').then((m) => ({ default: m.Copyright }))
8
8
  );
9
9
  var LazyMasterLayout = lazy(
10
- () => import('./MasterLayout-AZSOVNPR.js').then((m) => ({ default: m.MasterLayout }))
10
+ () => import('./MasterLayout-DWXUEODB.js').then((m) => ({ default: m.MasterLayout }))
11
11
  );
12
12
  var LazyWidgetHead = lazy(
13
13
  () => import('./WidgetHead-BCRIXIJQ.js').then((m) => ({ default: m.WidgetHead }))
14
14
  );
15
15
  var LazyCustomerLayout = lazy(
16
- () => import('./CustomerLayout-2E6ENXOH.js').then((m) => ({ default: m.CustomerLayout }))
16
+ () => import('./CustomerLayout-P5QZJDMR.js').then((m) => ({ default: m.CustomerLayout }))
17
17
  );
18
18
 
19
19
  export { LazyCopyright, LazyCustomerLayout, LazyFooter, LazyHeader, LazyMasterLayout, LazyWidgetHead };
20
- //# sourceMappingURL=chunk-DEDX3AIO.js.map
21
- //# sourceMappingURL=chunk-DEDX3AIO.js.map
20
+ //# sourceMappingURL=chunk-FU52JCUN.js.map
21
+ //# sourceMappingURL=chunk-FU52JCUN.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/layout/lazy.ts"],"names":[],"mappings":";;;AAMO,IAAM,UAAA,GAAa,IAAA,CAAK,MAAM,OAAO,sBAAU,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,MAAA,GAAS,CAAC;AAErF,IAAM,UAAA,GAAa,IAAA,CAAK,MAAM,OAAO,sBAAU,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,MAAA,GAAS,CAAC;AAErF,IAAM,aAAA,GAAgB,IAAA;AAAA,EAAK,MAChC,OAAO,yBAAa,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,SAAA,EAAU,CAAE;AAC9D;AAEO,IAAM,gBAAA,GAAmB,IAAA;AAAA,EAAK,MACnC,OAAO,4BAAgB,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,YAAA,EAAa,CAAE;AACpE;AAEO,IAAM,cAAA,GAAiB,IAAA;AAAA,EAAK,MACjC,OAAO,0BAAc,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,UAAA,EAAW,CAAE;AAChE;AAEO,IAAM,kBAAA,GAAqB,IAAA;AAAA,EAAK,MACrC,OAAO,8BAAkB,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,cAAA,EAAe,CAAE;AACxE","file":"chunk-DEDX3AIO.js","sourcesContent":["import { lazy } from 'react';\n\n/**\n * Lazy-loaded layout components\n * Use these for code-splitting layout sections\n */\nexport const LazyHeader = lazy(() => import('./Header').then((m) => ({ default: m.Header })));\n\nexport const LazyFooter = lazy(() => import('./Footer').then((m) => ({ default: m.Footer })));\n\nexport const LazyCopyright = lazy(() =>\n import('./Copyright').then((m) => ({ default: m.Copyright }))\n);\n\nexport const LazyMasterLayout = lazy(() =>\n import('./MasterLayout').then((m) => ({ default: m.MasterLayout }))\n);\n\nexport const LazyWidgetHead = lazy(() =>\n import('./WidgetHead').then((m) => ({ default: m.WidgetHead }))\n);\n\nexport const LazyCustomerLayout = lazy(() =>\n import('./CustomerLayout').then((m) => ({ default: m.CustomerLayout }))\n);\n"]}
1
+ {"version":3,"sources":["../src/components/layout/lazy.ts"],"names":[],"mappings":";;;AAMO,IAAM,UAAA,GAAa,IAAA,CAAK,MAAM,OAAO,sBAAU,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,MAAA,GAAS,CAAC;AAErF,IAAM,UAAA,GAAa,IAAA,CAAK,MAAM,OAAO,sBAAU,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,MAAA,GAAS,CAAC;AAErF,IAAM,aAAA,GAAgB,IAAA;AAAA,EAAK,MAChC,OAAO,yBAAa,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,SAAA,EAAU,CAAE;AAC9D;AAEO,IAAM,gBAAA,GAAmB,IAAA;AAAA,EAAK,MACnC,OAAO,4BAAgB,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,YAAA,EAAa,CAAE;AACpE;AAEO,IAAM,cAAA,GAAiB,IAAA;AAAA,EAAK,MACjC,OAAO,0BAAc,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,UAAA,EAAW,CAAE;AAChE;AAEO,IAAM,kBAAA,GAAqB,IAAA;AAAA,EAAK,MACrC,OAAO,8BAAkB,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,cAAA,EAAe,CAAE;AACxE","file":"chunk-FU52JCUN.js","sourcesContent":["import { lazy } from 'react';\n\n/**\n * Lazy-loaded layout components\n * Use these for code-splitting layout sections\n */\nexport const LazyHeader = lazy(() => import('./Header').then((m) => ({ default: m.Header })));\n\nexport const LazyFooter = lazy(() => import('./Footer').then((m) => ({ default: m.Footer })));\n\nexport const LazyCopyright = lazy(() =>\n import('./Copyright').then((m) => ({ default: m.Copyright }))\n);\n\nexport const LazyMasterLayout = lazy(() =>\n import('./MasterLayout').then((m) => ({ default: m.MasterLayout }))\n);\n\nexport const LazyWidgetHead = lazy(() =>\n import('./WidgetHead').then((m) => ({ default: m.WidgetHead }))\n);\n\nexport const LazyCustomerLayout = lazy(() =>\n import('./CustomerLayout').then((m) => ({ default: m.CustomerLayout }))\n);\n"]}