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

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 (372) hide show
  1. package/dist/{AddToCartForm-B5C2M4OZ.js → AddToCartForm-5X2WZDWR.js} +3 -3
  2. package/dist/{AddToCartForm-B5C2M4OZ.js.map → AddToCartForm-5X2WZDWR.js.map} +1 -1
  3. package/dist/{BlogAuthorPage-GTF4UGSS.js → BlogAuthorPage-LO7FSSJR.js} +12 -10
  4. package/dist/BlogAuthorPage-LO7FSSJR.js.map +1 -0
  5. package/dist/{BlogCategoryPage-TN7Y4NBP.js → BlogCategoryPage-KKFQ3PGR.js} +12 -10
  6. package/dist/BlogCategoryPage-KKFQ3PGR.js.map +1 -0
  7. package/dist/{BlogPage-TDB3M3PI.js → BlogPage-VLF3NSGE.js} +11 -9
  8. package/dist/BlogPage-VLF3NSGE.js.map +1 -0
  9. package/dist/{BlogSinglePage-4A52Q5QW.js → BlogSinglePage-AVK535IW.js} +11 -9
  10. package/dist/BlogSinglePage-AVK535IW.js.map +1 -0
  11. package/dist/{BlogTagPage-TOVPBETA.js → BlogTagPage-F3T4D7RH.js} +12 -10
  12. package/dist/BlogTagPage-F3T4D7RH.js.map +1 -0
  13. package/dist/{BrandsPage-VUDGYSQI.js → BrandsPage-LVSBZSVC.js} +11 -9
  14. package/dist/BrandsPage-LVSBZSVC.js.map +1 -0
  15. package/dist/{Breadcrumb-CI3SN5YR.js → Breadcrumb-VLFTXRFC.js} +11 -9
  16. package/dist/Breadcrumb-VLFTXRFC.js.map +1 -0
  17. package/dist/{CartItem-BHLEURAB.js → CartItem-G3H34GW6.js} +11 -9
  18. package/dist/CartItem-G3H34GW6.js.map +1 -0
  19. package/dist/{CartSummary-QERVESYN.js → CartSummary-VH37RPUI.js} +11 -9
  20. package/dist/CartSummary-VH37RPUI.js.map +1 -0
  21. package/dist/{Copyright-RL6ALKRC.js → Copyright-HE5ZWINZ.js} +3 -3
  22. package/dist/{Copyright-RL6ALKRC.js.map → Copyright-HE5ZWINZ.js.map} +1 -1
  23. package/dist/{CustomerLayout-VRZUWGQK.js → CustomerLayout-LKBLOAVW.js} +11 -9
  24. package/dist/CustomerLayout-LKBLOAVW.js.map +1 -0
  25. package/dist/{Footer-ZWBZCMDL.js → Footer-HHXAST72.js} +5 -5
  26. package/dist/{Footer-ZWBZCMDL.js.map → Footer-HHXAST72.js.map} +1 -1
  27. package/dist/{Header-WNK4O66B.js → Header-GEVZM2YG.js} +8 -6
  28. package/dist/{Header-WNK4O66B.js.map → Header-GEVZM2YG.js.map} +1 -1
  29. package/dist/{LoyaltyPage-CGTHWJ76.js → LoyaltyPage-M5CT3CFD.js} +11 -9
  30. package/dist/LoyaltyPage-M5CT3CFD.js.map +1 -0
  31. package/dist/{LoyaltyPointsPage-QSU6K3PW.js → LoyaltyPointsPage-SDJB52U6.js} +10 -3
  32. package/dist/LoyaltyPointsPage-SDJB52U6.js.map +1 -0
  33. package/dist/{MainMenu-V3T7F32R.js → MainMenu-I7EYS752.js} +3 -3
  34. package/dist/{MainMenu-V3T7F32R.js.map → MainMenu-I7EYS752.js.map} +1 -1
  35. package/dist/{MasterLayout-XQF644LD.js → MasterLayout-QDK4T3NE.js} +11 -9
  36. package/dist/{MasterLayout-XQF644LD.js.map → MasterLayout-QDK4T3NE.js.map} +1 -1
  37. package/dist/{MobileMenu-U4BVQYKH.js → MobileMenu-7VTCWAVJ.js} +11 -9
  38. package/dist/MobileMenu-7VTCWAVJ.js.map +1 -0
  39. package/dist/{NotificationsPage-ZRRQY7TF.js → NotificationsPage-QCABE6QD.js} +11 -9
  40. package/dist/NotificationsPage-QCABE6QD.js.map +1 -0
  41. package/dist/{OrderSinglePage-O3XYVMG5.js → OrderSinglePage-2HVBKBG4.js} +11 -9
  42. package/dist/OrderSinglePage-2HVBKBG4.js.map +1 -0
  43. package/dist/{OrdersPage-CMXZF5MI.js → OrdersPage-5MNCPCM3.js} +11 -9
  44. package/dist/OrdersPage-5MNCPCM3.js.map +1 -0
  45. package/dist/{PageSingle-IIG2US43.js → PageSingle-EN5XIM2B.js} +3 -3
  46. package/dist/{PageSingle-IIG2US43.js.map → PageSingle-EN5XIM2B.js.map} +1 -1
  47. package/dist/{ProductDetails-65GDABI7.js → ProductDetails-UEWQPPDZ.js} +13 -6
  48. package/dist/ProductDetails-UEWQPPDZ.js.map +1 -0
  49. package/dist/{ProfilePage-SNJ4WXU4.js → ProfilePage-TZSU3GHZ.js} +11 -9
  50. package/dist/ProfilePage-TZSU3GHZ.js.map +1 -0
  51. package/dist/{ReviewsPage-UT7UT55J.js → ReviewsPage-WYZ6CHF2.js} +3 -3
  52. package/dist/{ReviewsPage-UT7UT55J.js.map → ReviewsPage-WYZ6CHF2.js.map} +1 -1
  53. package/dist/{SeoCartWidget-DBJAXJKT.js → SeoCartWidget-5JR5RXQM.js} +11 -9
  54. package/dist/SeoCartWidget-5JR5RXQM.js.map +1 -0
  55. package/dist/{SettingsPage-FLTIOPU5.js → SettingsPage-DIDRQXMM.js} +11 -9
  56. package/dist/SettingsPage-DIDRQXMM.js.map +1 -0
  57. package/dist/{StoreClosedNotification-ZT3QKDKS.js → StoreClosedNotification-C2G32E34.js} +12 -10
  58. package/dist/{StoreClosedNotification-ZT3QKDKS.js.map → StoreClosedNotification-C2G32E34.js.map} +1 -1
  59. package/dist/{TestimonialsPage-CU7HKU4O.js → TestimonialsPage-XPHFRBZ7.js} +3 -3
  60. package/dist/{TestimonialsPage-CU7HKU4O.js.map → TestimonialsPage-XPHFRBZ7.js.map} +1 -1
  61. package/dist/{ThankYouPage-5X6B4X3T.js → ThankYouPage-UA6YYFB2.js} +11 -9
  62. package/dist/ThankYouPage-UA6YYFB2.js.map +1 -0
  63. package/dist/{WalletPage-H2BKIDPA.js → WalletPage-AJVV7LVL.js} +11 -9
  64. package/dist/WalletPage-AJVV7LVL.js.map +1 -0
  65. package/dist/{WishlistPage-RS5UCIQ3.js → WishlistPage-UW6LJLSW.js} +11 -9
  66. package/dist/WishlistPage-UW6LJLSW.js.map +1 -0
  67. package/dist/api/advertisement.d.ts +33 -0
  68. package/dist/api/advertisement.d.ts.map +1 -0
  69. package/dist/api/advertisement.js +8 -0
  70. package/dist/api/advertisement.js.map +1 -0
  71. package/dist/boot/critical-style.d.ts +3 -0
  72. package/dist/boot/critical-style.d.ts.map +1 -0
  73. package/dist/boot/index.d.ts +15 -0
  74. package/dist/boot/index.d.ts.map +1 -0
  75. package/dist/boot.d.ts +1 -0
  76. package/dist/boot.js +69 -0
  77. package/dist/boot.js.map +1 -0
  78. package/dist/{chunk-SE5JYWOK.js → chunk-2HCCIHU7.js} +4 -4
  79. package/dist/{chunk-SE5JYWOK.js.map → chunk-2HCCIHU7.js.map} +1 -1
  80. package/dist/chunk-4FJGZQD3.js +6 -0
  81. package/dist/chunk-4FJGZQD3.js.map +1 -0
  82. package/dist/{chunk-SDFDS4Q3.js → chunk-4WVJJ7SN.js} +20 -4
  83. package/dist/chunk-4WVJJ7SN.js.map +1 -0
  84. package/dist/{chunk-NXQJA7D3.js → chunk-BAYGWTNM.js} +3 -3
  85. package/dist/{chunk-NXQJA7D3.js.map → chunk-BAYGWTNM.js.map} +1 -1
  86. package/dist/{chunk-OWX2CPNQ.js → chunk-CLBFF2CY.js} +3 -3
  87. package/dist/{chunk-OWX2CPNQ.js.map → chunk-CLBFF2CY.js.map} +1 -1
  88. package/dist/chunk-DBW7XXNE.js +103 -0
  89. package/dist/chunk-DBW7XXNE.js.map +1 -0
  90. package/dist/{chunk-KHBSGD2D.js → chunk-DBXH3EMJ.js} +3 -3
  91. package/dist/{chunk-KHBSGD2D.js.map → chunk-DBXH3EMJ.js.map} +1 -1
  92. package/dist/{chunk-JRNH3FUF.js → chunk-E26YG3AO.js} +4 -4
  93. package/dist/{chunk-JRNH3FUF.js.map → chunk-E26YG3AO.js.map} +1 -1
  94. package/dist/{chunk-22SH7OVF.js → chunk-E7WWO3V3.js} +3 -3
  95. package/dist/{chunk-22SH7OVF.js.map → chunk-E7WWO3V3.js.map} +1 -1
  96. package/dist/{chunk-UJKFBZFJ.js → chunk-HQ7WA37L.js} +7 -7
  97. package/dist/{chunk-UJKFBZFJ.js.map → chunk-HQ7WA37L.js.map} +1 -1
  98. package/dist/chunk-IVBOLREE.js +29 -0
  99. package/dist/chunk-IVBOLREE.js.map +1 -0
  100. package/dist/{chunk-6SWDSRIL.js → chunk-KP3VYG4F.js} +6 -6
  101. package/dist/{chunk-6SWDSRIL.js.map → chunk-KP3VYG4F.js.map} +1 -1
  102. package/dist/{chunk-4CZRUAZB.js → chunk-PWTXR4RR.js} +10 -10
  103. package/dist/{chunk-4CZRUAZB.js.map → chunk-PWTXR4RR.js.map} +1 -1
  104. package/dist/chunk-QJYUTRAQ.js +14 -0
  105. package/dist/{chunk-7WAXN2PP.js.map → chunk-QJYUTRAQ.js.map} +1 -1
  106. package/dist/{chunk-JO7JWV34.js → chunk-U55ZJC2X.js} +4 -4
  107. package/dist/{chunk-JO7JWV34.js.map → chunk-U55ZJC2X.js.map} +1 -1
  108. package/dist/{chunk-SX5MF2YA.js → chunk-WSDG4ZRI.js} +4 -4
  109. package/dist/{chunk-SX5MF2YA.js.map → chunk-WSDG4ZRI.js.map} +1 -1
  110. package/dist/{chunk-NZVR4OF7.js → chunk-X54QP332.js} +8 -8
  111. package/dist/chunk-X54QP332.js.map +1 -0
  112. package/dist/components/cart/index.js +1 -1
  113. package/dist/components/common/index.js +1 -1
  114. package/dist/components/drawer/index.js +9 -7
  115. package/dist/components/home/index.js +11 -9
  116. package/dist/components/layout/PageAdvertisements.d.ts +7 -0
  117. package/dist/components/layout/PageAdvertisements.d.ts.map +1 -0
  118. package/dist/components/layout/index.d.ts +1 -0
  119. package/dist/components/layout/index.d.ts.map +1 -1
  120. package/dist/components/layout/index.js +8 -1
  121. package/dist/components/product/index.js +10 -8
  122. package/dist/components/store/index.js +11 -9
  123. package/dist/components/store/index.js.map +1 -1
  124. package/dist/{document-class-67HTP45G.js → document-class-7AXAAWGZ.js} +6 -5
  125. package/dist/{document-class-67HTP45G.js.map → document-class-7AXAAWGZ.js.map} +1 -1
  126. package/dist/hooks/index.js +9 -7
  127. package/dist/hooks/useGtm.js +9 -7
  128. package/dist/hooks/useMoney.js +9 -7
  129. package/dist/hooks/useStore.js +9 -7
  130. package/dist/index.js +9 -7
  131. package/dist/index.js.map +1 -1
  132. package/dist/{not-found-QTHBFPNT.js → not-found-3EEMQZMU.js} +11 -9
  133. package/dist/not-found-3EEMQZMU.js.map +1 -0
  134. package/dist/providers/index.js +9 -7
  135. package/dist/routes/account/orders.js +1 -1
  136. package/dist/routes/account.js +6 -6
  137. package/dist/routes/blog.js +5 -5
  138. package/dist/routes/brands.js +1 -1
  139. package/dist/routes/cart.js +13 -11
  140. package/dist/routes/cart.js.map +1 -1
  141. package/dist/routes/home.js +12 -10
  142. package/dist/routes/loyalty.js +2 -2
  143. package/dist/routes/page.js +1 -1
  144. package/dist/routes/product-listing.js +11 -9
  145. package/dist/routes/product-listing.js.map +1 -1
  146. package/dist/routes/product.js +11 -9
  147. package/dist/routes/product.js.map +1 -1
  148. package/dist/routes/root/beforeLoad.d.ts +2 -2
  149. package/dist/routes/root/beforeLoad.d.ts.map +1 -1
  150. package/dist/routes/root/head.d.ts.map +1 -1
  151. package/dist/routes/testimonials.js +2 -2
  152. package/dist/routes/thank-you.js +1 -1
  153. package/dist/skeleton.js +12 -10
  154. package/dist/tanstack/document-class.d.ts.map +1 -1
  155. package/dist/tanstack/index.d.ts +1 -0
  156. package/dist/tanstack/index.d.ts.map +1 -1
  157. package/dist/tanstack/stylesheet.d.ts +15 -0
  158. package/dist/tanstack/stylesheet.d.ts.map +1 -0
  159. package/dist/tanstack.js +34 -5
  160. package/dist/tanstack.js.map +1 -1
  161. package/dist/utils/index.js +1 -1
  162. package/dist/vite/index.js +1 -1
  163. package/package.json +12 -3
  164. package/tailwind/components/Component.tsx.txt +21 -0
  165. package/tailwind/components/ComponentRegistry.ts.txt +66 -0
  166. package/tailwind/components/cart/CartItem.tsx.txt +211 -0
  167. package/tailwind/components/cart/CartSummary.tsx.txt +269 -0
  168. package/tailwind/components/cart/PreOrderNotification.tsx.txt +16 -0
  169. package/tailwind/components/cart/PriceQuoteButton.tsx.txt +21 -0
  170. package/tailwind/components/cart/SeoCartWidget.tsx.txt +99 -0
  171. package/tailwind/components/cart/index.ts.txt +11 -0
  172. package/tailwind/components/cart/lazy.ts.txt +15 -0
  173. package/tailwind/components/collapse/Collapse.tsx.txt +95 -0
  174. package/tailwind/components/collapse/index.ts.txt +41 -0
  175. package/tailwind/components/common/Breadcrumb.tsx.txt +27 -0
  176. package/tailwind/components/common/BreadcrumbJsonLd.tsx.txt +40 -0
  177. package/tailwind/components/common/BreadcrumbTrail.tsx.txt +97 -0
  178. package/tailwind/components/common/CurrencySymbol.tsx.txt +8 -0
  179. package/tailwind/components/common/DeferredData.tsx.txt +122 -0
  180. package/tailwind/components/common/ErrorPage.tsx.txt +69 -0
  181. package/tailwind/components/common/Image.tsx.txt +119 -0
  182. package/tailwind/components/common/Link.tsx.txt +36 -0
  183. package/tailwind/components/common/Link.types.ts.txt +85 -0
  184. package/tailwind/components/common/NoContent.tsx.txt +27 -0
  185. package/tailwind/components/common/RenderWhenVisible.tsx.txt +92 -0
  186. package/tailwind/components/common/index.ts.txt +42 -0
  187. package/tailwind/components/common/lazy.ts.txt +28 -0
  188. package/tailwind/components/defineComponent.ts.txt +32 -0
  189. package/tailwind/components/drawer/Drawer.tsx.txt +219 -0
  190. package/tailwind/components/drawer/index.ts.txt +38 -0
  191. package/tailwind/components/dropdown/Dropdown.tsx.txt +166 -0
  192. package/tailwind/components/dropdown/index.ts.txt +40 -0
  193. package/tailwind/components/home/BundleComponent.tsx.txt +35 -0
  194. package/tailwind/components/home/ComponentErrorBoundary.tsx.txt +98 -0
  195. package/tailwind/components/home/FeaturedProductsStyle1.tsx.txt +125 -0
  196. package/tailwind/components/home/FeaturedProductsStyle2.tsx.txt +127 -0
  197. package/tailwind/components/home/FeaturedProductsStyle3.tsx.txt +71 -0
  198. package/tailwind/components/home/FixedBanner.tsx.txt +68 -0
  199. package/tailwind/components/home/FixedProducts.tsx.txt +72 -0
  200. package/tailwind/components/home/HomePageRenderer.tsx.txt +284 -0
  201. package/tailwind/components/home/PageBlocks.tsx.txt +24 -0
  202. package/tailwind/components/home/ParallaxBackground.tsx.txt +50 -0
  203. package/tailwind/components/home/PhotosSlider.tsx.txt +61 -0
  204. package/tailwind/components/home/ProductsSlider.tsx.txt +87 -0
  205. package/tailwind/components/home/ReorderProducts.tsx.txt +38 -0
  206. package/tailwind/components/home/SquarePhotos.tsx.txt +68 -0
  207. package/tailwind/components/home/StoreFeatures.tsx.txt +34 -0
  208. package/tailwind/components/home/Testimonials.tsx.txt +36 -0
  209. package/tailwind/components/home/Youtube.tsx.txt +48 -0
  210. package/tailwind/components/home/index.ts.txt +50 -0
  211. package/tailwind/components/home/lazy.ts.txt +17 -0
  212. package/tailwind/components/home/register.ts.txt +44 -0
  213. package/tailwind/components/home/reorder-hooks.ts.txt +52 -0
  214. package/tailwind/components/home/types.ts.txt +4 -0
  215. package/tailwind/components/layout/Copyright.tsx.txt +23 -0
  216. package/tailwind/components/layout/CustomerLayout.tsx.txt +91 -0
  217. package/tailwind/components/layout/Footer.tsx.txt +343 -0
  218. package/tailwind/components/layout/Header.tsx.txt +154 -0
  219. package/tailwind/components/layout/MasterLayout.tsx.txt +63 -0
  220. package/tailwind/components/layout/PageAdvertisements.tsx.txt +131 -0
  221. package/tailwind/components/layout/WidgetHead.tsx.txt +53 -0
  222. package/tailwind/components/layout/index.ts.txt +27 -0
  223. package/tailwind/components/layout/lazy.ts.txt +25 -0
  224. package/tailwind/components/layout/types.ts.txt +11 -0
  225. package/tailwind/components/modal/ImageModal.tsx.txt +70 -0
  226. package/tailwind/components/modal/Modal.tsx.txt +245 -0
  227. package/tailwind/components/modal/index.ts.txt +39 -0
  228. package/tailwind/components/modal/lazy.ts.txt +10 -0
  229. package/tailwind/components/navigation/MainMenu.tsx.txt +94 -0
  230. package/tailwind/components/navigation/MobileMenu.tsx.txt +160 -0
  231. package/tailwind/components/navigation/index.ts.txt +4 -0
  232. package/tailwind/components/navigation/lazy.ts.txt +11 -0
  233. package/tailwind/components/product/AddToCartForm.tsx.txt +365 -0
  234. package/tailwind/components/product/ProductCard.tsx.txt +305 -0
  235. package/tailwind/components/product/ProductDetails.tsx.txt +267 -0
  236. package/tailwind/components/product/ProductGallery.tsx.txt +234 -0
  237. package/tailwind/components/product/index.ts.txt +15 -0
  238. package/tailwind/components/product/lazy.ts.txt +9 -0
  239. package/tailwind/components/snippets/AppsSnippets.tsx.txt +225 -0
  240. package/tailwind/components/snippets/SallaSdkScripts.tsx.txt +14 -0
  241. package/tailwind/components/snippets/index.ts.txt +4 -0
  242. package/tailwind/components/store/StoreClosedNotification.tsx.txt +73 -0
  243. package/tailwind/components/store/index.ts.txt +8 -0
  244. package/tailwind/components/store/lazy.ts.txt +8 -0
  245. package/tailwind/components/toast/Toaster.tsx.txt +177 -0
  246. package/tailwind/components/toast/index.ts.txt +10 -0
  247. package/tailwind/components/toast/types.ts.txt +38 -0
  248. package/tailwind/components/toast/useToast.ts.txt +61 -0
  249. package/tailwind/components/tracking/GoogleTag.tsx.txt +77 -0
  250. package/tailwind/components/tracking/SiftSnippet.tsx.txt +49 -0
  251. package/tailwind/components/tracking/TwilightBundles.tsx.txt +67 -0
  252. package/tailwind/components/tracking/index.ts.txt +11 -0
  253. package/tailwind/components/tracking/lazy.ts.txt +11 -0
  254. package/tailwind/components/useComponent.ts.txt +12 -0
  255. package/tailwind/routes/account/index.tsx.txt +16 -0
  256. package/tailwind/routes/account/notifications/NotificationsPage.tsx.txt +54 -0
  257. package/tailwind/routes/account/notifications/index.tsx.txt +39 -0
  258. package/tailwind/routes/account/notifications/loader.ts.txt +22 -0
  259. package/tailwind/routes/account/notifications/types.ts.txt +18 -0
  260. package/tailwind/routes/account/orders/OrderSinglePage.tsx.txt +181 -0
  261. package/tailwind/routes/account/orders/OrdersPage.tsx.txt +28 -0
  262. package/tailwind/routes/account/orders/index.tsx.txt +86 -0
  263. package/tailwind/routes/account/orders/loader.ts.txt +66 -0
  264. package/tailwind/routes/account/orders/single/OrderActions.tsx.txt +197 -0
  265. package/tailwind/routes/account/orders/single/OrderHeader.tsx.txt +143 -0
  266. package/tailwind/routes/account/orders/single/OrderItemRow.tsx.txt +209 -0
  267. package/tailwind/routes/account/orders/single/OrderSections.tsx.txt +215 -0
  268. package/tailwind/routes/account/orders/single/types.ts.txt +38 -0
  269. package/tailwind/routes/account/orders/types.ts.txt +29 -0
  270. package/tailwind/routes/account/profile/ProfilePage.tsx.txt +30 -0
  271. package/tailwind/routes/account/profile/index.tsx.txt +39 -0
  272. package/tailwind/routes/account/profile/loader.ts.txt +16 -0
  273. package/tailwind/routes/account/profile/types.ts.txt +5 -0
  274. package/tailwind/routes/account/settings/SettingsPage.tsx.txt +13 -0
  275. package/tailwind/routes/account/settings/index.tsx.txt +39 -0
  276. package/tailwind/routes/account/settings/loader.ts.txt +13 -0
  277. package/tailwind/routes/account/settings/types.ts.txt +5 -0
  278. package/tailwind/routes/account/types.ts.txt +320 -0
  279. package/tailwind/routes/account/wallet/WalletPage.tsx.txt +195 -0
  280. package/tailwind/routes/account/wallet/index.tsx.txt +38 -0
  281. package/tailwind/routes/account/wallet/loader.ts.txt +27 -0
  282. package/tailwind/routes/account/wallet/types.ts.txt +11 -0
  283. package/tailwind/routes/account/wishlist/WishlistPage.tsx.txt +314 -0
  284. package/tailwind/routes/account/wishlist/WishlistShare.tsx.txt +248 -0
  285. package/tailwind/routes/account/wishlist/index.tsx.txt +40 -0
  286. package/tailwind/routes/account/wishlist/loader.ts.txt +26 -0
  287. package/tailwind/routes/account/wishlist/types.ts.txt +9 -0
  288. package/tailwind/routes/blog/BlogAuthorPage.tsx.txt +82 -0
  289. package/tailwind/routes/blog/BlogCategoryPage.tsx.txt +84 -0
  290. package/tailwind/routes/blog/BlogPage.tsx.txt +191 -0
  291. package/tailwind/routes/blog/BlogSinglePage.tsx.txt +168 -0
  292. package/tailwind/routes/blog/BlogTagPage.tsx.txt +84 -0
  293. package/tailwind/routes/blog/BlogTags.tsx.txt +54 -0
  294. package/tailwind/routes/blog/components.tsx.txt +87 -0
  295. package/tailwind/routes/blog/index.tsx.txt +238 -0
  296. package/tailwind/routes/blog/loader.ts.txt +173 -0
  297. package/tailwind/routes/blog/types.ts.txt +106 -0
  298. package/tailwind/routes/brands/BrandsPage.tsx.txt +179 -0
  299. package/tailwind/routes/brands/index.tsx.txt +47 -0
  300. package/tailwind/routes/brands/loader.ts.txt +14 -0
  301. package/tailwind/routes/brands/types.ts.txt +53 -0
  302. package/tailwind/routes/cart/CartPage.tsx.txt +112 -0
  303. package/tailwind/routes/cart/index.tsx.txt +39 -0
  304. package/tailwind/routes/cart/loader.ts.txt +15 -0
  305. package/tailwind/routes/cart/types.ts.txt +6 -0
  306. package/tailwind/routes/home/HomePage.tsx.txt +53 -0
  307. package/tailwind/routes/home/index.tsx.txt +56 -0
  308. package/tailwind/routes/home/loader.ts.txt +24 -0
  309. package/tailwind/routes/home/types.ts.txt +11 -0
  310. package/tailwind/routes/index.ts.txt +94 -0
  311. package/tailwind/routes/lazy.ts.txt +105 -0
  312. package/tailwind/routes/loyalty/LoyaltyPage.tsx.txt +17 -0
  313. package/tailwind/routes/loyalty/LoyaltyPointsPage.tsx.txt +11 -0
  314. package/tailwind/routes/loyalty/index.tsx.txt +81 -0
  315. package/tailwind/routes/loyalty/loader.ts.txt +53 -0
  316. package/tailwind/routes/loyalty/types.ts.txt +109 -0
  317. package/tailwind/routes/not-found.tsx.txt +50 -0
  318. package/tailwind/routes/page/PageSingle.tsx.txt +34 -0
  319. package/tailwind/routes/page/index.tsx.txt +60 -0
  320. package/tailwind/routes/page/loader.ts.txt +19 -0
  321. package/tailwind/routes/page/types.ts.txt +34 -0
  322. package/tailwind/routes/product/ProductPage.tsx.txt +77 -0
  323. package/tailwind/routes/product/index.tsx.txt +157 -0
  324. package/tailwind/routes/product/loader.ts.txt +35 -0
  325. package/tailwind/routes/product/types.ts.txt +6 -0
  326. package/tailwind/routes/product-listing/ProductListPage.tsx.txt +321 -0
  327. package/tailwind/routes/product-listing/index.tsx.txt +95 -0
  328. package/tailwind/routes/product-listing/loader.ts.txt +323 -0
  329. package/tailwind/routes/product-listing/types.ts.txt +96 -0
  330. package/tailwind/routes/product-listing/useAppliedFilters.ts.txt +130 -0
  331. package/tailwind/routes/product-short-link.ts.txt +104 -0
  332. package/tailwind/routes/root/beforeLoad.ts.txt +354 -0
  333. package/tailwind/routes/root/head.ts.txt +424 -0
  334. package/tailwind/routes/root/index.ts.txt +2 -0
  335. package/tailwind/routes/seo-redirects.ts.txt +82 -0
  336. package/tailwind/routes/testimonials/ReviewsPage.tsx.txt +12 -0
  337. package/tailwind/routes/testimonials/TestimonialsPage.tsx.txt +80 -0
  338. package/tailwind/routes/testimonials/index.tsx.txt +80 -0
  339. package/tailwind/routes/testimonials/loader.ts.txt +29 -0
  340. package/tailwind/routes/testimonials/types.ts.txt +9 -0
  341. package/tailwind/routes/thank-you/ThankYouPage.tsx.txt +241 -0
  342. package/tailwind/routes/thank-you/index.tsx.txt +49 -0
  343. package/tailwind/routes/thank-you/loader.ts.txt +40 -0
  344. package/tailwind/routes/thank-you/types.ts.txt +16 -0
  345. package/tailwind/routes/types.ts.txt +41 -0
  346. package/dist/BlogAuthorPage-GTF4UGSS.js.map +0 -1
  347. package/dist/BlogCategoryPage-TN7Y4NBP.js.map +0 -1
  348. package/dist/BlogPage-TDB3M3PI.js.map +0 -1
  349. package/dist/BlogSinglePage-4A52Q5QW.js.map +0 -1
  350. package/dist/BlogTagPage-TOVPBETA.js.map +0 -1
  351. package/dist/BrandsPage-VUDGYSQI.js.map +0 -1
  352. package/dist/Breadcrumb-CI3SN5YR.js.map +0 -1
  353. package/dist/CartItem-BHLEURAB.js.map +0 -1
  354. package/dist/CartSummary-QERVESYN.js.map +0 -1
  355. package/dist/CustomerLayout-VRZUWGQK.js.map +0 -1
  356. package/dist/LoyaltyPage-CGTHWJ76.js.map +0 -1
  357. package/dist/LoyaltyPointsPage-QSU6K3PW.js.map +0 -1
  358. package/dist/MobileMenu-U4BVQYKH.js.map +0 -1
  359. package/dist/NotificationsPage-ZRRQY7TF.js.map +0 -1
  360. package/dist/OrderSinglePage-O3XYVMG5.js.map +0 -1
  361. package/dist/OrdersPage-CMXZF5MI.js.map +0 -1
  362. package/dist/ProductDetails-65GDABI7.js.map +0 -1
  363. package/dist/ProfilePage-SNJ4WXU4.js.map +0 -1
  364. package/dist/SeoCartWidget-DBJAXJKT.js.map +0 -1
  365. package/dist/SettingsPage-FLTIOPU5.js.map +0 -1
  366. package/dist/ThankYouPage-5X6B4X3T.js.map +0 -1
  367. package/dist/WalletPage-H2BKIDPA.js.map +0 -1
  368. package/dist/WishlistPage-RS5UCIQ3.js.map +0 -1
  369. package/dist/chunk-7WAXN2PP.js +0 -14
  370. package/dist/chunk-NZVR4OF7.js.map +0 -1
  371. package/dist/chunk-SDFDS4Q3.js.map +0 -1
  372. package/dist/not-found-QTHBFPNT.js.map +0 -1
