@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,209 @@
1
+ import { createElement } from 'react';
2
+ import { SallaOrderDetails } from '@salla.sa/twilight-components-react/order-details';
3
+ import { useDate, useNumber } from '../../../../hooks';
4
+ import { useTranslation } from '../../../../providers/I18nProvider';
5
+ import type { FormatMoney, OrderItem, TwigItem } from './types';
6
+
7
+ function ItemAttachments({ item }: { item: OrderItem }) {
8
+ const { t } = useTranslation();
9
+ if (!item.attachments?.length) return null;
10
+ return (
11
+ <div className="flow-root rounded-md px-4 border border-gray-200">
12
+ <dl className="text-sm text-dark divide-y divide-border-color">
13
+ {item.attachments.map((attachment) => (
14
+ <div
15
+ key={`${attachment.type}:${attachment.url}`}
16
+ className="py-3.5 md:flex items-center justify-between"
17
+ >
18
+ <dt className="mb-2 md:mb-0">{t('pages.products.attachments')}</dt>
19
+ <dd
20
+ className={`font-medium ${attachment.type === 'image' ? 'text-gray-900' : 'text-xs'}`}
21
+ >
22
+ {attachment.type === 'image' ? (
23
+ <div className="flex rtl:space-x-reverse space-x-2.5">
24
+ <a href={attachment.url} target="_blank" rel="noreferrer">
25
+ <img
26
+ className="h-7 w-7 object-cover rounded-md"
27
+ src={attachment.url}
28
+ alt={item.name}
29
+ />
30
+ </a>
31
+ </div>
32
+ ) : (
33
+ <a href={attachment.url}>{t('pages.orders.file_url')}</a>
34
+ )}
35
+ </dd>
36
+ </div>
37
+ ))}
38
+ </dl>
39
+ </div>
40
+ );
41
+ }
42
+
43
+ /** A date-only day (`2026-09-20`) as that calendar day wherever it is formatted, not UTC midnight. */
44
+ function calendarDay(day: unknown): Date | string {
45
+ const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(String(day));
46
+ return match ? new Date(+match[1], +match[2] - 1, +match[3]) : String(day);
47
+ }
48
+
49
+ /** Twig's booking block: the location and each reservation's day and time. */
50
+ function ItemReservations({ item, productType }: { item: OrderItem; productType?: string }) {
51
+ const { t } = useTranslation();
52
+ const { format: formatDate } = useDate();
53
+ const { format: formatNumber, useArabicNumerals } = useNumber();
54
+ const reservations = item.product_reservations ?? [];
55
+ if (productType !== 'booking' || !reservations.length) return null;
56
+ const time = (value: unknown) =>
57
+ useArabicNumerals
58
+ ? formatNumber(String(value)).replace(/PM/g, 'م').replace(/AM/g, 'ص')
59
+ : String(value);
60
+
61
+ return (
62
+ <>
63
+ {item.booking_location && (
64
+ <ul className="font-medium text-xs text-gray-600">
65
+ <li className="py-1 flex justify-between items-baseline">
66
+ <span className="mt-5 mb-3.5 text-sm font-bold">{t('common.elements.location')}</span>
67
+ <span className="text-unicode">{item.booking_location}</span>
68
+ </li>
69
+ </ul>
70
+ )}
71
+ <h2 className="mt-5 mb-3.5 text-sm font-bold">
72
+ {reservations.length > 1 ? t('pages.cart.reservations') : t('pages.cart.item_options')}
73
+ </h2>
74
+ <div className="rounded-md p-4 border border-gray-200 mb-2">
75
+ <ul className="font-medium text-xs text-gray-600">
76
+ {reservations.map((reservation) => (
77
+ <li key={`${reservation.day}:${reservation.from}`} className="py-1">
78
+ <span className="text-unicode">
79
+ {formatNumber(formatDate(calendarDay(reservation.day)))}
80
+ {reservation.from_timestamp
81
+ ? ` (${time(reservation.from)} - ${time(reservation.to)})`
82
+ : ''}
83
+ </span>
84
+ </li>
85
+ ))}
86
+ </ul>
87
+ </div>
88
+ </>
89
+ );
90
+ }
91
+
92
+ function ItemSummary({
93
+ item,
94
+ twigItem,
95
+ money,
96
+ currency,
97
+ }: {
98
+ item: OrderItem;
99
+ twigItem?: TwigItem;
100
+ money: FormatMoney;
101
+ currency: string;
102
+ }) {
103
+ const { t } = useTranslation();
104
+ const product = twigItem?.product;
105
+ const image = product?.image?.url || item.image || item.thumbnail;
106
+ const price = item.amounts.amount ?? { amount: 0, currency };
107
+ const priceText = money(price.amount, price.currency);
108
+ const total = item.amounts.total ?? { amount: 0, currency };
109
+
110
+ return (
111
+ <div className="mb-5 last:mb-0">
112
+ {product ? (
113
+ <div className="flex rtl:space-x-reverse space-x-5 mb-4">
114
+ <a href={product.url} className="shrink-0">
115
+ <img
116
+ src={image || '/images/placeholder.png'}
117
+ alt={item.name}
118
+ className={`w-18 h-14 object-${image ? 'cover' : 'contain'} rounded-md`}
119
+ />
120
+ </a>
121
+ <div>
122
+ <a
123
+ href={product.url}
124
+ className="block leading-5 mb-1.5 md:text-base font-semibold transition-colors text-gray-500 hover:text-primary"
125
+ >
126
+ {item.name}
127
+ </a>
128
+ <b>{priceText}</b>
129
+ </div>
130
+ </div>
131
+ ) : (
132
+ <div className="w-full flex justify-between text-sm py-2.5">
133
+ <span className="w-40 inline-block font-normal">{item.name}</span>
134
+ <b>{priceText}</b>
135
+ </div>
136
+ )}
137
+
138
+ <div className="w-full flex justify-between text-sm py-2.5">
139
+ <span className="w-40 inline-block font-normal">{t('pages.products.quantity')}</span>
140
+ <b>{item.quantity}</b>
141
+ </div>
142
+ <div className="flex justify-between text-sm py-2.5">
143
+ <span className=" w-40 inline-block font-normal">{t('pages.products.price')}</span>
144
+ <b>{priceText}</b>
145
+ </div>
146
+ <div className="flex justify-between text-sm py-2.5">
147
+ <span className="w-40 inline-block font-normal">{t('pages.orders.total')}</span>
148
+ <b>{money(total.amount, total.currency)}</b>
149
+ </div>
150
+ </div>
151
+ );
152
+ }
153
+
154
+ /** One item of the order page (the body of `{% for item in package.items %}`). */
155
+ export function OrderItemRow({
156
+ item,
157
+ twigItem,
158
+ money,
159
+ currency,
160
+ }: {
161
+ item: OrderItem;
162
+ twigItem?: TwigItem;
163
+ money: FormatMoney;
164
+ currency: string;
165
+ }) {
166
+ const { t } = useTranslation();
167
+ const productId = twigItem?.product?.id;
168
+
169
+ return (
170
+ <div
171
+ data-testid={`store-order-item-${item.id}`}
172
+ data-order-item-id={item.id}
173
+ data-order-item-product-id={productId}
174
+ className="order-item bg-white p-5 border-b border-gray-100 first:rounded-t-md last:rounded-b-md last:border-none"
175
+ >
176
+ <ItemSummary item={item} twigItem={twigItem} money={money} currency={currency} />
177
+
178
+ {item.availability_date && (
179
+ <div className="flex gap-2 text-sm py-2.5 text-blue-500">
180
+ <i className="sicon-info"></i>
181
+ <span>
182
+ {t('pages.products.expected_to_be')}:{' '}
183
+ <b>{String(item.availability_date).slice(0, 10)}</b>
184
+ </span>
185
+ </div>
186
+ )}
187
+
188
+ <ItemReservations item={item} productType={twigItem?.product?.type ?? item.product?.type} />
189
+
190
+ <SallaOrderDetails orderDetails={JSON.stringify(twigItem ?? item)} />
191
+
192
+ {item.note && (
193
+ <p className="mt-3 text-sm text-gray-500">
194
+ <span>{t('common.elements.note')} : </span>
195
+ {item.note}
196
+ </p>
197
+ )}
198
+
199
+ <ItemAttachments item={item} />
200
+
201
+ {/* No React wrapper yet; Twilight upgrades it (adds `hydrated`) before React hydrates. */}
202
+ {productId &&
203
+ createElement('salla-review-order-item', {
204
+ 'product-id': productId,
205
+ suppressHydrationWarning: true,
206
+ })}
207
+ </div>
208
+ );
209
+ }
@@ -0,0 +1,215 @@
1
+ import { SallaButton } from '@salla.sa/twilight-components-react/button';
2
+ import { SallaRatingStars } from '@salla.sa/twilight-components-react/rating-stars';
3
+ import { useTranslation } from '../../../../providers/I18nProvider';
4
+ import { useQuery } from '@tanstack/react-query';
5
+ import { order as orderApi } from '../../../../api/order';
6
+ import type { FormatMoney, Order, TwigOrder, TwigRating } from './types';
7
+
8
+ function RatingAction({
9
+ disabled,
10
+ endedKey,
11
+ color,
12
+ fill,
13
+ icon,
14
+ onClick,
15
+ }: {
16
+ disabled: boolean;
17
+ endedKey: string;
18
+ color: 'dark' | 'danger';
19
+ fill: 'outline';
20
+ icon: string;
21
+ onClick: () => void;
22
+ }) {
23
+ const { t } = useTranslation();
24
+ return (
25
+ <div className="tooltip-toggle tooltip-toggle--hover icon-trigger mobile-shifted">
26
+ {disabled && (
27
+ <div className="tooltip-content shadow-md rounded">
28
+ <small> {t(endedKey)}.</small>
29
+ </div>
30
+ )}
31
+ <SallaButton
32
+ loaderPosition="center"
33
+ disabled={disabled}
34
+ shape="icon"
35
+ fill={fill}
36
+ color={color}
37
+ size="medium"
38
+ onClick={disabled ? undefined : onClick}
39
+ >
40
+ <i className={`${icon} text-xl`}></i>
41
+ </SallaButton>
42
+ </div>
43
+ );
44
+ }
45
+
46
+ /** A store or shipping rating the customer left, with its edit / delete buttons. */
47
+ export function RatingSection({
48
+ title,
49
+ rating,
50
+ type,
51
+ allowUpdate,
52
+ }: {
53
+ title: string;
54
+ rating: TwigRating;
55
+ type: 'store' | 'shipping';
56
+ allowUpdate: boolean;
57
+ }) {
58
+ const dispatch = (event: string, payload: Record<string, unknown>) =>
59
+ window.salla?.event?.dispatch(event, payload);
60
+ const locked = !rating.can_update;
61
+
62
+ return (
63
+ <section className="flex justify-between items-start bg-white p-5 rounded-md">
64
+ <div>
65
+ <h2 className="text-lg font-bold mb-5">{title}</h2>
66
+ <p className="mb-2">{rating.content}</p>
67
+ <SallaRatingStars withLabel value={rating.stars} />
68
+ </div>
69
+ <div className="rating-actions">
70
+ {allowUpdate && (
71
+ <>
72
+ <RatingAction
73
+ disabled={locked}
74
+ endedKey="pages.order.edit_period_ended"
75
+ color="dark"
76
+ fill="outline"
77
+ icon="sicon-format-border-color"
78
+ onClick={() => dispatch('rating::edit', { type, feedback_id: String(rating.id) })}
79
+ />
80
+ <RatingAction
81
+ disabled={locked}
82
+ endedKey="pages.order.delete_period_ended"
83
+ color="danger"
84
+ fill="outline"
85
+ icon="sicon-trash-2"
86
+ onClick={() => dispatch('rating::delete', { feedback_id: String(rating.id) })}
87
+ />
88
+ </>
89
+ )}
90
+ </div>
91
+ </section>
92
+ );
93
+ }
94
+
95
+ interface Shipment {
96
+ id?: number;
97
+ name?: string;
98
+ logo?: string;
99
+ number?: string;
100
+ tracking?: string | null;
101
+ }
102
+
103
+ function ShippingRow({ shipment }: { shipment: Shipment }) {
104
+ const { t } = useTranslation();
105
+ // Twig treats the string "0" as empty.
106
+ const hasNumber = !!shipment.number && shipment.number !== '0';
107
+
108
+ return (
109
+ <div className="flex flex-col md:flex-row justify-between md:items-center bg-white px-5 py-3 border-b border-gray-100 rounded-t-md text-sm space-y-4 md:space-y-0">
110
+ <div className="flex items-center space-x-2 rtl:space-x-reverse">
111
+ {shipment.logo && (
112
+ <img src={shipment.logo} className="max-w-16 max-h-8" alt={shipment.name} />
113
+ )}
114
+ <span>{shipment.name}</span>
115
+ </div>
116
+ <div className="flex space-x-5 rtl:space-x-reverse">
117
+ {hasNumber && (
118
+ <span>
119
+ {t('pages.orders.shipment_no')}: <span className="font-bold">{shipment.number}</span>
120
+ </span>
121
+ )}
122
+ {shipment.tracking && (
123
+ <a
124
+ className="font-bold text-primary hover:opacity-80 flex items-center"
125
+ href={shipment.tracking}
126
+ target="_blank"
127
+ rel="noreferrer"
128
+ >
129
+ <span className="sicon-shipping rtl:ml-1 ltr:mr-1"></span>
130
+ {t('pages.orders.tracking_url')}
131
+ </a>
132
+ )}
133
+ </div>
134
+ </div>
135
+ );
136
+ }
137
+
138
+ /**
139
+ * The shipping company rows above the items (Twig's per-package titles). The order carries only
140
+ * its first shipment, so the rest come from the shipments endpoint.
141
+ */
142
+ export function ShippingHeader({ twig, order }: { twig: TwigOrder; order: Order }) {
143
+ const { data } = useQuery({
144
+ ...orderApi.queries.shipments(String(order.id)),
145
+ enabled: order.features.shippable && !twig.is_pickable,
146
+ });
147
+ if (twig.is_pickable) return null;
148
+
149
+ const shipments: Shipment[] = data?.length
150
+ ? data.map((shipment) => ({ ...shipment, tracking: shipment.tracking_url }))
151
+ : twig.shipping
152
+ ? [{ ...twig.shipping, tracking: twig.shipping.tracing_link }]
153
+ : [];
154
+
155
+ return (
156
+ <>
157
+ {shipments.map((shipment) => (
158
+ <ShippingRow key={shipment.id ?? shipment.name} shipment={shipment} />
159
+ ))}
160
+ </>
161
+ );
162
+ }
163
+
164
+ /** An option's price as a number: the API sends a number, `{ amount }` or an empty array. */
165
+ const optionPrice = (price: unknown): number =>
166
+ typeof price === 'number' ? price : ((price as { amount?: number } | null)?.amount ?? 0);
167
+
168
+ /** The order-level options table (`order.options`). */
169
+ export function OrderOptionsTable({
170
+ options,
171
+ money,
172
+ currency,
173
+ }: {
174
+ options: NonNullable<TwigOrder['options']>;
175
+ money: FormatMoney;
176
+ currency: string;
177
+ }) {
178
+ const { t } = useTranslation();
179
+ return (
180
+ <div className="bg-white p-5 rounded-md">
181
+ <h2 className="mb-3.5 text-sm font-bold">{t('pages.checkout.cart_options_title')}</h2>
182
+ <table className="table-fixed w-full border border-gray-200">
183
+ <thead>
184
+ <tr className="border-b border-gray-200">
185
+ <th scope="col" className="p-3 text-start text-sm">
186
+ {t('pages.order.option_name')}
187
+ </th>
188
+ <th scope="col" className="p-3 text-sm">
189
+ {t('pages.order.option_content')}
190
+ </th>
191
+ <th scope="col" className="p-3 rtl:text-left ltr:text-right text-sm">
192
+ {t('pages.products.price')}
193
+ </th>
194
+ </tr>
195
+ </thead>
196
+ <tbody>
197
+ {options.flatMap((option) =>
198
+ (option.options ?? []).map((value) => (
199
+ <tr
200
+ key={`${value.name}:${value.value}`}
201
+ className="border-b last:border-b-0 border-gray-200"
202
+ >
203
+ <td className="text-sm p-3">{value.name} :</td>
204
+ <td className="text-center p-3 font-medium text-xs">{value.value}</td>
205
+ <td className="rtl:text-start ltr:text-end p-3 font-medium text-xs">
206
+ <strong>{money(optionPrice(value.price), currency)}</strong>
207
+ </td>
208
+ </tr>
209
+ ))
210
+ )}
211
+ </tbody>
212
+ </table>
213
+ </div>
214
+ );
215
+ }
@@ -0,0 +1,38 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { OrderSinglePageProps } from '../types';
3
+
4
+ export type Order = OrderSinglePageProps['order'];
5
+ export type OrderItem = Order['items'][number];
6
+
7
+ export interface TwigRating {
8
+ id?: number;
9
+ stars?: number;
10
+ content?: string;
11
+ can_update?: boolean;
12
+ }
13
+
14
+ export interface TwigItem {
15
+ name: string;
16
+ quantity: number;
17
+ product?: { id: number; url?: string; type?: string; image?: { url?: string } };
18
+ options?: unknown[];
19
+ }
20
+
21
+ /** The order as `orders/{id}` answers a non-React theme: what the Twig templates read. */
22
+ export interface TwigOrder {
23
+ items: TwigItem[];
24
+ links?: Array<{ url: string; label: string }>;
25
+ shipping?: {
26
+ id?: number;
27
+ name?: string;
28
+ logo?: string;
29
+ number?: string;
30
+ tracing_link?: string | null;
31
+ };
32
+ rating?: { store?: TwigRating; shipping?: TwigRating } | unknown[];
33
+ can_rate?: boolean;
34
+ is_pickable?: boolean;
35
+ options?: Array<{ options?: Array<{ name: string; value: string; price?: unknown }> }>;
36
+ }
37
+
38
+ export type FormatMoney = (amount: number, currency?: string) => ReactNode;
@@ -0,0 +1,29 @@
1
+ import type { Page } from '../../../types';
2
+ import type { Pagination } from '../../../api/types';
3
+ import type { TwilightOrder } from '../../../api/order';
4
+ import type { Order, OrderListItem } from '../types';
5
+
6
+ export type { Order, OrderListItem };
7
+
8
+ /** URL query parameters for orders page */
9
+ export interface OrdersQuery {
10
+ status?: string;
11
+ feedback_status?: string;
12
+ }
13
+
14
+ export interface OrdersPageProps {
15
+ page: Page;
16
+ orders: OrderListItem[];
17
+ cursor?: Pagination;
18
+ query?: OrdersQuery;
19
+ }
20
+
21
+ export interface OrderSinglePageProps {
22
+ page: Page;
23
+ order: Order;
24
+ /** The same order as the Twilight components read it; null when it could not be loaded. */
25
+ componentsOrder?: TwilightOrder | null;
26
+ }
27
+
28
+ /** URL search params for orders routes - aliases OrdersQuery */
29
+ export type OrdersSearchParams = OrdersQuery;
@@ -0,0 +1,30 @@
1
+ import { SallaUserProfile } from '@salla.sa/twilight-components-react/user-profile';
2
+ import { SallaVerify } from '@salla.sa/twilight-components-react/verify';
3
+ import { SallaUserSettings } from '@salla.sa/twilight-components-react/user-settings';
4
+ import { HookSlot, useUser } from '../../../hooks';
5
+ import type { ProfilePageProps } from './types';
6
+
7
+ export function ProfilePage(_props: ProfilePageProps) {
8
+ const { data: user } = useUser();
9
+
10
+ return (
11
+ <>
12
+ <HookSlot name="customer:profile.start" />
13
+
14
+ <HookSlot name="customer:profile.form.start" />
15
+
16
+ <SallaUserProfile />
17
+
18
+ <HookSlot name="customer:profile.form.end" />
19
+
20
+ <SallaVerify />
21
+
22
+ <SallaUserSettings
23
+ {...(user?.preferences?.notifications_enabled ? { isNotifiable: true } : {})}
24
+ className="mt-10 block"
25
+ />
26
+
27
+ <HookSlot name="customer:profile.end" />
28
+ </>
29
+ );
30
+ }
@@ -0,0 +1,39 @@
1
+ import type { HeadDescriptor } from '../../../utils/head';
2
+ import { buildHreflangAlternates } from '../../../utils/baseHead';
3
+ import { lazy } from 'react';
4
+ import { profileLoader } from './loader';
5
+ import type { ProfilePageProps } from './types';
6
+ import type { TwilightContext } from '../../../twilight/context';
7
+ import { RouteId } from '../../../router/route-ids';
8
+
9
+ const LazyProfilePage = lazy(() =>
10
+ import('./ProfilePage').then((m) => ({ default: m.ProfilePage }))
11
+ );
12
+
13
+ export const ProfilePage = LazyProfilePage;
14
+ export { profileLoader } from './loader';
15
+ export type { ProfilePageProps } from './types';
16
+
17
+ export const Profile = {
18
+ id: RouteId.CUSTOMER_PROFILE,
19
+ loader: async (
20
+ _ctx: { locale?: string },
21
+ extend?: (
22
+ data: ProfilePageProps,
23
+ ctx: { params: Record<string, never> }
24
+ ) => Promise<Record<string, unknown>> | Record<string, unknown>
25
+ ): Promise<ProfilePageProps> => {
26
+ const data = await profileLoader({ locale: _ctx.locale ?? 'ar' });
27
+ if (extend) {
28
+ const extra = await extend(data, { params: {} });
29
+ return { ...data, ...extra } as ProfilePageProps;
30
+ }
31
+ return data;
32
+ },
33
+ head: (ctx: TwilightContext, data: ProfilePageProps): HeadDescriptor => ({
34
+ title: data.page.title,
35
+ description: data.page.description,
36
+ alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),
37
+ }),
38
+ Component: LazyProfilePage,
39
+ } as const;
@@ -0,0 +1,16 @@
1
+ import type { ProfilePageProps } from './types';
2
+ import { getTwilightContext } from '../../../twilight/context';
3
+ import { unauthorized } from '../../../providers/NavigationProvider';
4
+ import { getAuthToken } from '../../../api/client';
5
+ import { RouteId } from '../../../router/route-ids';
6
+
7
+ export async function profileLoader(_ctx: { locale: string }): Promise<ProfilePageProps> {
8
+ if (!getAuthToken()) throw unauthorized();
9
+ const { i18n } = getTwilightContext();
10
+ return {
11
+ page: {
12
+ title: i18n.t('common.titles.profile') || 'Profile',
13
+ slug: RouteId.CUSTOMER_PROFILE,
14
+ },
15
+ };
16
+ }
@@ -0,0 +1,5 @@
1
+ import type { Page } from '../../../types';
2
+
3
+ export interface ProfilePageProps {
4
+ page: Page;
5
+ }
@@ -0,0 +1,13 @@
1
+ import { SallaUserSettings } from '@salla.sa/twilight-components-react/user-settings';
2
+ import { HookSlot } from '../../../hooks';
3
+ import type { SettingsPageProps } from './types';
4
+
5
+ export function SettingsPage(_props: SettingsPageProps) {
6
+ return (
7
+ <>
8
+ <HookSlot name="customer:settings.start" />
9
+ <SallaUserSettings />
10
+ <HookSlot name="customer:settings.end" />
11
+ </>
12
+ );
13
+ }
@@ -0,0 +1,39 @@
1
+ import type { HeadDescriptor } from '../../../utils/head';
2
+ import { buildHreflangAlternates } from '../../../utils/baseHead';
3
+ import { lazy } from 'react';
4
+ import { settingsLoader } from './loader';
5
+ import type { SettingsPageProps } from './types';
6
+ import type { TwilightContext } from '../../../twilight/context';
7
+ import { RouteId } from '../../../router/route-ids';
8
+
9
+ const LazySettingsPage = lazy(() =>
10
+ import('./SettingsPage').then((m) => ({ default: m.SettingsPage }))
11
+ );
12
+
13
+ export const SettingsPage = LazySettingsPage;
14
+ export { settingsLoader } from './loader';
15
+ export type { SettingsPageProps } from './types';
16
+
17
+ export const Settings = {
18
+ id: RouteId.CUSTOMER_SETTINGS,
19
+ loader: async (
20
+ _ctx: { locale?: string },
21
+ extend?: (
22
+ data: SettingsPageProps,
23
+ ctx: { params: Record<string, never> }
24
+ ) => Promise<Record<string, unknown>> | Record<string, unknown>
25
+ ): Promise<SettingsPageProps> => {
26
+ const data = await settingsLoader({ locale: _ctx.locale ?? 'ar' });
27
+ if (extend) {
28
+ const extra = await extend(data, { params: {} });
29
+ return { ...data, ...extra } as SettingsPageProps;
30
+ }
31
+ return data;
32
+ },
33
+ head: (ctx: TwilightContext, data: SettingsPageProps): HeadDescriptor => ({
34
+ title: data.page.title,
35
+ description: data.page.description,
36
+ alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),
37
+ }),
38
+ Component: LazySettingsPage,
39
+ } as const;
@@ -0,0 +1,13 @@
1
+ import type { SettingsPageProps } from './types';
2
+ import { getTwilightContext } from '../../../twilight/context';
3
+ import { unauthorized } from '../../../providers/NavigationProvider';
4
+ import { getAuthToken } from '../../../api/client';
5
+
6
+ export async function settingsLoader(_ctx: { locale: string }): Promise<SettingsPageProps> {
7
+ if (!getAuthToken()) throw unauthorized();
8
+ const { i18n } = getTwilightContext();
9
+ return {
10
+ // Twig's slug for this page; the advertisements API does not filter it, as on Twig.
11
+ page: { title: i18n.t('common.titles.settings') || 'Settings', slug: 'customer-settings' },
12
+ };
13
+ }
@@ -0,0 +1,5 @@
1
+ import type { Page } from '../../../types';
2
+
3
+ export interface SettingsPageProps {
4
+ page: Page;
5
+ }