@salla.sa/twilight-theme-engine 1.0.85 → 1.0.87

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 (390) hide show
  1. package/README.md +4 -3
  2. package/bin/twilight-check-manifest.mjs +16 -0
  3. package/dist/{AddToCartForm-B5C2M4OZ.js → AddToCartForm-P644O2QL.js} +4 -4
  4. package/dist/{AddToCartForm-B5C2M4OZ.js.map → AddToCartForm-P644O2QL.js.map} +1 -1
  5. package/dist/{BlogAuthorPage-GTF4UGSS.js → BlogAuthorPage-VWSO6MPY.js} +13 -11
  6. package/dist/BlogAuthorPage-VWSO6MPY.js.map +1 -0
  7. package/dist/{BlogCategoryPage-TN7Y4NBP.js → BlogCategoryPage-K2KSQ6T6.js} +13 -11
  8. package/dist/BlogCategoryPage-K2KSQ6T6.js.map +1 -0
  9. package/dist/{BlogPage-TDB3M3PI.js → BlogPage-XRM7VWOZ.js} +12 -10
  10. package/dist/BlogPage-XRM7VWOZ.js.map +1 -0
  11. package/dist/{BlogSinglePage-4A52Q5QW.js → BlogSinglePage-XIAXT54H.js} +12 -10
  12. package/dist/BlogSinglePage-XIAXT54H.js.map +1 -0
  13. package/dist/{BlogTagPage-TOVPBETA.js → BlogTagPage-IHOA267V.js} +13 -11
  14. package/dist/BlogTagPage-IHOA267V.js.map +1 -0
  15. package/dist/{BrandsPage-VUDGYSQI.js → BrandsPage-ZFEILRT3.js} +12 -10
  16. package/dist/BrandsPage-ZFEILRT3.js.map +1 -0
  17. package/dist/{Breadcrumb-CI3SN5YR.js → Breadcrumb-CVSISL2K.js} +12 -10
  18. package/dist/Breadcrumb-CVSISL2K.js.map +1 -0
  19. package/dist/{CartItem-BHLEURAB.js → CartItem-EOI7P3JA.js} +12 -10
  20. package/dist/CartItem-EOI7P3JA.js.map +1 -0
  21. package/dist/{CartSummary-QERVESYN.js → CartSummary-RZGUBDKJ.js} +12 -10
  22. package/dist/CartSummary-RZGUBDKJ.js.map +1 -0
  23. package/dist/{Copyright-RL6ALKRC.js → Copyright-5BLYSP24.js} +4 -4
  24. package/dist/{Copyright-RL6ALKRC.js.map → Copyright-5BLYSP24.js.map} +1 -1
  25. package/dist/{CustomerLayout-VRZUWGQK.js → CustomerLayout-6F4BJAMU.js} +12 -10
  26. package/dist/CustomerLayout-6F4BJAMU.js.map +1 -0
  27. package/dist/{Footer-ZWBZCMDL.js → Footer-NF2NLDLR.js} +6 -6
  28. package/dist/{Footer-ZWBZCMDL.js.map → Footer-NF2NLDLR.js.map} +1 -1
  29. package/dist/{Header-WNK4O66B.js → Header-6DQJ5X7J.js} +9 -7
  30. package/dist/{Header-WNK4O66B.js.map → Header-6DQJ5X7J.js.map} +1 -1
  31. package/dist/{LoyaltyPage-CGTHWJ76.js → LoyaltyPage-YHWHIWCS.js} +12 -10
  32. package/dist/LoyaltyPage-YHWHIWCS.js.map +1 -0
  33. package/dist/{LoyaltyPointsPage-QSU6K3PW.js → LoyaltyPointsPage-T6K3H5A5.js} +10 -3
  34. package/dist/LoyaltyPointsPage-T6K3H5A5.js.map +1 -0
  35. package/dist/{MainMenu-V3T7F32R.js → MainMenu-Y2TAM7DK.js} +4 -4
  36. package/dist/{MainMenu-V3T7F32R.js.map → MainMenu-Y2TAM7DK.js.map} +1 -1
  37. package/dist/{MasterLayout-XQF644LD.js → MasterLayout-GBEEFFPG.js} +12 -10
  38. package/dist/{MasterLayout-XQF644LD.js.map → MasterLayout-GBEEFFPG.js.map} +1 -1
  39. package/dist/{MobileMenu-U4BVQYKH.js → MobileMenu-RE5XVGZL.js} +12 -10
  40. package/dist/MobileMenu-RE5XVGZL.js.map +1 -0
  41. package/dist/{NotificationsPage-ZRRQY7TF.js → NotificationsPage-QAFWZAS3.js} +12 -10
  42. package/dist/NotificationsPage-QAFWZAS3.js.map +1 -0
  43. package/dist/{OrderSinglePage-O3XYVMG5.js → OrderSinglePage-T4PRXTKG.js} +12 -10
  44. package/dist/OrderSinglePage-T4PRXTKG.js.map +1 -0
  45. package/dist/{OrdersPage-CMXZF5MI.js → OrdersPage-3S6ZS56E.js} +12 -10
  46. package/dist/OrdersPage-3S6ZS56E.js.map +1 -0
  47. package/dist/{PageSingle-IIG2US43.js → PageSingle-W3UTXDOW.js} +4 -4
  48. package/dist/{PageSingle-IIG2US43.js.map → PageSingle-W3UTXDOW.js.map} +1 -1
  49. package/dist/{ProductDetails-65GDABI7.js → ProductDetails-X5A7TG3F.js} +14 -7
  50. package/dist/ProductDetails-X5A7TG3F.js.map +1 -0
  51. package/dist/{ProfilePage-SNJ4WXU4.js → ProfilePage-DUH3AILJ.js} +12 -10
  52. package/dist/ProfilePage-DUH3AILJ.js.map +1 -0
  53. package/dist/{ReviewsPage-UT7UT55J.js → ReviewsPage-2C2P7VS3.js} +4 -4
  54. package/dist/{ReviewsPage-UT7UT55J.js.map → ReviewsPage-2C2P7VS3.js.map} +1 -1
  55. package/dist/{SeoCartWidget-DBJAXJKT.js → SeoCartWidget-VYLGEW2I.js} +12 -10
  56. package/dist/SeoCartWidget-VYLGEW2I.js.map +1 -0
  57. package/dist/{SettingsPage-FLTIOPU5.js → SettingsPage-OZJEW6CW.js} +12 -10
  58. package/dist/SettingsPage-OZJEW6CW.js.map +1 -0
  59. package/dist/{StoreClosedNotification-ZT3QKDKS.js → StoreClosedNotification-QHIZBNXO.js} +13 -11
  60. package/dist/{StoreClosedNotification-ZT3QKDKS.js.map → StoreClosedNotification-QHIZBNXO.js.map} +1 -1
  61. package/dist/{TestimonialsPage-CU7HKU4O.js → TestimonialsPage-K6WJKKME.js} +4 -4
  62. package/dist/{TestimonialsPage-CU7HKU4O.js.map → TestimonialsPage-K6WJKKME.js.map} +1 -1
  63. package/dist/{ThankYouPage-5X6B4X3T.js → ThankYouPage-H6QQEI5R.js} +12 -10
  64. package/dist/ThankYouPage-H6QQEI5R.js.map +1 -0
  65. package/dist/{WalletPage-H2BKIDPA.js → WalletPage-G5IBGN6B.js} +12 -10
  66. package/dist/WalletPage-G5IBGN6B.js.map +1 -0
  67. package/dist/{WishlistPage-RS5UCIQ3.js → WishlistPage-AIOTAB6L.js} +12 -10
  68. package/dist/WishlistPage-AIOTAB6L.js.map +1 -0
  69. package/dist/api/advertisement.d.ts +33 -0
  70. package/dist/api/advertisement.d.ts.map +1 -0
  71. package/dist/api/advertisement.js +8 -0
  72. package/dist/api/advertisement.js.map +1 -0
  73. package/dist/boot/critical-style.d.ts +3 -0
  74. package/dist/boot/critical-style.d.ts.map +1 -0
  75. package/dist/boot/index.d.ts +15 -0
  76. package/dist/boot/index.d.ts.map +1 -0
  77. package/dist/boot.d.ts +1 -0
  78. package/dist/boot.js +69 -0
  79. package/dist/boot.js.map +1 -0
  80. package/dist/chunk-4FJGZQD3.js +6 -0
  81. package/dist/chunk-4FJGZQD3.js.map +1 -0
  82. package/dist/{chunk-SDFDS4Q3.js → chunk-BCJTF3V7.js} +20 -4
  83. package/dist/chunk-BCJTF3V7.js.map +1 -0
  84. package/dist/chunk-DBW7XXNE.js +103 -0
  85. package/dist/chunk-DBW7XXNE.js.map +1 -0
  86. package/dist/{chunk-22SH7OVF.js → chunk-E7WWO3V3.js} +3 -3
  87. package/dist/{chunk-22SH7OVF.js.map → chunk-E7WWO3V3.js.map} +1 -1
  88. package/dist/{chunk-SE5JYWOK.js → chunk-EZHXVHXY.js} +4 -4
  89. package/dist/{chunk-SE5JYWOK.js.map → chunk-EZHXVHXY.js.map} +1 -1
  90. package/dist/{chunk-JO7JWV34.js → chunk-FWYKOQV5.js} +5 -5
  91. package/dist/chunk-FWYKOQV5.js.map +1 -0
  92. package/dist/{chunk-JRNH3FUF.js → chunk-FYHF62KI.js} +4 -4
  93. package/dist/{chunk-JRNH3FUF.js.map → chunk-FYHF62KI.js.map} +1 -1
  94. package/dist/{chunk-UJKFBZFJ.js → chunk-GJ5IMPNY.js} +7 -7
  95. package/dist/{chunk-UJKFBZFJ.js.map → chunk-GJ5IMPNY.js.map} +1 -1
  96. package/dist/chunk-IVBOLREE.js +29 -0
  97. package/dist/chunk-IVBOLREE.js.map +1 -0
  98. package/dist/chunk-LWPKBVIE.js +14 -0
  99. package/dist/{chunk-7WAXN2PP.js.map → chunk-LWPKBVIE.js.map} +1 -1
  100. package/dist/{chunk-SX5MF2YA.js → chunk-N3BCZIGS.js} +4 -4
  101. package/dist/{chunk-SX5MF2YA.js.map → chunk-N3BCZIGS.js.map} +1 -1
  102. package/dist/{chunk-NZVR4OF7.js → chunk-NXQZ4RLM.js} +8 -8
  103. package/dist/chunk-NXQZ4RLM.js.map +1 -0
  104. package/dist/{chunk-NXQJA7D3.js → chunk-PCURRKIH.js} +3 -3
  105. package/dist/{chunk-NXQJA7D3.js.map → chunk-PCURRKIH.js.map} +1 -1
  106. package/dist/{chunk-4CZRUAZB.js → chunk-PU2LHFDQ.js} +10 -11
  107. package/dist/chunk-PU2LHFDQ.js.map +1 -0
  108. package/dist/{chunk-OWX2CPNQ.js → chunk-UQIVX4YA.js} +3 -3
  109. package/dist/{chunk-OWX2CPNQ.js.map → chunk-UQIVX4YA.js.map} +1 -1
  110. package/dist/chunk-X5NK4TZH.js +228 -0
  111. package/dist/chunk-X5NK4TZH.js.map +1 -0
  112. package/dist/{chunk-6SWDSRIL.js → chunk-XKNXYQ2K.js} +6 -6
  113. package/dist/{chunk-6SWDSRIL.js.map → chunk-XKNXYQ2K.js.map} +1 -1
  114. package/dist/{chunk-KHBSGD2D.js → chunk-XO7B3VWS.js} +3 -3
  115. package/dist/{chunk-KHBSGD2D.js.map → chunk-XO7B3VWS.js.map} +1 -1
  116. package/dist/cli/check-manifest.d.ts +10 -0
  117. package/dist/cli/check-manifest.d.ts.map +1 -0
  118. package/dist/cli/check-manifest.js +44 -0
  119. package/dist/cli/check-manifest.js.map +1 -0
  120. package/dist/components/cart/index.js +1 -1
  121. package/dist/components/common/index.js +2 -2
  122. package/dist/components/drawer/index.js +10 -8
  123. package/dist/components/home/index.js +12 -10
  124. package/dist/components/layout/Footer.d.ts.map +1 -1
  125. package/dist/components/layout/MasterLayout.d.ts.map +1 -1
  126. package/dist/components/layout/PageAdvertisements.d.ts +7 -0
  127. package/dist/components/layout/PageAdvertisements.d.ts.map +1 -0
  128. package/dist/components/layout/index.d.ts +1 -0
  129. package/dist/components/layout/index.d.ts.map +1 -1
  130. package/dist/components/layout/index.js +8 -1
  131. package/dist/components/product/index.js +11 -9
  132. package/dist/components/store/index.js +12 -10
  133. package/dist/components/store/index.js.map +1 -1
  134. package/dist/{document-class-67HTP45G.js → document-class-FRL7JHWD.js} +6 -5
  135. package/dist/{document-class-67HTP45G.js.map → document-class-FRL7JHWD.js.map} +1 -1
  136. package/dist/hooks/index.js +10 -8
  137. package/dist/hooks/useGtm.js +10 -8
  138. package/dist/hooks/useMoney.js +10 -8
  139. package/dist/hooks/useStore.js +10 -8
  140. package/dist/index.js +10 -8
  141. package/dist/index.js.map +1 -1
  142. package/dist/{not-found-QTHBFPNT.js → not-found-E6AR4CZ4.js} +12 -10
  143. package/dist/not-found-E6AR4CZ4.js.map +1 -0
  144. package/dist/providers/index.js +10 -8
  145. package/dist/routes/account/orders.js +1 -1
  146. package/dist/routes/account.js +6 -6
  147. package/dist/routes/blog.js +5 -5
  148. package/dist/routes/brands.js +1 -1
  149. package/dist/routes/cart.js +14 -12
  150. package/dist/routes/cart.js.map +1 -1
  151. package/dist/routes/home.js +13 -11
  152. package/dist/routes/loyalty.js +2 -2
  153. package/dist/routes/page.js +1 -1
  154. package/dist/routes/product-listing.js +12 -10
  155. package/dist/routes/product-listing.js.map +1 -1
  156. package/dist/routes/product.js +12 -10
  157. package/dist/routes/product.js.map +1 -1
  158. package/dist/routes/root/beforeLoad.d.ts +2 -2
  159. package/dist/routes/root/beforeLoad.d.ts.map +1 -1
  160. package/dist/routes/root/head.d.ts.map +1 -1
  161. package/dist/routes/testimonials.js +2 -2
  162. package/dist/routes/thank-you.js +1 -1
  163. package/dist/skeleton.js +13 -11
  164. package/dist/tanstack/document-class.d.ts.map +1 -1
  165. package/dist/tanstack/index.d.ts +1 -0
  166. package/dist/tanstack/index.d.ts.map +1 -1
  167. package/dist/tanstack/stylesheet.d.ts +15 -0
  168. package/dist/tanstack/stylesheet.d.ts.map +1 -0
  169. package/dist/tanstack.js +33 -4
  170. package/dist/tanstack.js.map +1 -1
  171. package/dist/utils/index.js +2 -2
  172. package/dist/vite/index.d.ts +1 -1
  173. package/dist/vite/index.d.ts.map +1 -1
  174. package/dist/vite/index.js +14 -25
  175. package/dist/vite/index.js.map +1 -1
  176. package/dist/vite/plugins/twilight-manifest.d.ts +23 -0
  177. package/dist/vite/plugins/twilight-manifest.d.ts.map +1 -1
  178. package/dist/vite/plugins/twilight-schema.plugin.d.ts.map +1 -1
  179. package/package.json +16 -3
  180. package/tailwind/components/Component.tsx.txt +21 -0
  181. package/tailwind/components/ComponentRegistry.ts.txt +66 -0
  182. package/tailwind/components/cart/CartItem.tsx.txt +211 -0
  183. package/tailwind/components/cart/CartSummary.tsx.txt +269 -0
  184. package/tailwind/components/cart/PreOrderNotification.tsx.txt +16 -0
  185. package/tailwind/components/cart/PriceQuoteButton.tsx.txt +21 -0
  186. package/tailwind/components/cart/SeoCartWidget.tsx.txt +99 -0
  187. package/tailwind/components/cart/index.ts.txt +11 -0
  188. package/tailwind/components/cart/lazy.ts.txt +15 -0
  189. package/tailwind/components/collapse/Collapse.tsx.txt +95 -0
  190. package/tailwind/components/collapse/index.ts.txt +41 -0
  191. package/tailwind/components/common/Breadcrumb.tsx.txt +27 -0
  192. package/tailwind/components/common/BreadcrumbJsonLd.tsx.txt +40 -0
  193. package/tailwind/components/common/BreadcrumbTrail.tsx.txt +97 -0
  194. package/tailwind/components/common/CurrencySymbol.tsx.txt +8 -0
  195. package/tailwind/components/common/DeferredData.tsx.txt +122 -0
  196. package/tailwind/components/common/ErrorPage.tsx.txt +69 -0
  197. package/tailwind/components/common/Image.tsx.txt +119 -0
  198. package/tailwind/components/common/Link.tsx.txt +36 -0
  199. package/tailwind/components/common/Link.types.ts.txt +85 -0
  200. package/tailwind/components/common/NoContent.tsx.txt +27 -0
  201. package/tailwind/components/common/RenderWhenVisible.tsx.txt +92 -0
  202. package/tailwind/components/common/index.ts.txt +42 -0
  203. package/tailwind/components/common/lazy.ts.txt +28 -0
  204. package/tailwind/components/defineComponent.ts.txt +32 -0
  205. package/tailwind/components/drawer/Drawer.tsx.txt +219 -0
  206. package/tailwind/components/drawer/index.ts.txt +38 -0
  207. package/tailwind/components/dropdown/Dropdown.tsx.txt +166 -0
  208. package/tailwind/components/dropdown/index.ts.txt +40 -0
  209. package/tailwind/components/home/BundleComponent.tsx.txt +35 -0
  210. package/tailwind/components/home/ComponentErrorBoundary.tsx.txt +98 -0
  211. package/tailwind/components/home/FeaturedProductsStyle1.tsx.txt +125 -0
  212. package/tailwind/components/home/FeaturedProductsStyle2.tsx.txt +127 -0
  213. package/tailwind/components/home/FeaturedProductsStyle3.tsx.txt +71 -0
  214. package/tailwind/components/home/FixedBanner.tsx.txt +68 -0
  215. package/tailwind/components/home/FixedProducts.tsx.txt +72 -0
  216. package/tailwind/components/home/HomePageRenderer.tsx.txt +284 -0
  217. package/tailwind/components/home/PageBlocks.tsx.txt +24 -0
  218. package/tailwind/components/home/ParallaxBackground.tsx.txt +50 -0
  219. package/tailwind/components/home/PhotosSlider.tsx.txt +61 -0
  220. package/tailwind/components/home/ProductsSlider.tsx.txt +87 -0
  221. package/tailwind/components/home/ReorderProducts.tsx.txt +38 -0
  222. package/tailwind/components/home/SquarePhotos.tsx.txt +68 -0
  223. package/tailwind/components/home/StoreFeatures.tsx.txt +34 -0
  224. package/tailwind/components/home/Testimonials.tsx.txt +36 -0
  225. package/tailwind/components/home/Youtube.tsx.txt +48 -0
  226. package/tailwind/components/home/index.ts.txt +50 -0
  227. package/tailwind/components/home/lazy.ts.txt +17 -0
  228. package/tailwind/components/home/register.ts.txt +44 -0
  229. package/tailwind/components/home/reorder-hooks.ts.txt +52 -0
  230. package/tailwind/components/home/types.ts.txt +4 -0
  231. package/tailwind/components/layout/Copyright.tsx.txt +23 -0
  232. package/tailwind/components/layout/CustomerLayout.tsx.txt +91 -0
  233. package/tailwind/components/layout/Footer.tsx.txt +341 -0
  234. package/tailwind/components/layout/Header.tsx.txt +154 -0
  235. package/tailwind/components/layout/MasterLayout.tsx.txt +62 -0
  236. package/tailwind/components/layout/PageAdvertisements.tsx.txt +131 -0
  237. package/tailwind/components/layout/WidgetHead.tsx.txt +53 -0
  238. package/tailwind/components/layout/index.ts.txt +27 -0
  239. package/tailwind/components/layout/lazy.ts.txt +25 -0
  240. package/tailwind/components/layout/types.ts.txt +11 -0
  241. package/tailwind/components/modal/ImageModal.tsx.txt +70 -0
  242. package/tailwind/components/modal/Modal.tsx.txt +245 -0
  243. package/tailwind/components/modal/index.ts.txt +39 -0
  244. package/tailwind/components/modal/lazy.ts.txt +10 -0
  245. package/tailwind/components/navigation/MainMenu.tsx.txt +94 -0
  246. package/tailwind/components/navigation/MobileMenu.tsx.txt +160 -0
  247. package/tailwind/components/navigation/index.ts.txt +4 -0
  248. package/tailwind/components/navigation/lazy.ts.txt +11 -0
  249. package/tailwind/components/product/AddToCartForm.tsx.txt +365 -0
  250. package/tailwind/components/product/ProductCard.tsx.txt +305 -0
  251. package/tailwind/components/product/ProductDetails.tsx.txt +267 -0
  252. package/tailwind/components/product/ProductGallery.tsx.txt +234 -0
  253. package/tailwind/components/product/index.ts.txt +15 -0
  254. package/tailwind/components/product/lazy.ts.txt +9 -0
  255. package/tailwind/components/snippets/AppsSnippets.tsx.txt +225 -0
  256. package/tailwind/components/snippets/SallaSdkScripts.tsx.txt +14 -0
  257. package/tailwind/components/snippets/index.ts.txt +4 -0
  258. package/tailwind/components/store/StoreClosedNotification.tsx.txt +73 -0
  259. package/tailwind/components/store/index.ts.txt +8 -0
  260. package/tailwind/components/store/lazy.ts.txt +8 -0
  261. package/tailwind/components/toast/Toaster.tsx.txt +177 -0
  262. package/tailwind/components/toast/index.ts.txt +10 -0
  263. package/tailwind/components/toast/types.ts.txt +38 -0
  264. package/tailwind/components/toast/useToast.ts.txt +61 -0
  265. package/tailwind/components/tracking/GoogleTag.tsx.txt +77 -0
  266. package/tailwind/components/tracking/SiftSnippet.tsx.txt +49 -0
  267. package/tailwind/components/tracking/TwilightBundles.tsx.txt +67 -0
  268. package/tailwind/components/tracking/index.ts.txt +11 -0
  269. package/tailwind/components/tracking/lazy.ts.txt +11 -0
  270. package/tailwind/components/useComponent.ts.txt +12 -0
  271. package/tailwind/routes/account/index.tsx.txt +16 -0
  272. package/tailwind/routes/account/notifications/NotificationsPage.tsx.txt +54 -0
  273. package/tailwind/routes/account/notifications/index.tsx.txt +39 -0
  274. package/tailwind/routes/account/notifications/loader.ts.txt +22 -0
  275. package/tailwind/routes/account/notifications/types.ts.txt +18 -0
  276. package/tailwind/routes/account/orders/OrderSinglePage.tsx.txt +181 -0
  277. package/tailwind/routes/account/orders/OrdersPage.tsx.txt +28 -0
  278. package/tailwind/routes/account/orders/index.tsx.txt +86 -0
  279. package/tailwind/routes/account/orders/loader.ts.txt +66 -0
  280. package/tailwind/routes/account/orders/single/OrderActions.tsx.txt +197 -0
  281. package/tailwind/routes/account/orders/single/OrderHeader.tsx.txt +143 -0
  282. package/tailwind/routes/account/orders/single/OrderItemRow.tsx.txt +209 -0
  283. package/tailwind/routes/account/orders/single/OrderSections.tsx.txt +215 -0
  284. package/tailwind/routes/account/orders/single/types.ts.txt +38 -0
  285. package/tailwind/routes/account/orders/types.ts.txt +29 -0
  286. package/tailwind/routes/account/profile/ProfilePage.tsx.txt +30 -0
  287. package/tailwind/routes/account/profile/index.tsx.txt +39 -0
  288. package/tailwind/routes/account/profile/loader.ts.txt +16 -0
  289. package/tailwind/routes/account/profile/types.ts.txt +5 -0
  290. package/tailwind/routes/account/settings/SettingsPage.tsx.txt +13 -0
  291. package/tailwind/routes/account/settings/index.tsx.txt +39 -0
  292. package/tailwind/routes/account/settings/loader.ts.txt +13 -0
  293. package/tailwind/routes/account/settings/types.ts.txt +5 -0
  294. package/tailwind/routes/account/types.ts.txt +320 -0
  295. package/tailwind/routes/account/wallet/WalletPage.tsx.txt +195 -0
  296. package/tailwind/routes/account/wallet/index.tsx.txt +38 -0
  297. package/tailwind/routes/account/wallet/loader.ts.txt +27 -0
  298. package/tailwind/routes/account/wallet/types.ts.txt +11 -0
  299. package/tailwind/routes/account/wishlist/WishlistPage.tsx.txt +314 -0
  300. package/tailwind/routes/account/wishlist/WishlistShare.tsx.txt +248 -0
  301. package/tailwind/routes/account/wishlist/index.tsx.txt +40 -0
  302. package/tailwind/routes/account/wishlist/loader.ts.txt +26 -0
  303. package/tailwind/routes/account/wishlist/types.ts.txt +9 -0
  304. package/tailwind/routes/blog/BlogAuthorPage.tsx.txt +82 -0
  305. package/tailwind/routes/blog/BlogCategoryPage.tsx.txt +84 -0
  306. package/tailwind/routes/blog/BlogPage.tsx.txt +191 -0
  307. package/tailwind/routes/blog/BlogSinglePage.tsx.txt +168 -0
  308. package/tailwind/routes/blog/BlogTagPage.tsx.txt +84 -0
  309. package/tailwind/routes/blog/BlogTags.tsx.txt +54 -0
  310. package/tailwind/routes/blog/components.tsx.txt +87 -0
  311. package/tailwind/routes/blog/index.tsx.txt +238 -0
  312. package/tailwind/routes/blog/loader.ts.txt +173 -0
  313. package/tailwind/routes/blog/types.ts.txt +106 -0
  314. package/tailwind/routes/brands/BrandsPage.tsx.txt +179 -0
  315. package/tailwind/routes/brands/index.tsx.txt +47 -0
  316. package/tailwind/routes/brands/loader.ts.txt +14 -0
  317. package/tailwind/routes/brands/types.ts.txt +53 -0
  318. package/tailwind/routes/cart/CartPage.tsx.txt +112 -0
  319. package/tailwind/routes/cart/index.tsx.txt +39 -0
  320. package/tailwind/routes/cart/loader.ts.txt +15 -0
  321. package/tailwind/routes/cart/types.ts.txt +6 -0
  322. package/tailwind/routes/home/HomePage.tsx.txt +53 -0
  323. package/tailwind/routes/home/index.tsx.txt +56 -0
  324. package/tailwind/routes/home/loader.ts.txt +24 -0
  325. package/tailwind/routes/home/types.ts.txt +11 -0
  326. package/tailwind/routes/index.ts.txt +94 -0
  327. package/tailwind/routes/lazy.ts.txt +105 -0
  328. package/tailwind/routes/loyalty/LoyaltyPage.tsx.txt +17 -0
  329. package/tailwind/routes/loyalty/LoyaltyPointsPage.tsx.txt +11 -0
  330. package/tailwind/routes/loyalty/index.tsx.txt +81 -0
  331. package/tailwind/routes/loyalty/loader.ts.txt +53 -0
  332. package/tailwind/routes/loyalty/types.ts.txt +109 -0
  333. package/tailwind/routes/not-found.tsx.txt +50 -0
  334. package/tailwind/routes/page/PageSingle.tsx.txt +34 -0
  335. package/tailwind/routes/page/index.tsx.txt +60 -0
  336. package/tailwind/routes/page/loader.ts.txt +19 -0
  337. package/tailwind/routes/page/types.ts.txt +34 -0
  338. package/tailwind/routes/product/ProductPage.tsx.txt +77 -0
  339. package/tailwind/routes/product/index.tsx.txt +157 -0
  340. package/tailwind/routes/product/loader.ts.txt +35 -0
  341. package/tailwind/routes/product/types.ts.txt +6 -0
  342. package/tailwind/routes/product-listing/ProductListPage.tsx.txt +321 -0
  343. package/tailwind/routes/product-listing/index.tsx.txt +95 -0
  344. package/tailwind/routes/product-listing/loader.ts.txt +323 -0
  345. package/tailwind/routes/product-listing/types.ts.txt +96 -0
  346. package/tailwind/routes/product-listing/useAppliedFilters.ts.txt +130 -0
  347. package/tailwind/routes/product-short-link.ts.txt +104 -0
  348. package/tailwind/routes/root/beforeLoad.ts.txt +354 -0
  349. package/tailwind/routes/root/head.ts.txt +424 -0
  350. package/tailwind/routes/root/index.ts.txt +2 -0
  351. package/tailwind/routes/seo-redirects.ts.txt +82 -0
  352. package/tailwind/routes/testimonials/ReviewsPage.tsx.txt +12 -0
  353. package/tailwind/routes/testimonials/TestimonialsPage.tsx.txt +80 -0
  354. package/tailwind/routes/testimonials/index.tsx.txt +80 -0
  355. package/tailwind/routes/testimonials/loader.ts.txt +29 -0
  356. package/tailwind/routes/testimonials/types.ts.txt +9 -0
  357. package/tailwind/routes/thank-you/ThankYouPage.tsx.txt +241 -0
  358. package/tailwind/routes/thank-you/index.tsx.txt +49 -0
  359. package/tailwind/routes/thank-you/loader.ts.txt +40 -0
  360. package/tailwind/routes/thank-you/types.ts.txt +16 -0
  361. package/tailwind/routes/types.ts.txt +41 -0
  362. package/dist/BlogAuthorPage-GTF4UGSS.js.map +0 -1
  363. package/dist/BlogCategoryPage-TN7Y4NBP.js.map +0 -1
  364. package/dist/BlogPage-TDB3M3PI.js.map +0 -1
  365. package/dist/BlogSinglePage-4A52Q5QW.js.map +0 -1
  366. package/dist/BlogTagPage-TOVPBETA.js.map +0 -1
  367. package/dist/BrandsPage-VUDGYSQI.js.map +0 -1
  368. package/dist/Breadcrumb-CI3SN5YR.js.map +0 -1
  369. package/dist/CartItem-BHLEURAB.js.map +0 -1
  370. package/dist/CartSummary-QERVESYN.js.map +0 -1
  371. package/dist/CustomerLayout-VRZUWGQK.js.map +0 -1
  372. package/dist/LoyaltyPage-CGTHWJ76.js.map +0 -1
  373. package/dist/LoyaltyPointsPage-QSU6K3PW.js.map +0 -1
  374. package/dist/MobileMenu-U4BVQYKH.js.map +0 -1
  375. package/dist/NotificationsPage-ZRRQY7TF.js.map +0 -1
  376. package/dist/OrderSinglePage-O3XYVMG5.js.map +0 -1
  377. package/dist/OrdersPage-CMXZF5MI.js.map +0 -1
  378. package/dist/ProductDetails-65GDABI7.js.map +0 -1
  379. package/dist/ProfilePage-SNJ4WXU4.js.map +0 -1
  380. package/dist/SeoCartWidget-DBJAXJKT.js.map +0 -1
  381. package/dist/SettingsPage-FLTIOPU5.js.map +0 -1
  382. package/dist/ThankYouPage-5X6B4X3T.js.map +0 -1
  383. package/dist/WalletPage-H2BKIDPA.js.map +0 -1
  384. package/dist/WishlistPage-RS5UCIQ3.js.map +0 -1
  385. package/dist/chunk-4CZRUAZB.js.map +0 -1
  386. package/dist/chunk-7WAXN2PP.js +0 -14
  387. package/dist/chunk-JO7JWV34.js.map +0 -1
  388. package/dist/chunk-NZVR4OF7.js.map +0 -1
  389. package/dist/chunk-SDFDS4Q3.js.map +0 -1
  390. package/dist/not-found-QTHBFPNT.js.map +0 -1