@@ -0,0 +1,77 @@
1
+ import { useEffect } from 'react';
2
+
3
+ export interface GoogleTagBodyProps {
4
+ /** GTM container IDs - if empty, renders nothing */
5
+ gtmIds?: string[];
6
+ }
7
+
8
+ /**
9
+ * Generates the GTM head script content.
10
+ */
11
+ function gtmScript(gtmId: string): string {
12
+ return `
13
+ window.dataLayer = window.dataLayer || [];
14
+ (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
15
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
16
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
17
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
18
+ })(window,document,'script','dataLayer','${gtmId}');
19
+
20
+ window.dataLayer = new Proxy(window.dataLayer, {
21
+ set(target, property, value) {
22
+ target[property] = value;
23
+ if (typeof value === 'object') {
24
+ ['form_data', 'data', 'gateway', 'config', 'request', 'headers']
25
+ .forEach(function(key) { value && value.hasOwnProperty(key) && delete value[key]; });
26
+ }
27
+ return true;
28
+ }
29
+ });
30
+ `.trim();
31
+ }
32
+
33
+ const INTERACTION_EVENTS = ['pointerdown', 'keydown', 'touchstart', 'scroll', 'wheel'] as const;
34
+
35
+ /** How long after `load` GTM waits for a visitor who never interacts. */
36
+ export const GTM_LOAD_DELAY_MS = 4000;
37
+
38
+ /** Injects GTM on the first interaction or GTM_LOAD_DELAY_MS after `load`, off the page's load path. */
39
+ export function GoogleTagBody({ gtmIds }: GoogleTagBodyProps): null {
40
+ const gtmId = gtmIds?.[0];
41
+
42
+ useEffect(() => {
43
+ if (!gtmId) return;
44
+ const id = gtmId;
45
+
46
+ let timer: number | undefined;
47
+ const stopWaiting = () => {
48
+ window.clearTimeout(timer);
49
+ window.removeEventListener('load', onLoad);
50
+ INTERACTION_EVENTS.forEach((type) => window.removeEventListener(type, inject));
51
+ };
52
+ function inject() {
53
+ stopWaiting();
54
+ if (document.getElementById('gtm-script')) return;
55
+ const script = document.createElement('script');
56
+ script.id = 'gtm-script';
57
+ script.textContent = gtmScript(id);
58
+ document.head.appendChild(script);
59
+ }
60
+ function onLoad() {
61
+ timer = window.setTimeout(inject, GTM_LOAD_DELAY_MS);
62
+ }
63
+
64
+ INTERACTION_EVENTS.forEach((type) =>
65
+ window.addEventListener(type, inject, { once: true, passive: true })
66
+ );
67
+ if (document.readyState === 'complete') onLoad();
68
+ else window.addEventListener('load', onLoad, { once: true });
69
+
70
+ return () => {
71
+ stopWaiting();
72
+ document.getElementById('gtm-script')?.remove();
73
+ };
74
+ }, [gtmId]);
75
+
76
+ return null;
77
+ }
@@ -0,0 +1,49 @@
1
+ import { useEffect } from 'react';
2
+
3
+ export interface SiftSnippetProps {
4
+ /** Sift Science beacon key - if empty, renders nothing */
5
+ beaconKey?: string;
6
+ /** Logged-in customer ID, or empty for guests */
7
+ customerId?: string;
8
+ }
9
+
10
+ /**
11
+ * SiftSnippet - Injects Sift Science fraud detection script.
12
+ *
13
+ * Mirrors PHP SiftSnippetJsWidget:
14
+ * - Injects Sift Science beacon script via useEffect
15
+ * - Tracks user ID, session ID, and page views
16
+ * - Used for fraud detection and risk scoring
17
+ */
18
+ export function SiftSnippet({ beaconKey, customerId }: SiftSnippetProps): null {
19
+ useEffect(() => {
20
+ if (!beaconKey) return;
21
+
22
+ // Get session ID from Salla analytics
23
+ const salla = window.salla;
24
+ const sessionId = salla?.analytics?._anonymousId || '';
25
+
26
+ window._sift = window._sift ?? [];
27
+ const _sift = window._sift;
28
+
29
+ // Push configuration
30
+ _sift.push(['_setAccount', beaconKey]);
31
+ _sift.push(['_setUserId', customerId || '']);
32
+ _sift.push(['_setSessionId', sessionId]);
33
+ _sift.push(['_trackPageview']);
34
+
35
+ // Load the Sift script
36
+ const script = document.createElement('script');
37
+ script.src = 'https://cdn.sift.com/s.js';
38
+ script.async = true;
39
+ document.body.appendChild(script);
40
+
41
+ return () => {
42
+ script.remove();
43
+ // Clear sift queue on unmount
44
+ window._sift = undefined;
45
+ };
46
+ }, [beaconKey, customerId]);
47
+
48
+ return null;
49
+ }
@@ -0,0 +1,67 @@
1
+ import { useEffect } from 'react';
2
+
3
+ /**
4
+ * TwilightBundles - Injects twilight bundles script when custom components are detected.
5
+ *
6
+ * Mirrors PHP TwilightThemesAdditionsWidget:
7
+ * - Sets up MutationObserver to watch for `salla-custom-component` tags
8
+ * - Injects bundles script when a custom component is detected
9
+ * - Uses importmap for lit dependencies
10
+ * - Runs only once
11
+ */
12
+ export function TwilightBundles(): null {
13
+ useEffect(() => {
14
+ // Check if already injected
15
+ if (document.getElementById('twilight-bundles-assets')) {
16
+ return;
17
+ }
18
+
19
+ const bundlesUrl =
20
+ 'https://cdn.assets.salla.network/prod/@salla.sa/twilight-bundles/latest/twilight-bundles.js';
21
+
22
+ const injectBundles = () => {
23
+ // Disconnect observer since we only need to inject once
24
+ window.twilightBundlesObserver?.disconnect?.();
25
+
26
+ if (document.getElementById('twilight-bundles-assets')) {
27
+ return;
28
+ }
29
+
30
+ const script = document.createElement('script');
31
+ script.type = 'module';
32
+ script.src = bundlesUrl;
33
+ script.defer = true;
34
+ script.id = 'twilight-bundles-assets';
35
+ document.head.appendChild(script);
36
+ };
37
+
38
+ // Set up MutationObserver to watch for salla-custom-component
39
+ const observer = new MutationObserver((mutations) => {
40
+ for (const mutation of mutations) {
41
+ for (const node of mutation.addedNodes) {
42
+ if (
43
+ node.nodeType === 1 &&
44
+ (node as Element).tagName?.toLowerCase() === 'salla-custom-component'
45
+ ) {
46
+ injectBundles();
47
+ return;
48
+ }
49
+ }
50
+ }
51
+ });
52
+
53
+ observer.observe(document.body, { childList: true, subtree: true });
54
+ window.twilightBundlesObserver = observer;
55
+
56
+ // Check if component already exists on mount
57
+ if (document.querySelector('salla-custom-component')) {
58
+ injectBundles();
59
+ }
60
+
61
+ return () => {
62
+ observer.disconnect();
63
+ };
64
+ }, []);
65
+
66
+ return null;
67
+ }
@@ -0,0 +1,11 @@
1
+ // Component - injects GTM script + noscript via useEffect
2
+ export { GoogleTagBody, type GoogleTagBodyProps } from './GoogleTag';
3
+
4
+ // Component - injects Sift Science fraud detection script
5
+ export { SiftSnippet, type SiftSnippetProps } from './SiftSnippet';
6
+
7
+ // Component - injects twilight bundles when custom components detected
8
+ export { TwilightBundles } from './TwilightBundles';
9
+
10
+ // Lazy components
11
+ export { LazyGoogleTagBody, LazySiftSnippet } from './lazy';
@@ -0,0 +1,11 @@
1
+ import { lazy } from 'react';
2
+
3
+ /** Lazy-loaded GoogleTagBody component. */
4
+ export const LazyGoogleTagBody = lazy(() =>
5
+ import('./GoogleTag').then((m) => ({ default: m.GoogleTagBody }))
6
+ );
7
+
8
+ /** Lazy-loaded SiftSnippet component. */
9
+ export const LazySiftSnippet = lazy(() =>
10
+ import('./SiftSnippet').then((m) => ({ default: m.SiftSnippet }))
11
+ );
@@ -0,0 +1,12 @@
1
+ import { registry } from './ComponentRegistry';
2
+ import type { ComponentType } from '../types';
3
+
4
+ export function useComponent<P = Record<string, unknown>>(name: string): ComponentType<P> | null {
5
+ return registry.resolve<P>(name);
6
+ }
7
+
8
+ export function useOriginalComponent<P = Record<string, unknown>>(
9
+ name: string
10
+ ): ComponentType<P> | null {
11
+ return registry.getOriginal<P>(name);
12
+ }
@@ -0,0 +1,16 @@
1
+ // Re-export from organized route folders
2
+ export * from './profile';
3
+ export * from './wishlist';
4
+ export * from './wallet';
5
+ export * from './notifications';
6
+ export * from './settings';
7
+ export * from './orders';
8
+
9
+ // Re-export shared types for backward compatibility
10
+ export type {
11
+ Order,
12
+ OrderItem,
13
+ OrderListItem,
14
+ OrdersPageProps,
15
+ OrderSinglePageProps,
16
+ } from './types';
@@ -0,0 +1,54 @@
1
+ import { HookSlot } from '../../../hooks';
2
+ import { NoContent } from '../../../components/common';
3
+ import { useTranslation } from '../../../providers/I18nProvider';
4
+ import type { NotificationsPageProps, Notification } from './types';
5
+
6
+ function NotificationItem({ notification }: { notification: Notification }) {
7
+ return (
8
+ <a
9
+ href={notification.url}
10
+ className={`s-notifications-item s-notifications-item-shadow${notification.is_read ? ' s-notifications-item-read' : ''}`}
11
+ >
12
+ <span className="s-notifications-item-icon">
13
+ <i
14
+ className={`s-notifications-item-icon sicon-bell-ring${!notification.is_read ? ' s-notifications-item-icon-new' : ''}`}
15
+ ></i>
16
+ </span>
17
+ <div className="s-notifications-item-content">
18
+ <div className="s-notifications-item-content-leading">
19
+ <h4>{notification.title}</h4>
20
+ <p>{notification.body}</p>
21
+ </div>
22
+ <span className="s-notifications-item-content-trailing">
23
+ <i className="sicon-time s-notifications-item-content-trailing-icon"></i>
24
+ <span>{notification.time_ago}</span>
25
+ </span>
26
+ </div>
27
+ </a>
28
+ );
29
+ }
30
+
31
+ export function NotificationsPage({ notifications }: NotificationsPageProps) {
32
+ const { t } = useTranslation();
33
+
34
+ return (
35
+ <>
36
+ <HookSlot name="customer:notifications.items.start" />
37
+ <div className="s-notifications-wrapper">
38
+ {notifications.length > 0 ? (
39
+ <div className="s-notifications-container space-y-2">
40
+ {notifications.map((item: Notification) => (
41
+ <NotificationItem key={item.id} notification={item} />
42
+ ))}
43
+ </div>
44
+ ) : (
45
+ <NoContent
46
+ icon="sicon-bell-ring"
47
+ message={t('blocks.header.no_notifications', 'No notifications')}
48
+ />
49
+ )}
50
+ </div>
51
+ <HookSlot name="customer:notifications.items.end" />
52
+ </>
53
+ );
54
+ }
@@ -0,0 +1,39 @@
1
+ import type { HeadDescriptor } from '../../../utils/head';
2
+ import { buildHreflangAlternates } from '../../../utils/baseHead';
3
+ import { lazy } from 'react';
4
+ import { notificationsLoader } from './loader';
5
+ import type { NotificationsPageProps } from './types';
6
+ import type { TwilightContext } from '../../../twilight/context';
7
+ import { RouteId } from '../../../router/route-ids';
8
+
9
+ const LazyNotificationsPage = lazy(() =>
10
+ import('./NotificationsPage').then((m) => ({ default: m.NotificationsPage }))
11
+ );
12
+
13
+ export const NotificationsPage = LazyNotificationsPage;
14
+ export { notificationsLoader } from './loader';
15
+ export type { NotificationsPageProps, Notification } from './types';
16
+
17
+ export const Notifications = {
18
+ id: RouteId.CUSTOMER_NOTIFICATIONS,
19
+ loader: async (
20
+ _ctx: { locale?: string },
21
+ extend?: (
22
+ data: NotificationsPageProps,
23
+ ctx: { params: Record<string, never> }
24
+ ) => Promise<Record<string, unknown>> | Record<string, unknown>
25
+ ): Promise<NotificationsPageProps> => {
26
+ const data = await notificationsLoader({ locale: _ctx.locale ?? 'ar' });
27
+ if (extend) {
28
+ const extra = await extend(data, { params: {} });
29
+ return { ...data, ...extra } as NotificationsPageProps;
30
+ }
31
+ return data;
32
+ },
33
+ head: (ctx: TwilightContext, data: NotificationsPageProps): HeadDescriptor => ({
34
+ title: data.page.title,
35
+ description: data.page.description,
36
+ alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),
37
+ }),
38
+ Component: LazyNotificationsPage,
39
+ } as const;
@@ -0,0 +1,22 @@
1
+ import { notification } from '../../../api/notification';
2
+ import { getTwilightContext } from '../../../twilight/context';
3
+ import { orUnauthorized, unauthorized } from '../../../providers/NavigationProvider';
4
+ import { getAuthToken } from '../../../api/client';
5
+ import type { NotificationsPageProps } from './types';
6
+ import { RouteId } from '../../../router/route-ids';
7
+
8
+ export async function notificationsLoader(_ctx: {
9
+ locale: string;
10
+ }): Promise<NotificationsPageProps> {
11
+ if (!getAuthToken()) throw unauthorized();
12
+ const i18n = getTwilightContext().i18n;
13
+ const response = await orUnauthorized(notification.list());
14
+
15
+ return {
16
+ page: {
17
+ title: i18n.t('common.titles.notifications') || 'Notifications',
18
+ slug: RouteId.CUSTOMER_NOTIFICATIONS,
19
+ },
20
+ notifications: response.data,
21
+ };
22
+ }
@@ -0,0 +1,18 @@
1
+ import type { Page } from '../../../types';
2
+
3
+ export interface Notification {
4
+ id: number;
5
+ title: string;
6
+ color: string;
7
+ icon: string;
8
+ url: string;
9
+ body: string;
10
+ is_read: boolean;
11
+ time_ago: string;
12
+ created_at: number;
13
+ }
14
+
15
+ export interface NotificationsPageProps {
16
+ page: Page;
17
+ notifications: Notification[];
18
+ }
@@ -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
+ }