@salla.sa/twilight-theme-engine 1.0.56 → 1.0.58
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.
- package/dist/{AddToCartForm-QKJ72MFV.js → AddToCartForm-MTD46H63.js} +3 -3
- package/dist/{AddToCartForm-QKJ72MFV.js.map → AddToCartForm-MTD46H63.js.map} +1 -1
- package/dist/{BlogAuthorPage-75HKHV53.js → BlogAuthorPage-BT5BGQQJ.js} +15 -16
- package/dist/BlogAuthorPage-BT5BGQQJ.js.map +1 -0
- package/dist/{BlogCategoryPage-R7QE3DNT.js → BlogCategoryPage-IDHUIFVG.js} +15 -16
- package/dist/BlogCategoryPage-IDHUIFVG.js.map +1 -0
- package/dist/{BlogPage-OAEP7OOU.js → BlogPage-VSZPR4AD.js} +13 -14
- package/dist/BlogPage-VSZPR4AD.js.map +1 -0
- package/dist/{BlogSinglePage-NSCAOZMR.js → BlogSinglePage-3FWJ6UTQ.js} +13 -14
- package/dist/BlogSinglePage-3FWJ6UTQ.js.map +1 -0
- package/dist/{BlogTagPage-QNAZWE5P.js → BlogTagPage-TIPPV2WW.js} +15 -16
- package/dist/BlogTagPage-TIPPV2WW.js.map +1 -0
- package/dist/{BrandsPage-5JHLX2XO.js → BrandsPage-LEXRPFVK.js} +13 -14
- package/dist/BrandsPage-LEXRPFVK.js.map +1 -0
- package/dist/{Breadcrumb-A4FLPDBV.js → Breadcrumb-Q3P72LPT.js} +13 -14
- package/dist/Breadcrumb-Q3P72LPT.js.map +1 -0
- package/dist/{CartItem-VZKFYO57.js → CartItem-LJYCK3UP.js} +13 -14
- package/dist/CartItem-LJYCK3UP.js.map +1 -0
- package/dist/{CartSummary-7ZSG6I6S.js → CartSummary-645YDH2N.js} +13 -14
- package/dist/CartSummary-645YDH2N.js.map +1 -0
- package/dist/{Copyright-C4NN5NWB.js → Copyright-N5323WE7.js} +3 -3
- package/dist/{Copyright-C4NN5NWB.js.map → Copyright-N5323WE7.js.map} +1 -1
- package/dist/{CustomerLayout-3HW7J2BB.js → CustomerLayout-LB2EWG2P.js} +13 -14
- package/dist/CustomerLayout-LB2EWG2P.js.map +1 -0
- package/dist/{Footer-373V56WN.js → Footer-TTYS7K4V.js} +13 -14
- package/dist/{Footer-373V56WN.js.map → Footer-TTYS7K4V.js.map} +1 -1
- package/dist/{Header-F4H4CBCL.js → Header-26PWNGDF.js} +6 -6
- package/dist/{Header-F4H4CBCL.js.map → Header-26PWNGDF.js.map} +1 -1
- package/dist/{LoyaltyPage-UMWLPECY.js → LoyaltyPage-F4QVHJAH.js} +14 -15
- package/dist/LoyaltyPage-F4QVHJAH.js.map +1 -0
- package/dist/{MainMenu-DP2N74AL.js → MainMenu-SACYMDKQ.js} +7 -7
- package/dist/{MainMenu-DP2N74AL.js.map → MainMenu-SACYMDKQ.js.map} +1 -1
- package/dist/{MasterLayout-27XOOCFM.js → MasterLayout-MVY5N7G6.js} +13 -14
- package/dist/{MasterLayout-27XOOCFM.js.map → MasterLayout-MVY5N7G6.js.map} +1 -1
- package/dist/{MobileMenu-RDTHWQC3.js → MobileMenu-DBIJRXTA.js} +14 -15
- package/dist/MobileMenu-DBIJRXTA.js.map +1 -0
- package/dist/{NotificationsPage-KTZLNZHM.js → NotificationsPage-TMGF4BQM.js} +13 -14
- package/dist/NotificationsPage-TMGF4BQM.js.map +1 -0
- package/dist/{OrderSinglePage-PQ74PMJK.js → OrderSinglePage-NCQR6ADR.js} +14 -15
- package/dist/OrderSinglePage-NCQR6ADR.js.map +1 -0
- package/dist/{OrdersPage-7NGAJPK2.js → OrdersPage-O2LSXL4W.js} +14 -15
- package/dist/OrdersPage-O2LSXL4W.js.map +1 -0
- package/dist/{PageSingle-2OITZXHA.js → PageSingle-745SGJUG.js} +3 -3
- package/dist/{PageSingle-2OITZXHA.js.map → PageSingle-745SGJUG.js.map} +1 -1
- package/dist/{ProductDetails-CCN7LHV7.js → ProductDetails-AHYFTGM6.js} +3 -3
- package/dist/{ProductDetails-CCN7LHV7.js.map → ProductDetails-AHYFTGM6.js.map} +1 -1
- package/dist/{ProfilePage-FBAQ4YFY.js → ProfilePage-5JUXB5SB.js} +13 -14
- package/dist/ProfilePage-5JUXB5SB.js.map +1 -0
- package/dist/{SeoCartWidget-IZSJ6YTX.js → SeoCartWidget-XPPMBCQB.js} +13 -14
- package/dist/SeoCartWidget-XPPMBCQB.js.map +1 -0
- package/dist/{SettingsPage-RAEWPKMK.js → SettingsPage-NFSZ4CKO.js} +13 -14
- package/dist/SettingsPage-NFSZ4CKO.js.map +1 -0
- package/dist/{StoreClosedNotification-OALAFI4Y.js → StoreClosedNotification-5XWRDBPA.js} +14 -15
- package/dist/{StoreClosedNotification-OALAFI4Y.js.map → StoreClosedNotification-5XWRDBPA.js.map} +1 -1
- package/dist/{TestimonialsPage-RWIXMIR6.js → TestimonialsPage-JHGMJMGG.js} +3 -3
- package/dist/{TestimonialsPage-RWIXMIR6.js.map → TestimonialsPage-JHGMJMGG.js.map} +1 -1
- package/dist/{ThankYouPage-TLFQE3TA.js → ThankYouPage-CYCVSBAO.js} +13 -14
- package/dist/ThankYouPage-CYCVSBAO.js.map +1 -0
- package/dist/{WalletPage-EFOMPLFB.js → WalletPage-2JZ32SNZ.js} +14 -15
- package/dist/WalletPage-2JZ32SNZ.js.map +1 -0
- package/dist/{WishlistPage-D6WQCUIS.js → WishlistPage-N3K6MBMC.js} +15 -16
- package/dist/WishlistPage-N3K6MBMC.js.map +1 -0
- package/dist/api/apps.js +4 -4
- package/dist/api/brands.js +5 -5
- package/dist/api/cart.js +5 -5
- package/dist/api/category.js +5 -5
- package/dist/api/client.d.ts +9 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +3 -3
- package/dist/api/home.js +4 -4
- package/dist/api/loyalty.js +5 -5
- package/dist/api/menu.js +4 -4
- package/dist/api/notification.js +4 -4
- package/dist/api/order.js +5 -5
- package/dist/api/page.js +5 -5
- package/dist/api/product.js +5 -5
- package/dist/api/profile.js +3 -3
- package/dist/api/store.js +4 -4
- package/dist/api/translations-key.d.ts +25 -0
- package/dist/api/translations-key.d.ts.map +1 -0
- package/dist/api/translations.d.ts +27 -4
- package/dist/api/translations.d.ts.map +1 -1
- package/dist/api/translations.js +4 -4
- package/dist/api/user.js +4 -4
- package/dist/api/wishlist.js +6 -6
- package/dist/{chunk-WMSOSA74.js → chunk-2KU5ANFZ.js} +5 -5
- package/dist/{chunk-WMSOSA74.js.map → chunk-2KU5ANFZ.js.map} +1 -1
- package/dist/{chunk-QBIW266S.js → chunk-2OX3JML4.js} +4 -4
- package/dist/{chunk-QBIW266S.js.map → chunk-2OX3JML4.js.map} +1 -1
- package/dist/{chunk-NSSKTF6I.js → chunk-36PDYP56.js} +40 -19
- package/dist/chunk-36PDYP56.js.map +1 -0
- package/dist/chunk-3H27IEME.js +14 -0
- package/dist/{chunk-TUUBKHTD.js.map → chunk-3H27IEME.js.map} +1 -1
- package/dist/{chunk-BVB75J3R.js → chunk-3R7YKSO6.js} +5 -5
- package/dist/{chunk-BVB75J3R.js.map → chunk-3R7YKSO6.js.map} +1 -1
- package/dist/{chunk-XEQ6ILIP.js → chunk-675NJ2XP.js} +4 -4
- package/dist/{chunk-XEQ6ILIP.js.map → chunk-675NJ2XP.js.map} +1 -1
- package/dist/{chunk-OZV5P4VP.js → chunk-7BWZYECG.js} +5 -5
- package/dist/{chunk-OZV5P4VP.js.map → chunk-7BWZYECG.js.map} +1 -1
- package/dist/{chunk-PZL3JWM2.js → chunk-BFZ47MS5.js} +3 -3
- package/dist/{chunk-PZL3JWM2.js.map → chunk-BFZ47MS5.js.map} +1 -1
- package/dist/{chunk-NCGZMLBS.js → chunk-BZ7ZIO33.js} +3 -3
- package/dist/{chunk-NCGZMLBS.js.map → chunk-BZ7ZIO33.js.map} +1 -1
- package/dist/{chunk-O6XXHXC4.js → chunk-F4MMWEII.js} +9 -5
- package/dist/chunk-F4MMWEII.js.map +1 -0
- package/dist/{chunk-R6M6RM6U.js → chunk-GLRXYGYI.js} +3 -3
- package/dist/{chunk-R6M6RM6U.js.map → chunk-GLRXYGYI.js.map} +1 -1
- package/dist/{chunk-MENDTTOA.js → chunk-HOE2P2HU.js} +3 -3
- package/dist/{chunk-MENDTTOA.js.map → chunk-HOE2P2HU.js.map} +1 -1
- package/dist/{chunk-62SHHET3.js → chunk-HVHFTVZT.js} +4 -4
- package/dist/{chunk-62SHHET3.js.map → chunk-HVHFTVZT.js.map} +1 -1
- package/dist/chunk-IE2FU6BR.js +83 -0
- package/dist/chunk-IE2FU6BR.js.map +1 -0
- package/dist/{chunk-F5IEB43R.js → chunk-J2GGMK3X.js} +6 -6
- package/dist/{chunk-F5IEB43R.js.map → chunk-J2GGMK3X.js.map} +1 -1
- package/dist/{chunk-NQ5FQOE2.js → chunk-JBNI5ZVG.js} +3 -3
- package/dist/{chunk-NQ5FQOE2.js.map → chunk-JBNI5ZVG.js.map} +1 -1
- package/dist/{chunk-63GHZIAG.js → chunk-JDROOL5C.js} +3 -3
- package/dist/{chunk-63GHZIAG.js.map → chunk-JDROOL5C.js.map} +1 -1
- package/dist/{chunk-P4DUWQU4.js → chunk-K4YT7TOV.js} +3 -3
- package/dist/{chunk-P4DUWQU4.js.map → chunk-K4YT7TOV.js.map} +1 -1
- package/dist/{chunk-JD4J2ZB6.js → chunk-KTOKX3GC.js} +3 -3
- package/dist/{chunk-JD4J2ZB6.js.map → chunk-KTOKX3GC.js.map} +1 -1
- package/dist/{chunk-IVDXRPIG.js → chunk-LKRI35NZ.js} +15 -19
- package/dist/chunk-LKRI35NZ.js.map +1 -0
- package/dist/{chunk-7XBSSGRK.js → chunk-MQBGRVOJ.js} +4 -4
- package/dist/{chunk-7XBSSGRK.js.map → chunk-MQBGRVOJ.js.map} +1 -1
- package/dist/{chunk-MDIUVANI.js → chunk-O2YV5DAL.js} +4 -4
- package/dist/{chunk-MDIUVANI.js.map → chunk-O2YV5DAL.js.map} +1 -1
- package/dist/{chunk-GLJX3BH2.js → chunk-PSRSWHML.js} +4 -4
- package/dist/{chunk-GLJX3BH2.js.map → chunk-PSRSWHML.js.map} +1 -1
- package/dist/{chunk-A2ZO3IR7.js → chunk-RBVFIPX2.js} +4 -4
- package/dist/{chunk-A2ZO3IR7.js.map → chunk-RBVFIPX2.js.map} +1 -1
- package/dist/{chunk-BQ4CV7YX.js → chunk-RJAV554G.js} +4 -4
- package/dist/{chunk-BQ4CV7YX.js.map → chunk-RJAV554G.js.map} +1 -1
- package/dist/{chunk-UV5BRJH4.js → chunk-S7XYSF4X.js} +4 -4
- package/dist/{chunk-UV5BRJH4.js.map → chunk-S7XYSF4X.js.map} +1 -1
- package/dist/{chunk-PJWFEMBX.js → chunk-SOPK72TP.js} +9 -4
- package/dist/chunk-SOPK72TP.js.map +1 -0
- package/dist/{chunk-YGAU6PFQ.js → chunk-TJGYL7GD.js} +5 -5
- package/dist/{chunk-YGAU6PFQ.js.map → chunk-TJGYL7GD.js.map} +1 -1
- package/dist/{chunk-3FIWHGCZ.js → chunk-TX6ZP4FF.js} +3 -3
- package/dist/{chunk-3FIWHGCZ.js.map → chunk-TX6ZP4FF.js.map} +1 -1
- package/dist/{chunk-QKIQ3K24.js → chunk-UOALND7V.js} +4 -4
- package/dist/{chunk-QKIQ3K24.js.map → chunk-UOALND7V.js.map} +1 -1
- package/dist/{chunk-TIDHWQIS.js → chunk-VO5ODVVL.js} +4 -4
- package/dist/{chunk-TIDHWQIS.js.map → chunk-VO5ODVVL.js.map} +1 -1
- package/dist/{chunk-U43L4ZLH.js → chunk-WFSOVIYU.js} +6 -6
- package/dist/{chunk-U43L4ZLH.js.map → chunk-WFSOVIYU.js.map} +1 -1
- package/dist/{chunk-4D44TJ72.js → chunk-WIAPOLEA.js} +3 -3
- package/dist/{chunk-4D44TJ72.js.map → chunk-WIAPOLEA.js.map} +1 -1
- package/dist/{chunk-EPDF4ZU7.js → chunk-XDB2POG3.js} +7 -7
- package/dist/{chunk-EPDF4ZU7.js.map → chunk-XDB2POG3.js.map} +1 -1
- package/dist/{chunk-UIDPX3GA.js → chunk-YJ6ZSGQY.js} +3 -3
- package/dist/{chunk-UIDPX3GA.js.map → chunk-YJ6ZSGQY.js.map} +1 -1
- package/dist/{chunk-QM75GGXX.js → chunk-YJJZN5UP.js} +4 -4
- package/dist/{chunk-QM75GGXX.js.map → chunk-YJJZN5UP.js.map} +1 -1
- package/dist/{chunk-3MHDV5JS.js → chunk-YNY5P2DG.js} +3 -3
- package/dist/{chunk-3MHDV5JS.js.map → chunk-YNY5P2DG.js.map} +1 -1
- package/dist/{chunk-Z74NUTEI.js → chunk-YSFWVMBA.js} +3 -3
- package/dist/{chunk-Z74NUTEI.js.map → chunk-YSFWVMBA.js.map} +1 -1
- package/dist/components/cart/index.js +1 -1
- package/dist/components/common/index.js +1 -1
- package/dist/components/drawer/index.js +11 -12
- package/dist/components/home/index.js +14 -15
- package/dist/components/layout/index.js +5 -5
- package/dist/components/product/index.js +12 -13
- package/dist/components/store/index.js +13 -14
- package/dist/components/store/index.js.map +1 -1
- package/dist/document-class-YYEVAIVJ.js +25 -0
- package/dist/{document-class-JZAILFK3.js.map → document-class-YYEVAIVJ.js.map} +1 -1
- package/dist/hooks/index.js +11 -12
- package/dist/hooks/registerDefaultHooks.d.ts.map +1 -1
- package/dist/hooks/useGtm.js +11 -12
- package/dist/hooks/useMoney.js +11 -12
- package/dist/hooks/useStore.js +11 -12
- package/dist/hooks/useUser.js +5 -5
- package/dist/index.js +11 -12
- package/dist/index.js.map +1 -1
- package/dist/{navigation-JINL5V44.js → navigation-4VEQUXHI.js} +5 -5
- package/dist/{navigation-JINL5V44.js.map → navigation-4VEQUXHI.js.map} +1 -1
- package/dist/{navigation-ERMAPC4D.js → navigation-MVKZENRD.js} +4 -4
- package/dist/{navigation-ERMAPC4D.js.map → navigation-MVKZENRD.js.map} +1 -1
- package/dist/{not-found-OSTTTMCL.js → not-found-JGDH4AQ3.js} +14 -15
- package/dist/not-found-JGDH4AQ3.js.map +1 -0
- package/dist/providers/index.js +11 -12
- package/dist/routes/account/orders.js +6 -6
- package/dist/routes/account.js +15 -15
- package/dist/routes/blog.js +10 -10
- package/dist/routes/brands.js +6 -6
- package/dist/routes/cart.js +19 -20
- package/dist/routes/cart.js.map +1 -1
- package/dist/routes/home.js +16 -17
- package/dist/routes/index.js +3 -3
- package/dist/routes/loyalty.js +6 -6
- package/dist/routes/page.js +6 -6
- package/dist/routes/product/index.d.ts.map +1 -1
- package/dist/routes/product-listing.js +16 -17
- package/dist/routes/product-listing.js.map +1 -1
- package/dist/routes/product.js +19 -16
- package/dist/routes/product.js.map +1 -1
- package/dist/routes/root/head.d.ts.map +1 -1
- package/dist/routes/seo-redirects.js +3 -3
- package/dist/routes/testimonials.js +2 -2
- package/dist/routes/thank-you.js +6 -6
- package/dist/skeleton.js +16 -17
- package/dist/tanstack/router.d.ts.map +1 -1
- package/dist/tanstack.js +15 -16
- package/dist/tanstack.js.map +1 -1
- package/dist/twilight/context.d.ts.map +1 -1
- package/dist/utils/fast-checkout.d.ts +16 -1
- package/dist/utils/fast-checkout.d.ts.map +1 -1
- package/dist/utils/index.js +4 -4
- package/dist/vite/index.js +2 -2
- package/package.json +1 -1
- package/dist/BlogAuthorPage-75HKHV53.js.map +0 -1
- package/dist/BlogCategoryPage-R7QE3DNT.js.map +0 -1
- package/dist/BlogPage-OAEP7OOU.js.map +0 -1
- package/dist/BlogSinglePage-NSCAOZMR.js.map +0 -1
- package/dist/BlogTagPage-QNAZWE5P.js.map +0 -1
- package/dist/BrandsPage-5JHLX2XO.js.map +0 -1
- package/dist/Breadcrumb-A4FLPDBV.js.map +0 -1
- package/dist/CartItem-VZKFYO57.js.map +0 -1
- package/dist/CartSummary-7ZSG6I6S.js.map +0 -1
- package/dist/CustomerLayout-3HW7J2BB.js.map +0 -1
- package/dist/LoyaltyPage-UMWLPECY.js.map +0 -1
- package/dist/MobileMenu-RDTHWQC3.js.map +0 -1
- package/dist/NotificationsPage-KTZLNZHM.js.map +0 -1
- package/dist/OrderSinglePage-PQ74PMJK.js.map +0 -1
- package/dist/OrdersPage-7NGAJPK2.js.map +0 -1
- package/dist/ProfilePage-FBAQ4YFY.js.map +0 -1
- package/dist/SeoCartWidget-IZSJ6YTX.js.map +0 -1
- package/dist/SettingsPage-RAEWPKMK.js.map +0 -1
- package/dist/ThankYouPage-TLFQE3TA.js.map +0 -1
- package/dist/WalletPage-EFOMPLFB.js.map +0 -1
- package/dist/WishlistPage-D6WQCUIS.js.map +0 -1
- package/dist/chunk-6IATCGID.js +0 -7
- package/dist/chunk-6IATCGID.js.map +0 -1
- package/dist/chunk-IVDXRPIG.js.map +0 -1
- package/dist/chunk-KT2MUSRN.js +0 -25
- package/dist/chunk-KT2MUSRN.js.map +0 -1
- package/dist/chunk-NSSKTF6I.js.map +0 -1
- package/dist/chunk-O6XXHXC4.js.map +0 -1
- package/dist/chunk-PJWFEMBX.js.map +0 -1
- package/dist/chunk-TUUBKHTD.js +0 -14
- package/dist/document-class-JZAILFK3.js +0 -26
- package/dist/not-found-OSTTTMCL.js.map +0 -1
package/dist/routes/loyalty.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { loyalty } from '../chunk-
|
|
1
|
+
import { loyalty } from '../chunk-HVHFTVZT.js';
|
|
2
2
|
import { buildHreflangAlternates } from '../chunk-TZ3E5BN4.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-JDROOL5C.js';
|
|
4
4
|
import { RouteId } from '../chunk-TFB3QXYH.js';
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-
|
|
5
|
+
import '../chunk-F4MMWEII.js';
|
|
6
|
+
import '../chunk-TX6ZP4FF.js';
|
|
7
7
|
import '../chunk-XTMHHLNK.js';
|
|
8
|
-
import '../chunk-
|
|
8
|
+
import '../chunk-SOPK72TP.js';
|
|
9
9
|
import '../chunk-T72DAX7R.js';
|
|
10
10
|
import '../chunk-DF6FBKDN.js';
|
|
11
11
|
import '../chunk-DGUM43GV.js';
|
|
@@ -19,7 +19,7 @@ async function loyaltyLoader() {
|
|
|
19
19
|
|
|
20
20
|
// src/routes/loyalty/index.tsx
|
|
21
21
|
var LazyLoyaltyPage = lazy(
|
|
22
|
-
() => import('../LoyaltyPage-
|
|
22
|
+
() => import('../LoyaltyPage-F4QVHJAH.js').then((m) => ({ default: m.LoyaltyPage }))
|
|
23
23
|
);
|
|
24
24
|
var LoyaltyPage = LazyLoyaltyPage;
|
|
25
25
|
async function loader(_ctx, extend) {
|
package/dist/routes/page.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { page } from '../chunk-
|
|
1
|
+
import { page } from '../chunk-VO5ODVVL.js';
|
|
2
2
|
import { buildHreflangAlternates } from '../chunk-TZ3E5BN4.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-JDROOL5C.js';
|
|
4
4
|
import { RouteId } from '../chunk-TFB3QXYH.js';
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-
|
|
5
|
+
import '../chunk-F4MMWEII.js';
|
|
6
|
+
import '../chunk-TX6ZP4FF.js';
|
|
7
7
|
import '../chunk-XTMHHLNK.js';
|
|
8
|
-
import '../chunk-
|
|
8
|
+
import '../chunk-SOPK72TP.js';
|
|
9
9
|
import '../chunk-T72DAX7R.js';
|
|
10
10
|
import '../chunk-DF6FBKDN.js';
|
|
11
11
|
import '../chunk-DGUM43GV.js';
|
|
@@ -28,7 +28,7 @@ async function pageSingleLoader({ params }) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// src/routes/page/index.tsx
|
|
31
|
-
var LazyPageSingle = lazy(() => import('../PageSingle-
|
|
31
|
+
var LazyPageSingle = lazy(() => import('../PageSingle-745SGJUG.js').then((m) => ({ default: m.PageSingle })));
|
|
32
32
|
var PageSingleLazy = LazyPageSingle;
|
|
33
33
|
async function loader(ctx, extend) {
|
|
34
34
|
const data = await pageSingleLoader({ params: ctx.params });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routes/product/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routes/product/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,iBAAe,MAAM,CACnB,GAAG,EAAE;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1C,MAAM,CAAC,EAAE,CACP,IAAI,EAAE,gBAAgB,EACtB,GAAG,EAAE;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,KACtB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9D,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAED,iBAAS,IAAI,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,gBAAgB,GAAG,cAAc,CAqH1E;AAED,eAAO,MAAM,OAAO;;;;;CAKV,CAAC"}
|
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
import { sortOptions } from '../chunk-6Z4MOC4S.js';
|
|
2
|
-
import { category } from '../chunk-
|
|
3
|
-
import { brand } from '../chunk-
|
|
2
|
+
import { category } from '../chunk-RBVFIPX2.js';
|
|
3
|
+
import { brand } from '../chunk-675NJ2XP.js';
|
|
4
4
|
import { buildHreflangAlternates } from '../chunk-TZ3E5BN4.js';
|
|
5
|
-
import { LazyTestimonials } from '../chunk-
|
|
6
|
-
import { product } from '../chunk-
|
|
5
|
+
import { LazyTestimonials } from '../chunk-7BWZYECG.js';
|
|
6
|
+
import { product } from '../chunk-3R7YKSO6.js';
|
|
7
7
|
import { Drawer } from '../chunk-6TKIUG5C.js';
|
|
8
|
-
import { ProductCard } from '../chunk-
|
|
8
|
+
import { ProductCard } from '../chunk-WFSOVIYU.js';
|
|
9
9
|
import '../chunk-342EPVXN.js';
|
|
10
|
-
import { useStore } from '../chunk-
|
|
11
|
-
import '../chunk-
|
|
10
|
+
import { useStore } from '../chunk-36PDYP56.js';
|
|
11
|
+
import '../chunk-J2GGMK3X.js';
|
|
12
12
|
import '../chunk-JKIRRMBU.js';
|
|
13
13
|
import '../chunk-2JV6WZ6O.js';
|
|
14
|
-
import '../chunk-
|
|
15
|
-
import '../chunk-3MHDV5JS.js';
|
|
14
|
+
import '../chunk-YNY5P2DG.js';
|
|
16
15
|
import '../chunk-VVZNW5CB.js';
|
|
17
|
-
import '../chunk-
|
|
18
|
-
import { notFound, useNavigate, useLocation } from '../chunk-
|
|
16
|
+
import '../chunk-KTOKX3GC.js';
|
|
17
|
+
import { notFound, useNavigate, useLocation } from '../chunk-JDROOL5C.js';
|
|
19
18
|
import { RouteId } from '../chunk-TFB3QXYH.js';
|
|
20
19
|
import '../chunk-C5X6CVXC.js';
|
|
21
|
-
import '../chunk-
|
|
22
|
-
import '../chunk-
|
|
23
|
-
import '../chunk-
|
|
24
|
-
import '../chunk-
|
|
20
|
+
import '../chunk-UOALND7V.js';
|
|
21
|
+
import '../chunk-YSFWVMBA.js';
|
|
22
|
+
import '../chunk-F4MMWEII.js';
|
|
23
|
+
import '../chunk-TX6ZP4FF.js';
|
|
25
24
|
import '../chunk-XTMHHLNK.js';
|
|
26
|
-
import { getTwilightContext } from '../chunk-
|
|
25
|
+
import { getTwilightContext } from '../chunk-SOPK72TP.js';
|
|
27
26
|
import '../chunk-TP3LCGE7.js';
|
|
28
27
|
import '../chunk-Z653O7MX.js';
|
|
29
28
|
import '../chunk-ZCH7W7DZ.js';
|
|
@@ -39,7 +38,7 @@ import '../chunk-YMVLYYLU.js';
|
|
|
39
38
|
import '../chunk-RJPPO3ET.js';
|
|
40
39
|
import { HookSlot } from '../chunk-Q7VWURUR.js';
|
|
41
40
|
import '../chunk-GU2KUQVD.js';
|
|
42
|
-
import { LazyBreadcrumb, Image, LazyNoContent, ProductCardSkeleton, LazyRenderWhenVisible } from '../chunk-
|
|
41
|
+
import { LazyBreadcrumb, Image, LazyNoContent, ProductCardSkeleton, LazyRenderWhenVisible } from '../chunk-JBNI5ZVG.js';
|
|
43
42
|
import '../chunk-AXW67SY7.js';
|
|
44
43
|
import '../chunk-BYMOPN2S.js';
|
|
45
44
|
import '../chunk-SKLEJJ6M.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/routes/product-listing/loader.ts","../../src/routes/product-listing/useAppliedFilters.ts","../../src/routes/product-listing/ProductListPage.tsx","../../src/routes/product-listing/index.tsx"],"names":["i18n","useState","brand","useEffect","useCallback","category"],"mappings":"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","file":"product-listing.js","sourcesContent":["import type { ProductListLoaderData, ProductListLoaderContext, ProductListSource } from './types';\nimport type { ProductsListSource } from '../../api/product';\nimport { category } from '../../api/category';\nimport { product } from '../../api/product';\nimport { brand } from '../../api/brands';\nimport { notFound } from '../../providers/NavigationProvider';\nimport { getTwilightContext } from '../../twilight/context';\nimport { RouteId } from '../../router/route-ids';\n\nconst DEFAULT_SORT = 'ourSuggest';\n\nconst SOURCE_TO_API: Record<ProductListSource, ProductsListSource> = {\n categories: 'categories',\n latest: 'latest',\n sales: 'sales',\n offers: 'offers',\n search: 'search',\n tags: 'tags',\n brands: 'brands',\n};\n\nconst SOURCE_TITLE_KEY: Record<'latest' | 'sales' | 'offers', string> = {\n latest: 'blocks.home.latest_products',\n sales: 'common.titles.most_sales',\n offers: 'blocks.header.offers',\n};\n\nconst SOURCE_SLUG: Record<'latest' | 'sales' | 'offers', string> = {\n latest: 'latest-products',\n sales: 'most-sales-products',\n offers: 'offers',\n};\n\nexport async function productListLoader(\n ctx: ProductListLoaderContext\n): Promise<ProductListLoaderData> {\n const { params, search } = ctx;\n const cursor = search?.page ? String(search.page) : undefined;\n const sort = search?.sort ?? DEFAULT_SORT;\n\n const sourceType = params.source ?? (params.id ? 'categories' : undefined);\n\n if (!sourceType) {\n throw new Error('ProductList loader requires source type');\n }\n\n if (sourceType === 'categories' && params.id) {\n return loadCategoryProducts(params.id, cursor, sort);\n }\n\n if (sourceType === 'search') {\n const keyword = (search?.q ?? params.keyword ?? '').trim();\n return loadSearchProducts(keyword, cursor, sort);\n }\n\n if (sourceType === 'tags' && params.id) {\n return loadTagProducts(params.id, cursor, sort);\n }\n\n if (sourceType === 'brands' && params.id) {\n return loadBrandProducts(params.id, cursor, sort);\n }\n\n if (sourceType === 'latest' || sourceType === 'sales' || sourceType === 'offers') {\n return loadStaticProducts(\n sourceType as 'latest' | 'sales' | 'offers',\n params.title ?? '',\n params.slug ?? '',\n cursor,\n sort\n );\n }\n\n throw new Error(`Unknown source type: ${sourceType}`);\n}\n\n// ============================================================================\n// Source-Specific Loaders\n// ============================================================================\n\nasync function loadCategoryProducts(\n id: string,\n cursor: string | undefined,\n sort: string\n): Promise<ProductListLoaderData> {\n const { queryClient, i18n } = getTwilightContext();\n let categoryData, productsResult;\n try {\n [categoryData, productsResult] = await Promise.all([\n queryClient.fetchQuery(category.queries.detail(id)),\n queryClient.fetchQuery(\n product.queries.list({\n source: 'categories',\n sourceValue: id,\n cursor,\n sort,\n filterable: true,\n })\n ),\n ]);\n } catch {\n throw notFound();\n }\n\n if (!categoryData) throw notFound();\n\n return {\n page: {\n slug: RouteId.PRODUCT_INDEX,\n id,\n title: categoryData.name,\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: categoryData.name, url: categoryData.url },\n ],\n },\n source: { type: 'categories', value: id, entity: categoryData },\n query: { sort, filters: true },\n products: productsResult.items,\n pagination: {\n next: productsResult.next,\n },\n filters: productsResult.filters,\n };\n}\n\nasync function loadSearchProducts(\n keyword: string,\n cursor: string | undefined,\n sort: string\n): Promise<ProductListLoaderData> {\n if (!keyword) {\n const { i18n } = getTwilightContext();\n return {\n page: {\n slug: RouteId.SEARCH,\n title: i18n.t('common.titles.search') || 'Search Results',\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: i18n.t('common.titles.search') || 'Search Results', url: '/search' },\n ],\n },\n source: { type: 'search', value: '' },\n query: { sort, filters: true },\n products: [],\n pagination: { next: null },\n };\n }\n\n const { queryClient, i18n } = getTwilightContext();\n const productsResult = await queryClient.fetchQuery(\n product.queries.list({\n source: 'search',\n sourceValue: keyword,\n cursor,\n sort,\n filterable: true,\n })\n );\n\n return {\n page: {\n slug: RouteId.SEARCH,\n title: keyword,\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: keyword, url: '/search' },\n ],\n },\n source: { type: 'search', value: keyword },\n query: { sort, filters: true },\n products: productsResult.items,\n pagination: {\n next: productsResult.next,\n },\n filters: productsResult.filters,\n };\n}\n\nasync function loadTagProducts(\n id: string,\n cursor: string | undefined,\n sort: string\n): Promise<ProductListLoaderData> {\n const { queryClient, i18n } = getTwilightContext();\n const productsResult = await queryClient.fetchQuery(\n product.queries.list({\n source: 'tags',\n sourceValue: id,\n cursor,\n sort,\n })\n );\n\n const tagFromProduct = productsResult.items[0]?.tags?.find((t) => String(t.id) === id);\n if (!tagFromProduct) throw notFound();\n\n const tag = { id: Number(tagFromProduct.id), name: tagFromProduct.name, url: tagFromProduct.url };\n\n return {\n page: {\n slug: RouteId.PRODUCT_INDEX_TAG,\n id,\n title: tag.name,\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: tag.name, url: tag.url },\n ],\n },\n source: { type: 'tags', value: id, entity: tag },\n query: { sort, filters: false },\n products: productsResult.items,\n pagination: {\n next: productsResult.next,\n },\n };\n}\n\nasync function loadBrandProducts(\n id: string,\n cursor: string | undefined,\n sort: string\n): Promise<ProductListLoaderData> {\n const { queryClient, i18n } = getTwilightContext();\n let brandData, productsResult;\n try {\n [brandData, productsResult] = await Promise.all([\n queryClient.fetchQuery(brand.queries.detail(id)),\n queryClient.fetchQuery(\n product.queries.list({\n source: 'brands',\n sourceValue: id,\n cursor,\n sort,\n })\n ),\n ]);\n } catch {\n throw notFound();\n }\n\n if (!brandData) throw notFound();\n\n return {\n page: {\n slug: RouteId.BRANDS_INDEX,\n id,\n title: brandData.name,\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: brandData.name, url: brandData.url },\n ],\n },\n source: { type: 'brands', value: id, entity: brandData },\n query: { sort, filters: false },\n products: productsResult.items,\n pagination: {\n next: productsResult.next,\n },\n };\n}\n\nconst SOURCE_ROUTE_ID: Record<'latest' | 'sales' | 'offers', string> = {\n latest: RouteId.PRODUCT_INDEX_LATEST,\n sales: RouteId.PRODUCT_INDEX_SALES,\n offers: RouteId.PRODUCT_INDEX_OFFERS,\n};\n\nasync function loadStaticProducts(\n source: 'latest' | 'sales' | 'offers',\n title: string,\n slug: string,\n cursor: string | undefined,\n sort: string\n): Promise<ProductListLoaderData> {\n const { queryClient, i18n } = getTwilightContext();\n const resolvedTitle = title || i18n.t(SOURCE_TITLE_KEY[source]);\n const resolvedSlug = slug || SOURCE_SLUG[source];\n const productsResult = await queryClient.fetchQuery(\n product.queries.list({\n source: SOURCE_TO_API[source],\n cursor,\n sort,\n })\n );\n\n return {\n page: {\n slug: SOURCE_ROUTE_ID[source],\n title: resolvedTitle,\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: resolvedTitle, url: `/${resolvedSlug}` },\n ],\n },\n source: { type: source },\n query: { sort, filters: false },\n products: productsResult.items,\n pagination: {\n next: productsResult.next,\n },\n };\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { product } from '../../api/product';\nimport type { ProductListFilters } from '../../api/product';\nimport type { Product } from '../../types';\nimport type { ProductListLoaderData } from './types';\n\ntype Source = ProductListLoaderData['source'];\ntype Node = Record<string, unknown>;\n\n/** Path segments that would reach the shared prototype chain if used as object keys. */\nconst UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Reads the `filters[...]` selection `<salla-filters>` writes to the address bar\n * (`filters[k]=v`, `filters[k][]=v`, `filters[k][sub]=v`) back into an object, so a\n * filtered link can be opened directly.\n *\n * The keys come straight from the URL, so nodes are null-prototype objects and any\n * `__proto__` / `constructor` / `prototype` segment drops the whole entry — a crafted\n * `?filters[__proto__][x]=1` must never reach `Object.prototype`.\n */\nexport function parseFiltersFromSearch(search: string): ProductListFilters | null {\n const out: Node = Object.create(null);\n new URLSearchParams(search).forEach((value, rawKey) => {\n if (!rawKey.startsWith('filters[')) return;\n const path = [...rawKey.matchAll(/\\[([^\\]]*)\\]/g)].map((m) => m[1]);\n const isList = path[path.length - 1] === '';\n const keys = isList ? path.slice(0, -1) : path;\n if (!keys.length || keys.includes('') || keys.some((key) => UNSAFE_KEYS.has(key))) return;\n\n let node = out;\n keys.slice(0, -1).forEach((key) => {\n const existing = node[key];\n if (typeof existing !== 'object' || existing === null || Array.isArray(existing)) {\n node[key] = Object.create(null);\n }\n node = node[key] as Node;\n });\n const leaf = keys[keys.length - 1];\n if (isList) {\n node[leaf] = [...(Array.isArray(node[leaf]) ? (node[leaf] as string[]) : []), value];\n } else {\n node[leaf] = value;\n }\n });\n return Object.keys(out).length ? (out as ProductListFilters) : null;\n}\n\ninterface FilteredPage {\n items: Product[];\n next: string | null;\n}\n\nexport type AppliedFiltersStatus = 'idle' | 'loading' | 'ready' | 'error';\n\n/**\n * Applies the `<salla-filters>` selection to the product list.\n *\n * The filters component only rewrites the address bar (`history.pushState`, invisible\n * to the router) and emits `salla-filters::changed`; nothing re-queries the list, so\n * the route's loader output — fetched without filters — kept showing. This listens\n * for that event (and for a filtered URL on first load) and fetches the first page\n * with the selection.\n *\n * Each fetched page is stored with the selection that produced it, so `page` is only\n * ever the page for the *current* selection. Until it arrives `status` is `loading`\n * (and `lastPage` is the previous selection's page, for a dimmed placeholder); if the\n * request fails `status` is `error` and `retry` re-runs it — the old products never\n * pass for the new selection.\n */\nexport function useAppliedFilters(\n source: Source,\n sort: string,\n enabled: boolean\n): {\n filters: ProductListFilters | null;\n page: FilteredPage | null;\n lastPage: FilteredPage | null;\n status: AppliedFiltersStatus;\n retry: () => void;\n} {\n const [filters, setFilters] = useState<ProductListFilters | null>(null);\n const [result, setResult] = useState<{ key: string; page: FilteredPage } | null>(null);\n const [failedKey, setFailedKey] = useState<string | null>(null);\n const [attempt, setAttempt] = useState(0);\n\n useEffect(() => {\n if (!enabled) return;\n setFilters(parseFiltersFromSearch(window.location.search));\n const sdk = window.salla;\n if (!sdk?.event) return;\n const onChanged = (...args: unknown[]) => {\n const next = args[0] as ProductListFilters | undefined;\n setFilters(next && Object.keys(next).length ? { ...next } : null);\n };\n sdk.event.on('salla-filters::changed', onChanged);\n return () => sdk.event.off('salla-filters::changed', onChanged);\n }, [enabled, source.type, source.value]);\n\n const key = filters ? JSON.stringify([source.type, source.value, sort, filters]) : '';\n\n useEffect(() => {\n if (!filters) return;\n const controller = new AbortController();\n setFailedKey(null);\n product\n .list({\n source: source.type,\n sourceValue: source.value,\n sort,\n filterable: true,\n filters,\n signal: controller.signal,\n })\n .then((res) => setResult({ key, page: { items: res.items, next: res.next } }))\n .catch(() => {\n // Aborted by a newer selection (its own effect run owns the state now), or failed.\n if (!controller.signal.aborted) setFailedKey(key);\n });\n return () => controller.abort();\n // `key` already encodes filters + source + sort.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [key, attempt]);\n\n const retry = useCallback(() => setAttempt((n) => n + 1), []);\n\n if (!filters) return { filters: null, page: null, lastPage: null, status: 'idle', retry };\n\n const page = result?.key === key ? result.page : null;\n const status: AppliedFiltersStatus = page ? 'ready' : failedKey === key ? 'error' : 'loading';\n return { filters, page, lastPage: result?.page ?? null, status, retry };\n}\n","import { useState, useRef, useEffect, useMemo, useCallback } from 'react';\nimport { HookSlot, useStore } from '../../hooks';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { useNavigate, useLocation } from '../../providers/NavigationProvider';\nimport { useTwilight } from '../../providers/TwilightProvider';\nimport { sortOptions } from '../../utils/sort-options';\nimport { Drawer } from '../../components/drawer';\nimport { Breadcrumb } from '../../components/common';\nimport { SallaFilters } from '@salla.sa/twilight-components-react/filters';\nimport { ItemsList, ReviewItemSkeleton } from '@salla.sa/twilight-components-react';\nimport { Testimonials } from '../../components/home';\nimport { ProductCard } from '../../components/product';\nimport { NoContent, ProductCardSkeleton, Image, RenderWhenVisible } from '../../components/common';\nimport { product } from '../../api/product';\nimport { useAppliedFilters } from './useAppliedFilters';\nimport type { ProductListLoaderData } from './types';\nimport type { Brand } from '../brands/types';\nimport type { Product } from '../../types';\n\n/** 3-col + 288px sidebar from md; 3-col of the full container below md. */\nconst FILTERED_PRODUCT_IMAGE_SIZES = '(min-width: 768px) 25vw, 33vw';\n\n/**\n * Product List Page - Unified component for all product listing pages\n *\n * Handles:\n * - Category pages (with filters, category entity, testimonials)\n * - Search pages (keyword display, product count)\n * - Tag pages (tag entity)\n * - Brand pages (brand entity with banner/logo)\n * - Static listings (latest, sales, offers)\n */\nexport function ProductListPage({\n page,\n source,\n query,\n products,\n pagination,\n filters,\n}: ProductListLoaderData) {\n const { t } = useTranslation();\n const store = useStore();\n const { theme } = useTwilight();\n const navigate = useNavigate();\n // Sort is now SSR-driven, no local state needed\n const selectedSort = query.sort;\n const [filtersOpen, setFiltersOpen] = useState(false);\n\n // Determine filters visibility\n const showFilters = query.filters && store?.settings?.product?.filters;\n // const isSearch = source.type === 'search';\n const isBrand = source.type === 'brands';\n const brand = isBrand ? (source.entity as Brand | undefined) : null;\n\n // Generate sort options with translations\n const sortOptionsWithTrans = useMemo(() => sortOptions(selectedSort, t), [selectedSort, t]);\n\n // Get location from hook for consistent URL handling\n const location = useLocation();\n\n // Re-query the list with the selection made in `<salla-filters>`: the component only\n // rewrites the address bar and emits `salla-filters::changed`, and the route's loader\n // output was fetched without it.\n const {\n filters: appliedFilters,\n page: filteredPage,\n lastPage,\n status: filterStatus,\n retry: retryFilters,\n } = useAppliedFilters(source, selectedSort, !!showFilters);\n // While the new selection loads, the previous page stays up (dimmed, `aria-busy`); if\n // the request fails nothing stale passes for the new selection. Infinite scroll is only\n // live for the loader's own page or a fully loaded filtered one.\n const shownPage = filterStatus === 'ready' ? filteredPage : lastPage;\n const shownProducts =\n filterStatus === 'error'\n ? []\n : filterStatus === 'idle'\n ? products\n : (shownPage?.items ?? products);\n const shownNext =\n filterStatus === 'idle'\n ? pagination?.next\n : filterStatus === 'ready'\n ? filteredPage?.next\n : null;\n const filteredKey =\n filterStatus === 'idle'\n ? ''\n : `-${filterStatus}${filterStatus === 'ready' ? JSON.stringify(appliedFilters) : ''}`;\n\n // Listen for filters changed event to close drawer\n useEffect(() => {\n const handleFiltersChanged = () => setFiltersOpen(false);\n const sdk = window.salla;\n if (typeof sdk === 'undefined') return;\n\n sdk.event.on('salla-filters::changed', handleFiltersChanged);\n\n return () => {\n sdk.event.off('salla-filters::changed', handleFiltersChanged);\n };\n }, []);\n\n // Handle sort change - use client-side navigation to trigger route loader re-run\n const handleSortChange = useCallback(\n (event: React.ChangeEvent<HTMLSelectElement>) => {\n const newSort = event.target.value;\n\n const params = new URLSearchParams(location.searchStr);\n params.set('sort', newSort);\n params.delete('page'); // clear any cursor token from URL on sort change\n\n // Use client-side navigation to trigger route loader re-execution (SSR-like).\n // Built from the router's location rather than `window.location`: on a host\n // where the store is the root, the address bar carries the store segment and\n // `navigate` would add it a second time.\n navigate(`${location.pathname}?${params.toString()}`);\n },\n [navigate, location.pathname, location.searchStr]\n );\n\n // Key for remounting products list\n const listKey = source.value ?? source.type;\n\n // Track cursor for the next page — initialized from SSR pagination response.\n // On sort change the key prop remounts ItemsList and this effect resets the cursor.\n const nextCursorRef = useRef<string | null>(shownNext ?? null);\n useEffect(() => {\n nextCursorRef.current = shownNext ?? null;\n }, [shownNext]);\n\n const loader = useCallback(async () => {\n const nextUrl = nextCursorRef.current;\n // Extract the cursor token from the next URL provided by the previous response\n const cursorMatch = nextUrl?.match(/[?&]cursor=([^&]+)/);\n const cursor = cursorMatch ? decodeURIComponent(cursorMatch[1]) : (nextUrl ?? undefined);\n\n const result = await product.list({\n source: source.type,\n sourceValue: source.value,\n ...(cursor && { cursor }),\n sort: selectedSort,\n ...(appliedFilters && { filterable: true, filters: appliedFilters }),\n });\n\n nextCursorRef.current = result.next;\n\n return result;\n }, [source.type, source.value, selectedSort, appliedFilters]);\n\n return (\n <div key={listKey} className=\"container px-2.5 ms:px-5 mb-10\">\n {theme?.settings?.product_index_show_breadcrumbs !== false && <Breadcrumb page={page} />}\n\n {isBrand && brand && (\n <>\n <Image\n width={1200}\n height={300}\n className=\"w-full max-h-[300px] object-cover rounded-md bg-gray-100\"\n src={brand.banner || undefined}\n alt={brand.name}\n priority\n />\n <header className=\"flex flex-col md:flex-row items-center md:items-start text-center rtl:md:text-right ltr:md:text-left mt-2 mb-8\">\n <Image\n className=\"rounded-md w-40 h-24 object-contain shadow-md p-4 bg-white shrink-0\"\n src={brand.logo || undefined}\n alt={brand.name}\n aspectRatio=\"5/3\"\n />\n <div className=\"px-5 pt-3 rtl:text-right\">\n <h1 className=\"text-2xl font-bold mb-1\">{brand.name}</h1>\n {brand.description && (\n <p\n className=\"text-base text-gray-500 font-medium\"\n dangerouslySetInnerHTML={{ __html: brand.description }}\n />\n )}\n </div>\n </header>\n </>\n )}\n\n <HookSlot name=\"product:list.start\" />\n\n <div className={showFilters ? 'md:grid md:grid-cols-[288px_1fr] gap-8' : ''}>\n {/* <FiltersSkeleton></FiltersSkeleton> */}\n {showFilters && (\n <SallaFilters\n id=\"filters-menu\"\n className=\"hidden md:block lg:sticky lg:top-20\"\n filters={filters as any}\n />\n )}\n\n <div className=\"min-w-0\">\n <div className=\"mb-4 sm:mb-6 flex justify-between items-center\">\n <h1 className=\"font-bold text-xl rtl:pl-3 ltr:pr-3\" id=\"page-main-title\">\n {isBrand ? t('common.titles.products') : page.title}\n </h1>\n\n <div className=\"flex items-center space-x-2 rtl:space-x-reverse\">\n {showFilters && (\n <button\n type=\"button\"\n onClick={() => setFiltersOpen(true)}\n className=\"filters-trigger bg-border-color text-primary lg:hidden p-2 rounded\"\n >\n <i className=\"sicon-filter text-gray-text text-2xl\" />\n </button>\n )}\n\n {sortOptionsWithTrans.length > 0 && (\n <div className=\"flex items-center\">\n <label\n className=\"hidden sm:block rtl:ml-3 ltr:mr-3 whitespace-nowrap\"\n htmlFor=\"product-sort\"\n >\n {t('pages.categories.sorting', 'Sort By')}\n </label>\n <select\n id=\"product-sort\"\n className=\"form-input pt-0 pb-1 rtl:md:pl-10 ltr:md:pr-10\"\n value={selectedSort}\n onChange={handleSortChange}\n >\n {sortOptionsWithTrans.map((option) => (\n <option key={option.id} value={option.id}>\n {option.name}\n </option>\n ))}\n </select>\n </div>\n )}\n </div>\n </div>\n\n <HookSlot name=\"product:list.items.start\" />\n\n <div\n className={`flex min-h-screen${filterStatus === 'loading' ? ' opacity-60' : ''}`}\n aria-busy={filterStatus === 'loading'}\n >\n {filterStatus === 'error' ? (\n <div className=\"flex-1 min-w-0 flex flex-col items-center\">\n <NoContent\n icon=\"sicon-shopping-bag\"\n message={t('common.errors.error_occurred', 'Something went wrong')}\n />\n <button type=\"button\" className=\"link--primary mt-4\" onClick={retryFilters}>\n {t('common.elements.try_again', 'Try again')}\n </button>\n </div>\n ) : (\n <ItemsList<Product>\n key={`${listKey}-${selectedSort}${filteredKey}`}\n resetKey={`${listKey}-${selectedSort}${filteredKey}`}\n items={shownProducts}\n loader={loader}\n mode={shownNext ? 'infinite' : 'static'}\n pageUrl={location.pathname + location.searchStr}\n className=\"s-products-list flex-1 min-w-0\"\n itemsClassName={`s-products-list-wrapper s-products-list-vertical-cards${showFilters ? ' s-products-list-with-filters' : ''}`}\n skeleton={<ProductCardSkeleton />}\n skeletonType=\"item\"\n skeletonCount={12}\n empty={\n <NoContent\n icon=\"sicon-shopping-bag\"\n message={t(\n 'pages.categories.no_products',\n 'No products found in this category'\n )}\n />\n }\n t={(key, fallback) => t(key, fallback || key)}\n >\n {(items) =>\n items.map((prod, idx) => (\n <ProductCard\n key={prod.id}\n product={prod}\n index={idx}\n sizes={showFilters ? FILTERED_PRODUCT_IMAGE_SIZES : undefined}\n />\n ))\n }\n </ItemsList>\n )}\n </div>\n\n <HookSlot name=\"product:list.items.end\" />\n </div>\n </div>\n\n {showFilters && (\n <Drawer isOpen={filtersOpen} onClose={() => setFiltersOpen(false)} size=\"md\">\n <div className=\"p-4\">\n <div className=\"flex justify-between items-center mb-4\">\n <h3 className=\"font-bold text-lg\">{t('pages.categories.filters', 'Filters')}</h3>\n <button\n type=\"button\"\n onClick={() => setFiltersOpen(false)}\n className=\"btn--close-sm sicon-cancel text-gray-500\"\n />\n </div>\n <SallaFilters id=\"filters-menu-mobile\" filters={filters as any} />\n </div>\n </Drawer>\n )}\n\n {source.type === 'categories' && store?.settings?.category?.testimonial_enabled && (\n <RenderWhenVisible placeholder={<ReviewItemSkeleton />}>\n <Testimonials data={{}} />\n </RenderWhenVisible>\n )}\n\n <HookSlot name=\"product:list.end\" />\n </div>\n );\n}\n","import type { HeadDescriptor } from '../../utils/head';\nimport { buildHreflangAlternates } from '../../utils/baseHead';\nimport { productListLoader } from './loader';\nimport type { ProductListLoaderData, ProductListTag, Category } from './types';\nimport type { TwilightContext } from '../../twilight/context';\nimport { RouteId } from '../../router/route-ids';\nimport { ProductListPage } from './ProductListPage';\n\nexport function head(ctx: TwilightContext, data: ProductListLoaderData): HeadDescriptor {\n const entity = data.source.entity;\n const category = data.source.type === 'categories' ? (entity as Category | undefined) : undefined;\n const tag = data.source.type === 'tags' ? (entity as ProductListTag | undefined) : undefined;\n\n const canonical = category?.url ?? tag?.url;\n const title = category?.name ?? tag?.name ?? data.page.title;\n const image = category?.image ?? undefined;\n\n const base: HeadDescriptor = {\n title,\n description: `Browse ${title}`,\n canonical,\n openGraph: {\n type: 'website',\n title,\n description: `Browse ${title}`,\n images: image,\n url: canonical,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description: `Browse ${title}`,\n images: image,\n },\n alternateLanguages: buildHreflangAlternates(ctx.settings, canonical ?? ctx.location.pathname),\n };\n\n return base;\n}\n\nexport const ProductListing = {\n id: RouteId.PRODUCT_INDEX,\n loader: productListLoader,\n head,\n Component: ProductListPage,\n} as const;\n\nexport { ProductListPage };\nexport { productListLoader };\nexport { useAppliedFilters, parseFiltersFromSearch } from './useAppliedFilters';\nexport type { AppliedFiltersStatus } from './useAppliedFilters';\n\nexport type {\n ProductListLoaderData,\n ProductListLoaderParams,\n ProductListLoaderContext,\n ProductListSource,\n ProductListTag,\n ProductListEntity,\n ProductListPageMeta,\n ProductListSourceConfig,\n ProductListQuery,\n CategoryPageProps,\n} from './types';\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/routes/product-listing/loader.ts","../../src/routes/product-listing/useAppliedFilters.ts","../../src/routes/product-listing/ProductListPage.tsx","../../src/routes/product-listing/index.tsx"],"names":["i18n","useState","brand","useEffect","useCallback","category"],"mappings":"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","file":"product-listing.js","sourcesContent":["import type { ProductListLoaderData, ProductListLoaderContext, ProductListSource } from './types';\nimport type { ProductsListSource } from '../../api/product';\nimport { category } from '../../api/category';\nimport { product } from '../../api/product';\nimport { brand } from '../../api/brands';\nimport { notFound } from '../../providers/NavigationProvider';\nimport { getTwilightContext } from '../../twilight/context';\nimport { RouteId } from '../../router/route-ids';\n\nconst DEFAULT_SORT = 'ourSuggest';\n\nconst SOURCE_TO_API: Record<ProductListSource, ProductsListSource> = {\n categories: 'categories',\n latest: 'latest',\n sales: 'sales',\n offers: 'offers',\n search: 'search',\n tags: 'tags',\n brands: 'brands',\n};\n\nconst SOURCE_TITLE_KEY: Record<'latest' | 'sales' | 'offers', string> = {\n latest: 'blocks.home.latest_products',\n sales: 'common.titles.most_sales',\n offers: 'blocks.header.offers',\n};\n\nconst SOURCE_SLUG: Record<'latest' | 'sales' | 'offers', string> = {\n latest: 'latest-products',\n sales: 'most-sales-products',\n offers: 'offers',\n};\n\nexport async function productListLoader(\n ctx: ProductListLoaderContext\n): Promise<ProductListLoaderData> {\n const { params, search } = ctx;\n const cursor = search?.page ? String(search.page) : undefined;\n const sort = search?.sort ?? DEFAULT_SORT;\n\n const sourceType = params.source ?? (params.id ? 'categories' : undefined);\n\n if (!sourceType) {\n throw new Error('ProductList loader requires source type');\n }\n\n if (sourceType === 'categories' && params.id) {\n return loadCategoryProducts(params.id, cursor, sort);\n }\n\n if (sourceType === 'search') {\n const keyword = (search?.q ?? params.keyword ?? '').trim();\n return loadSearchProducts(keyword, cursor, sort);\n }\n\n if (sourceType === 'tags' && params.id) {\n return loadTagProducts(params.id, cursor, sort);\n }\n\n if (sourceType === 'brands' && params.id) {\n return loadBrandProducts(params.id, cursor, sort);\n }\n\n if (sourceType === 'latest' || sourceType === 'sales' || sourceType === 'offers') {\n return loadStaticProducts(\n sourceType as 'latest' | 'sales' | 'offers',\n params.title ?? '',\n params.slug ?? '',\n cursor,\n sort\n );\n }\n\n throw new Error(`Unknown source type: ${sourceType}`);\n}\n\n// ============================================================================\n// Source-Specific Loaders\n// ============================================================================\n\nasync function loadCategoryProducts(\n id: string,\n cursor: string | undefined,\n sort: string\n): Promise<ProductListLoaderData> {\n const { queryClient, i18n } = getTwilightContext();\n let categoryData, productsResult;\n try {\n [categoryData, productsResult] = await Promise.all([\n queryClient.fetchQuery(category.queries.detail(id)),\n queryClient.fetchQuery(\n product.queries.list({\n source: 'categories',\n sourceValue: id,\n cursor,\n sort,\n filterable: true,\n })\n ),\n ]);\n } catch {\n throw notFound();\n }\n\n if (!categoryData) throw notFound();\n\n return {\n page: {\n slug: RouteId.PRODUCT_INDEX,\n id,\n title: categoryData.name,\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: categoryData.name, url: categoryData.url },\n ],\n },\n source: { type: 'categories', value: id, entity: categoryData },\n query: { sort, filters: true },\n products: productsResult.items,\n pagination: {\n next: productsResult.next,\n },\n filters: productsResult.filters,\n };\n}\n\nasync function loadSearchProducts(\n keyword: string,\n cursor: string | undefined,\n sort: string\n): Promise<ProductListLoaderData> {\n if (!keyword) {\n const { i18n } = getTwilightContext();\n return {\n page: {\n slug: RouteId.SEARCH,\n title: i18n.t('common.titles.search') || 'Search Results',\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: i18n.t('common.titles.search') || 'Search Results', url: '/search' },\n ],\n },\n source: { type: 'search', value: '' },\n query: { sort, filters: true },\n products: [],\n pagination: { next: null },\n };\n }\n\n const { queryClient, i18n } = getTwilightContext();\n const productsResult = await queryClient.fetchQuery(\n product.queries.list({\n source: 'search',\n sourceValue: keyword,\n cursor,\n sort,\n filterable: true,\n })\n );\n\n return {\n page: {\n slug: RouteId.SEARCH,\n title: keyword,\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: keyword, url: '/search' },\n ],\n },\n source: { type: 'search', value: keyword },\n query: { sort, filters: true },\n products: productsResult.items,\n pagination: {\n next: productsResult.next,\n },\n filters: productsResult.filters,\n };\n}\n\nasync function loadTagProducts(\n id: string,\n cursor: string | undefined,\n sort: string\n): Promise<ProductListLoaderData> {\n const { queryClient, i18n } = getTwilightContext();\n const productsResult = await queryClient.fetchQuery(\n product.queries.list({\n source: 'tags',\n sourceValue: id,\n cursor,\n sort,\n })\n );\n\n const tagFromProduct = productsResult.items[0]?.tags?.find((t) => String(t.id) === id);\n if (!tagFromProduct) throw notFound();\n\n const tag = { id: Number(tagFromProduct.id), name: tagFromProduct.name, url: tagFromProduct.url };\n\n return {\n page: {\n slug: RouteId.PRODUCT_INDEX_TAG,\n id,\n title: tag.name,\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: tag.name, url: tag.url },\n ],\n },\n source: { type: 'tags', value: id, entity: tag },\n query: { sort, filters: false },\n products: productsResult.items,\n pagination: {\n next: productsResult.next,\n },\n };\n}\n\nasync function loadBrandProducts(\n id: string,\n cursor: string | undefined,\n sort: string\n): Promise<ProductListLoaderData> {\n const { queryClient, i18n } = getTwilightContext();\n let brandData, productsResult;\n try {\n [brandData, productsResult] = await Promise.all([\n queryClient.fetchQuery(brand.queries.detail(id)),\n queryClient.fetchQuery(\n product.queries.list({\n source: 'brands',\n sourceValue: id,\n cursor,\n sort,\n })\n ),\n ]);\n } catch {\n throw notFound();\n }\n\n if (!brandData) throw notFound();\n\n return {\n page: {\n slug: RouteId.BRANDS_INDEX,\n id,\n title: brandData.name,\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: brandData.name, url: brandData.url },\n ],\n },\n source: { type: 'brands', value: id, entity: brandData },\n query: { sort, filters: false },\n products: productsResult.items,\n pagination: {\n next: productsResult.next,\n },\n };\n}\n\nconst SOURCE_ROUTE_ID: Record<'latest' | 'sales' | 'offers', string> = {\n latest: RouteId.PRODUCT_INDEX_LATEST,\n sales: RouteId.PRODUCT_INDEX_SALES,\n offers: RouteId.PRODUCT_INDEX_OFFERS,\n};\n\nasync function loadStaticProducts(\n source: 'latest' | 'sales' | 'offers',\n title: string,\n slug: string,\n cursor: string | undefined,\n sort: string\n): Promise<ProductListLoaderData> {\n const { queryClient, i18n } = getTwilightContext();\n const resolvedTitle = title || i18n.t(SOURCE_TITLE_KEY[source]);\n const resolvedSlug = slug || SOURCE_SLUG[source];\n const productsResult = await queryClient.fetchQuery(\n product.queries.list({\n source: SOURCE_TO_API[source],\n cursor,\n sort,\n })\n );\n\n return {\n page: {\n slug: SOURCE_ROUTE_ID[source],\n title: resolvedTitle,\n breadcrumbs: [\n { name: i18n.t('common.titles.home'), url: '/' },\n { name: resolvedTitle, url: `/${resolvedSlug}` },\n ],\n },\n source: { type: source },\n query: { sort, filters: false },\n products: productsResult.items,\n pagination: {\n next: productsResult.next,\n },\n };\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { product } from '../../api/product';\nimport type { ProductListFilters } from '../../api/product';\nimport type { Product } from '../../types';\nimport type { ProductListLoaderData } from './types';\n\ntype Source = ProductListLoaderData['source'];\ntype Node = Record<string, unknown>;\n\n/** Path segments that would reach the shared prototype chain if used as object keys. */\nconst UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n/**\n * Reads the `filters[...]` selection `<salla-filters>` writes to the address bar\n * (`filters[k]=v`, `filters[k][]=v`, `filters[k][sub]=v`) back into an object, so a\n * filtered link can be opened directly.\n *\n * The keys come straight from the URL, so nodes are null-prototype objects and any\n * `__proto__` / `constructor` / `prototype` segment drops the whole entry — a crafted\n * `?filters[__proto__][x]=1` must never reach `Object.prototype`.\n */\nexport function parseFiltersFromSearch(search: string): ProductListFilters | null {\n const out: Node = Object.create(null);\n new URLSearchParams(search).forEach((value, rawKey) => {\n if (!rawKey.startsWith('filters[')) return;\n const path = [...rawKey.matchAll(/\\[([^\\]]*)\\]/g)].map((m) => m[1]);\n const isList = path[path.length - 1] === '';\n const keys = isList ? path.slice(0, -1) : path;\n if (!keys.length || keys.includes('') || keys.some((key) => UNSAFE_KEYS.has(key))) return;\n\n let node = out;\n keys.slice(0, -1).forEach((key) => {\n const existing = node[key];\n if (typeof existing !== 'object' || existing === null || Array.isArray(existing)) {\n node[key] = Object.create(null);\n }\n node = node[key] as Node;\n });\n const leaf = keys[keys.length - 1];\n if (isList) {\n node[leaf] = [...(Array.isArray(node[leaf]) ? (node[leaf] as string[]) : []), value];\n } else {\n node[leaf] = value;\n }\n });\n return Object.keys(out).length ? (out as ProductListFilters) : null;\n}\n\ninterface FilteredPage {\n items: Product[];\n next: string | null;\n}\n\nexport type AppliedFiltersStatus = 'idle' | 'loading' | 'ready' | 'error';\n\n/**\n * Applies the `<salla-filters>` selection to the product list.\n *\n * The filters component only rewrites the address bar (`history.pushState`, invisible\n * to the router) and emits `salla-filters::changed`; nothing re-queries the list, so\n * the route's loader output — fetched without filters — kept showing. This listens\n * for that event (and for a filtered URL on first load) and fetches the first page\n * with the selection.\n *\n * Each fetched page is stored with the selection that produced it, so `page` is only\n * ever the page for the *current* selection. Until it arrives `status` is `loading`\n * (and `lastPage` is the previous selection's page, for a dimmed placeholder); if the\n * request fails `status` is `error` and `retry` re-runs it — the old products never\n * pass for the new selection.\n */\nexport function useAppliedFilters(\n source: Source,\n sort: string,\n enabled: boolean\n): {\n filters: ProductListFilters | null;\n page: FilteredPage | null;\n lastPage: FilteredPage | null;\n status: AppliedFiltersStatus;\n retry: () => void;\n} {\n const [filters, setFilters] = useState<ProductListFilters | null>(null);\n const [result, setResult] = useState<{ key: string; page: FilteredPage } | null>(null);\n const [failedKey, setFailedKey] = useState<string | null>(null);\n const [attempt, setAttempt] = useState(0);\n\n useEffect(() => {\n if (!enabled) return;\n setFilters(parseFiltersFromSearch(window.location.search));\n const sdk = window.salla;\n if (!sdk?.event) return;\n const onChanged = (...args: unknown[]) => {\n const next = args[0] as ProductListFilters | undefined;\n setFilters(next && Object.keys(next).length ? { ...next } : null);\n };\n sdk.event.on('salla-filters::changed', onChanged);\n return () => sdk.event.off('salla-filters::changed', onChanged);\n }, [enabled, source.type, source.value]);\n\n const key = filters ? JSON.stringify([source.type, source.value, sort, filters]) : '';\n\n useEffect(() => {\n if (!filters) return;\n const controller = new AbortController();\n setFailedKey(null);\n product\n .list({\n source: source.type,\n sourceValue: source.value,\n sort,\n filterable: true,\n filters,\n signal: controller.signal,\n })\n .then((res) => setResult({ key, page: { items: res.items, next: res.next } }))\n .catch(() => {\n // Aborted by a newer selection (its own effect run owns the state now), or failed.\n if (!controller.signal.aborted) setFailedKey(key);\n });\n return () => controller.abort();\n // `key` already encodes filters + source + sort.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [key, attempt]);\n\n const retry = useCallback(() => setAttempt((n) => n + 1), []);\n\n if (!filters) return { filters: null, page: null, lastPage: null, status: 'idle', retry };\n\n const page = result?.key === key ? result.page : null;\n const status: AppliedFiltersStatus = page ? 'ready' : failedKey === key ? 'error' : 'loading';\n return { filters, page, lastPage: result?.page ?? null, status, retry };\n}\n","import { useState, useRef, useEffect, useMemo, useCallback } from 'react';\nimport { HookSlot, useStore } from '../../hooks';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { useNavigate, useLocation } from '../../providers/NavigationProvider';\nimport { useTwilight } from '../../providers/TwilightProvider';\nimport { sortOptions } from '../../utils/sort-options';\nimport { Drawer } from '../../components/drawer';\nimport { Breadcrumb } from '../../components/common';\nimport { SallaFilters } from '@salla.sa/twilight-components-react/filters';\nimport { ItemsList, ReviewItemSkeleton } from '@salla.sa/twilight-components-react';\nimport { Testimonials } from '../../components/home';\nimport { ProductCard } from '../../components/product';\nimport { NoContent, ProductCardSkeleton, Image, RenderWhenVisible } from '../../components/common';\nimport { product } from '../../api/product';\nimport { useAppliedFilters } from './useAppliedFilters';\nimport type { ProductListLoaderData } from './types';\nimport type { Brand } from '../brands/types';\nimport type { Product } from '../../types';\n\n/** 3-col + 288px sidebar from md; 3-col of the full container below md. */\nconst FILTERED_PRODUCT_IMAGE_SIZES = '(min-width: 768px) 25vw, 33vw';\n\n/**\n * Product List Page - Unified component for all product listing pages\n *\n * Handles:\n * - Category pages (with filters, category entity, testimonials)\n * - Search pages (keyword display, product count)\n * - Tag pages (tag entity)\n * - Brand pages (brand entity with banner/logo)\n * - Static listings (latest, sales, offers)\n */\nexport function ProductListPage({\n page,\n source,\n query,\n products,\n pagination,\n filters,\n}: ProductListLoaderData) {\n const { t } = useTranslation();\n const store = useStore();\n const { theme } = useTwilight();\n const navigate = useNavigate();\n // Sort is now SSR-driven, no local state needed\n const selectedSort = query.sort;\n const [filtersOpen, setFiltersOpen] = useState(false);\n\n // Determine filters visibility\n const showFilters = query.filters && store?.settings?.product?.filters;\n // const isSearch = source.type === 'search';\n const isBrand = source.type === 'brands';\n const brand = isBrand ? (source.entity as Brand | undefined) : null;\n\n // Generate sort options with translations\n const sortOptionsWithTrans = useMemo(() => sortOptions(selectedSort, t), [selectedSort, t]);\n\n // Get location from hook for consistent URL handling\n const location = useLocation();\n\n // Re-query the list with the selection made in `<salla-filters>`: the component only\n // rewrites the address bar and emits `salla-filters::changed`, and the route's loader\n // output was fetched without it.\n const {\n filters: appliedFilters,\n page: filteredPage,\n lastPage,\n status: filterStatus,\n retry: retryFilters,\n } = useAppliedFilters(source, selectedSort, !!showFilters);\n // While the new selection loads, the previous page stays up (dimmed, `aria-busy`); if\n // the request fails nothing stale passes for the new selection. Infinite scroll is only\n // live for the loader's own page or a fully loaded filtered one.\n const shownPage = filterStatus === 'ready' ? filteredPage : lastPage;\n const shownProducts =\n filterStatus === 'error'\n ? []\n : filterStatus === 'idle'\n ? products\n : (shownPage?.items ?? products);\n const shownNext =\n filterStatus === 'idle'\n ? pagination?.next\n : filterStatus === 'ready'\n ? filteredPage?.next\n : null;\n const filteredKey =\n filterStatus === 'idle'\n ? ''\n : `-${filterStatus}${filterStatus === 'ready' ? JSON.stringify(appliedFilters) : ''}`;\n\n // Listen for filters changed event to close drawer\n useEffect(() => {\n const handleFiltersChanged = () => setFiltersOpen(false);\n const sdk = window.salla;\n if (typeof sdk === 'undefined') return;\n\n sdk.event.on('salla-filters::changed', handleFiltersChanged);\n\n return () => {\n sdk.event.off('salla-filters::changed', handleFiltersChanged);\n };\n }, []);\n\n // Handle sort change - use client-side navigation to trigger route loader re-run\n const handleSortChange = useCallback(\n (event: React.ChangeEvent<HTMLSelectElement>) => {\n const newSort = event.target.value;\n\n const params = new URLSearchParams(location.searchStr);\n params.set('sort', newSort);\n params.delete('page'); // clear any cursor token from URL on sort change\n\n // Use client-side navigation to trigger route loader re-execution (SSR-like).\n // Built from the router's location rather than `window.location`: on a host\n // where the store is the root, the address bar carries the store segment and\n // `navigate` would add it a second time.\n navigate(`${location.pathname}?${params.toString()}`);\n },\n [navigate, location.pathname, location.searchStr]\n );\n\n // Key for remounting products list\n const listKey = source.value ?? source.type;\n\n // Track cursor for the next page — initialized from SSR pagination response.\n // On sort change the key prop remounts ItemsList and this effect resets the cursor.\n const nextCursorRef = useRef<string | null>(shownNext ?? null);\n useEffect(() => {\n nextCursorRef.current = shownNext ?? null;\n }, [shownNext]);\n\n const loader = useCallback(async () => {\n const nextUrl = nextCursorRef.current;\n // Extract the cursor token from the next URL provided by the previous response\n const cursorMatch = nextUrl?.match(/[?&]cursor=([^&]+)/);\n const cursor = cursorMatch ? decodeURIComponent(cursorMatch[1]) : (nextUrl ?? undefined);\n\n const result = await product.list({\n source: source.type,\n sourceValue: source.value,\n ...(cursor && { cursor }),\n sort: selectedSort,\n ...(appliedFilters && { filterable: true, filters: appliedFilters }),\n });\n\n nextCursorRef.current = result.next;\n\n return result;\n }, [source.type, source.value, selectedSort, appliedFilters]);\n\n return (\n <div key={listKey} className=\"container px-2.5 ms:px-5 mb-10\">\n {theme?.settings?.product_index_show_breadcrumbs !== false && <Breadcrumb page={page} />}\n\n {isBrand && brand && (\n <>\n <Image\n width={1200}\n height={300}\n className=\"w-full max-h-[300px] object-cover rounded-md bg-gray-100\"\n src={brand.banner || undefined}\n alt={brand.name}\n priority\n />\n <header className=\"flex flex-col md:flex-row items-center md:items-start text-center rtl:md:text-right ltr:md:text-left mt-2 mb-8\">\n <Image\n className=\"rounded-md w-40 h-24 object-contain shadow-md p-4 bg-white shrink-0\"\n src={brand.logo || undefined}\n alt={brand.name}\n aspectRatio=\"5/3\"\n />\n <div className=\"px-5 pt-3 rtl:text-right\">\n <h1 className=\"text-2xl font-bold mb-1\">{brand.name}</h1>\n {brand.description && (\n <p\n className=\"text-base text-gray-500 font-medium\"\n dangerouslySetInnerHTML={{ __html: brand.description }}\n />\n )}\n </div>\n </header>\n </>\n )}\n\n <HookSlot name=\"product:list.start\" />\n\n <div className={showFilters ? 'md:grid md:grid-cols-[288px_1fr] gap-8' : ''}>\n {/* <FiltersSkeleton></FiltersSkeleton> */}\n {showFilters && (\n <SallaFilters\n id=\"filters-menu\"\n className=\"hidden md:block lg:sticky lg:top-20\"\n filters={filters as any}\n />\n )}\n\n <div className=\"min-w-0\">\n <div className=\"mb-4 sm:mb-6 flex justify-between items-center\">\n <h1 className=\"font-bold text-xl rtl:pl-3 ltr:pr-3\" id=\"page-main-title\">\n {isBrand ? t('common.titles.products') : page.title}\n </h1>\n\n <div className=\"flex items-center space-x-2 rtl:space-x-reverse\">\n {showFilters && (\n <button\n type=\"button\"\n onClick={() => setFiltersOpen(true)}\n className=\"filters-trigger bg-border-color text-primary lg:hidden p-2 rounded\"\n >\n <i className=\"sicon-filter text-gray-text text-2xl\" />\n </button>\n )}\n\n {sortOptionsWithTrans.length > 0 && (\n <div className=\"flex items-center\">\n <label\n className=\"hidden sm:block rtl:ml-3 ltr:mr-3 whitespace-nowrap\"\n htmlFor=\"product-sort\"\n >\n {t('pages.categories.sorting', 'Sort By')}\n </label>\n <select\n id=\"product-sort\"\n className=\"form-input pt-0 pb-1 rtl:md:pl-10 ltr:md:pr-10\"\n value={selectedSort}\n onChange={handleSortChange}\n >\n {sortOptionsWithTrans.map((option) => (\n <option key={option.id} value={option.id}>\n {option.name}\n </option>\n ))}\n </select>\n </div>\n )}\n </div>\n </div>\n\n <HookSlot name=\"product:list.items.start\" />\n\n <div\n className={`flex min-h-screen${filterStatus === 'loading' ? ' opacity-60' : ''}`}\n aria-busy={filterStatus === 'loading'}\n >\n {filterStatus === 'error' ? (\n <div className=\"flex-1 min-w-0 flex flex-col items-center\">\n <NoContent\n icon=\"sicon-shopping-bag\"\n message={t('common.errors.error_occurred', 'Something went wrong')}\n />\n <button type=\"button\" className=\"link--primary mt-4\" onClick={retryFilters}>\n {t('common.elements.try_again', 'Try again')}\n </button>\n </div>\n ) : (\n <ItemsList<Product>\n key={`${listKey}-${selectedSort}${filteredKey}`}\n resetKey={`${listKey}-${selectedSort}${filteredKey}`}\n items={shownProducts}\n loader={loader}\n mode={shownNext ? 'infinite' : 'static'}\n pageUrl={location.pathname + location.searchStr}\n className=\"s-products-list flex-1 min-w-0\"\n itemsClassName={`s-products-list-wrapper s-products-list-vertical-cards${showFilters ? ' s-products-list-with-filters' : ''}`}\n skeleton={<ProductCardSkeleton />}\n skeletonType=\"item\"\n skeletonCount={12}\n empty={\n <NoContent\n icon=\"sicon-shopping-bag\"\n message={t(\n 'pages.categories.no_products',\n 'No products found in this category'\n )}\n />\n }\n t={(key, fallback) => t(key, fallback || key)}\n >\n {(items) =>\n items.map((prod, idx) => (\n <ProductCard\n key={prod.id}\n product={prod}\n index={idx}\n sizes={showFilters ? FILTERED_PRODUCT_IMAGE_SIZES : undefined}\n />\n ))\n }\n </ItemsList>\n )}\n </div>\n\n <HookSlot name=\"product:list.items.end\" />\n </div>\n </div>\n\n {showFilters && (\n <Drawer isOpen={filtersOpen} onClose={() => setFiltersOpen(false)} size=\"md\">\n <div className=\"p-4\">\n <div className=\"flex justify-between items-center mb-4\">\n <h3 className=\"font-bold text-lg\">{t('pages.categories.filters', 'Filters')}</h3>\n <button\n type=\"button\"\n onClick={() => setFiltersOpen(false)}\n className=\"btn--close-sm sicon-cancel text-gray-500\"\n />\n </div>\n <SallaFilters id=\"filters-menu-mobile\" filters={filters as any} />\n </div>\n </Drawer>\n )}\n\n {source.type === 'categories' && store?.settings?.category?.testimonial_enabled && (\n <RenderWhenVisible placeholder={<ReviewItemSkeleton />}>\n <Testimonials data={{}} />\n </RenderWhenVisible>\n )}\n\n <HookSlot name=\"product:list.end\" />\n </div>\n );\n}\n","import type { HeadDescriptor } from '../../utils/head';\nimport { buildHreflangAlternates } from '../../utils/baseHead';\nimport { productListLoader } from './loader';\nimport type { ProductListLoaderData, ProductListTag, Category } from './types';\nimport type { TwilightContext } from '../../twilight/context';\nimport { RouteId } from '../../router/route-ids';\nimport { ProductListPage } from './ProductListPage';\n\nexport function head(ctx: TwilightContext, data: ProductListLoaderData): HeadDescriptor {\n const entity = data.source.entity;\n const category = data.source.type === 'categories' ? (entity as Category | undefined) : undefined;\n const tag = data.source.type === 'tags' ? (entity as ProductListTag | undefined) : undefined;\n\n const canonical = category?.url ?? tag?.url;\n const title = category?.name ?? tag?.name ?? data.page.title;\n const image = category?.image ?? undefined;\n\n const base: HeadDescriptor = {\n title,\n description: `Browse ${title}`,\n canonical,\n openGraph: {\n type: 'website',\n title,\n description: `Browse ${title}`,\n images: image,\n url: canonical,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description: `Browse ${title}`,\n images: image,\n },\n alternateLanguages: buildHreflangAlternates(ctx.settings, canonical ?? ctx.location.pathname),\n };\n\n return base;\n}\n\nexport const ProductListing = {\n id: RouteId.PRODUCT_INDEX,\n loader: productListLoader,\n head,\n Component: ProductListPage,\n} as const;\n\nexport { ProductListPage };\nexport { productListLoader };\nexport { useAppliedFilters, parseFiltersFromSearch } from './useAppliedFilters';\nexport type { AppliedFiltersStatus } from './useAppliedFilters';\n\nexport type {\n ProductListLoaderData,\n ProductListLoaderParams,\n ProductListLoaderContext,\n ProductListSource,\n ProductListTag,\n ProductListEntity,\n ProductListPageMeta,\n ProductListSourceConfig,\n ProductListQuery,\n CategoryPageProps,\n} from './types';\n"]}
|
package/dist/routes/product.js
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import { buildHreflangAlternates } from '../chunk-TZ3E5BN4.js';
|
|
2
|
-
import { ProductsSlider, LazyTestimonials } from '../chunk-
|
|
3
|
-
import { product } from '../chunk-
|
|
4
|
-
import { ProductGallery, LazyProductDetails, LazyAddToCartForm } from '../chunk-
|
|
2
|
+
import { ProductsSlider, LazyTestimonials } from '../chunk-7BWZYECG.js';
|
|
3
|
+
import { product } from '../chunk-3R7YKSO6.js';
|
|
4
|
+
import { ProductGallery, LazyProductDetails, LazyAddToCartForm } from '../chunk-WFSOVIYU.js';
|
|
5
5
|
import '../chunk-342EPVXN.js';
|
|
6
|
-
import '../chunk-
|
|
7
|
-
import '../chunk-
|
|
6
|
+
import { fastCheckoutScript } from '../chunk-36PDYP56.js';
|
|
7
|
+
import '../chunk-J2GGMK3X.js';
|
|
8
8
|
import '../chunk-JKIRRMBU.js';
|
|
9
9
|
import '../chunk-2JV6WZ6O.js';
|
|
10
|
-
import '../chunk-
|
|
11
|
-
import '../chunk-3MHDV5JS.js';
|
|
10
|
+
import '../chunk-YNY5P2DG.js';
|
|
12
11
|
import '../chunk-VVZNW5CB.js';
|
|
13
|
-
import '../chunk-
|
|
14
|
-
import '../chunk-
|
|
12
|
+
import '../chunk-KTOKX3GC.js';
|
|
13
|
+
import '../chunk-JDROOL5C.js';
|
|
15
14
|
import { RouteId } from '../chunk-TFB3QXYH.js';
|
|
16
15
|
import '../chunk-C5X6CVXC.js';
|
|
17
|
-
import '../chunk-
|
|
18
|
-
import '../chunk-
|
|
19
|
-
import '../chunk-
|
|
20
|
-
import '../chunk-
|
|
16
|
+
import '../chunk-UOALND7V.js';
|
|
17
|
+
import '../chunk-YSFWVMBA.js';
|
|
18
|
+
import '../chunk-F4MMWEII.js';
|
|
19
|
+
import '../chunk-TX6ZP4FF.js';
|
|
21
20
|
import '../chunk-XTMHHLNK.js';
|
|
22
|
-
import { getTwilightContext } from '../chunk-
|
|
21
|
+
import { getTwilightContext } from '../chunk-SOPK72TP.js';
|
|
23
22
|
import '../chunk-TP3LCGE7.js';
|
|
24
23
|
import '../chunk-Z653O7MX.js';
|
|
25
24
|
import '../chunk-ZCH7W7DZ.js';
|
|
@@ -35,7 +34,7 @@ import { useComments } from '../chunk-YMVLYYLU.js';
|
|
|
35
34
|
import '../chunk-RJPPO3ET.js';
|
|
36
35
|
import { HookSlot } from '../chunk-Q7VWURUR.js';
|
|
37
36
|
import '../chunk-GU2KUQVD.js';
|
|
38
|
-
import { LazyBreadcrumb, LazyRenderWhenVisible } from '../chunk-
|
|
37
|
+
import { LazyBreadcrumb, LazyRenderWhenVisible } from '../chunk-JBNI5ZVG.js';
|
|
39
38
|
import '../chunk-AXW67SY7.js';
|
|
40
39
|
import '../chunk-BYMOPN2S.js';
|
|
41
40
|
import '../chunk-SKLEJJ6M.js';
|
|
@@ -215,7 +214,11 @@ function head(ctx, data) {
|
|
|
215
214
|
images: product2.image?.url
|
|
216
215
|
},
|
|
217
216
|
jsonLd,
|
|
218
|
-
alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname)
|
|
217
|
+
alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),
|
|
218
|
+
// Quick-buy widget code, eager only here: the Buy Now button is above the fold on this page.
|
|
219
|
+
// Other routes load it on idle from the body:end default hook, which also owns the
|
|
220
|
+
// `#fast-checkout-js` marker `salla-add-product-button` checks for.
|
|
221
|
+
scripts: ctx.settings?.store?.settings?.buy_now ? [fastCheckoutScript()] : []
|
|
219
222
|
};
|
|
220
223
|
return base;
|
|
221
224
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/routes/product/loader.ts","../../src/routes/product/ProductPage.tsx","../../src/routes/product/index.tsx"],"names":["product"],"mappings":"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","file":"product.js","sourcesContent":["import type { ProductPageProps } from './types';\nimport type { IdParams } from '../types';\nimport { product } from '../../api/product';\nimport { getTwilightContext } from '../../twilight/context';\nimport { RouteId } from '../../router/route-ids';\nimport type { Breadcrumb } from '../../types';\n\nexport async function productLoader({ params }: { params: IdParams }): Promise<ProductPageProps> {\n const data = await product.findOrThrow(params.id);\n const i18n = getTwilightContext().i18n;\n const home: Breadcrumb = { name: i18n.t('common.titles.home'), url: '/' };\n\n const breadcrumbs: Breadcrumb[] = [home];\n if (data.category) {\n breadcrumbs.push({ name: data.category.name, url: data.category.url });\n }\n breadcrumbs.push({ name: data.name, url: data.url });\n\n const page = {\n slug: RouteId.PRODUCT_SINGLE,\n id: data.id,\n title: data.name,\n url: data.url,\n parent:\n data.category && data.category.id\n ? { id: data.category.id, name: data.category.name, url: data.category.url }\n : null,\n breadcrumbs,\n };\n\n return {\n page,\n product: data,\n };\n}\n","import { SallaQuickOrder } from '@salla.sa/twilight-components-react/quick-order';\nimport { SallaOffer } from '@salla.sa/twilight-components-react/offer';\nimport { SallaComments } from '@salla.sa/twilight-components-react/comments';\nimport { HookSlot } from '../../hooks';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { useProduct } from '../../hooks/useProduct';\nimport { useComments } from '../../hooks/useComments';\nimport type { ProductPageProps } from './types';\nimport { Breadcrumb, RenderWhenVisible } from '../../components/common';\nimport { ProductDetails, AddToCartForm, ProductGallery } from '../../components/product';\nimport { ProductsSlider, Testimonials } from '../../components/home';\nimport { useTwilight } from '../../providers/twilight-context';\n\nexport function ProductPage({ product: initialProduct, page }: ProductPageProps) {\n const { theme, store } = useTwilight();\n const { t } = useTranslation();\n const { product } = useProduct(initialProduct);\n const { commentsKey } = useComments();\n\n return (\n <div key={product.id}>\n <div className=\"container\">\n {theme?.settings?.product_show_breadcrumbs !== false && <Breadcrumb page={page} />}\n\n <HookSlot name=\"product:start\" />\n\n <div className=\"flex flex-col items-start md:flex-row\" id={`product-${product.id}`}>\n <ProductGallery product={product} />\n\n <div className=\"main-content md:sticky md:overflow-hidden top-24 w-full md:w-2/4 md:pb-16\">\n <HookSlot name=\"product:details.start\" />\n <HookSlot name=\"product:single.description.start\" />\n <ProductDetails product={product} showTags={theme.settings.show_tags} />\n <HookSlot name=\"product:single.description\" />\n <HookSlot name=\"product:single.description.end\" />\n <HookSlot name=\"product:details.end\" />\n\n <HookSlot name=\"product:single.form.start\" />\n <AddToCartForm product={product} stickyAddToCart={theme.settings.sticky_add_to_cart} />\n <HookSlot name=\"product:single.form.end\" />\n\n <SallaQuickOrder className=\"mt-5 md:-mb-2 block\" />\n </div>\n </div>\n\n <SallaOffer />\n </div>\n\n {store.settings?.rating?.show_on_product && (\n <RenderWhenVisible>\n <SallaComments key={commentsKey} itemId={product.id} type={'product' as any} />\n </RenderWhenVisible>\n )}\n\n <HookSlot name=\"product:related.start\" />\n <RenderWhenVisible>\n <div className=\"container\">\n <ProductsSlider\n data={{\n products: { source: 'related', source_value: product.id },\n title: t('pages.products.similar_products'),\n display_all_url: '',\n }}\n />\n </div>\n </RenderWhenVisible>\n <HookSlot name=\"product:related.end\" />\n\n <RenderWhenVisible>\n <div className=\"container\">\n <Testimonials data={{}} />\n </div>\n </RenderWhenVisible>\n\n <HookSlot name=\"product:end\" />\n </div>\n );\n}\n","import type { HeadDescriptor } from '../../utils/head';\nimport { buildHreflangAlternates } from '../../utils/baseHead';\nimport type { ProductPageProps } from './types';\nimport type { IdParams } from '../types';\nimport type { TwilightContext } from '../../twilight/context';\nimport { productLoader } from './loader';\nimport { RouteId } from '../../router/route-ids';\nimport { ProductPage } from './ProductPage';\nexport { productLoader } from './loader';\nexport type { ProductPageProps } from './types';\n\nasync function loader(\n ctx: { params: IdParams; locale?: string },\n extend?: (\n data: ProductPageProps,\n ctx: { params: IdParams }\n ) => Promise<Record<string, unknown>> | Record<string, unknown>\n): Promise<ProductPageProps> {\n const data = await productLoader({ params: ctx.params });\n\n if (extend) {\n const extra = await extend(data, ctx);\n return { ...data, ...extra } as ProductPageProps;\n }\n return data;\n}\n\nfunction head(ctx: TwilightContext, data: ProductPageProps): HeadDescriptor {\n if (!data?.product) {\n return {\n title: 'Products',\n description: 'Browse our products',\n };\n }\n const product = data.product;\n const storeName = ctx.settings?.store?.name ?? '';\n\n // Strip HTML and limit description to 160 chars\n const description = product.description?.replace(/<[^>]*>/g, '').slice(0, 160) ?? '';\n\n // Price valid until: 1 month from now\n const priceValidUntil = new Date();\n priceValidUntil.setMonth(priceValidUntil.getMonth() + 1);\n\n // Collect all product images\n const images = product.images?.map((img) => img.url).filter(Boolean) ?? [];\n if (product.image?.url && !images.includes(product.image.url)) {\n images.unshift(product.image.url);\n }\n\n // Build JSON-LD schema matching SchemaProductWidget.php\n const jsonLd: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': 'Product',\n name: product.name,\n description,\n sku: product.sku,\n image: images.length > 0 ? images : undefined,\n offers: {\n '@type': 'Offer',\n url: product.url,\n availability: product.is_available\n ? 'https://schema.org/InStock'\n : 'https://schema.org/OutOfStock',\n price: product.sale_price,\n priceCurrency: product.currency,\n priceValidUntil: priceValidUntil.toISOString().split('T')[0],\n seller: storeName\n ? {\n '@type': 'Organization',\n name: storeName,\n }\n : undefined,\n },\n };\n\n // Add brand if exists\n if (product.brand) {\n jsonLd.brand = {\n '@type': 'Brand',\n name: product.brand.name,\n description: product.brand.description,\n logo: product.brand.logo,\n };\n }\n\n // Add aggregateRating and review if rating exists\n if (product.rating && product.rating.count > 0) {\n const ratingValue = product.rating.stars;\n jsonLd.aggregateRating = {\n '@type': 'AggregateRating',\n ratingCount: product.rating.count,\n ratingValue,\n };\n jsonLd.review = {\n '@type': 'Review',\n author: storeName\n ? {\n '@type': 'Organization',\n name: storeName,\n }\n : undefined,\n reviewRating: {\n '@type': 'Rating',\n bestRating: 5,\n ratingValue,\n },\n };\n }\n\n if (product.gtin && product.gtin.length === 8) {\n jsonLd.gtin8 = product.gtin;\n }\n\n if (product.mpn) {\n jsonLd.mpn = product.mpn;\n }\n\n const base: HeadDescriptor = {\n title: product.name,\n description,\n canonical: product.url,\n openGraph: {\n type: 'product',\n title: product.name,\n description,\n images: product.image?.url,\n url: product.url,\n },\n twitter: {\n card: 'summary_large_image',\n title: product.name,\n description,\n images: product.image?.url,\n },\n jsonLd,\n alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),\n };\n\n return base;\n}\n\nexport const Product = {\n id: RouteId.PRODUCT_SINGLE,\n loader,\n head,\n Component: ProductPage,\n} as const;\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/routes/product/loader.ts","../../src/routes/product/ProductPage.tsx","../../src/routes/product/index.tsx"],"names":["product"],"mappings":"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","file":"product.js","sourcesContent":["import type { ProductPageProps } from './types';\nimport type { IdParams } from '../types';\nimport { product } from '../../api/product';\nimport { getTwilightContext } from '../../twilight/context';\nimport { RouteId } from '../../router/route-ids';\nimport type { Breadcrumb } from '../../types';\n\nexport async function productLoader({ params }: { params: IdParams }): Promise<ProductPageProps> {\n const data = await product.findOrThrow(params.id);\n const i18n = getTwilightContext().i18n;\n const home: Breadcrumb = { name: i18n.t('common.titles.home'), url: '/' };\n\n const breadcrumbs: Breadcrumb[] = [home];\n if (data.category) {\n breadcrumbs.push({ name: data.category.name, url: data.category.url });\n }\n breadcrumbs.push({ name: data.name, url: data.url });\n\n const page = {\n slug: RouteId.PRODUCT_SINGLE,\n id: data.id,\n title: data.name,\n url: data.url,\n parent:\n data.category && data.category.id\n ? { id: data.category.id, name: data.category.name, url: data.category.url }\n : null,\n breadcrumbs,\n };\n\n return {\n page,\n product: data,\n };\n}\n","import { SallaQuickOrder } from '@salla.sa/twilight-components-react/quick-order';\nimport { SallaOffer } from '@salla.sa/twilight-components-react/offer';\nimport { SallaComments } from '@salla.sa/twilight-components-react/comments';\nimport { HookSlot } from '../../hooks';\nimport { useTranslation } from '../../providers/I18nProvider';\nimport { useProduct } from '../../hooks/useProduct';\nimport { useComments } from '../../hooks/useComments';\nimport type { ProductPageProps } from './types';\nimport { Breadcrumb, RenderWhenVisible } from '../../components/common';\nimport { ProductDetails, AddToCartForm, ProductGallery } from '../../components/product';\nimport { ProductsSlider, Testimonials } from '../../components/home';\nimport { useTwilight } from '../../providers/twilight-context';\n\nexport function ProductPage({ product: initialProduct, page }: ProductPageProps) {\n const { theme, store } = useTwilight();\n const { t } = useTranslation();\n const { product } = useProduct(initialProduct);\n const { commentsKey } = useComments();\n\n return (\n <div key={product.id}>\n <div className=\"container\">\n {theme?.settings?.product_show_breadcrumbs !== false && <Breadcrumb page={page} />}\n\n <HookSlot name=\"product:start\" />\n\n <div className=\"flex flex-col items-start md:flex-row\" id={`product-${product.id}`}>\n <ProductGallery product={product} />\n\n <div className=\"main-content md:sticky md:overflow-hidden top-24 w-full md:w-2/4 md:pb-16\">\n <HookSlot name=\"product:details.start\" />\n <HookSlot name=\"product:single.description.start\" />\n <ProductDetails product={product} showTags={theme.settings.show_tags} />\n <HookSlot name=\"product:single.description\" />\n <HookSlot name=\"product:single.description.end\" />\n <HookSlot name=\"product:details.end\" />\n\n <HookSlot name=\"product:single.form.start\" />\n <AddToCartForm product={product} stickyAddToCart={theme.settings.sticky_add_to_cart} />\n <HookSlot name=\"product:single.form.end\" />\n\n <SallaQuickOrder className=\"mt-5 md:-mb-2 block\" />\n </div>\n </div>\n\n <SallaOffer />\n </div>\n\n {store.settings?.rating?.show_on_product && (\n <RenderWhenVisible>\n <SallaComments key={commentsKey} itemId={product.id} type={'product' as any} />\n </RenderWhenVisible>\n )}\n\n <HookSlot name=\"product:related.start\" />\n <RenderWhenVisible>\n <div className=\"container\">\n <ProductsSlider\n data={{\n products: { source: 'related', source_value: product.id },\n title: t('pages.products.similar_products'),\n display_all_url: '',\n }}\n />\n </div>\n </RenderWhenVisible>\n <HookSlot name=\"product:related.end\" />\n\n <RenderWhenVisible>\n <div className=\"container\">\n <Testimonials data={{}} />\n </div>\n </RenderWhenVisible>\n\n <HookSlot name=\"product:end\" />\n </div>\n );\n}\n","import type { HeadDescriptor } from '../../utils/head';\nimport { buildHreflangAlternates } from '../../utils/baseHead';\nimport type { ProductPageProps } from './types';\nimport type { IdParams } from '../types';\nimport type { TwilightContext } from '../../twilight/context';\nimport { productLoader } from './loader';\nimport { RouteId } from '../../router/route-ids';\nimport { ProductPage } from './ProductPage';\nimport { fastCheckoutScript } from '../../utils/fast-checkout';\nexport { productLoader } from './loader';\nexport type { ProductPageProps } from './types';\n\nasync function loader(\n ctx: { params: IdParams; locale?: string },\n extend?: (\n data: ProductPageProps,\n ctx: { params: IdParams }\n ) => Promise<Record<string, unknown>> | Record<string, unknown>\n): Promise<ProductPageProps> {\n const data = await productLoader({ params: ctx.params });\n\n if (extend) {\n const extra = await extend(data, ctx);\n return { ...data, ...extra } as ProductPageProps;\n }\n return data;\n}\n\nfunction head(ctx: TwilightContext, data: ProductPageProps): HeadDescriptor {\n if (!data?.product) {\n return {\n title: 'Products',\n description: 'Browse our products',\n };\n }\n const product = data.product;\n const storeName = ctx.settings?.store?.name ?? '';\n\n // Strip HTML and limit description to 160 chars\n const description = product.description?.replace(/<[^>]*>/g, '').slice(0, 160) ?? '';\n\n // Price valid until: 1 month from now\n const priceValidUntil = new Date();\n priceValidUntil.setMonth(priceValidUntil.getMonth() + 1);\n\n // Collect all product images\n const images = product.images?.map((img) => img.url).filter(Boolean) ?? [];\n if (product.image?.url && !images.includes(product.image.url)) {\n images.unshift(product.image.url);\n }\n\n // Build JSON-LD schema matching SchemaProductWidget.php\n const jsonLd: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': 'Product',\n name: product.name,\n description,\n sku: product.sku,\n image: images.length > 0 ? images : undefined,\n offers: {\n '@type': 'Offer',\n url: product.url,\n availability: product.is_available\n ? 'https://schema.org/InStock'\n : 'https://schema.org/OutOfStock',\n price: product.sale_price,\n priceCurrency: product.currency,\n priceValidUntil: priceValidUntil.toISOString().split('T')[0],\n seller: storeName\n ? {\n '@type': 'Organization',\n name: storeName,\n }\n : undefined,\n },\n };\n\n // Add brand if exists\n if (product.brand) {\n jsonLd.brand = {\n '@type': 'Brand',\n name: product.brand.name,\n description: product.brand.description,\n logo: product.brand.logo,\n };\n }\n\n // Add aggregateRating and review if rating exists\n if (product.rating && product.rating.count > 0) {\n const ratingValue = product.rating.stars;\n jsonLd.aggregateRating = {\n '@type': 'AggregateRating',\n ratingCount: product.rating.count,\n ratingValue,\n };\n jsonLd.review = {\n '@type': 'Review',\n author: storeName\n ? {\n '@type': 'Organization',\n name: storeName,\n }\n : undefined,\n reviewRating: {\n '@type': 'Rating',\n bestRating: 5,\n ratingValue,\n },\n };\n }\n\n if (product.gtin && product.gtin.length === 8) {\n jsonLd.gtin8 = product.gtin;\n }\n\n if (product.mpn) {\n jsonLd.mpn = product.mpn;\n }\n\n const base: HeadDescriptor = {\n title: product.name,\n description,\n canonical: product.url,\n openGraph: {\n type: 'product',\n title: product.name,\n description,\n images: product.image?.url,\n url: product.url,\n },\n twitter: {\n card: 'summary_large_image',\n title: product.name,\n description,\n images: product.image?.url,\n },\n jsonLd,\n alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),\n // Quick-buy widget code, eager only here: the Buy Now button is above the fold on this page.\n // Other routes load it on idle from the body:end default hook, which also owns the\n // `#fast-checkout-js` marker `salla-add-product-button` checks for.\n scripts: ctx.settings?.store?.settings?.buy_now ? [fastCheckoutScript()] : [],\n };\n\n return base;\n}\n\nexport const Product = {\n id: RouteId.PRODUCT_SINGLE,\n loader,\n head,\n Component: ProductPage,\n} as const;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../../../src/routes/root/head.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../../../src/routes/root/head.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA4CjD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,YAAY,GAAG,MAAM,CAoBrE;AA6BD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,GAAG,SAAS,GAAG,MAAM,EAAE,CAgB9F;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;CAC3C,GAAG,UAAU,CA6Bb"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { LogoutRedirect, pendingOrdersRedirectLoader, slugBrandRedirectLoader } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { LogoutRedirect, pendingOrdersRedirectLoader, slugBrandRedirectLoader } from '../chunk-YJ6ZSGQY.js';
|
|
2
|
+
import '../chunk-JDROOL5C.js';
|
|
3
3
|
import '../chunk-TFB3QXYH.js';
|
|
4
4
|
import '../chunk-XTMHHLNK.js';
|
|
5
|
-
import '../chunk-
|
|
5
|
+
import '../chunk-SOPK72TP.js';
|
|
6
6
|
import '../chunk-T72DAX7R.js';
|
|
7
7
|
import '../chunk-DF6FBKDN.js';
|
|
8
8
|
import '../chunk-DGUM43GV.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { buildHreflangAlternates } from '../chunk-TZ3E5BN4.js';
|
|
2
2
|
import { RouteId } from '../chunk-TFB3QXYH.js';
|
|
3
|
-
import { getTwilightContext } from '../chunk-
|
|
3
|
+
import { getTwilightContext } from '../chunk-SOPK72TP.js';
|
|
4
4
|
import '../chunk-T72DAX7R.js';
|
|
5
5
|
import '../chunk-DGUM43GV.js';
|
|
6
6
|
import { lazy } from 'react';
|
|
@@ -18,7 +18,7 @@ async function testimonialsLoader(_ctx) {
|
|
|
18
18
|
|
|
19
19
|
// src/routes/testimonials/index.tsx
|
|
20
20
|
var LazyTestimonialsPage = lazy(
|
|
21
|
-
() => import('../TestimonialsPage-
|
|
21
|
+
() => import('../TestimonialsPage-JHGMJMGG.js').then((m) => ({ default: m.TestimonialsPage }))
|
|
22
22
|
);
|
|
23
23
|
var TestimonialsPage = LazyTestimonialsPage;
|
|
24
24
|
async function loader(ctx, extend) {
|
package/dist/routes/thank-you.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { order } from '../chunk-
|
|
1
|
+
import { order } from '../chunk-YJJZN5UP.js';
|
|
2
2
|
import { buildHreflangAlternates } from '../chunk-TZ3E5BN4.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-JDROOL5C.js';
|
|
4
4
|
import { RouteId } from '../chunk-TFB3QXYH.js';
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-
|
|
5
|
+
import '../chunk-F4MMWEII.js';
|
|
6
|
+
import '../chunk-TX6ZP4FF.js';
|
|
7
7
|
import '../chunk-XTMHHLNK.js';
|
|
8
|
-
import { getTwilightContext } from '../chunk-
|
|
8
|
+
import { getTwilightContext } from '../chunk-SOPK72TP.js';
|
|
9
9
|
import '../chunk-T72DAX7R.js';
|
|
10
10
|
import '../chunk-DF6FBKDN.js';
|
|
11
11
|
import '../chunk-DGUM43GV.js';
|
|
@@ -39,7 +39,7 @@ async function thankYouLoader({
|
|
|
39
39
|
|
|
40
40
|
// src/routes/thank-you/index.tsx
|
|
41
41
|
var LazyThankYouPage = lazy(
|
|
42
|
-
() => import('../ThankYouPage-
|
|
42
|
+
() => import('../ThankYouPage-CYCVSBAO.js').then((m) => ({ default: m.ThankYouPage }))
|
|
43
43
|
);
|
|
44
44
|
var ThankYouPage = LazyThankYouPage;
|
|
45
45
|
async function loader(ctx, extend) {
|