@@ -0,0 +1,181 @@
1
+ import { SallaButton } from '@salla.sa/twilight-components-react/button';
2
+ import { SallaRatingModal } from '@salla.sa/twilight-components-react/rating-modal';
3
+ import { SallaEditOrderButton } from '@salla.sa/twilight-components-react/edit-order-button';
4
+ import { SallaOrderBranch } from '@salla.sa/twilight-components-react/order-branch';
5
+ import { SallaOrderTotalsCard } from '@salla.sa/twilight-components-react/order-totals-card';
6
+ import { HookSlot, usePageConfig } from '../../../hooks';
7
+ import { useMoney } from '../../../hooks/useMoney';
8
+ import { useTranslation } from '../../../providers/I18nProvider';
9
+ import { useTwilight } from '../../../providers/twilight-context';
10
+ import type { OrderSinglePageProps } from '../types';
11
+ import { OrderHeader } from './single/OrderHeader';
12
+ import { OrderItemRow } from './single/OrderItemRow';
13
+ import { OrderActions } from './single/OrderActions';
14
+ import { OrderOptionsTable, RatingSection, ShippingHeader } from './single/OrderSections';
15
+ import type { TwigOrder } from './single/types';
16
+
17
+ /** Twig's `inner_title` extras: the gift tag and the edit-order button. */
18
+ function TitleRow({ order }: { order: OrderSinglePageProps['order'] }) {
19
+ const { t } = useTranslation();
20
+ return (
21
+ <div className="flex justify-between items-center">
22
+ {order.type === 'buy_as_gift' || order.source?.type === 'buy_as_gift' ? (
23
+ <span className="inline-block text-primary">
24
+ <i className="sicon-gift-sharing"></i>&nbsp;{t('pages.orders.gift_tag')}
25
+ </span>
26
+ ) : (
27
+ <span />
28
+ )}
29
+ <div className="flex items-center gap-3 flex-wrap">
30
+ <SallaEditOrderButton data-testid="store-order-edit-btn" orderId={String(order.id)} />
31
+ </div>
32
+ </div>
33
+ );
34
+ }
35
+
36
+ function RefundMessage({ message }: { message?: string }) {
37
+ if (!message) return null;
38
+ return (
39
+ <div className="min-w-full rounded-md overflow-hidden">
40
+ <div className="bg-white flex items-center gap-1 rounded-md px-3 py-5 md:px-5">
41
+ <i className="sicon-refund h-6 w-6"></i>
42
+ <p className="font-medium text-base" dangerouslySetInnerHTML={{ __html: message }} />
43
+ </div>
44
+ </div>
45
+ );
46
+ }
47
+
48
+ function RatingNotices({ twig }: { twig: TwigOrder }) {
49
+ const { t } = useTranslation();
50
+ const { store } = useTwilight();
51
+ const settings = store?.settings?.rating;
52
+ const rated = !!twig.rating && !Array.isArray(twig.rating);
53
+
54
+ return (
55
+ <>
56
+ {settings?.allow_update && rated && (
57
+ <div className="flex items-start gap-2 bg-blue-50 border border-blue-200 text-blue-500 px-2 py-3 rounded-md text-sm">
58
+ <i className="sicon-info"></i>
59
+ <p>
60
+ {t('pages.order.can_edit_or_delete_your_review_within')} {settings.update_period}{' '}
61
+ {t('pages.order.days_since_added')}.
62
+ </p>
63
+ </div>
64
+ )}
65
+ {twig.can_rate && (
66
+ <div className="rating-header gradient-bg center-between">
67
+ <div>
68
+ <h2 className="font-bold mb-1">{t('pages.order.order_rating_title')}</h2>
69
+ <p className="text-sm">{t('pages.order.order_rating_message')}</p>
70
+ </div>
71
+ <SallaButton
72
+ data-testid="store-order-rate-btn"
73
+ color="light"
74
+ className="btn--rounded-full !text-primary"
75
+ onClick={() => window.salla?.event?.dispatch('rating::open')}
76
+ >
77
+ {t('pages.rating.rate')}
78
+ </SallaButton>
79
+ </div>
80
+ )}
81
+ </>
82
+ );
83
+ }
84
+
85
+ function OrderRatings({ twig }: { twig: TwigOrder }) {
86
+ const { t } = useTranslation();
87
+ const { store } = useTwilight();
88
+ const allowUpdate = !!store?.settings?.rating?.allow_update;
89
+ const rating = Array.isArray(twig.rating) ? undefined : twig.rating;
90
+
91
+ return (
92
+ <>
93
+ {rating?.store?.stars ? (
94
+ <RatingSection
95
+ title={t('pages.rating.rate_the_store')}
96
+ rating={rating.store}
97
+ type="store"
98
+ allowUpdate={allowUpdate}
99
+ />
100
+ ) : null}
101
+ {rating?.shipping?.stars ? (
102
+ <RatingSection
103
+ title={t('pages.rating.rate_shipping')}
104
+ rating={rating.shipping}
105
+ type="shipping"
106
+ allowUpdate={allowUpdate}
107
+ />
108
+ ) : null}
109
+ </>
110
+ );
111
+ }
112
+
113
+ /**
114
+ * The order page as the Twig storefront renders it (Raed's `pages/customer/orders/single.twig`).
115
+ * The markup and the Twilight components read the order in Twig's shape (`componentsOrder`);
116
+ * `order` supplies what that shape lacks and Twig computed on the server: the actions and the
117
+ * receipt and payment URLs.
118
+ */
119
+ export function OrderSinglePage({ order, page, componentsOrder }: OrderSinglePageProps) {
120
+ // The order components read the order id from `salla.config.page.id`, which the router
121
+ // only sets on client-side navigations — seed it so a direct load works too.
122
+ usePageConfig(page);
123
+ const { store } = useTwilight();
124
+ const { format } = useMoney();
125
+ const twig = (componentsOrder ?? { items: [] }) as unknown as TwigOrder;
126
+ const paymentExpired =
127
+ order.actions.payable && (order.payment?.pending_payment_ends_at ?? 0) === 0;
128
+ const money = (amount: number, currency?: string) => format(amount, { currency });
129
+
130
+ return (
131
+ <div className="space-y-4">
132
+ <TitleRow order={order} />
133
+
134
+ <HookSlot name="customer:orders.single.details.start" />
135
+
136
+ <OrderHeader order={order} links={twig.links} paymentExpired={paymentExpired} />
137
+
138
+ {twig.is_pickable && <SallaOrderBranch data-testid="store-order-branch" stackCards />}
139
+
140
+ <RefundMessage message={order.refund_message} />
141
+
142
+ <RatingNotices twig={twig} />
143
+
144
+ <div className="overflow-hidden space-y-5">
145
+ <div className="shipping-orders">
146
+ <ShippingHeader twig={twig} order={order} />
147
+ {order.items.map((item, index) => (
148
+ <OrderItemRow
149
+ key={item.id}
150
+ item={item}
151
+ twigItem={twig.items[index]}
152
+ money={money}
153
+ currency={order.currency}
154
+ />
155
+ ))}
156
+ </div>
157
+
158
+ {!!twig.options?.length && (
159
+ <OrderOptionsTable options={twig.options} money={money} currency={order.currency} />
160
+ )}
161
+ </div>
162
+
163
+ {componentsOrder && (
164
+ <SallaOrderTotalsCard
165
+ data-testid="store-order-totals"
166
+ order={JSON.stringify(componentsOrder)}
167
+ />
168
+ )}
169
+
170
+ <OrderActions order={order} paymentExpired={paymentExpired} />
171
+
172
+ <OrderRatings twig={twig} />
173
+
174
+ <HookSlot name="customer:orders.single.details.end" />
175
+
176
+ {(twig.can_rate || store?.settings?.rating?.allow_update) && (
177
+ <SallaRatingModal data-testid="store-order-rating-modal" />
178
+ )}
179
+ </div>
180
+ );
181
+ }
@@ -0,0 +1,28 @@
1
+ import { SallaOrders } from '@salla.sa/twilight-components-react/orders';
2
+ import { HookSlot } from '../../../hooks';
3
+ import { useTranslation } from '../../../providers/I18nProvider';
4
+ import type { OrdersPageProps } from './types';
5
+
6
+ /** The orders list as the Twig storefront renders it: `<salla-orders>` loads and shows it. */
7
+ export function OrdersPage({ orders, query }: OrdersPageProps) {
8
+ const { t } = useTranslation();
9
+
10
+ return (
11
+ <>
12
+ <HookSlot name="customer:orders.index.items.start" />
13
+ {orders.length ? (
14
+ <SallaOrders
15
+ data-testid="store-orders-list"
16
+ // Typed as status ids; the API also takes the `pending` slug the loader uses.
17
+ params={query?.status ? ({ status: query.status } as never) : undefined}
18
+ />
19
+ ) : (
20
+ <div data-testid="store-orders-empty" className="no-content-placeholder">
21
+ <i className="sicon-packed-box icon"></i>
22
+ <p>{t('pages.orders.non_orders')}</p>
23
+ </div>
24
+ )}
25
+ <HookSlot name="customer:orders.index.items.end" />
26
+ </>
27
+ );
28
+ }
@@ -0,0 +1,86 @@
1
+ import type { HeadDescriptor } from '../../../utils/head';
2
+ import { buildHreflangAlternates } from '../../../utils/baseHead';
3
+ import { lazy } from 'react';
4
+ import { ordersLoader, orderSingleLoader } from './loader';
5
+ import type { OrdersPageProps, OrderSinglePageProps, OrdersSearchParams } from './types';
6
+ import type { IdParams } from '../../types';
7
+ import type { TwilightContext } from '../../../twilight/context';
8
+ import { RouteId } from '../../../router/route-ids';
9
+
10
+ // Lazy-load components for code-splitting
11
+ const LazyOrdersPage = lazy(() => import('./OrdersPage').then((m) => ({ default: m.OrdersPage })));
12
+ const LazyOrderSinglePage = lazy(() =>
13
+ import('./OrderSinglePage').then((m) => ({ default: m.OrderSinglePage }))
14
+ );
15
+
16
+ export const OrdersPage = LazyOrdersPage;
17
+ export const OrderSinglePage = LazyOrderSinglePage;
18
+ export { ordersLoader, orderSingleLoader } from './loader';
19
+ export type {
20
+ OrdersPageProps,
21
+ OrderSinglePageProps,
22
+ OrdersSearchParams,
23
+ OrdersQuery,
24
+ } from './types';
25
+
26
+ async function ordersLoaderWithExtend(
27
+ ctx: { search?: OrdersSearchParams; locale?: string; with_items?: boolean | number },
28
+ extend?: (
29
+ data: OrdersPageProps,
30
+ ctx: { params: Record<string, never> }
31
+ ) => Promise<Record<string, unknown>> | Record<string, unknown>
32
+ ): Promise<OrdersPageProps> {
33
+ const query = ctx.search;
34
+ // ordersLoader already merges the result of `extend`; calling it again here ran it twice.
35
+ return ordersLoader({ query, with_items: ctx.with_items }, extend);
36
+ }
37
+
38
+ function ordersHead(ctx: TwilightContext, data: OrdersPageProps): HeadDescriptor {
39
+ const isPending = data.query?.status === 'pending';
40
+ const base: HeadDescriptor = {
41
+ title: ctx.i18n.t(isPending ? 'common.titles.pending_orders' : 'common.titles.orders'),
42
+ description: data.page.description,
43
+ alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),
44
+ };
45
+
46
+ return base;
47
+ }
48
+
49
+ async function orderSingleLoaderWithExtend(
50
+ ctx: { params: IdParams; locale?: string },
51
+ extend?: (
52
+ data: OrderSinglePageProps,
53
+ ctx: { params: IdParams }
54
+ ) => Promise<Record<string, unknown>> | Record<string, unknown>
55
+ ): Promise<OrderSinglePageProps> {
56
+ const data = await orderSingleLoader({ params: ctx.params });
57
+
58
+ if (extend) {
59
+ const extra = await extend(data, ctx);
60
+ return { ...data, ...extra } as OrderSinglePageProps;
61
+ }
62
+ return data;
63
+ }
64
+
65
+ function orderSingleHead(ctx: TwilightContext, data: OrderSinglePageProps): HeadDescriptor {
66
+ const base: HeadDescriptor = {
67
+ title: data.page.title,
68
+ description: data.page.description,
69
+ alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),
70
+ };
71
+
72
+ return base;
73
+ }
74
+
75
+ export const Orders = {
76
+ id: RouteId.CUSTOMER_ORDERS_INDEX,
77
+ loader: ordersLoaderWithExtend,
78
+ head: ordersHead,
79
+ Component: LazyOrdersPage,
80
+ } as const;
81
+ export const OrderSingle = {
82
+ id: RouteId.CUSTOMER_ORDERS_SINGLE,
83
+ loader: orderSingleLoaderWithExtend,
84
+ head: orderSingleHead,
85
+ Component: LazyOrderSinglePage,
86
+ } as const;
@@ -0,0 +1,66 @@
1
+ import { order } from '../../../api/order';
2
+ import { getTwilightContext } from '../../../twilight/context';
3
+ import { RouteId } from '../../../router/route-ids';
4
+ import { orThrow, orUnauthorized, unauthorized } from '../../../providers/NavigationProvider';
5
+ import { getAuthToken } from '../../../api/client';
6
+ import type { OrdersPageProps, OrderSinglePageProps, OrdersQuery } from './types';
7
+ import type { IdParams } from '../../types';
8
+
9
+ export async function ordersLoader(
10
+ ctx: { query?: OrdersQuery; with_items?: boolean | number },
11
+ extend?: (
12
+ data: OrdersPageProps,
13
+ ctx: { params: Record<string, never> }
14
+ ) => Promise<Record<string, unknown>> | Record<string, unknown>
15
+ ): Promise<OrdersPageProps> {
16
+ if (!getAuthToken()) throw unauthorized();
17
+ const query = ctx.query;
18
+ const isPending = query?.status === 'pending';
19
+ const response = await orUnauthorized(
20
+ order.list({
21
+ // Only decides the empty state; <salla-orders> applies its own review filter (`?tab=waiting`).
22
+ status: query?.status,
23
+ ...(ctx.with_items ? { with_items: ctx.with_items } : {}),
24
+ })
25
+ );
26
+ const i18n = getTwilightContext().i18n;
27
+ const pageData: OrdersPageProps = {
28
+ page: {
29
+ title: isPending ? i18n.t('common.titles.pending_orders') : i18n.t('common.titles.orders'),
30
+ slug: RouteId.CUSTOMER_ORDERS_INDEX,
31
+ },
32
+ orders: response.data,
33
+ cursor: response.cursor,
34
+ query,
35
+ };
36
+
37
+ if (extend) {
38
+ const extra = await extend(pageData, { params: {} });
39
+ return { ...pageData, ...extra } as OrdersPageProps;
40
+ }
41
+ return pageData;
42
+ }
43
+
44
+ export async function orderSingleLoader({
45
+ params,
46
+ }: {
47
+ params: IdParams;
48
+ }): Promise<OrderSinglePageProps> {
49
+ if (!getAuthToken()) throw unauthorized();
50
+ const [data, componentsOrder] = await Promise.all([
51
+ order.findOrThrow(params.id),
52
+ orThrow(orUnauthorized(order.findForComponents(params.id))),
53
+ ]);
54
+ const i18n = getTwilightContext().i18n;
55
+ return {
56
+ page: {
57
+ slug: RouteId.CUSTOMER_ORDERS_SINGLE,
58
+ id: String(params.id),
59
+ title: i18n
60
+ .t('pages.orders.order_details')
61
+ .replace(':id', String(data.order.reference_id ?? params.id)),
62
+ },
63
+ order: data.order,
64
+ componentsOrder,
65
+ };
66
+ }
@@ -0,0 +1,197 @@
1
+ import { useState } from 'react';
2
+ import { SallaButton } from '@salla.sa/twilight-components-react/button';
3
+ import { SallaModal } from '@salla.sa/twilight-components-react/modal';
4
+ import { useIsClient, useUser } from '../../../../hooks';
5
+ import { useAsyncFn } from '../../../../hooks/useAsyncFn';
6
+ import { useTranslation } from '../../../../providers/I18nProvider';
7
+ import { useLocation, useNavigate } from '../../../../providers/NavigationProvider';
8
+ import type { Order } from './types';
9
+
10
+ function ConfirmModal({
11
+ visible,
12
+ onVisibleChange,
13
+ title,
14
+ subTitle,
15
+ iconStyle,
16
+ confirmColor,
17
+ onConfirm,
18
+ busy,
19
+ }: {
20
+ visible: boolean;
21
+ onVisibleChange: (visible: boolean) => void;
22
+ title: string;
23
+ subTitle: string;
24
+ iconStyle: 'success' | 'error';
25
+ confirmColor?: 'danger';
26
+ onConfirm: () => void;
27
+ busy: boolean;
28
+ }) {
29
+ const { t } = useTranslation();
30
+ // The modal wrapper renders only in the browser, so mount after hydration to match the server.
31
+ const isClient = useIsClient();
32
+ if (!isClient) return null;
33
+ return (
34
+ <SallaModal
35
+ width="sm"
36
+ visible={visible}
37
+ onModalVisibilityChanged={(e) => onVisibleChange(Boolean(e.detail))}
38
+ {...{ 'modal-title': title }}
39
+ subTitle={subTitle}
40
+ iconStyle={iconStyle}
41
+ >
42
+ <div slot="footer" className="grid grid-cols-2 gap-3">
43
+ <SallaButton
44
+ width="wide"
45
+ color={confirmColor}
46
+ className="w-full cursor-pointer"
47
+ onClick={onConfirm}
48
+ disabled={busy}
49
+ >
50
+ {t('common.elements.ok')}
51
+ </SallaButton>
52
+ <SallaButton
53
+ className="w-full"
54
+ fill="outline"
55
+ color="light"
56
+ onClick={() => onVisibleChange(false)}
57
+ disabled={busy}
58
+ >
59
+ {t('common.elements.cancel')}
60
+ </SallaButton>
61
+ </div>
62
+ </SallaModal>
63
+ );
64
+ }
65
+
66
+ function PaymentOrReorder({
67
+ order,
68
+ paymentExpired,
69
+ canReorder,
70
+ onReorder,
71
+ busy,
72
+ }: {
73
+ order: Order;
74
+ paymentExpired: boolean;
75
+ canReorder: boolean;
76
+ onReorder: () => void;
77
+ busy: boolean;
78
+ }) {
79
+ const { t } = useTranslation();
80
+ if (order.actions.payable) {
81
+ return paymentExpired || !order.urls.checkout ? (
82
+ <span className="text-red-500">{t('pages.orders.pending_payment_expired')}</span>
83
+ ) : (
84
+ <SallaButton width="wide" href={order.urls.checkout}>
85
+ <i className="sicon sicon-wallet rtl:ml-2 ltr:mr-2"></i>
86
+ <span>{t('pages.orders.finish_payment')}</span>
87
+ </SallaButton>
88
+ );
89
+ }
90
+ if (!canReorder) return null;
91
+ return (
92
+ <>
93
+ <div className="text-sm">
94
+ <h3 className="font-bold text-lg leading-none mb-1">{t('pages.orders.reorder')}</h3>
95
+ <p className="text-gray-500">{t('pages.orders.reorder_description')}</p>
96
+ </div>
97
+ <SallaButton
98
+ data-testid="store-order-reorder-btn"
99
+ shape="link"
100
+ onClick={onReorder}
101
+ disabled={busy}
102
+ >
103
+ <i className="sicon sicon-rotate rtl:ml-2 ltr:mr-2"></i>
104
+ <span>{t('pages.orders.reorder')}</span>
105
+ </SallaButton>
106
+ </>
107
+ );
108
+ }
109
+
110
+ /** The "Reorder & Cancel" card, its pending-payment state and the two confirmations. */
111
+ export function OrderActions({ order, paymentExpired }: { order: Order; paymentExpired: boolean }) {
112
+ const { t } = useTranslation();
113
+ // Token-based, so the server and the first client render agree (the user query loads later).
114
+ const { isLoggedIn } = useUser();
115
+ const navigate = useNavigate();
116
+ const location = useLocation();
117
+ const [showReorder, setShowReorder] = useState(false);
118
+ const [showCancel, setShowCancel] = useState(false);
119
+ const { reorderable, cancellable, payable } = order.actions;
120
+ const canReorder = isLoggedIn && reorderable;
121
+
122
+ const [reorderState, handleReorder] = useAsyncFn(async () => {
123
+ await window.salla?.order.createCartFromOrder(Number(order.id));
124
+ setShowReorder(false);
125
+ navigate('/cart');
126
+ }, [navigate, order.id]);
127
+
128
+ const [cancelState, handleCancel] = useAsyncFn(async () => {
129
+ await window.salla?.order.cancel(Number(order.id));
130
+ setShowCancel(false);
131
+ navigate(location.pathname, { replace: true });
132
+ }, [navigate, order.id, location.pathname]);
133
+
134
+ if (!reorderable && !cancellable && !payable) return null;
135
+
136
+ return (
137
+ <>
138
+ <div className="bg-white rounded-md p-5 divide-y divide-border-color space-y-4">
139
+ {(reorderable || payable) && (
140
+ <div className={payable ? 'flex-center' : 'center-between'}>
141
+ <PaymentOrReorder
142
+ order={order}
143
+ paymentExpired={paymentExpired}
144
+ canReorder={!!canReorder}
145
+ onReorder={() => setShowReorder(true)}
146
+ busy={reorderState.loading}
147
+ />
148
+ </div>
149
+ )}
150
+
151
+ {cancellable && (
152
+ <div className="center-between pt-4">
153
+ <div className="text-sm">
154
+ <h3 className="font-bold text-lg leading-none mb-1">{t('pages.orders.cancel')}</h3>
155
+ <p className="text-gray-500">{t('pages.order.order_cancelation_desc')}</p>
156
+ </div>
157
+ <SallaButton
158
+ data-testid="store-order-cancel-btn"
159
+ shape="link"
160
+ color="danger"
161
+ onClick={() => setShowCancel(true)}
162
+ disabled={cancelState.loading}
163
+ >
164
+ <i className="sicon sicon-cancel-circle rtl:ml-2 ltr:mr-2"></i>
165
+ <span>{t('pages.orders.cancel')}</span>
166
+ </SallaButton>
167
+ </div>
168
+ )}
169
+ </div>
170
+
171
+ {/* Always mounted: salla-modal moves itself under <body> and opens from `visible`. */}
172
+ {canReorder && (
173
+ <ConfirmModal
174
+ visible={showReorder}
175
+ onVisibleChange={setShowReorder}
176
+ title={t('pages.orders.reorder')}
177
+ subTitle={t('pages.orders.reorder_confirmation')}
178
+ iconStyle="success"
179
+ onConfirm={handleReorder}
180
+ busy={reorderState.loading}
181
+ />
182
+ )}
183
+ {cancellable && (
184
+ <ConfirmModal
185
+ visible={showCancel}
186
+ onVisibleChange={setShowCancel}
187
+ title={t('common.elements.warning')}
188
+ subTitle={t('pages.orders.cancel_confirmation')}
189
+ iconStyle="error"
190
+ confirmColor="danger"
191
+ onConfirm={handleCancel}
192
+ busy={cancelState.loading}
193
+ />
194
+ )}
195
+ </>
196
+ );
197
+ }