@salla.sa/twilight-theme-engine 1.0.61 → 1.0.63
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-RAQX7VHU.js → AddToCartForm-365O6IQY.js} +26 -6
- package/dist/AddToCartForm-365O6IQY.js.map +1 -0
- package/dist/{BlogAuthorPage-HV6JUJNL.js → BlogAuthorPage-QIII3YRK.js} +12 -11
- package/dist/BlogAuthorPage-QIII3YRK.js.map +1 -0
- package/dist/{BlogCategoryPage-ATPIVUAL.js → BlogCategoryPage-HNGWYTN6.js} +12 -11
- package/dist/BlogCategoryPage-HNGWYTN6.js.map +1 -0
- package/dist/{BlogPage-6IIOSB45.js → BlogPage-7NGO5VLL.js} +10 -9
- package/dist/BlogPage-7NGO5VLL.js.map +1 -0
- package/dist/{BlogSinglePage-DV3XYB26.js → BlogSinglePage-Y42LPA2L.js} +10 -9
- package/dist/BlogSinglePage-Y42LPA2L.js.map +1 -0
- package/dist/{BlogTagPage-RVJIXERD.js → BlogTagPage-ZCFYLXH6.js} +12 -11
- package/dist/BlogTagPage-ZCFYLXH6.js.map +1 -0
- package/dist/{BrandsPage-RQXP67LV.js → BrandsPage-PPJVASUW.js} +11 -10
- package/dist/BrandsPage-PPJVASUW.js.map +1 -0
- package/dist/{Breadcrumb-NXXVZJJD.js → Breadcrumb-4DUAJK3V.js} +10 -9
- package/dist/Breadcrumb-4DUAJK3V.js.map +1 -0
- package/dist/{CartItem-XRWTSJB5.js → CartItem-T4N3HMXU.js} +83 -59
- package/dist/CartItem-T4N3HMXU.js.map +1 -0
- package/dist/{CartSummary-F6BY5APF.js → CartSummary-Z25JDFWN.js} +10 -9
- package/dist/CartSummary-Z25JDFWN.js.map +1 -0
- package/dist/{Copyright-TEDF6HMC.js → Copyright-WNJIDKSR.js} +3 -3
- package/dist/{Copyright-TEDF6HMC.js.map → Copyright-WNJIDKSR.js.map} +1 -1
- package/dist/{CustomerLayout-T5BSTU6T.js → CustomerLayout-A6DVYYC3.js} +10 -9
- package/dist/CustomerLayout-A6DVYYC3.js.map +1 -0
- package/dist/{Footer-IRX2WAEF.js → Footer-3YBOSAO5.js} +10 -9
- package/dist/{Footer-IRX2WAEF.js.map → Footer-3YBOSAO5.js.map} +1 -1
- package/dist/{Header-HQKDTZSI.js → Header-6M7TVMSW.js} +6 -6
- package/dist/{Header-HQKDTZSI.js.map → Header-6M7TVMSW.js.map} +1 -1
- package/dist/LoyaltyPage-XQJ6RDT6.js +61 -0
- package/dist/LoyaltyPage-XQJ6RDT6.js.map +1 -0
- package/dist/LoyaltyPointsPage-K75LJNNP.js +16 -0
- package/dist/LoyaltyPointsPage-K75LJNNP.js.map +1 -0
- package/dist/{MainMenu-4ZPVIJCN.js → MainMenu-V7GPKDTU.js} +3 -3
- package/dist/{MainMenu-4ZPVIJCN.js.map → MainMenu-V7GPKDTU.js.map} +1 -1
- package/dist/{MasterLayout-G3MVZLYZ.js → MasterLayout-MBQ4JM3D.js} +10 -9
- package/dist/{MasterLayout-G3MVZLYZ.js.map → MasterLayout-MBQ4JM3D.js.map} +1 -1
- package/dist/{MobileMenu-A5DBTPS7.js → MobileMenu-UFX4ZHW7.js} +10 -9
- package/dist/MobileMenu-UFX4ZHW7.js.map +1 -0
- package/dist/{NotificationsPage-T2O67MLD.js → NotificationsPage-M3YK2HRM.js} +10 -9
- package/dist/NotificationsPage-M3YK2HRM.js.map +1 -0
- package/dist/{OrderSinglePage-4W4JZX7I.js → OrderSinglePage-7LIUMNRB.js} +11 -10
- package/dist/OrderSinglePage-7LIUMNRB.js.map +1 -0
- package/dist/{OrdersPage-DYKFBMRC.js → OrdersPage-WI4OSGBF.js} +11 -10
- package/dist/OrdersPage-WI4OSGBF.js.map +1 -0
- package/dist/{PageSingle-6U6GPMXJ.js → PageSingle-HRMSVNHN.js} +4 -4
- package/dist/{PageSingle-6U6GPMXJ.js.map → PageSingle-HRMSVNHN.js.map} +1 -1
- package/dist/{ProductDetails-OWSIL357.js → ProductDetails-GAC3NYQM.js} +10 -3
- package/dist/ProductDetails-GAC3NYQM.js.map +1 -0
- package/dist/{ProfilePage-LLCIJHAI.js → ProfilePage-33I2XTJ6.js} +10 -9
- package/dist/ProfilePage-33I2XTJ6.js.map +1 -0
- package/dist/{SeoCartWidget-ZL3FTBWK.js → SeoCartWidget-AEG2YLEF.js} +13 -12
- package/dist/SeoCartWidget-AEG2YLEF.js.map +1 -0
- package/dist/{SettingsPage-2XU5IF4A.js → SettingsPage-N3M677LP.js} +10 -9
- package/dist/SettingsPage-N3M677LP.js.map +1 -0
- package/dist/{StoreClosedNotification-CNJI2Q26.js → StoreClosedNotification-5MTDRRC3.js} +11 -10
- package/dist/{StoreClosedNotification-CNJI2Q26.js.map → StoreClosedNotification-5MTDRRC3.js.map} +1 -1
- package/dist/{TestimonialsPage-QYPLMNWL.js → TestimonialsPage-Z64P6MZX.js} +4 -4
- package/dist/{TestimonialsPage-QYPLMNWL.js.map → TestimonialsPage-Z64P6MZX.js.map} +1 -1
- package/dist/{ThankYouPage-WG3CM5JP.js → ThankYouPage-ZXQZMWCX.js} +14 -12
- package/dist/ThankYouPage-ZXQZMWCX.js.map +1 -0
- package/dist/{WalletPage-J7CH22JM.js → WalletPage-557AU5GH.js} +10 -9
- package/dist/WalletPage-557AU5GH.js.map +1 -0
- package/dist/{WishlistPage-ZXWYB56R.js → WishlistPage-HTDQW2N2.js} +150 -26
- package/dist/WishlistPage-HTDQW2N2.js.map +1 -0
- package/dist/api/brands.js +3 -3
- package/dist/api/cart.d.ts +7 -6
- package/dist/api/cart.d.ts.map +1 -1
- package/dist/api/cart.js +3 -3
- package/dist/api/category.js +3 -3
- package/dist/api/loyalty.js +3 -3
- package/dist/api/order.js +3 -3
- package/dist/api/page.js +3 -3
- package/dist/api/product.js +3 -3
- package/dist/api/store.d.ts +12 -0
- package/dist/api/store.d.ts.map +1 -1
- package/dist/api/store.js +1 -1
- package/dist/api/wishlist.js +4 -4
- package/dist/{chunk-3YVAYIM4.js → chunk-4KTY2FT6.js} +6 -6
- package/dist/{chunk-3YVAYIM4.js.map → chunk-4KTY2FT6.js.map} +1 -1
- package/dist/chunk-7V36I5GT.js +26 -0
- package/dist/chunk-7V36I5GT.js.map +1 -0
- package/dist/{chunk-OET4G4XC.js → chunk-BE3JDKE2.js} +19 -3
- package/dist/chunk-BE3JDKE2.js.map +1 -0
- package/dist/{chunk-2U3PUO3V.js → chunk-EIJXSBL6.js} +34 -17
- package/dist/chunk-EIJXSBL6.js.map +1 -0
- package/dist/{chunk-7OIP65ER.js → chunk-EQ32CL4D.js} +7 -4
- package/dist/chunk-EQ32CL4D.js.map +1 -0
- package/dist/{chunk-IZFZLJHD.js → chunk-EXKTSWBC.js} +5 -5
- package/dist/{chunk-IZFZLJHD.js.map → chunk-EXKTSWBC.js.map} +1 -1
- package/dist/{chunk-PK7EU5TM.js → chunk-GD26FI4J.js} +2 -2
- package/dist/chunk-GD26FI4J.js.map +1 -0
- package/dist/{chunk-YMVLYYLU.js → chunk-GOPUP26T.js} +4 -4
- package/dist/chunk-GOPUP26T.js.map +1 -0
- package/dist/{chunk-N4THXNXA.js → chunk-HSVGQ2DV.js} +12 -10
- package/dist/chunk-HSVGQ2DV.js.map +1 -0
- package/dist/{chunk-WH225GEC.js → chunk-I62RENKM.js} +3 -3
- package/dist/{chunk-WH225GEC.js.map → chunk-I62RENKM.js.map} +1 -1
- package/dist/{chunk-TDZSHACC.js → chunk-IC7YN4OQ.js} +3 -3
- package/dist/{chunk-TDZSHACC.js.map → chunk-IC7YN4OQ.js.map} +1 -1
- package/dist/{chunk-4DHLIY6V.js → chunk-IIYK56TI.js} +4 -3
- package/dist/chunk-IIYK56TI.js.map +1 -0
- package/dist/chunk-JKT44Y2M.js +14 -0
- package/dist/{chunk-ZPRZQTYM.js.map → chunk-JKT44Y2M.js.map} +1 -1
- package/dist/{chunk-W2B5P54C.js → chunk-KHRIGLYL.js} +3 -3
- package/dist/{chunk-W2B5P54C.js.map → chunk-KHRIGLYL.js.map} +1 -1
- package/dist/{chunk-NHKP5XIG.js → chunk-KILNHLWE.js} +4 -4
- package/dist/{chunk-NHKP5XIG.js.map → chunk-KILNHLWE.js.map} +1 -1
- package/dist/{chunk-ZQGMVUPE.js → chunk-KWHCKGLL.js} +3 -3
- package/dist/{chunk-ZQGMVUPE.js.map → chunk-KWHCKGLL.js.map} +1 -1
- package/dist/{chunk-LCJW7JKZ.js → chunk-LUTMPFRW.js} +4 -4
- package/dist/{chunk-LCJW7JKZ.js.map → chunk-LUTMPFRW.js.map} +1 -1
- package/dist/{chunk-YH4O3H4R.js → chunk-NPEI4SAZ.js} +3 -3
- package/dist/{chunk-YH4O3H4R.js.map → chunk-NPEI4SAZ.js.map} +1 -1
- package/dist/{chunk-JVGZDLFP.js → chunk-PE3LLBNR.js} +3 -3
- package/dist/{chunk-JVGZDLFP.js.map → chunk-PE3LLBNR.js.map} +1 -1
- package/dist/{chunk-3U26OMNO.js → chunk-PWBMSGMU.js} +24 -17
- package/dist/chunk-PWBMSGMU.js.map +1 -0
- package/dist/{chunk-VSJLPWFI.js → chunk-Q5UYV2EN.js} +3 -3
- package/dist/{chunk-VSJLPWFI.js.map → chunk-Q5UYV2EN.js.map} +1 -1
- package/dist/{chunk-GUGZ4CEG.js → chunk-S3CC2YGF.js} +3 -3
- package/dist/{chunk-GUGZ4CEG.js.map → chunk-S3CC2YGF.js.map} +1 -1
- package/dist/{chunk-NFTOMTTI.js → chunk-UFPZXWGM.js} +4 -4
- package/dist/{chunk-NFTOMTTI.js.map → chunk-UFPZXWGM.js.map} +1 -1
- package/dist/{chunk-TLAEW7TB.js → chunk-UH5ZXDEO.js} +3 -3
- package/dist/{chunk-TLAEW7TB.js.map → chunk-UH5ZXDEO.js.map} +1 -1
- package/dist/{chunk-3ITQB3PY.js → chunk-VLBQPVHM.js} +3 -3
- package/dist/{chunk-3ITQB3PY.js.map → chunk-VLBQPVHM.js.map} +1 -1
- package/dist/{chunk-TLO2M5TJ.js → chunk-W66OHTSM.js} +3 -3
- package/dist/{chunk-TLO2M5TJ.js.map → chunk-W66OHTSM.js.map} +1 -1
- package/dist/{chunk-6IDCWH5K.js → chunk-XFCJM6RN.js} +7 -7
- package/dist/{chunk-6IDCWH5K.js.map → chunk-XFCJM6RN.js.map} +1 -1
- package/dist/chunk-Y7HKVYDG.js +21 -0
- package/dist/chunk-Y7HKVYDG.js.map +1 -0
- package/dist/{chunk-VJHDE6UT.js → chunk-YEY3SO23.js} +3 -3
- package/dist/{chunk-VJHDE6UT.js.map → chunk-YEY3SO23.js.map} +1 -1
- package/dist/{chunk-FUIPNVQY.js → chunk-YLPI4HDD.js} +9 -6
- package/dist/chunk-YLPI4HDD.js.map +1 -0
- package/dist/{chunk-TFB3QXYH.js → chunk-ZGHRSRDO.js} +3 -2
- package/dist/chunk-ZGHRSRDO.js.map +1 -0
- package/dist/components/cart/CartItem.d.ts.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 +8 -7
- package/dist/components/home/index.js +11 -10
- package/dist/components/layout/index.js +1 -18
- package/dist/components/layout/index.js.map +1 -1
- package/dist/components/product/AddToCartForm.d.ts.map +1 -1
- package/dist/components/product/ProductCard.d.ts.map +1 -1
- package/dist/components/product/ProductDetails.d.ts.map +1 -1
- package/dist/components/product/index.js +9 -8
- package/dist/components/store/index.js +10 -9
- package/dist/components/store/index.js.map +1 -1
- package/dist/{document-class-7KPUN2DK.js → document-class-SKCL6IJF.js} +9 -9
- package/dist/{document-class-7KPUN2DK.js.map → document-class-SKCL6IJF.js.map} +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +8 -7
- package/dist/hooks/useComments.js +1 -1
- package/dist/hooks/useGtm.js +8 -7
- package/dist/hooks/useHostAttributes.d.ts +4 -0
- package/dist/hooks/useHostAttributes.d.ts.map +1 -0
- package/dist/hooks/useHostAttributes.js +4 -0
- package/dist/hooks/useHostAttributes.js.map +1 -0
- package/dist/hooks/useMoney.js +8 -7
- package/dist/hooks/useProduct.d.ts.map +1 -1
- package/dist/hooks/useProduct.js +1 -1
- package/dist/hooks/useStore.js +8 -7
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/dist/{navigation-QMBOIYJI.js → navigation-ESPAHRXM.js} +5 -5
- package/dist/{navigation-QMBOIYJI.js.map → navigation-ESPAHRXM.js.map} +1 -1
- package/dist/{navigation-XZJCQXY3.js → navigation-YKRXGGSL.js} +4 -4
- package/dist/{navigation-XZJCQXY3.js.map → navigation-YKRXGGSL.js.map} +1 -1
- package/dist/{not-found-UE5XOV5C.js → not-found-KBOXJ3AG.js} +11 -10
- package/dist/not-found-KBOXJ3AG.js.map +1 -0
- package/dist/providers/TwilightProvider.d.ts.map +1 -1
- package/dist/providers/index.js +8 -7
- package/dist/providers/twilight-init.d.ts.map +1 -1
- package/dist/router/route-ids.d.ts +1 -0
- package/dist/router/route-ids.d.ts.map +1 -1
- package/dist/routes/account/orders.js +4 -4
- package/dist/routes/account/wishlist/WishlistPage.d.ts +1 -1
- package/dist/routes/account/wishlist/WishlistPage.d.ts.map +1 -1
- package/dist/routes/account/wishlist/WishlistShare.d.ts +1 -0
- package/dist/routes/account/wishlist/WishlistShare.d.ts.map +1 -1
- package/dist/routes/account.js +11 -11
- package/dist/routes/blog.js +8 -8
- package/dist/routes/brands.js +4 -4
- package/dist/routes/cart/CartPage.d.ts.map +1 -1
- package/dist/routes/cart.js +17 -16
- package/dist/routes/cart.js.map +1 -1
- package/dist/routes/home.js +12 -11
- package/dist/routes/index.d.ts +1 -1
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +3 -3
- package/dist/routes/loyalty/LoyaltyPage.d.ts +1 -1
- package/dist/routes/loyalty/LoyaltyPage.d.ts.map +1 -1
- package/dist/routes/loyalty/LoyaltyPointsPage.d.ts +3 -0
- package/dist/routes/loyalty/LoyaltyPointsPage.d.ts.map +1 -0
- package/dist/routes/loyalty/index.d.ts +15 -3
- package/dist/routes/loyalty/index.d.ts.map +1 -1
- package/dist/routes/loyalty/loader.d.ts +2 -1
- package/dist/routes/loyalty/loader.d.ts.map +1 -1
- package/dist/routes/loyalty/types.d.ts +3 -0
- package/dist/routes/loyalty/types.d.ts.map +1 -1
- package/dist/routes/loyalty.js +62 -11
- package/dist/routes/loyalty.js.map +1 -1
- package/dist/routes/page.js +4 -4
- package/dist/routes/product/index.d.ts.map +1 -1
- package/dist/routes/product-listing/index.d.ts.map +1 -1
- package/dist/routes/product-listing.js +23 -19
- package/dist/routes/product-listing.js.map +1 -1
- package/dist/routes/product.js +16 -13
- package/dist/routes/product.js.map +1 -1
- package/dist/routes/seo-redirects.js +3 -3
- package/dist/routes/testimonials.js +2 -2
- package/dist/routes/thank-you/ThankYouPage.d.ts.map +1 -1
- package/dist/routes/thank-you.js +4 -4
- package/dist/skeleton.js +12 -11
- package/dist/tanstack/document-class.d.ts.map +1 -1
- package/dist/tanstack/head.d.ts +1 -4
- package/dist/tanstack/head.d.ts.map +1 -1
- package/dist/tanstack/router.d.ts.map +1 -1
- package/dist/tanstack/templates/locale-wrapper.d.ts.map +1 -1
- package/dist/tanstack.js +10 -10
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/salla-sdk.d.ts +1 -1
- package/dist/types/salla-sdk.d.ts.map +1 -1
- package/dist/utils/head.d.ts +3 -0
- package/dist/utils/head.d.ts.map +1 -1
- package/dist/utils/head.js +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/vite/adapters/tanstack.adapter.d.ts.map +1 -1
- package/dist/vite/index.js +92 -11
- package/dist/vite/index.js.map +1 -1
- package/dist/vite/plugins/best-practices/hooks-registry.d.ts.map +1 -1
- package/dist/vite/plugins/component-deps.d.ts +5 -0
- package/dist/vite/plugins/component-deps.d.ts.map +1 -0
- package/dist/vite/plugins/package-aliases.plugin.d.ts.map +1 -1
- package/package.json +5 -1
- package/dist/AddToCartForm-RAQX7VHU.js.map +0 -1
- package/dist/BlogAuthorPage-HV6JUJNL.js.map +0 -1
- package/dist/BlogCategoryPage-ATPIVUAL.js.map +0 -1
- package/dist/BlogPage-6IIOSB45.js.map +0 -1
- package/dist/BlogSinglePage-DV3XYB26.js.map +0 -1
- package/dist/BlogTagPage-RVJIXERD.js.map +0 -1
- package/dist/BrandsPage-RQXP67LV.js.map +0 -1
- package/dist/Breadcrumb-NXXVZJJD.js.map +0 -1
- package/dist/CartItem-XRWTSJB5.js.map +0 -1
- package/dist/CartSummary-F6BY5APF.js.map +0 -1
- package/dist/CustomerLayout-T5BSTU6T.js.map +0 -1
- package/dist/LoyaltyPage-AIUDZLT7.js +0 -194
- package/dist/LoyaltyPage-AIUDZLT7.js.map +0 -1
- package/dist/MobileMenu-A5DBTPS7.js.map +0 -1
- package/dist/NotificationsPage-T2O67MLD.js.map +0 -1
- package/dist/OrderSinglePage-4W4JZX7I.js.map +0 -1
- package/dist/OrdersPage-DYKFBMRC.js.map +0 -1
- package/dist/ProductDetails-OWSIL357.js.map +0 -1
- package/dist/ProfilePage-LLCIJHAI.js.map +0 -1
- package/dist/SeoCartWidget-ZL3FTBWK.js.map +0 -1
- package/dist/SettingsPage-2XU5IF4A.js.map +0 -1
- package/dist/ThankYouPage-WG3CM5JP.js.map +0 -1
- package/dist/WalletPage-J7CH22JM.js.map +0 -1
- package/dist/WishlistPage-ZXWYB56R.js.map +0 -1
- package/dist/chunk-2U3PUO3V.js.map +0 -1
- package/dist/chunk-3U26OMNO.js.map +0 -1
- package/dist/chunk-4DHLIY6V.js.map +0 -1
- package/dist/chunk-7OIP65ER.js.map +0 -1
- package/dist/chunk-FUIPNVQY.js.map +0 -1
- package/dist/chunk-N4THXNXA.js.map +0 -1
- package/dist/chunk-OET4G4XC.js.map +0 -1
- package/dist/chunk-PK7EU5TM.js.map +0 -1
- package/dist/chunk-TFB3QXYH.js.map +0 -1
- package/dist/chunk-YMVLYYLU.js.map +0 -1
- package/dist/chunk-ZPRZQTYM.js +0 -14
- package/dist/not-found-UE5XOV5C.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/brands.ts"],"names":[],"mappings":";;;;AAMO,IAAM,KAAA,GAAQ;AAAA,EACnB,IAAA,EAAM,OAAO,IAAA,KAAmD;AAC9D,IAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAO,GAAI,MAAM,GAAA,CAC5B,GAAA,CAAI,IAAA,GAAO,CAAA,YAAA,EAAe,IAAI,CAAA,CAAA,GAAK,QAAQ,EAC3C,IAAA,EAAoD;AACvD,IAAA,OAAO,EAAE,OAAO,IAAA,IAAQ,IAAI,IAAA,EAAM,MAAA,EAAQ,QAAQ,IAAA,EAAK;AAAA,EACzD,CAAA;AAAA,EAEA,IAAA,EAAM,OAAO,EAAA,KAA+B;AAC1C,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,OAAA,EAAU,EAAE,CAAA,CAAE,CAAA,CAAE,IAAA,EAAsB;AACrE,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EAEA,aAAa,CAAC,EAAA,KAA+B,QAAQ,KAAA,CAAM,IAAA,CAAK,EAAE,CAAC,CAAA;AAAA,EAEnE,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,CAAC,IAAA,KACL,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,QAAA,EAAU,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAAA,MACtC,OAAA,EAAS,MAAM,KAAA,CAAM,IAAA,CAAK,IAAI;AAAA,KAC/B,CAAA;AAAA,IACH,MAAA,EAAQ,CAAC,EAAA,KACP,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,QAAA,EAAU,QAAA,EAAU,EAAE,CAAA;AAAA,MACjC,OAAA,EAAS,MAAM,KAAA,CAAM,IAAA,CAAK,EAAE;AAAA,KAC7B;AAAA;AAEP","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/api/brands.ts"],"names":[],"mappings":";;;;AAMO,IAAM,KAAA,GAAQ;AAAA,EACnB,IAAA,EAAM,OAAO,IAAA,KAAmD;AAC9D,IAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAO,GAAI,MAAM,GAAA,CAC5B,GAAA,CAAI,IAAA,GAAO,CAAA,YAAA,EAAe,IAAI,CAAA,CAAA,GAAK,QAAQ,EAC3C,IAAA,EAAoD;AACvD,IAAA,OAAO,EAAE,OAAO,IAAA,IAAQ,IAAI,IAAA,EAAM,MAAA,EAAQ,QAAQ,IAAA,EAAK;AAAA,EACzD,CAAA;AAAA,EAEA,IAAA,EAAM,OAAO,EAAA,KAA+B;AAC1C,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,OAAA,EAAU,EAAE,CAAA,CAAE,CAAA,CAAE,IAAA,EAAsB;AACrE,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EAEA,aAAa,CAAC,EAAA,KAA+B,QAAQ,KAAA,CAAM,IAAA,CAAK,EAAE,CAAC,CAAA;AAAA,EAEnE,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,CAAC,IAAA,KACL,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,QAAA,EAAU,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAAA,MACtC,OAAA,EAAS,MAAM,KAAA,CAAM,IAAA,CAAK,IAAI;AAAA,KAC/B,CAAA;AAAA,IACH,MAAA,EAAQ,CAAC,EAAA,KACP,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,QAAA,EAAU,QAAA,EAAU,EAAE,CAAA;AAAA,MACjC,OAAA,EAAS,MAAM,KAAA,CAAM,IAAA,CAAK,EAAE;AAAA,KAC7B;AAAA;AAEP","file":"chunk-KWHCKGLL.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api } from './client';\nimport type { Brand } from '../routes/brands/types';\nimport type { PaginatedResult, Pagination } from './types';\nimport { orThrow } from '../providers/NavigationProvider';\n\nexport const brand = {\n list: async (page?: number): Promise<PaginatedResult<Brand>> => {\n const { data, cursor } = await api\n .get(page ? `brands?page=${page}` : 'brands')\n .json<{ data: Brand[] | null; cursor?: Pagination }>();\n return { items: data ?? [], next: cursor?.next ?? null };\n },\n\n find: async (id: string): Promise<Brand> => {\n const { data } = await api.get(`brands/${id}`).json<{ data: Brand }>();\n return data;\n },\n\n findOrThrow: (id: string): Promise<Brand> => orThrow(brand.find(id)),\n\n queries: {\n list: (page?: number) =>\n queryOptions({\n queryKey: ['brands', 'list', page ?? 1],\n queryFn: () => brand.list(page),\n }),\n detail: (id: string) =>\n queryOptions({\n queryKey: ['brands', 'detail', id],\n queryFn: () => brand.find(id),\n }),\n },\n};\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { home } from './chunk-NQVJ7NJ6.js';
|
|
2
2
|
import { buildHreflangAlternates } from './chunk-TZ3E5BN4.js';
|
|
3
|
-
import { HomeComponentRenderer } from './chunk-
|
|
3
|
+
import { HomeComponentRenderer } from './chunk-EXKTSWBC.js';
|
|
4
4
|
import { useDevHomeComponentOverrides } from './chunk-2JV6WZ6O.js';
|
|
5
|
-
import { RouteId } from './chunk-
|
|
5
|
+
import { RouteId } from './chunk-ZGHRSRDO.js';
|
|
6
6
|
import { getTwilightContext } from './chunk-N2S25NXP.js';
|
|
7
7
|
import { HookSlot } from './chunk-Q7VWURUR.js';
|
|
8
8
|
import { memo } from 'react';
|
|
@@ -84,5 +84,5 @@ function head(ctx) {
|
|
|
84
84
|
var Home = { id: RouteId.INDEX, loader, head, Component: HomePage };
|
|
85
85
|
|
|
86
86
|
export { Home, HomeSkeleton, homeLoader };
|
|
87
|
-
//# sourceMappingURL=chunk-
|
|
88
|
-
//# sourceMappingURL=chunk-
|
|
87
|
+
//# sourceMappingURL=chunk-LUTMPFRW.js.map
|
|
88
|
+
//# sourceMappingURL=chunk-LUTMPFRW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/routes/home/loader.ts","../src/routes/home/HomePage.tsx","../src/routes/home/index.tsx"],"names":["HomeSkeleton","HomePage"],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/routes/home/loader.ts","../src/routes/home/HomePage.tsx","../src/routes/home/index.tsx"],"names":["HomeSkeleton","HomePage"],"mappings":";;;;;;;;;;;;AAWA,eAAsB,WAAW,GAAA,EAAoD;AACnF,EAAA,MAAM,EAAE,WAAA,EAAY,GAAI,kBAAA,EAAmB;AAC3C,EAAA,MAAM,aAAa,MAAM,WAAA,CAAY,gBAAgB,IAAA,CAAK,OAAA,CAAQ,YAAY,CAAA;AAC9E,EAAA,MAAM,MAAA,GAAS;AAAA,IACb,MAAA,EAAQ,KAAK,MAAA,IAAU,IAAA;AAAA,IACvB,UAAA,EAAY,UAAA,CAAW,GAAA,CAAI,CAAC,IAAA,MAAU;AAAA,MACpC,GAAG,IAAA;AAAA,MACH,MAAM,IAAA,CAAK,IAAA,EAAM,QAAQ,OAAA,EAAS,EAAE,KAAK,IAAA,CAAK;AAAA,KAChD,CAAE,CAAA;AAAA,IACF,IAAA,EAAM,EAAE,IAAA,EAAM,OAAA,CAAQ,KAAA;AAAM,GAC9B;AACA,EAAA,OAAO,MAAA;AACT;AChBO,IAAM,YAAA,GAAe,IAAA,CAAK,SAASA,aAAAA,GAAe;AACvD,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,SAAI,SAAA,EAAU,uCAAA,EACb,8BAAC,KAAA,EAAA,EAAM,SAAA,EAAU,2BAA0B,CAAA,EAC7C,CAAA;AAAA,oBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2CAAA,EACb,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,WAAU,gBAAA,EAAiB,CAAA;AAAA,0BACjC,KAAA,EAAA,EAAI,SAAA,EAAU,yCACZ,QAAA,EAAA,CAAC,CAAA,EAAG,GAAG,CAAA,EAAG,CAAC,EAAE,GAAA,CAAI,CAAC,sBACjB,GAAA,CAAC,KAAA,EAAA,EAAc,WAAU,MAAA,EAAA,EAAb,CAAoB,CACjC,CAAA,EACH;AAAA,KAAA,EACF,CAAA;AAAA,oBACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2CAAA,EACb,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,WAAU,gBAAA,EAAiB,CAAA;AAAA,0BACjC,KAAA,EAAA,EAAI,SAAA,EAAU,yCACZ,QAAA,EAAA,CAAC,CAAA,EAAG,GAAG,CAAA,EAAG,CAAC,EAAE,GAAA,CAAI,CAAC,sBACjB,GAAA,CAAC,KAAA,EAAA,EAAc,WAAU,MAAA,EAAA,EAAb,CAAoB,CACjC,CAAA,EACH;AAAA,KAAA,EACF;AAAA,GAAA,EACF,CAAA;AAEJ,CAAC;AAEM,IAAM,QAAA,GAAW,KAAK,SAASC,SAAAA,CAAS,EAAE,UAAA,GAAa,IAAG,EAAkB;AAGjF,EAAA,MAAM,kBAAA,GAAqB,6BAA6B,UAAU,CAAA;AAClE,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,MAAK,YAAA,EAAa,CAAA;AAAA,oBAC5B,GAAA,CAAC,QAAA,EAAA,EAAS,IAAA,EAAK,cAAA,EAAe,CAAA;AAAA,IAC7B,kBAAA,CAAmB,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA;AAAA;AAAA;AAAA,sBAG7B,GAAA,CAAC,qBAAA,EAAA,EAAkC,IAAA,EAAY,KAAA,EAAA,EAAnB,KAAiC;AAAA,KAC9D,CAAA;AAAA,oBACD,GAAA,CAAC,QAAA,EAAA,EAAS,IAAA,EAAK,UAAA,EAAW;AAAA,GAAA,EAC5B,CAAA;AAEJ,CAAC,CAAA;;;AC9BD,SAAS,OAAO,IAAA,EAAqD;AACnE,EAAA,OAAO,UAAA,CAAW,EAAE,MAAA,EAAQ,IAAA,EAAM,QAAQ,CAAA;AAC5C;AAEA,SAAS,KAAK,GAAA,EAAsC;AAClD,EAAA,MAAM,KAAA,GAAQ,IAAI,QAAA,EAAU,KAAA;AAC5B,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAC;AAEpB,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,EAAM,KAAA,IAAS,KAAA,CAAM,IAAA;AACzC,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,IAAA,EAAM,WAAA,IAAe,KAAA,CAAM,WAAA;AACrD,EAAA,MAAM,QAAA,GAAW,MAAM,IAAA,EAAM,QAAA;AAE7B,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,WAAW,KAAA,CAAM,GAAA;AAAA,IACjB,SAAA,EAAW;AAAA,MACT,IAAA,EAAM,SAAA;AAAA,MACN,KAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAQ,KAAA,CAAM,IAAA;AAAA,MACd,KAAK,KAAA,CAAM;AAAA,KACb;AAAA,IACA,OAAA,EAAS;AAAA,MACP,IAAA,EAAM,qBAAA;AAAA,MACN,KAAA;AAAA,MACA,WAAA;AAAA,MACA,QAAQ,KAAA,CAAM;AAAA,KAChB;AAAA,IACA,oBAAoB,uBAAA,CAAwB,GAAA,CAAI,QAAA,EAAU,GAAA,CAAI,SAAS,QAAQ;AAAA,GACjF;AACF;AAEO,IAAM,IAAA,GAAO,EAAE,EAAA,EAAI,OAAA,CAAQ,OAAO,MAAA,EAAQ,IAAA,EAAM,WAAW,QAAA","file":"chunk-LUTMPFRW.js","sourcesContent":["import { getTwilightContext } from '../../twilight/context';\nimport { home } from '../../api/home';\nimport type { HomeComponentData } from '../../types';\nimport { RouteId } from '../../router/route-ids';\n\nexport interface HomeLoaderData {\n locale: string;\n components: HomeComponentData[];\n page: { slug: string };\n}\n\nexport async function homeLoader(ctx?: { locale?: string }): Promise<HomeLoaderData> {\n const { queryClient } = getTwilightContext();\n const components = await queryClient.ensureQueryData(home.queries.components());\n const result = {\n locale: ctx?.locale || 'ar',\n components: components.map((comp) => ({\n ...comp,\n path: comp.path?.replace('home.', '') || comp.path,\n })),\n page: { slug: RouteId.INDEX },\n };\n return result;\n}\n","import { memo } from 'react';\nimport { useDevHomeComponentOverrides } from '../../dev/dev-settings-store';\nimport { HookSlot } from '../../hooks';\nimport { HomeComponentRenderer } from '../../components/home';\nimport type { HomePageProps } from './types';\nimport { Pulse } from '@salla.sa/twilight-components-react';\n\nexport const HomeSkeleton = memo(function HomeSkeleton() {\n return (\n <>\n <div className=\"s-block container skeleton-block-hero\">\n <Pulse className=\"h-64 sm:h-80 rounded-md\" />\n </div>\n <div className=\"s-block container skeleton-block-products\">\n <Pulse className=\"h-10 w-48 mb-4\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <Pulse key={i} className=\"h-56\" />\n ))}\n </div>\n </div>\n <div className=\"s-block container skeleton-block-products\">\n <Pulse className=\"h-10 w-48 mb-4\" />\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <Pulse key={i} className=\"h-56\" />\n ))}\n </div>\n </div>\n </>\n );\n});\n\nexport const HomePage = memo(function HomePage({ components = [] }: HomePageProps) {\n // Dev-mode only: overlay DevSettingsWidget component-field overrides onto the\n // blocks so edits render live. No-op passthrough in production builds.\n const renderedComponents = useDevHomeComponentOverrides(components);\n return (\n <>\n <HookSlot name=\"home:start\" />\n <HookSlot name=\"home:content\" />\n {renderedComponents.map((data, index) => (\n // `data.key` is the twilight.json catalog id, shared by every placement\n // of that block. Platform blocks send null. Position is unique.\n <HomeComponentRenderer key={index} data={data} index={index} />\n ))}\n <HookSlot name=\"home:end\" />\n </>\n );\n});\n\nexport { HomePage as default };\n","import type { HeadDescriptor } from '../../utils/head';\nimport { buildHreflangAlternates } from '../../utils/baseHead';\nimport type { HomeLoaderData } from './loader';\nimport { homeLoader } from './loader';\nimport type { TwilightContext } from '../../twilight/context';\nimport { HomePage } from './HomePage';\nimport { RouteId } from '../../router/route-ids';\n\nexport { HomeSkeleton } from './HomePage';\nexport { registerHomeComponents, DefaultHomeComponents } from '../../components/home/register';\nexport { registerHomeComponentConfig } from '../../components/home';\nexport type { HomePageProps } from './types';\nexport type { HomeLoaderData } from './loader';\nexport type {\n HomeComponentsProps,\n AnyHomeComponent,\n HomeComponentConfig,\n} from '../../components/home';\n\nfunction loader(_ctx?: { locale?: string }): Promise<HomeLoaderData> {\n return homeLoader({ locale: _ctx?.locale });\n}\n\nfunction head(ctx: TwilightContext): HeadDescriptor {\n const store = ctx.settings?.store;\n if (!store) return {};\n\n const title = store.meta?.title ?? store.name;\n const description = store.meta?.description ?? store.description;\n const keywords = store.meta?.keywords;\n\n return {\n title,\n description,\n keywords,\n canonical: store.url,\n openGraph: {\n type: 'website',\n title,\n description,\n images: store.logo,\n url: store.url,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: store.logo,\n },\n alternateLanguages: buildHreflangAlternates(ctx.settings, ctx.location.pathname),\n };\n}\n\nexport const Home = { id: RouteId.INDEX, loader, head, Component: HomePage } as const;\n\nexport { homeLoader };\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { orThrow } from './chunk-
|
|
1
|
+
import { orThrow } from './chunk-I62RENKM.js';
|
|
2
2
|
import { getAuthToken, api } from './chunk-P3OPJL6I.js';
|
|
3
3
|
import { queryOptions } from '@tanstack/react-query';
|
|
4
4
|
|
|
@@ -29,5 +29,5 @@ var loyalty = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export { loyalty };
|
|
32
|
-
//# sourceMappingURL=chunk-
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
32
|
+
//# sourceMappingURL=chunk-NPEI4SAZ.js.map
|
|
33
|
+
//# sourceMappingURL=chunk-NPEI4SAZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/loyalty.ts"],"names":[],"mappings":";;;;AAKO,IAAM,OAAA,GAAU;AAAA,EACrB,KAAK,YAA8B;AACjC,IAAA,MAAM,EAAE,MAAK,GAAI,MAAM,IAAI,GAAA,CAAI,SAAS,EAAE,IAAA,EAAwB;AAClE,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EAEA,UAAA,EAAY,MAAwB,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAA;AAAA,EAEzD,kBAAkB,YAA6B;AAC7C,IAAA,MAAM,WAAW,MAAM,GAAA,CAAI,GAAA,CAAI,gBAAgB,EAAE,IAAA,EAA2B;AAC5E,IAAA,OAAO,QAAA,CAAS,OAAA;AAAA,EAClB,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,MACN,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,SAAS,CAAA;AAAA,MACpB,OAAA,EAAS,MAAM,OAAA,CAAQ,GAAA;AAAI,KAC5B,CAAA;AAAA,IACH,MAAA,EAAQ,MACN,YAAA,CAA4B;AAAA,MAC1B,QAAA,EAAU,CAAC,SAAA,EAAW,QAAQ,CAAA;AAAA,MAC9B,OAAA,EAAS,MAAM,OAAA,CAAQ,gBAAA,EAAiB;AAAA;AAAA;AAAA,MAGxC,OAAA,EAAS,CAAC,CAAC,YAAA,EAAa;AAAA,MACxB,SAAA,EAAW;AAAA,KACZ;AAAA;AAEP","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/api/loyalty.ts"],"names":[],"mappings":";;;;AAKO,IAAM,OAAA,GAAU;AAAA,EACrB,KAAK,YAA8B;AACjC,IAAA,MAAM,EAAE,MAAK,GAAI,MAAM,IAAI,GAAA,CAAI,SAAS,EAAE,IAAA,EAAwB;AAClE,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EAEA,UAAA,EAAY,MAAwB,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAA;AAAA,EAEzD,kBAAkB,YAA6B;AAC7C,IAAA,MAAM,WAAW,MAAM,GAAA,CAAI,GAAA,CAAI,gBAAgB,EAAE,IAAA,EAA2B;AAC5E,IAAA,OAAO,QAAA,CAAS,OAAA;AAAA,EAClB,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,MACN,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,SAAS,CAAA;AAAA,MACpB,OAAA,EAAS,MAAM,OAAA,CAAQ,GAAA;AAAI,KAC5B,CAAA;AAAA,IACH,MAAA,EAAQ,MACN,YAAA,CAA4B;AAAA,MAC1B,QAAA,EAAU,CAAC,SAAA,EAAW,QAAQ,CAAA;AAAA,MAC9B,OAAA,EAAS,MAAM,OAAA,CAAQ,gBAAA,EAAiB;AAAA;AAAA;AAAA,MAGxC,OAAA,EAAS,CAAC,CAAC,YAAA,EAAa;AAAA,MACxB,SAAA,EAAW;AAAA,KACZ;AAAA;AAEP","file":"chunk-NPEI4SAZ.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api, getAuthToken } from './client';\nimport type { Loyalty, PointBalanceResponse } from '../routes/loyalty/types';\nimport { orThrow } from '../providers/NavigationProvider';\n\nexport const loyalty = {\n get: async (): Promise<Loyalty> => {\n const { data } = await api.get('loyalty').json<{ data: Loyalty }>();\n return data;\n },\n\n getOrThrow: (): Promise<Loyalty> => orThrow(loyalty.get()),\n\n getPointsBalance: async (): Promise<number> => {\n const response = await api.get('balance/points').json<PointBalanceResponse>();\n return response.balance;\n },\n\n queries: {\n detail: () =>\n queryOptions({\n queryKey: ['loyalty'],\n queryFn: () => loyalty.get(),\n }),\n points: () =>\n queryOptions<number | null>({\n queryKey: ['loyalty', 'points'],\n queryFn: () => loyalty.getPointsBalance(),\n // Points are customer-scoped; skip for guests (no token) — the request would\n // otherwise 400 with `token_not_provided`.\n enabled: !!getAuthToken(),\n staleTime: 30_000,\n }),\n },\n};\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { orThrow } from './chunk-
|
|
1
|
+
import { orThrow } from './chunk-I62RENKM.js';
|
|
2
2
|
import { getActiveScope, api } from './chunk-P3OPJL6I.js';
|
|
3
3
|
import { queryOptions } from '@tanstack/react-query';
|
|
4
4
|
|
|
@@ -26,5 +26,5 @@ var category = {
|
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
export { category };
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
30
|
-
//# sourceMappingURL=chunk-
|
|
29
|
+
//# sourceMappingURL=chunk-PE3LLBNR.js.map
|
|
30
|
+
//# sourceMappingURL=chunk-PE3LLBNR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/category.ts"],"names":[],"mappings":";;;;AAKO,IAAM,QAAA,GAAW;AAAA,EACtB,IAAA,EAAM,OAAO,EAAA,KAAkC;AAC7C,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,WAAA,EAAc,EAAE,CAAA,CAAE,CAAA,CAAE,IAAA,EAAyB;AAC5E,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EAEA,aAAa,CAAC,EAAA,KAAkC,QAAQ,QAAA,CAAS,IAAA,CAAK,EAAE,CAAC,CAAA;AAAA,EAEzE,MAAM,YAAiC;AACrC,IAAA,MAAM,EAAE,MAAK,GAAI,MAAM,IAAI,GAAA,CAAI,YAAY,EAAE,IAAA,EAA2B;AACxE,IAAA,OAAO,QAAQ,EAAC;AAAA,EAClB,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,CAAC,EAAA,KACP,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,YAAA,EAAc,QAAA,EAAU,EAAE,CAAA;AAAA,MACrC,OAAA,EAAS,MAAM,QAAA,CAAS,IAAA,CAAK,EAAE;AAAA,KAChC,CAAA;AAAA,IAEH,IAAA,EAAM,MACJ,YAAA,CAAa;AAAA;AAAA,MAEX,QAAA,EAAU,CAAC,YAAA,EAAc,MAAA,EAAQ,EAAE,KAAA,EAAO,cAAA,IAAkB,CAAA;AAAA,MAC5D,OAAA,EAAS,MAAM,QAAA,CAAS,IAAA;AAAK,KAC9B;AAAA;AAEP","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/api/category.ts"],"names":[],"mappings":";;;;AAKO,IAAM,QAAA,GAAW;AAAA,EACtB,IAAA,EAAM,OAAO,EAAA,KAAkC;AAC7C,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,WAAA,EAAc,EAAE,CAAA,CAAE,CAAA,CAAE,IAAA,EAAyB;AAC5E,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EAEA,aAAa,CAAC,EAAA,KAAkC,QAAQ,QAAA,CAAS,IAAA,CAAK,EAAE,CAAC,CAAA;AAAA,EAEzE,MAAM,YAAiC;AACrC,IAAA,MAAM,EAAE,MAAK,GAAI,MAAM,IAAI,GAAA,CAAI,YAAY,EAAE,IAAA,EAA2B;AACxE,IAAA,OAAO,QAAQ,EAAC;AAAA,EAClB,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,CAAC,EAAA,KACP,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,YAAA,EAAc,QAAA,EAAU,EAAE,CAAA;AAAA,MACrC,OAAA,EAAS,MAAM,QAAA,CAAS,IAAA,CAAK,EAAE;AAAA,KAChC,CAAA;AAAA,IAEH,IAAA,EAAM,MACJ,YAAA,CAAa;AAAA;AAAA,MAEX,QAAA,EAAU,CAAC,YAAA,EAAc,MAAA,EAAQ,EAAE,KAAA,EAAO,cAAA,IAAkB,CAAA;AAAA,MAC5D,OAAA,EAAS,MAAM,QAAA,CAAS,IAAA;AAAK,KAC9B;AAAA;AAEP","file":"chunk-PE3LLBNR.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api, getActiveScope } from './client';\nimport type { Category } from '../types';\nimport { orThrow } from '../providers/NavigationProvider';\n\nexport const category = {\n find: async (id: string): Promise<Category> => {\n const { data } = await api.get(`categories/${id}`).json<{ data: Category }>();\n return data;\n },\n\n findOrThrow: (id: string): Promise<Category> => orThrow(category.find(id)),\n\n list: async (): Promise<Category[]> => {\n const { data } = await api.get('categories').json<{ data: Category[] }>();\n return data ?? [];\n },\n\n queries: {\n detail: (id: string) =>\n queryOptions({\n queryKey: ['categories', 'detail', id],\n queryFn: () => category.find(id),\n }),\n\n list: () =>\n queryOptions({\n // Scope (branch) varies the API response — key must include it.\n queryKey: ['categories', 'list', { scope: getActiveScope() }],\n queryFn: () => category.list(),\n }),\n },\n};\n"]}
|
|
@@ -34,26 +34,33 @@ function useProduct(initialProduct, options) {
|
|
|
34
34
|
}, [reload]);
|
|
35
35
|
useEffect(() => {
|
|
36
36
|
const salla = window.salla;
|
|
37
|
-
if (!salla?.
|
|
37
|
+
if (!salla?.event?.on) return;
|
|
38
38
|
const handlePriceUpdated = (res) => {
|
|
39
39
|
const data = res.data;
|
|
40
40
|
if (!data) return;
|
|
41
|
-
setProduct((prev) =>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
setProduct((prev) => {
|
|
42
|
+
const price = data.price ?? prev.price;
|
|
43
|
+
const regularPrice = data.regular_price ?? prev.regular_price;
|
|
44
|
+
const isOnSale = Boolean(data.has_sale_price) && regularPrice > price;
|
|
45
|
+
return {
|
|
46
|
+
...prev,
|
|
47
|
+
price,
|
|
48
|
+
sale_price: isOnSale ? price : prev.sale_price,
|
|
49
|
+
regular_price: regularPrice,
|
|
50
|
+
is_on_sale: isOnSale,
|
|
51
|
+
starting_price: null,
|
|
52
|
+
weight: data.weight || "",
|
|
53
|
+
// An empty variant SKU/barcode blanks it; a payload without the field keeps it (product.js).
|
|
54
|
+
sku: data.sku === void 0 ? prev.sku : data.sku || "",
|
|
55
|
+
barcode: data.barcode === void 0 ? prev.barcode : data.barcode || "",
|
|
56
|
+
is_out_of_stock: false
|
|
57
|
+
};
|
|
58
|
+
});
|
|
50
59
|
};
|
|
51
|
-
|
|
60
|
+
const listener = handlePriceUpdated;
|
|
61
|
+
salla.event.on("product::price.updated", listener);
|
|
52
62
|
return () => {
|
|
53
|
-
salla.event?.off?.(
|
|
54
|
-
"product::price.updated",
|
|
55
|
-
handlePriceUpdated
|
|
56
|
-
);
|
|
63
|
+
salla.event?.off?.("product::price.updated", listener);
|
|
57
64
|
};
|
|
58
65
|
}, []);
|
|
59
66
|
useEffect(() => {
|
|
@@ -71,5 +78,5 @@ function useProduct(initialProduct, options) {
|
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
export { useProduct };
|
|
74
|
-
//# sourceMappingURL=chunk-
|
|
75
|
-
//# sourceMappingURL=chunk-
|
|
81
|
+
//# sourceMappingURL=chunk-PWBMSGMU.js.map
|
|
82
|
+
//# sourceMappingURL=chunk-PWBMSGMU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useProduct.ts"],"names":[],"mappings":"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","file":"chunk-PWBMSGMU.js","sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport type { Product } from '../types';\n\n/**\n * UseProductResult - Return type for useProduct hook\n */\nexport interface UseProductResult {\n /** Current product state (updates on option changes) */\n product: Product;\n /** Reload product data from API */\n reload: () => Promise<void>;\n}\n\nexport interface UseProductOptions {\n /**\n * True while `initialProduct` is a list-card stand-in. When it flips to false\n * (details arrived), state re-seeds. Do not infer this from `options`/`images`\n * — list payloads may include those fields.\n */\n isPreview?: boolean;\n}\n\n/**\n * useProduct - Hook for managing product state with live updates\n *\n * Provides reactive product data with automatic updates for price, stock,\n * and variant changes. Handles manual reloads (e.g., after add-to-cart)\n * and subscribes to Salla SDK events for real-time price updates.\n *\n * Stock status is reflected in `product.is_out_of_stock` which updates\n * when price calculations succeed or fail (e.g., unavailable option combinations).\n *\n * @param initialProduct - The initial product object (typically from loader/SSR).\n * @param options.isPreview - Pass true for a list-card placeholder so the hook\n * re-seeds when details for the same id arrive (`isPreview` goes false).\n *\n * @returns Object with product and reload function\n *\n * @example\n * ```tsx\n * function ProductDetails({ product }) {\n * const { product: updatedProduct, reload } = useProduct(product);\n *\n * const handleAddToCart = async () => {\n * await addToCart(updatedProduct.id);\n * await reload(); // Refresh product state after cart update\n * };\n *\n * return (\n * <div>\n * <h1>{updatedProduct.name}</h1>\n * <p>Price: {formatMoney(updatedProduct.price)}</p>\n * {updatedProduct.is_out_of_stock && <p>Currently out of stock</p>}\n * <button onClick={handleAddToCart}>Add to Cart</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useProduct(initialProduct: Product, options?: UseProductOptions): UseProductResult {\n const [product, setProduct] = useState<Product>(initialProduct);\n\n // Always keep a ref to the latest initialProduct so the re-seed effect below\n // can read it without adding the full object to the dependency array.\n const initialProductRef = useRef<Product>(initialProduct);\n useEffect(() => {\n initialProductRef.current = initialProduct;\n });\n\n const reload = useCallback(async () => {\n const salla = window.salla;\n if (!salla?.api?.product?.getDetails) return;\n try {\n const response = await salla.api.product.getDetails(String(product.id), [\n 'images',\n 'category',\n ]);\n if (response?.success && response.data) {\n setProduct(response.data as Product);\n }\n } catch {\n // silently ignore network errors during reload\n }\n }, [product.id]);\n\n // Re-seed when the loader navigates to a different product, or when a\n // list-card placeholder (`isPreview`) is replaced by details for the same id.\n // Object identity is not a dependency — that would reset live option/price state.\n useEffect(() => {\n setProduct(initialProductRef.current);\n }, [initialProduct.id, options?.isPreview]);\n\n // Subscribe to Salla option-change events so price/stock stays in sync\n useEffect(() => {\n const salla = window.salla;\n if (!salla?.event?.on) return;\n\n salla.event.on('product:options.updated', reload);\n return () => {\n salla.event?.off?.('product:options.updated', reload);\n };\n }, [reload]);\n\n // Subscribe to price update events (matches product.js registerEvents)\n useEffect(() => {\n const salla = window.salla;\n if (!salla?.event?.on) return;\n\n const handlePriceUpdated = (res: { data?: Record<string, unknown> }) => {\n const data = res.data;\n if (!data) return;\n\n setProduct((prev) => {\n const price = (data.price as number) ?? prev.price;\n const regularPrice = (data.regular_price as number) ?? prev.regular_price;\n // The payload has no sale_price: like product.js, `price` is the payable (sale) figure.\n const isOnSale = Boolean(data.has_sale_price) && regularPrice > price;\n return {\n ...prev,\n price,\n sale_price: isOnSale ? price : prev.sale_price,\n regular_price: regularPrice,\n is_on_sale: isOnSale,\n starting_price: null,\n weight: (data.weight as string) || '',\n // An empty variant SKU/barcode blanks it; a payload without the field keeps it (product.js).\n sku: data.sku === undefined ? prev.sku : (data.sku as string) || '',\n barcode: data.barcode === undefined ? prev.barcode : (data.barcode as string) || '',\n is_out_of_stock: false,\n };\n });\n };\n\n const listener = handlePriceUpdated as (...args: unknown[]) => void;\n\n // Root on/off: onPriceUpdated registers a wrapper that salla.event.off can't match.\n salla.event.on('product::price.updated', listener);\n return () => {\n salla.event?.off?.('product::price.updated', listener);\n };\n }, []);\n\n // Subscribe to price update failed events (matches product.js)\n useEffect(() => {\n const salla = window.salla;\n if (!salla?.event?.on) return;\n\n const handlePriceFailed = () => {\n setProduct((prev) => ({ ...prev, is_out_of_stock: true }));\n };\n\n salla.event.on('product::price.updated.failed', handlePriceFailed);\n return () => {\n salla.event?.off?.('product::price.updated.failed', handlePriceFailed);\n };\n }, []);\n\n return { product, reload };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { redirect } from './chunk-
|
|
1
|
+
import { redirect } from './chunk-I62RENKM.js';
|
|
2
2
|
import { clearAuthTokenCookie } from './chunk-SR4OTLTJ.js';
|
|
3
3
|
import { FALLBACK_LOCALE } from './chunk-T72DAX7R.js';
|
|
4
4
|
import { useEffect } from 'react';
|
|
@@ -20,5 +20,5 @@ function LogoutRedirect() {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export { LogoutRedirect, pendingOrdersRedirectLoader, slugBrandRedirectLoader };
|
|
23
|
-
//# sourceMappingURL=chunk-
|
|
24
|
-
//# sourceMappingURL=chunk-
|
|
23
|
+
//# sourceMappingURL=chunk-Q5UYV2EN.js.map
|
|
24
|
+
//# sourceMappingURL=chunk-Q5UYV2EN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/routes/seo-redirects.ts"],"names":[],"mappings":";;;;;AAcA,eAAsB,wBAAwB,GAAA,EAAkD;AAC9F,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,SAAS,CAAA,CAAA,EAAI,MAAM,WAAW,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AACrD;AAOA,eAAsB,4BACpB,GAAA,GAA+C,EAAE,MAAA,EAAQ,IAAG,EAC5C;AAChB,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,QAAA,CAAS,CAAA,CAAA,EAAI,MAAM,CAAA,8BAAA,CAAgC,CAAA;AAC3D;AAUO,SAAS,cAAA,GAAuB;AACrC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,oBAAA,EAAqB;AAErB,IAAA,MAAA,CAAO,QAAA,CAAS,QAAQ,MAAA,CAAO,QAAA,CAAS,KAAK,OAAA,CAAQ,8BAAA,EAAgC,EAAE,CAAC,CAAA;AAAA,EAC1F,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,OAAO,IAAA;AACT","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/routes/seo-redirects.ts"],"names":[],"mappings":";;;;;AAcA,eAAsB,wBAAwB,GAAA,EAAkD;AAC9F,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,SAAS,CAAA,CAAA,EAAI,MAAM,WAAW,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,CAAE,CAAA;AACrD;AAOA,eAAsB,4BACpB,GAAA,GAA+C,EAAE,MAAA,EAAQ,IAAG,EAC5C;AAChB,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,MAAA,CAAO,MAAA,IAAU,eAAA;AACpC,EAAA,MAAM,QAAA,CAAS,CAAA,CAAA,EAAI,MAAM,CAAA,8BAAA,CAAgC,CAAA;AAC3D;AAUO,SAAS,cAAA,GAAuB;AACrC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,oBAAA,EAAqB;AAErB,IAAA,MAAA,CAAO,QAAA,CAAS,QAAQ,MAAA,CAAO,QAAA,CAAS,KAAK,OAAA,CAAQ,8BAAA,EAAgC,EAAE,CAAC,CAAA;AAAA,EAC1F,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,OAAO,IAAA;AACT","file":"chunk-Q5UYV2EN.js","sourcesContent":["import { useEffect } from 'react';\nimport { redirect } from '../providers/NavigationProvider';\nimport { FALLBACK_LOCALE } from '../providers/locale-constants';\nimport { clearAuthTokenCookie } from '../utils/cookies';\n\nexport interface SlugBrandParams {\n /** SEO slug segment (ignored — only here to match the route pattern). */\n slug: string;\n /** Brand numeric ID to redirect to. */\n id: string;\n /** Active locale from the `/$locale` parent layout (e.g. `'ar'`, `'en'`). */\n locale?: string;\n}\n\nexport async function slugBrandRedirectLoader(ctx: { params: SlugBrandParams }): Promise<never> {\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n throw redirect(`/${locale}/brands/${ctx.params.id}`);\n}\n\nexport interface PendingOrdersRedirectParams {\n /** Active locale from the `/$locale` parent layout (e.g. `'ar'`, `'en'`). */\n locale?: string;\n}\n\nexport async function pendingOrdersRedirectLoader(\n ctx: { params: PendingOrdersRedirectParams } = { params: {} }\n): Promise<never> {\n const locale = ctx.params.locale || FALLBACK_LOCALE;\n throw redirect(`/${locale}/account/orders?status=pending`);\n}\n\n/**\n * `/logout` — where the SDK sends the browser once `salla.auth.logout()` has run\n * (`salla.url.get('logout?from=…')`). The Twig storefront serves that URL server-side. Here\n * it renders nothing and, in the browser, removes the theme's own `token` cookie (the SDK's\n * `cookie.clearAll()` leaves it) and then does a full navigation home. It has to be a\n * component, not a loader redirect: a loader runs during server rendering, where the cookie\n * can't be cleared, so the redirect would leave the visitor signed in on the next request.\n */\nexport function LogoutRedirect(): null {\n useEffect(() => {\n clearAuthTokenCookie();\n // `/{store base}/{locale}/logout?from=…` → `/{store base}/{locale}`\n window.location.replace(window.location.href.replace(/\\/logout\\/?(\\?[^#]*)?(#.*)?$/, ''));\n }, []);\n return null;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { orThrow } from './chunk-
|
|
1
|
+
import { orThrow } from './chunk-I62RENKM.js';
|
|
2
2
|
import { api } from './chunk-P3OPJL6I.js';
|
|
3
3
|
import { queryOptions } from '@tanstack/react-query';
|
|
4
4
|
|
|
@@ -17,5 +17,5 @@ var page = {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
export { page };
|
|
20
|
-
//# sourceMappingURL=chunk-
|
|
21
|
-
//# sourceMappingURL=chunk-
|
|
20
|
+
//# sourceMappingURL=chunk-S3CC2YGF.js.map
|
|
21
|
+
//# sourceMappingURL=chunk-S3CC2YGF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/page.ts"],"names":[],"mappings":";;;;AAKO,IAAM,IAAA,GAAO;AAAA,EAClB,IAAA,EAAM,OAAO,IAAA,KAA2C;AACtD,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,MAAA,EAAS,IAAI,CAAA,CAAE,CAAA,CAAE,IAAA,EAAgC;AAChF,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EAEA,aAAa,CAAC,IAAA,KAA2C,QAAQ,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,EAEhF,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,CAAC,IAAA,KACP,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,OAAA,EAAS,QAAA,EAAU,IAAI,CAAA;AAAA,MAClC,OAAA,EAAS,MAAM,IAAA,CAAK,IAAA,CAAK,IAAI;AAAA,KAC9B;AAAA;AAEP","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/api/page.ts"],"names":[],"mappings":";;;;AAKO,IAAM,IAAA,GAAO;AAAA,EAClB,IAAA,EAAM,OAAO,IAAA,KAA2C;AACtD,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,GAAA,CAAI,IAAI,CAAA,MAAA,EAAS,IAAI,CAAA,CAAE,CAAA,CAAE,IAAA,EAAgC;AAChF,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EAEA,aAAa,CAAC,IAAA,KAA2C,QAAQ,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,EAEhF,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,CAAC,IAAA,KACP,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,OAAA,EAAS,QAAA,EAAU,IAAI,CAAA;AAAA,MAClC,OAAA,EAAS,MAAM,IAAA,CAAK,IAAA,CAAK,IAAI;AAAA,KAC9B;AAAA;AAEP","file":"chunk-S3CC2YGF.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api } from './client';\nimport type { ApiPageResponse } from '../routes/page/types';\nimport { orThrow } from '../providers/NavigationProvider';\n\nexport const page = {\n find: async (slug: string): Promise<ApiPageResponse> => {\n const { data } = await api.get(`pages/${slug}`).json<{ data: ApiPageResponse }>();\n return data;\n },\n\n findOrThrow: (slug: string): Promise<ApiPageResponse> => orThrow(page.find(slug)),\n\n queries: {\n detail: (slug: string) =>\n queryOptions({\n queryKey: ['pages', 'detail', slug],\n queryFn: () => page.find(slug),\n }),\n },\n};\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useOpeningHours } from './chunk-
|
|
2
|
-
import { useIsProduct } from './chunk-
|
|
1
|
+
import { useOpeningHours } from './chunk-EIJXSBL6.js';
|
|
2
|
+
import { useIsProduct } from './chunk-I62RENKM.js';
|
|
3
3
|
import { useTranslation } from './chunk-TYNZ5B2B.js';
|
|
4
4
|
import { useTwilight } from './chunk-DF6FBKDN.js';
|
|
5
5
|
import { useState } from 'react';
|
|
@@ -54,5 +54,5 @@ function StoreClosedNotification(_props) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
export { StoreClosedNotification };
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
57
|
+
//# sourceMappingURL=chunk-UFPZXWGM.js.map
|
|
58
|
+
//# sourceMappingURL=chunk-UFPZXWGM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/store/StoreClosedNotification.tsx"],"names":[],"mappings":";;;;;;;AAsBO,SAAS,wBAAwB,MAAA,EAAsC;AAC5E,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,WAAA,EAAY;AAC9B,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,cAAA,EAAe;AAC7B,EAAA,MAAM,EAAE,QAAQ,SAAA,EAAW,iBAAA,KAAsB,eAAA,CAAgB,KAAA,CAAM,UAAU,aAAa,CAAA;AAC9F,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAGhD,EAAA,MAAM,gBAAgB,YAAA,EAAa;AAGnC,EAAA,IAAI,CAAC,aAAA,IAAiB,CAAC,aAAa,MAAA,IAAU,SAAA,IAAa,CAAC,iBAAA,EAAmB;AAC7E,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAAwB;AAC3C,IAAA,CAAA,CAAE,cAAA,EAAe;AACjB,IAAA,YAAA,CAAa,IAAI,CAAA;AAAA,EACnB,CAAA;AAEA,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,cAAA;AAAA,MACV,EAAA,EAAG,2BAAA;AAAA,MACH,aAAA,EAAY,2BAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,SAAA;AAAA,QACjB,KAAA,EAAO,MAAA;AAAA,QACP,OAAA,EAAS,WAAA;AAAA,QACT,OAAA,EAAS,MAAA;AAAA,QACT,UAAA,EAAY,QAAA;AAAA,QACZ,cAAA,EAAgB,QAAA;AAAA,QAChB,QAAA,EAAU;AAAA,OACZ;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,GAAA;AAAA,YACL,EAAA,EAAG,cAAA;AAAA,YACH,OAAA,EAAS,WAAA;AAAA,YACT,KAAA,EAAO,EAAE,QAAA,EAAU,UAAA,EAAY,MAAM,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,cAAA,EAAgB,MAAA,EAAO;AAAA,YAE/E,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,cAAA,EAAe;AAAA;AAAA,SAC9B;AAAA,wBACA,GAAA,CAAC,GAAA,EAAA,EAAE,KAAA,EAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,SAAA,EAAW,QAAA,EAAU,IAAA,EAAM,CAAA,EAAE,EACjD,QAAA,EAAA,CAAA,CAAE,2BAAA,EAA6B;AAAA,UAC9B,YAAA,EAAc,qPAAkD,iBAAiB,CAAA,CAAA,CAAA;AAAA,UACjF,QAAA,EAAU;AAAA,SACX,CAAA,EACH;AAAA;AAAA;AAAA,GACF;AAEJ","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/components/store/StoreClosedNotification.tsx"],"names":[],"mappings":";;;;;;;AAsBO,SAAS,wBAAwB,MAAA,EAAsC;AAC5E,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,WAAA,EAAY;AAC9B,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,cAAA,EAAe;AAC7B,EAAA,MAAM,EAAE,QAAQ,SAAA,EAAW,iBAAA,KAAsB,eAAA,CAAgB,KAAA,CAAM,UAAU,aAAa,CAAA;AAC9F,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAGhD,EAAA,MAAM,gBAAgB,YAAA,EAAa;AAGnC,EAAA,IAAI,CAAC,aAAA,IAAiB,CAAC,aAAa,MAAA,IAAU,SAAA,IAAa,CAAC,iBAAA,EAAmB;AAC7E,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,KAAwB;AAC3C,IAAA,CAAA,CAAE,cAAA,EAAe;AACjB,IAAA,YAAA,CAAa,IAAI,CAAA;AAAA,EACnB,CAAA;AAEA,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,cAAA;AAAA,MACV,EAAA,EAAG,2BAAA;AAAA,MACH,aAAA,EAAY,2BAAA;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,eAAA,EAAiB,SAAA;AAAA,QACjB,KAAA,EAAO,MAAA;AAAA,QACP,OAAA,EAAS,WAAA;AAAA,QACT,OAAA,EAAS,MAAA;AAAA,QACT,UAAA,EAAY,QAAA;AAAA,QACZ,cAAA,EAAgB,QAAA;AAAA,QAChB,QAAA,EAAU;AAAA,OACZ;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,GAAA;AAAA,YACL,EAAA,EAAG,cAAA;AAAA,YACH,OAAA,EAAS,WAAA;AAAA,YACT,KAAA,EAAO,EAAE,QAAA,EAAU,UAAA,EAAY,MAAM,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,cAAA,EAAgB,MAAA,EAAO;AAAA,YAE/E,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,cAAA,EAAe;AAAA;AAAA,SAC9B;AAAA,wBACA,GAAA,CAAC,GAAA,EAAA,EAAE,KAAA,EAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,SAAA,EAAW,QAAA,EAAU,IAAA,EAAM,CAAA,EAAE,EACjD,QAAA,EAAA,CAAA,CAAE,2BAAA,EAA6B;AAAA,UAC9B,YAAA,EAAc,qPAAkD,iBAAiB,CAAA,CAAA,CAAA;AAAA,UACjF,QAAA,EAAU;AAAA,SACX,CAAA,EACH;AAAA;AAAA;AAAA,GACF;AAEJ","file":"chunk-UFPZXWGM.js","sourcesContent":["import { useState } from 'react';\nimport { useIsProduct } from '../../providers/NavigationProvider';\nimport { useTwilight } from '../../providers/TwilightProvider';\nimport { useOpeningHours } from '../../hooks/useOpeningHours';\nimport { useTranslation } from '../../providers/I18nProvider';\n\nexport interface StoreClosedNotificationProps {\n /** Whether to show the notification (defaults to true when store is closed on product page) */\n show?: boolean;\n}\n\n/**\n * StoreClosedNotification - Shows a notification bar when the store is closed.\n *\n * Mirrors PHP ReceivingOrdersTimesWidget:\n * - Only shows on product pages\n * - Only shows when store is closed for receiving orders\n * - Displays when the store will open next\n * - Has a close button to dismiss\n *\n * Injected via hook registry at body:start.\n */\nexport function StoreClosedNotification(_props: StoreClosedNotificationProps) {\n const { store } = useTwilight();\n const { t } = useTranslation();\n const { isOpen, isEnabled, nextOpenFormatted } = useOpeningHours(store.settings?.opening_hours);\n const [dismissed, setDismissed] = useState(false);\n\n // Check if we're on a product page\n const isProductPage = useIsProduct();\n\n // Conditions: product page, opening hours enabled, store closed, not dismissed\n if (!isProductPage || !isEnabled || isOpen || dismissed || !nextOpenFormatted) {\n return null;\n }\n\n const handleClose = (e: React.MouseEvent) => {\n e.preventDefault();\n setDismissed(true);\n };\n\n return (\n <div\n className=\"store-notify\"\n id=\"store-closed-notification\"\n data-testid=\"store-closed-notification\"\n style={{\n backgroundColor: '#d63031',\n color: '#fff',\n padding: '10px 15px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n position: 'relative',\n }}\n >\n <a\n href=\"#\"\n id=\"notify-close\"\n onClick={handleClose}\n style={{ position: 'absolute', left: 15, color: '#fff', textDecoration: 'none' }}\n >\n <i className=\"sicon-cancel\" />\n </a>\n <p style={{ margin: 0, textAlign: 'center', flex: 1 }}>\n {t('store.closed_notification', {\n defaultValue: `المتجر حاليا مغلق لاستقبال الطلبات وسيتم فتحه (${nextOpenFormatted})`,\n nextOpen: nextOpenFormatted,\n })}\n </p>\n </div>\n );\n}\n"]}
|
|
@@ -4,7 +4,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
4
4
|
export { BlogSkeleton, BreadcrumbSkeleton, CustomerLayoutSkeleton, CustomerPageSkeleton, PageSkeleton, ProductCardSkeleton, ProductDetailSkeleton, ProductGridSkeleton, SkeletonPulse } from '@salla.sa/twilight-components-react';
|
|
5
5
|
|
|
6
6
|
var LazyBreadcrumb = lazy(
|
|
7
|
-
() => import('./Breadcrumb-
|
|
7
|
+
() => import('./Breadcrumb-4DUAJK3V.js').then((m) => ({ default: m.Breadcrumb }))
|
|
8
8
|
);
|
|
9
9
|
var LazyNoContent = lazy(
|
|
10
10
|
() => import('./NoContent-63TMCPGY.js').then((m) => ({ default: m.NoContent }))
|
|
@@ -151,5 +151,5 @@ function DeferredData({ promise, fallback, children }) {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
export { DeferredData, Image, LazyBreadcrumb, LazyCurrencySymbol, LazyErrorPage, LazyNoContent, LazyRenderWhenVisible, resolveDeferred };
|
|
154
|
-
//# sourceMappingURL=chunk-
|
|
155
|
-
//# sourceMappingURL=chunk-
|
|
154
|
+
//# sourceMappingURL=chunk-UH5ZXDEO.js.map
|
|
155
|
+
//# sourceMappingURL=chunk-UH5ZXDEO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/common/lazy.ts","../src/components/common/Image.tsx","../src/components/common/DeferredData.tsx"],"names":["Image","memo","DeferredRenderer","jsx"],"mappings":"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","file":"chunk-TLAEW7TB.js","sourcesContent":["import { lazy } from 'react';\n\n/**\n * Lazy-loaded common components\n * Use these for code-splitting non-critical components\n *\n * NOTE: Skeleton components are sourced from @salla.sa/twilight-components-react\n * because they must render instantly during route transitions.\n */\nexport const LazyBreadcrumb = lazy(() =>\n import('./Breadcrumb').then((m) => ({ default: m.Breadcrumb }))\n);\n\nexport const LazyNoContent = lazy(() =>\n import('./NoContent').then((m) => ({ default: m.NoContent }))\n);\n\nexport const LazyRenderWhenVisible = lazy(() =>\n import('./RenderWhenVisible').then((m) => ({ default: m.RenderWhenVisible }))\n);\n\nexport const LazyCurrencySymbol = lazy(() =>\n import('./CurrencySymbol').then((m) => ({ default: m.CurrencySymbol }))\n);\n\nexport const LazyErrorPage = lazy(() =>\n import('./ErrorPage').then((m) => ({ default: m.ErrorPage }))\n);\n","import { memo } from 'react';\nimport { getCdnImageSrcSet, getCdnImageUrl } from '../../utils/cdn-image';\n\nexport interface ImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n /** Image source URL */\n src?: string;\n /** Alt text for accessibility */\n alt: string;\n /** Whether this image is above the fold / LCP candidate */\n priority?: boolean;\n /** Aspect ratio for CLS prevention (e.g. \"16/9\", \"1/1\", \"4/3\") */\n aspectRatio?: string;\n /** Object fit mode */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';\n /** Mobile image source for <picture> element */\n mobileSrc?: string;\n /** Mobile breakpoint for <source> media query (default: 768px) */\n mobileBreakpoint?: number;\n /** Skip the wrapper div */\n noWrapper?: boolean;\n /**\n * CDN widths for a density `srcset`. Pass `sizes` so the browser picks a\n * candidate close to the displayed CSS size.\n */\n srcSetWidths?: readonly number[];\n}\n\n/**\n * Optimized Image component with native browser lazy loading.\n *\n * - Uses `loading=\"lazy\"` + `decoding=\"async\"` by default for below-the-fold images.\n * - Uses `loading=\"eager\"` + `fetchPriority=\"high\"` for priority (above-the-fold / LCP) images.\n * - Supports responsive `<picture>` with mobile source.\n * - Provides `aspectRatio` for CLS prevention.\n * - When `srcSetWidths` + `sizes` are set, emits a sized CDN `srcset`.\n */\nexport const Image = memo(function Image({\n src,\n alt,\n priority = false,\n aspectRatio,\n objectFit = 'cover',\n mobileSrc,\n mobileBreakpoint = 768,\n noWrapper = false,\n className = '',\n style,\n width,\n height,\n sizes,\n srcSet: srcSetProp,\n srcSetWidths,\n ...rest\n}: ImageProps) {\n if (!src) return null;\n\n const generatedSrcSet =\n srcSetProp || (srcSetWidths?.length ? getCdnImageSrcSet(src, srcSetWidths) : undefined);\n const generatedMobileSrcSet =\n srcSetWidths?.length && mobileSrc ? getCdnImageSrcSet(mobileSrc, srcSetWidths) : undefined;\n const cdnWidth = srcSetWidths?.length\n ? width != null && srcSetWidths.includes(Number(width))\n ? Number(width)\n : srcSetWidths[0]\n : width;\n // Width-only CDN URLs so `src` matches a srcset candidate for preload.\n const cdnOptions = generatedSrcSet ? { width: cdnWidth } : { width: cdnWidth, height };\n\n const optimizedSrc = getCdnImageUrl(src, cdnOptions);\n const optimizedMobileSrc = getCdnImageUrl(mobileSrc, cdnOptions);\n\n const objectFitClass = `object-${objectFit}`;\n const imgClasses = [className, objectFitClass].filter(Boolean).join(' ');\n\n const loadingProps: React.ImgHTMLAttributes<HTMLImageElement> = priority\n ? { loading: 'eager' as const, fetchPriority: 'high' as const, decoding: 'sync' as const }\n : { loading: 'lazy' as const, decoding: 'async' as const };\n\n const img = (\n <img\n src={optimizedSrc}\n alt={alt}\n className={imgClasses}\n width={width}\n height={height}\n sizes={sizes}\n srcSet={generatedSrcSet}\n {...loadingProps}\n {...rest}\n />\n );\n\n const imgElement = optimizedMobileSrc ? (\n <picture>\n <source\n media={`(max-width: ${mobileBreakpoint}px)`}\n srcSet={generatedMobileSrcSet || optimizedMobileSrc}\n sizes={generatedMobileSrcSet ? sizes : undefined}\n />\n {img}\n </picture>\n ) : (\n img\n );\n\n if (noWrapper || !aspectRatio) {\n return imgElement;\n }\n\n return (\n <div className=\"relative overflow-hidden\" style={{ aspectRatio, ...style }}>\n {imgElement}\n </div>\n );\n});\n","import { Suspense, memo, use, type ReactNode } from 'react';\n\nexport interface DeferredDataProps<T> {\n promise: Promise<T> | T;\n fallback: ReactNode;\n children: (data: T) => ReactNode;\n}\n\nconst DEFERRED_KEY = Symbol.for('twilight.deferred');\n\ninterface DeferredState<T> {\n status: 'pending' | 'success' | 'error';\n value?: T;\n error?: unknown;\n}\n\nexport interface DeferredPromise<T> extends Promise<T> {\n [DEFERRED_KEY]?: DeferredState<T>;\n}\n\nconst seenPromises = typeof WeakSet !== 'undefined' ? new WeakSet() : null;\n\nfunction defer<T>(promise: Promise<T>): DeferredPromise<T> {\n const existing = (promise as DeferredPromise<T>)[DEFERRED_KEY];\n if (existing) return promise as DeferredPromise<T>;\n\n const state: DeferredState<T> = { status: 'pending' };\n\n const deferred = promise as DeferredPromise<T>;\n deferred[DEFERRED_KEY] = state;\n\n promise.then(\n (value) => {\n state.status = 'success';\n state.value = value;\n },\n (error) => {\n state.status = 'error';\n state.error = error;\n }\n );\n\n return deferred;\n}\n\nconst DeferredRenderer = memo(function DeferredRenderer<T>({\n promise,\n children,\n}: {\n promise: DeferredPromise<T>;\n children: (data: T) => ReactNode;\n}) {\n const state = promise[DEFERRED_KEY];\n\n if (state?.status === 'success') {\n return children(state.value!);\n }\n\n if (state?.status === 'error') {\n throw state.error;\n }\n\n const data = use(promise);\n return children(data);\n}) as <T>(props: { promise: DeferredPromise<T>; children: (data: T) => ReactNode }) => ReactNode;\n\nfunction DeferredFallback<T>({\n promise,\n fallback,\n children,\n}: {\n promise: DeferredPromise<T>;\n fallback: ReactNode;\n children: (data: T) => ReactNode;\n}) {\n const state = promise[DEFERRED_KEY];\n if (state?.status === 'success') {\n return children(state.value!);\n }\n return <>{fallback}</>;\n}\n\nexport function resolveDeferred<T>(\n promiseOrValue: Promise<T> | T | undefined\n): T | Promise<T> | undefined {\n if (promiseOrValue == null || !(promiseOrValue instanceof Promise)) return promiseOrValue;\n const deferred = defer(promiseOrValue);\n const state = deferred[DEFERRED_KEY];\n if (state?.status === 'success') return state.value as T;\n return promiseOrValue;\n}\n\nexport function DeferredData<T>({ promise, fallback, children }: DeferredDataProps<T>) {\n if (!(promise instanceof Promise)) {\n return children(promise);\n }\n\n if (seenPromises && promise instanceof Promise) seenPromises.add(promise);\n\n const deferred = defer(promise);\n const state = deferred[DEFERRED_KEY];\n\n if (state?.status === 'success') {\n return children(state.value!);\n }\n\n if (state?.status === 'error') {\n throw state.error;\n }\n\n return (\n <Suspense\n fallback={\n <DeferredFallback promise={deferred} fallback={fallback}>\n {children}\n </DeferredFallback>\n }\n >\n <DeferredRenderer promise={deferred}>{children}</DeferredRenderer>\n </Suspense>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/common/lazy.ts","../src/components/common/Image.tsx","../src/components/common/DeferredData.tsx"],"names":["Image","memo","DeferredRenderer","jsx"],"mappings":"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","file":"chunk-UH5ZXDEO.js","sourcesContent":["import { lazy } from 'react';\n\n/**\n * Lazy-loaded common components\n * Use these for code-splitting non-critical components\n *\n * NOTE: Skeleton components are sourced from @salla.sa/twilight-components-react\n * because they must render instantly during route transitions.\n */\nexport const LazyBreadcrumb = lazy(() =>\n import('./Breadcrumb').then((m) => ({ default: m.Breadcrumb }))\n);\n\nexport const LazyNoContent = lazy(() =>\n import('./NoContent').then((m) => ({ default: m.NoContent }))\n);\n\nexport const LazyRenderWhenVisible = lazy(() =>\n import('./RenderWhenVisible').then((m) => ({ default: m.RenderWhenVisible }))\n);\n\nexport const LazyCurrencySymbol = lazy(() =>\n import('./CurrencySymbol').then((m) => ({ default: m.CurrencySymbol }))\n);\n\nexport const LazyErrorPage = lazy(() =>\n import('./ErrorPage').then((m) => ({ default: m.ErrorPage }))\n);\n","import { memo } from 'react';\nimport { getCdnImageSrcSet, getCdnImageUrl } from '../../utils/cdn-image';\n\nexport interface ImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n /** Image source URL */\n src?: string;\n /** Alt text for accessibility */\n alt: string;\n /** Whether this image is above the fold / LCP candidate */\n priority?: boolean;\n /** Aspect ratio for CLS prevention (e.g. \"16/9\", \"1/1\", \"4/3\") */\n aspectRatio?: string;\n /** Object fit mode */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';\n /** Mobile image source for <picture> element */\n mobileSrc?: string;\n /** Mobile breakpoint for <source> media query (default: 768px) */\n mobileBreakpoint?: number;\n /** Skip the wrapper div */\n noWrapper?: boolean;\n /**\n * CDN widths for a density `srcset`. Pass `sizes` so the browser picks a\n * candidate close to the displayed CSS size.\n */\n srcSetWidths?: readonly number[];\n}\n\n/**\n * Optimized Image component with native browser lazy loading.\n *\n * - Uses `loading=\"lazy\"` + `decoding=\"async\"` by default for below-the-fold images.\n * - Uses `loading=\"eager\"` + `fetchPriority=\"high\"` for priority (above-the-fold / LCP) images.\n * - Supports responsive `<picture>` with mobile source.\n * - Provides `aspectRatio` for CLS prevention.\n * - When `srcSetWidths` + `sizes` are set, emits a sized CDN `srcset`.\n */\nexport const Image = memo(function Image({\n src,\n alt,\n priority = false,\n aspectRatio,\n objectFit = 'cover',\n mobileSrc,\n mobileBreakpoint = 768,\n noWrapper = false,\n className = '',\n style,\n width,\n height,\n sizes,\n srcSet: srcSetProp,\n srcSetWidths,\n ...rest\n}: ImageProps) {\n if (!src) return null;\n\n const generatedSrcSet =\n srcSetProp || (srcSetWidths?.length ? getCdnImageSrcSet(src, srcSetWidths) : undefined);\n const generatedMobileSrcSet =\n srcSetWidths?.length && mobileSrc ? getCdnImageSrcSet(mobileSrc, srcSetWidths) : undefined;\n const cdnWidth = srcSetWidths?.length\n ? width != null && srcSetWidths.includes(Number(width))\n ? Number(width)\n : srcSetWidths[0]\n : width;\n // Width-only CDN URLs so `src` matches a srcset candidate for preload.\n const cdnOptions = generatedSrcSet ? { width: cdnWidth } : { width: cdnWidth, height };\n\n const optimizedSrc = getCdnImageUrl(src, cdnOptions);\n const optimizedMobileSrc = getCdnImageUrl(mobileSrc, cdnOptions);\n\n const objectFitClass = `object-${objectFit}`;\n const imgClasses = [className, objectFitClass].filter(Boolean).join(' ');\n\n const loadingProps: React.ImgHTMLAttributes<HTMLImageElement> = priority\n ? { loading: 'eager' as const, fetchPriority: 'high' as const, decoding: 'sync' as const }\n : { loading: 'lazy' as const, decoding: 'async' as const };\n\n const img = (\n <img\n src={optimizedSrc}\n alt={alt}\n className={imgClasses}\n width={width}\n height={height}\n sizes={sizes}\n srcSet={generatedSrcSet}\n {...loadingProps}\n {...rest}\n />\n );\n\n const imgElement = optimizedMobileSrc ? (\n <picture>\n <source\n media={`(max-width: ${mobileBreakpoint}px)`}\n srcSet={generatedMobileSrcSet || optimizedMobileSrc}\n sizes={generatedMobileSrcSet ? sizes : undefined}\n />\n {img}\n </picture>\n ) : (\n img\n );\n\n if (noWrapper || !aspectRatio) {\n return imgElement;\n }\n\n return (\n <div className=\"relative overflow-hidden\" style={{ aspectRatio, ...style }}>\n {imgElement}\n </div>\n );\n});\n","import { Suspense, memo, use, type ReactNode } from 'react';\n\nexport interface DeferredDataProps<T> {\n promise: Promise<T> | T;\n fallback: ReactNode;\n children: (data: T) => ReactNode;\n}\n\nconst DEFERRED_KEY = Symbol.for('twilight.deferred');\n\ninterface DeferredState<T> {\n status: 'pending' | 'success' | 'error';\n value?: T;\n error?: unknown;\n}\n\nexport interface DeferredPromise<T> extends Promise<T> {\n [DEFERRED_KEY]?: DeferredState<T>;\n}\n\nconst seenPromises = typeof WeakSet !== 'undefined' ? new WeakSet() : null;\n\nfunction defer<T>(promise: Promise<T>): DeferredPromise<T> {\n const existing = (promise as DeferredPromise<T>)[DEFERRED_KEY];\n if (existing) return promise as DeferredPromise<T>;\n\n const state: DeferredState<T> = { status: 'pending' };\n\n const deferred = promise as DeferredPromise<T>;\n deferred[DEFERRED_KEY] = state;\n\n promise.then(\n (value) => {\n state.status = 'success';\n state.value = value;\n },\n (error) => {\n state.status = 'error';\n state.error = error;\n }\n );\n\n return deferred;\n}\n\nconst DeferredRenderer = memo(function DeferredRenderer<T>({\n promise,\n children,\n}: {\n promise: DeferredPromise<T>;\n children: (data: T) => ReactNode;\n}) {\n const state = promise[DEFERRED_KEY];\n\n if (state?.status === 'success') {\n return children(state.value!);\n }\n\n if (state?.status === 'error') {\n throw state.error;\n }\n\n const data = use(promise);\n return children(data);\n}) as <T>(props: { promise: DeferredPromise<T>; children: (data: T) => ReactNode }) => ReactNode;\n\nfunction DeferredFallback<T>({\n promise,\n fallback,\n children,\n}: {\n promise: DeferredPromise<T>;\n fallback: ReactNode;\n children: (data: T) => ReactNode;\n}) {\n const state = promise[DEFERRED_KEY];\n if (state?.status === 'success') {\n return children(state.value!);\n }\n return <>{fallback}</>;\n}\n\nexport function resolveDeferred<T>(\n promiseOrValue: Promise<T> | T | undefined\n): T | Promise<T> | undefined {\n if (promiseOrValue == null || !(promiseOrValue instanceof Promise)) return promiseOrValue;\n const deferred = defer(promiseOrValue);\n const state = deferred[DEFERRED_KEY];\n if (state?.status === 'success') return state.value as T;\n return promiseOrValue;\n}\n\nexport function DeferredData<T>({ promise, fallback, children }: DeferredDataProps<T>) {\n if (!(promise instanceof Promise)) {\n return children(promise);\n }\n\n if (seenPromises && promise instanceof Promise) seenPromises.add(promise);\n\n const deferred = defer(promise);\n const state = deferred[DEFERRED_KEY];\n\n if (state?.status === 'success') {\n return children(state.value!);\n }\n\n if (state?.status === 'error') {\n throw state.error;\n }\n\n return (\n <Suspense\n fallback={\n <DeferredFallback promise={deferred} fallback={fallback}>\n {children}\n </DeferredFallback>\n }\n >\n <DeferredRenderer promise={deferred}>{children}</DeferredRenderer>\n </Suspense>\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { rememberProductPreview } from './chunk-
|
|
1
|
+
import { rememberProductPreview } from './chunk-W66OHTSM.js';
|
|
2
2
|
import { getActiveScope, api } from './chunk-P3OPJL6I.js';
|
|
3
3
|
import { queryOptions } from '@tanstack/react-query';
|
|
4
4
|
|
|
@@ -31,5 +31,5 @@ var wishlist = {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export { wishlist };
|
|
34
|
-
//# sourceMappingURL=chunk-
|
|
35
|
-
//# sourceMappingURL=chunk-
|
|
34
|
+
//# sourceMappingURL=chunk-VLBQPVHM.js.map
|
|
35
|
+
//# sourceMappingURL=chunk-VLBQPVHM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/wishlist.ts"],"names":[],"mappings":";;;;AAmBO,IAAM,QAAA,GAAW;AAAA,EACtB,IAAA,EAAM,OAAO,MAAA,GAA6B,EAAC,KAAmC;AAC5E,IAAA,MAAM,EAAE,IAAA,GAAO,CAAA,EAAG,UAAU,EAAA,EAAI,UAAA,EAAY,QAAO,GAAI,MAAA;AAEvD,IAAA,MAAM,YAAA,GAAe,IAAI,eAAA,EAAgB;AACzC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAU,UAAU,CAAA;AACrC,IAAA,YAAA,CAAa,GAAA,CAAI,MAAA,EAAQ,MAAA,CAAO,IAAI,CAAC,CAAA;AACrC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAA,EAAY,MAAA,CAAO,OAAO,CAAC,CAAA;AAE5C,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,YAAA,CAAa,GAAA,CAAI,YAAA,EAAc,UAAA,GAAa,GAAA,GAAM,GAAG,CAAA;AAAA,IACvD;AAEA,IAAA,MAAM,UAAmC,EAAC;AAC1C,IAAA,IAAI,MAAA,UAAgB,MAAA,GAAS,MAAA;AAE7B,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CACpB,GAAA,CAAI,CAAA,SAAA,EAAY,YAAA,CAAa,QAAA,EAAU,CAAA,CAAA,EAAI,OAAc,CAAA,CACzD,IAAA,EAA2B;AAE9B,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,IAAQ,EAAC;AAChC,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,sBAAA,CAAuB,IAAI,CAAA;AAErD,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,IAAA,EAAM,QAAA,CAAS,MAAA,EAAQ,IAAA,IAAQ;AAAA,KACjC;AAAA,EACF,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,CAAC,MAAA,KACL,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,UAAA,EAAY,MAAA,EAAQ,QAAQ,EAAE,KAAA,EAAO,cAAA,EAAe,EAAG,CAAA;AAAA,MAClE,OAAA,EAAS,CAAC,EAAE,MAAA,EAAO,KAAM,QAAA,CAAS,IAAA,CAAK,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ;AAAA,KAC7D;AAAA;AAEP","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/api/wishlist.ts"],"names":[],"mappings":";;;;AAmBO,IAAM,QAAA,GAAW;AAAA,EACtB,IAAA,EAAM,OAAO,MAAA,GAA6B,EAAC,KAAmC;AAC5E,IAAA,MAAM,EAAE,IAAA,GAAO,CAAA,EAAG,UAAU,EAAA,EAAI,UAAA,EAAY,QAAO,GAAI,MAAA;AAEvD,IAAA,MAAM,YAAA,GAAe,IAAI,eAAA,EAAgB;AACzC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAU,UAAU,CAAA;AACrC,IAAA,YAAA,CAAa,GAAA,CAAI,MAAA,EAAQ,MAAA,CAAO,IAAI,CAAC,CAAA;AACrC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAA,EAAY,MAAA,CAAO,OAAO,CAAC,CAAA;AAE5C,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,YAAA,CAAa,GAAA,CAAI,YAAA,EAAc,UAAA,GAAa,GAAA,GAAM,GAAG,CAAA;AAAA,IACvD;AAEA,IAAA,MAAM,UAAmC,EAAC;AAC1C,IAAA,IAAI,MAAA,UAAgB,MAAA,GAAS,MAAA;AAE7B,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CACpB,GAAA,CAAI,CAAA,SAAA,EAAY,YAAA,CAAa,QAAA,EAAU,CAAA,CAAA,EAAI,OAAc,CAAA,CACzD,IAAA,EAA2B;AAE9B,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,IAAQ,EAAC;AAChC,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,sBAAA,CAAuB,IAAI,CAAA;AAErD,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,IAAA,EAAM,QAAA,CAAS,MAAA,EAAQ,IAAA,IAAQ;AAAA,KACjC;AAAA,EACF,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,CAAC,MAAA,KACL,YAAA,CAAa;AAAA,MACX,QAAA,EAAU,CAAC,UAAA,EAAY,MAAA,EAAQ,QAAQ,EAAE,KAAA,EAAO,cAAA,EAAe,EAAG,CAAA;AAAA,MAClE,OAAA,EAAS,CAAC,EAAE,MAAA,EAAO,KAAM,QAAA,CAAS,IAAA,CAAK,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ;AAAA,KAC7D;AAAA;AAEP","file":"chunk-VLBQPVHM.js","sourcesContent":["import { queryOptions } from '@tanstack/react-query';\nimport { api, getActiveScope } from './client';\nimport {\n rememberProductPreview,\n type ProductsListResult,\n type ProductsListResponse,\n} from './product';\n\nexport interface WishlistListParams {\n page?: number;\n perPage?: number;\n filterable?: boolean;\n signal?: AbortSignal;\n}\n\n/**\n * Wishlist API — page-based pagination only.\n * Kept separate from product.list to avoid mixing cursor and page pagination strategies.\n */\nexport const wishlist = {\n list: async (params: WishlistListParams = {}): Promise<ProductsListResult> => {\n const { page = 1, perPage = 15, filterable, signal } = params;\n\n const searchParams = new URLSearchParams();\n searchParams.set('source', 'wishlist');\n searchParams.set('page', String(page));\n searchParams.set('per_page', String(perPage));\n\n if (filterable !== undefined) {\n searchParams.set('filterable', filterable ? '1' : '0');\n }\n\n const options: Record<string, unknown> = {};\n if (signal) options.signal = signal;\n\n const response = await api\n .get(`products?${searchParams.toString()}`, options as any)\n .json<ProductsListResponse>();\n\n const items = response.data ?? [];\n for (const item of items) rememberProductPreview(item);\n\n return {\n items,\n next: response.cursor?.next ?? null,\n };\n },\n\n queries: {\n list: (params: Omit<WishlistListParams, 'signal'>) =>\n queryOptions({\n queryKey: ['wishlist', 'list', params, { scope: getActiveScope() }],\n queryFn: ({ signal }) => wishlist.list({ ...params, signal }),\n }),\n },\n};\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { orThrow } from './chunk-
|
|
1
|
+
import { orThrow } from './chunk-I62RENKM.js';
|
|
2
2
|
import { getActiveScope, api } from './chunk-P3OPJL6I.js';
|
|
3
3
|
import { getTwilightContext } from './chunk-N2S25NXP.js';
|
|
4
4
|
import { defaultShouldDehydrateQuery, queryOptions } from '@tanstack/react-query';
|
|
@@ -174,5 +174,5 @@ var product = {
|
|
|
174
174
|
};
|
|
175
175
|
|
|
176
176
|
export { getProductPreview, isProductPreviewQuery, product, productDetailQueryKey, productPreviewQueryKey, rememberProductPreview, shouldDehydrateQuery };
|
|
177
|
-
//# sourceMappingURL=chunk-
|
|
178
|
-
//# sourceMappingURL=chunk-
|
|
177
|
+
//# sourceMappingURL=chunk-W66OHTSM.js.map
|
|
178
|
+
//# sourceMappingURL=chunk-W66OHTSM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api/product.ts"],"names":["product"],"mappings":"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","file":"chunk-TLO2M5TJ.js","sourcesContent":["import { queryOptions, defaultShouldDehydrateQuery } from '@tanstack/react-query';\nimport { api, getActiveScope } from './client';\nimport type { Product } from '../types';\nimport type { Pagination, PaginatedResult } from './types';\nimport { orThrow } from '../providers/NavigationProvider';\nimport { getTwilightContext } from '../twilight/context';\nimport type { ActiveScope } from '../utils/cookies';\n\n// ===== Filter Types =====\n\nexport interface FilterValue {\n key?: string;\n count?: number;\n value?: string;\n from?: number | '*';\n to?: number | '*';\n}\n\nexport interface Filter {\n key?: string;\n label?: string;\n type?: string;\n values?: FilterValue[];\n max?: number;\n min?: number;\n}\n\n// ===== Product List Types =====\n\nexport type ProductsListSource =\n | 'brands'\n | 'categories'\n | 'json'\n | 'landing-page'\n | 'latest'\n | 'offers'\n | 'recently'\n | 'related'\n | 'selected'\n | 'tags'\n | 'top-rated'\n | 'wishlist'\n | 'search'\n | 'sales'\n | 'reorder'\n | 'best_selling';\n\nexport interface ProductsListParams {\n /** Source type (wishlist, latest, brands, etc.) */\n source: ProductsListSource;\n /**\n * The ids the source reads, as an array: category, brand, tag or product ids\n * (`sourceValue: [708738657]`). Sent as `source_value[]`.\n */\n sourceValue?: string | number | number[] | null;\n /** The search words when `source` is `'search'`. Sent as `keyword`; other sources ignore it. */\n keyword?: string;\n /** Page number for offset-based pagination */\n page?: number;\n /** Cursor for cursor-based pagination (from previous response) */\n cursor?: string | null;\n /** Items per page (default: 15) */\n perPage?: number;\n /** Sort option */\n sort?: string;\n /** Enable filters on the response */\n filterable?: boolean;\n /** Applied `<salla-filters>` selection (the `salla-filters::changed` payload). */\n filters?: ProductListFilters;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n}\n\n/** One `<salla-filters>` value: a scalar, a list, or a nested `{ sub-key: value }` (variants). */\nexport type ProductListFilterValue =\n string | number | Array<string | number> | { [key: string]: ProductListFilterValue };\n\n/** A `<salla-filters>` selection, i.e. the `salla-filters::changed` payload. */\nexport type ProductListFilters = Record<string, ProductListFilterValue>;\n\nexport type ProductsListResult = PaginatedResult<Product> & {\n filters?: Filter[];\n};\n\nexport interface ProductsListResponse {\n data: Product[];\n cursor?: Pagination;\n filters?: Filter[];\n}\n\n// ===== List-card preview cache =====\n// List payloads are a subset of details (one `image`, no `options` / `images[]`).\n// They live on a separate query key so they can paint a sheet/quick-view without\n// being treated as a successful `products/{id}/details` fetch.\n\nfunction queryClientOrNull() {\n try {\n const queryClient = getTwilightContext().queryClient;\n return queryClient && typeof queryClient.setQueryData === 'function' ? queryClient : null;\n } catch {\n return null;\n }\n}\n\nexport function productPreviewQueryKey(id: string) {\n return ['products', 'preview', String(id), { scope: getActiveScope() }] as const;\n}\n\nexport function productDetailQueryKey(id: string) {\n return ['products', 'detail', id, { scope: getActiveScope() }] as const;\n}\n\n/** True when this query is a list-card stand-in — skip it when dehydrating SSR. */\nexport function isProductPreviewQuery(query: { queryKey: readonly unknown[] }): boolean {\n return query.queryKey[0] === 'products' && query.queryKey[1] === 'preview';\n}\n\n/**\n * Default dehydrate policy (success) plus pending SSR-stream queries, minus\n * list-card stand-ins. Replacing the default wholesale would ship error states.\n */\nexport function shouldDehydrateQuery(\n query: Parameters<typeof defaultShouldDehydrateQuery>[0]\n): boolean {\n return (\n !isProductPreviewQuery(query) &&\n (defaultShouldDehydrateQuery(query) || query.state.status === 'pending')\n );\n}\n\n/**\n * Remember a list/card product so `product.queries.detail(id)` can use it as\n * `placeholderData` while details load. No-op if details for this id are already\n * cached. Themes that fetch products outside `product.list` should call this.\n */\nexport function rememberProductPreview(product: Product): void {\n const queryClient = queryClientOrNull();\n if (!queryClient || product?.id == null) return;\n const id = String(product.id);\n if (queryClient.getQueryState(productDetailQueryKey(id))?.status === 'success') return;\n queryClient.setQueryData(productPreviewQueryKey(id), product);\n}\n\nfunction scopeFromQueryKey(queryKey: readonly unknown[]): ActiveScope | null | undefined {\n const last = queryKey[queryKey.length - 1];\n if (last == null || typeof last !== 'object' || !('scope' in last)) return undefined;\n return (last as { scope: ActiveScope | null }).scope;\n}\n\nfunction isSameScope(a: ActiveScope | null | undefined, b: ActiveScope | null): boolean {\n if (a === undefined) return false;\n if (a === b) return true;\n if (a == null || b == null) return a == null && b == null;\n return (\n a.id === b.id &&\n a.type === b.type &&\n a.allocation_id === b.allocation_id &&\n a.allocation_type === b.allocation_type\n );\n}\n\nconst LIST_QUERY_PREFIXES = [\n ['products', 'list'],\n ['wishlist', 'list'],\n] as const;\n\n/**\n * Rebuild the scoped preview index from hydrated list/wishlist queries (SSR\n * dehydrate drops preview keys). Subsequent lookups hit `productPreviewQueryKey`.\n */\nfunction findProductInScopedLists(\n queryClient: NonNullable<ReturnType<typeof queryClientOrNull>>,\n id: string\n): Product | undefined {\n const scope = getActiveScope();\n let found: Product | undefined;\n for (const prefix of LIST_QUERY_PREFIXES) {\n for (const [queryKey, data] of queryClient.getQueriesData<ProductsListResult>({\n queryKey: prefix,\n })) {\n if (!isSameScope(scopeFromQueryKey(queryKey), scope)) continue;\n for (const item of data?.items ?? []) {\n if (item?.id == null) continue;\n rememberProductPreview(item);\n if (!found && String(item.id) === id) found = item;\n }\n }\n }\n return found;\n}\n\n/**\n * List-card product for `placeholderData`. Prefers the preview key; if that was\n * dropped on SSR dehydrate, rebuilds it from the current-scope list/wishlist.\n */\nexport function getProductPreview(id: string): Product | undefined {\n const queryClient = queryClientOrNull();\n if (!queryClient) return undefined;\n const key = String(id);\n return (\n queryClient.getQueryData(productPreviewQueryKey(key)) ??\n findProductInScopedLists(queryClient, key)\n );\n}\n\nfunction rememberProductPreviews(items: Product[]): void {\n for (const item of items) rememberProductPreview(item);\n}\n\n/**\n * Search sends its words as `keyword` (a `sourceValue` string is still read there, as before);\n * every other source sends its ids as `source_value[]`, which the API requires as an array.\n */\nfunction appendSourceParams(\n searchParams: URLSearchParams,\n { source, sourceValue, keyword }: Pick<ProductsListParams, 'source' | 'sourceValue' | 'keyword'>\n): void {\n if (source === 'search') {\n const words = keyword ?? sourceValue;\n if (words !== undefined) searchParams.set('keyword', String(words));\n } else if (Array.isArray(sourceValue)) {\n sourceValue.forEach((val) => searchParams.append('source_value[]', String(val)));\n } else if (sourceValue !== undefined) {\n searchParams.append('source_value[]', String(sourceValue));\n }\n}\n\n/**\n * Sends an applied filter selection the way the SDK's `<salla-products-list>` does:\n * `filters[key]=v`, `filters[key][]=v` or `filters[key][sub]=v`.\n */\nfunction appendFilterParams(\n searchParams: URLSearchParams,\n filters?: Record<string, ProductListFilterValue>,\n parentKey = 'filters'\n): void {\n if (!filters) return;\n for (const [key, value] of Object.entries(filters)) {\n const fullKey = `${parentKey}[${key}]`;\n if (Array.isArray(value)) {\n value.forEach((item) => searchParams.append(`${fullKey}[]`, String(item)));\n } else if (value !== null && typeof value === 'object') {\n appendFilterParams(searchParams, value, fullKey);\n } else if (value !== undefined && value !== null) {\n searchParams.append(fullKey, String(value));\n }\n }\n}\n\n/** A `category_id` filter replaces the page's category as the list source (as in the SDK). */\nfunction categoryFilterIds(filters?: ProductListFilters): number[] | null {\n const raw = filters?.category_id;\n if (raw === undefined || raw === null) return null;\n const ids = Array.isArray(raw) ? raw : typeof raw === 'object' ? Object.values(raw) : [raw];\n return ids.map(Number);\n}\n\n// ===== API Functions =====\n\nexport const product = {\n find: async (id: string): Promise<Product> => {\n const endpoint = `products/${id}/details?with[]=images&with[]=category&with[]=rating&with[]=notify_availability&with[]=tags&with[]=brand&with[]=options&with[]=skus&with[]=skus_availability&with[]=included_products&with[]=bundle&with[]=sold_quantity`;\n const { data } = await api.get(endpoint).json<{ data: Product }>();\n return data;\n },\n\n findOrThrow: (id: string): Promise<Product> => orThrow(product.find(id)),\n\n /**\n * Fetch products list with pagination support\n * Used by native ProductsList component for SSR loaders\n *\n * API pattern: GET /products?source=wishlist&page=1\n */\n list: async (params: ProductsListParams): Promise<ProductsListResult> => {\n const {\n source,\n sourceValue,\n keyword,\n page,\n cursor,\n perPage = 16,\n sort,\n filterable,\n filters,\n signal,\n } = params;\n\n // Build URL with query parameters\n const searchParams = new URLSearchParams();\n searchParams.set('source', source);\n // Only send page when explicitly provided — cursor-based callers omit it entirely\n if (page !== undefined) searchParams.set('page', String(page));\n searchParams.set('per_page', String(perPage));\n\n appendSourceParams(searchParams, {\n source,\n sourceValue: (source === 'categories' && categoryFilterIds(filters)) || sourceValue,\n keyword,\n });\n appendFilterParams(searchParams, filters);\n\n // Add filterable parameter\n if (filterable !== undefined) {\n searchParams.set('filterable', filterable ? '1' : '0');\n }\n\n // Add sort parameter\n if (sort) {\n searchParams.set('sort', sort);\n }\n\n // Add cursor for cursor-based pagination\n if (cursor) {\n searchParams.set('cursor', cursor);\n }\n\n // Make the request\n const options: Record<string, unknown> = {};\n if (signal) options.signal = signal;\n\n const response = await api\n .get(`products?${searchParams.toString()}`, options as any)\n .json<ProductsListResponse>();\n\n const items = response.data ?? [];\n rememberProductPreviews(items);\n\n return {\n items,\n next: response.cursor?.next ?? null,\n filters: response.filters,\n };\n },\n\n queries: {\n detail: (id: string) =>\n queryOptions({\n // Stock and availability are resolved per branch allocation — same as the list.\n queryKey: productDetailQueryKey(id),\n queryFn: () => product.find(id),\n // List-card product, if one was remembered. Not written as the detail\n // cache entry — `queryFn` still hits products/{id}/details.\n placeholderData: () => getProductPreview(id),\n }),\n list: (params: Omit<ProductsListParams, 'signal'>) =>\n queryOptions({\n // Scope (branch) varies product availability — key must include it.\n queryKey: ['products', 'list', params, { scope: getActiveScope() }],\n queryFn: ({ signal }) => product.list({ ...params, signal }),\n }),\n },\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/api/product.ts"],"names":["product"],"mappings":";;;;;AA+FA,SAAS,iBAAA,GAAoB;AAC3B,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAAc,oBAAmB,CAAE,WAAA;AACzC,IAAA,OAAO,WAAA,IAAe,OAAO,WAAA,CAAY,YAAA,KAAiB,aAAa,WAAA,GAAc,IAAA;AAAA,EACvF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEO,SAAS,uBAAuB,EAAA,EAAY;AACjD,EAAA,OAAO,CAAC,UAAA,EAAY,SAAA,EAAW,MAAA,CAAO,EAAE,GAAG,EAAE,KAAA,EAAO,cAAA,EAAe,EAAG,CAAA;AACxE;AAEO,SAAS,sBAAsB,EAAA,EAAY;AAChD,EAAA,OAAO,CAAC,YAAY,QAAA,EAAU,EAAA,EAAI,EAAE,KAAA,EAAO,cAAA,IAAkB,CAAA;AAC/D;AAGO,SAAS,sBAAsB,KAAA,EAAkD;AACtF,EAAA,OAAO,KAAA,CAAM,SAAS,CAAC,CAAA,KAAM,cAAc,KAAA,CAAM,QAAA,CAAS,CAAC,CAAA,KAAM,SAAA;AACnE;AAMO,SAAS,qBACd,KAAA,EACS;AACT,EAAA,OACE,CAAC,sBAAsB,KAAK,CAAA,KAC3B,4BAA4B,KAAK,CAAA,IAAK,KAAA,CAAM,KAAA,CAAM,MAAA,KAAW,SAAA,CAAA;AAElE;AAOO,SAAS,uBAAuBA,QAAAA,EAAwB;AAC7D,EAAA,MAAM,cAAc,iBAAA,EAAkB;AACtC,EAAA,IAAI,CAAC,WAAA,IAAeA,QAAAA,EAAS,EAAA,IAAM,IAAA,EAAM;AACzC,EAAA,MAAM,EAAA,GAAK,MAAA,CAAOA,QAAAA,CAAQ,EAAE,CAAA;AAC5B,EAAA,IAAI,YAAY,aAAA,CAAc,qBAAA,CAAsB,EAAE,CAAC,CAAA,EAAG,WAAW,SAAA,EAAW;AAChF,EAAA,WAAA,CAAY,YAAA,CAAa,sBAAA,CAAuB,EAAE,CAAA,EAAGA,QAAO,CAAA;AAC9D;AAEA,SAAS,kBAAkB,QAAA,EAA8D;AACvF,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,QAAA,CAAS,MAAA,GAAS,CAAC,CAAA;AACzC,EAAA,IAAI,IAAA,IAAQ,QAAQ,OAAO,IAAA,KAAS,YAAY,EAAE,OAAA,IAAW,OAAO,OAAO,MAAA;AAC3E,EAAA,OAAQ,IAAA,CAAuC,KAAA;AACjD;AAEA,SAAS,WAAA,CAAY,GAAmC,CAAA,EAAgC;AACtF,EAAA,IAAI,CAAA,KAAM,QAAW,OAAO,KAAA;AAC5B,EAAA,IAAI,CAAA,KAAM,GAAG,OAAO,IAAA;AACpB,EAAA,IAAI,KAAK,IAAA,IAAQ,CAAA,IAAK,MAAM,OAAO,CAAA,IAAK,QAAQ,CAAA,IAAK,IAAA;AACrD,EAAA,OACE,CAAA,CAAE,EAAA,KAAO,CAAA,CAAE,EAAA,IACX,EAAE,IAAA,KAAS,CAAA,CAAE,IAAA,IACb,CAAA,CAAE,aAAA,KAAkB,CAAA,CAAE,aAAA,IACtB,CAAA,CAAE,oBAAoB,CAAA,CAAE,eAAA;AAE5B;AAEA,IAAM,mBAAA,GAAsB;AAAA,EAC1B,CAAC,YAAY,MAAM,CAAA;AAAA,EACnB,CAAC,YAAY,MAAM;AACrB,CAAA;AAMA,SAAS,wBAAA,CACP,aACA,EAAA,EACqB;AACrB,EAAA,MAAM,QAAQ,cAAA,EAAe;AAC7B,EAAA,IAAI,KAAA;AACJ,EAAA,KAAA,MAAW,UAAU,mBAAA,EAAqB;AACxC,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,IAAI,CAAA,IAAK,YAAY,cAAA,CAAmC;AAAA,MAC5E,QAAA,EAAU;AAAA,KACX,CAAA,EAAG;AACF,MAAA,IAAI,CAAC,WAAA,CAAY,iBAAA,CAAkB,QAAQ,CAAA,EAAG,KAAK,CAAA,EAAG;AACtD,MAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,EAAM,KAAA,IAAS,EAAC,EAAG;AACpC,QAAA,IAAI,IAAA,EAAM,MAAM,IAAA,EAAM;AACtB,QAAA,sBAAA,CAAuB,IAAI,CAAA;AAC3B,QAAA,IAAI,CAAC,KAAA,IAAS,MAAA,CAAO,KAAK,EAAE,CAAA,KAAM,IAAI,KAAA,GAAQ,IAAA;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAMO,SAAS,kBAAkB,EAAA,EAAiC;AACjE,EAAA,MAAM,cAAc,iBAAA,EAAkB;AACtC,EAAA,IAAI,CAAC,aAAa,OAAO,MAAA;AACzB,EAAA,MAAM,GAAA,GAAM,OAAO,EAAE,CAAA;AACrB,EAAA,OACE,WAAA,CAAY,aAAa,sBAAA,CAAuB,GAAG,CAAC,CAAA,IACpD,wBAAA,CAAyB,aAAa,GAAG,CAAA;AAE7C;AAEA,SAAS,wBAAwB,KAAA,EAAwB;AACvD,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,sBAAA,CAAuB,IAAI,CAAA;AACvD;AAMA,SAAS,mBACP,YAAA,EACA,EAAE,MAAA,EAAQ,WAAA,EAAa,SAAQ,EACzB;AACN,EAAA,IAAI,WAAW,QAAA,EAAU;AACvB,IAAA,MAAM,QAAQ,OAAA,IAAW,WAAA;AACzB,IAAA,IAAI,UAAU,MAAA,EAAW,YAAA,CAAa,IAAI,SAAA,EAAW,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,EACpE,CAAA,MAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,EAAG;AACrC,IAAA,WAAA,CAAY,OAAA,CAAQ,CAAC,GAAA,KAAQ,YAAA,CAAa,OAAO,gBAAA,EAAkB,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,EACjF,CAAA,MAAA,IAAW,gBAAgB,MAAA,EAAW;AACpC,IAAA,YAAA,CAAa,MAAA,CAAO,gBAAA,EAAkB,MAAA,CAAO,WAAW,CAAC,CAAA;AAAA,EAC3D;AACF;AAMA,SAAS,kBAAA,CACP,YAAA,EACA,OAAA,EACA,SAAA,GAAY,SAAA,EACN;AACN,EAAA,IAAI,CAAC,OAAA,EAAS;AACd,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AAClD,IAAA,MAAM,OAAA,GAAU,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,CAAA;AACnC,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,KAAS,YAAA,CAAa,MAAA,CAAO,CAAA,EAAG,OAAO,CAAA,EAAA,CAAA,EAAM,MAAA,CAAO,IAAI,CAAC,CAAC,CAAA;AAAA,IAC3E,CAAA,MAAA,IAAW,KAAA,KAAU,IAAA,IAAQ,OAAO,UAAU,QAAA,EAAU;AACtD,MAAA,kBAAA,CAAmB,YAAA,EAAc,OAAO,OAAO,CAAA;AAAA,IACjD,CAAA,MAAA,IAAW,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AAChD,MAAA,YAAA,CAAa,MAAA,CAAO,OAAA,EAAS,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,IAC5C;AAAA,EACF;AACF;AAGA,SAAS,kBAAkB,OAAA,EAA+C;AACxE,EAAA,MAAM,MAAM,OAAA,EAAS,WAAA;AACrB,EAAA,IAAI,GAAA,KAAQ,MAAA,IAAa,GAAA,KAAQ,IAAA,EAAM,OAAO,IAAA;AAC9C,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,GAAG,IAAI,GAAA,GAAM,OAAO,GAAA,KAAQ,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA,GAAI,CAAC,GAAG,CAAA;AAC1F,EAAA,OAAO,GAAA,CAAI,IAAI,MAAM,CAAA;AACvB;AAIO,IAAM,OAAA,GAAU;AAAA,EACrB,IAAA,EAAM,OAAO,EAAA,KAAiC;AAC5C,IAAA,MAAM,QAAA,GAAW,YAAY,EAAE,CAAA,wNAAA,CAAA;AAC/B,IAAA,MAAM,EAAE,MAAK,GAAI,MAAM,IAAI,GAAA,CAAI,QAAQ,EAAE,IAAA,EAAwB;AACjE,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAAA,EAEA,aAAa,CAAC,EAAA,KAAiC,QAAQ,OAAA,CAAQ,IAAA,CAAK,EAAE,CAAC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQvE,IAAA,EAAM,OAAO,MAAA,KAA4D;AACvE,IAAA,MAAM;AAAA,MACJ,MAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA,GAAU,EAAA;AAAA,MACV,IAAA;AAAA,MACA,UAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACF,GAAI,MAAA;AAGJ,IAAA,MAAM,YAAA,GAAe,IAAI,eAAA,EAAgB;AACzC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAU,MAAM,CAAA;AAEjC,IAAA,IAAI,SAAS,MAAA,EAAW,YAAA,CAAa,IAAI,MAAA,EAAQ,MAAA,CAAO,IAAI,CAAC,CAAA;AAC7D,IAAA,YAAA,CAAa,GAAA,CAAI,UAAA,EAAY,MAAA,CAAO,OAAO,CAAC,CAAA;AAE5C,IAAA,kBAAA,CAAmB,YAAA,EAAc;AAAA,MAC/B,MAAA;AAAA,MACA,WAAA,EAAc,MAAA,KAAW,YAAA,IAAgB,iBAAA,CAAkB,OAAO,CAAA,IAAM,WAAA;AAAA,MACxE;AAAA,KACD,CAAA;AACD,IAAA,kBAAA,CAAmB,cAAc,OAAO,CAAA;AAGxC,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,YAAA,CAAa,GAAA,CAAI,YAAA,EAAc,UAAA,GAAa,GAAA,GAAM,GAAG,CAAA;AAAA,IACvD;AAGA,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,YAAA,CAAa,GAAA,CAAI,QAAQ,IAAI,CAAA;AAAA,IAC/B;AAGA,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,YAAA,CAAa,GAAA,CAAI,UAAU,MAAM,CAAA;AAAA,IACnC;AAGA,IAAA,MAAM,UAAmC,EAAC;AAC1C,IAAA,IAAI,MAAA,UAAgB,MAAA,GAAS,MAAA;AAE7B,IAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CACpB,GAAA,CAAI,CAAA,SAAA,EAAY,YAAA,CAAa,QAAA,EAAU,CAAA,CAAA,EAAI,OAAc,CAAA,CACzD,IAAA,EAA2B;AAE9B,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,IAAQ,EAAC;AAChC,IAAA,uBAAA,CAAwB,KAAK,CAAA;AAE7B,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,IAAA,EAAM,QAAA,CAAS,MAAA,EAAQ,IAAA,IAAQ,IAAA;AAAA,MAC/B,SAAS,QAAA,CAAS;AAAA,KACpB;AAAA,EACF,CAAA;AAAA,EAEA,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,CAAC,EAAA,KACP,YAAA,CAAa;AAAA;AAAA,MAEX,QAAA,EAAU,sBAAsB,EAAE,CAAA;AAAA,MAClC,OAAA,EAAS,MAAM,OAAA,CAAQ,IAAA,CAAK,EAAE,CAAA;AAAA;AAAA;AAAA,MAG9B,eAAA,EAAiB,MAAM,iBAAA,CAAkB,EAAE;AAAA,KAC5C,CAAA;AAAA,IACH,IAAA,EAAM,CAAC,MAAA,KACL,YAAA,CAAa;AAAA;AAAA,MAEX,QAAA,EAAU,CAAC,UAAA,EAAY,MAAA,EAAQ,QAAQ,EAAE,KAAA,EAAO,cAAA,EAAe,EAAG,CAAA;AAAA,MAClE,OAAA,EAAS,CAAC,EAAE,MAAA,EAAO,KAAM,OAAA,CAAQ,IAAA,CAAK,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ;AAAA,KAC5D;AAAA;AAEP","file":"chunk-W66OHTSM.js","sourcesContent":["import { queryOptions, defaultShouldDehydrateQuery } from '@tanstack/react-query';\nimport { api, getActiveScope } from './client';\nimport type { Product } from '../types';\nimport type { Pagination, PaginatedResult } from './types';\nimport { orThrow } from '../providers/NavigationProvider';\nimport { getTwilightContext } from '../twilight/context';\nimport type { ActiveScope } from '../utils/cookies';\n\n// ===== Filter Types =====\n\nexport interface FilterValue {\n key?: string;\n count?: number;\n value?: string;\n from?: number | '*';\n to?: number | '*';\n}\n\nexport interface Filter {\n key?: string;\n label?: string;\n type?: string;\n values?: FilterValue[];\n max?: number;\n min?: number;\n}\n\n// ===== Product List Types =====\n\nexport type ProductsListSource =\n | 'brands'\n | 'categories'\n | 'json'\n | 'landing-page'\n | 'latest'\n | 'offers'\n | 'recently'\n | 'related'\n | 'selected'\n | 'tags'\n | 'top-rated'\n | 'wishlist'\n | 'search'\n | 'sales'\n | 'reorder'\n | 'best_selling';\n\nexport interface ProductsListParams {\n /** Source type (wishlist, latest, brands, etc.) */\n source: ProductsListSource;\n /**\n * The ids the source reads, as an array: category, brand, tag or product ids\n * (`sourceValue: [708738657]`). Sent as `source_value[]`.\n */\n sourceValue?: string | number | number[] | null;\n /** The search words when `source` is `'search'`. Sent as `keyword`; other sources ignore it. */\n keyword?: string;\n /** Page number for offset-based pagination */\n page?: number;\n /** Cursor for cursor-based pagination (from previous response) */\n cursor?: string | null;\n /** Items per page (default: 15) */\n perPage?: number;\n /** Sort option */\n sort?: string;\n /** Enable filters on the response */\n filterable?: boolean;\n /** Applied `<salla-filters>` selection (the `salla-filters::changed` payload). */\n filters?: ProductListFilters;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n}\n\n/** One `<salla-filters>` value: a scalar, a list, or a nested `{ sub-key: value }` (variants). */\nexport type ProductListFilterValue =\n string | number | Array<string | number> | { [key: string]: ProductListFilterValue };\n\n/** A `<salla-filters>` selection, i.e. the `salla-filters::changed` payload. */\nexport type ProductListFilters = Record<string, ProductListFilterValue>;\n\nexport type ProductsListResult = PaginatedResult<Product> & {\n filters?: Filter[];\n};\n\nexport interface ProductsListResponse {\n data: Product[];\n cursor?: Pagination;\n filters?: Filter[];\n}\n\n// ===== List-card preview cache =====\n// List payloads are a subset of details (one `image`, no `options` / `images[]`).\n// They live on a separate query key so they can paint a sheet/quick-view without\n// being treated as a successful `products/{id}/details` fetch.\n\nfunction queryClientOrNull() {\n try {\n const queryClient = getTwilightContext().queryClient;\n return queryClient && typeof queryClient.setQueryData === 'function' ? queryClient : null;\n } catch {\n return null;\n }\n}\n\nexport function productPreviewQueryKey(id: string) {\n return ['products', 'preview', String(id), { scope: getActiveScope() }] as const;\n}\n\nexport function productDetailQueryKey(id: string) {\n return ['products', 'detail', id, { scope: getActiveScope() }] as const;\n}\n\n/** True when this query is a list-card stand-in — skip it when dehydrating SSR. */\nexport function isProductPreviewQuery(query: { queryKey: readonly unknown[] }): boolean {\n return query.queryKey[0] === 'products' && query.queryKey[1] === 'preview';\n}\n\n/**\n * Default dehydrate policy (success) plus pending SSR-stream queries, minus\n * list-card stand-ins. Replacing the default wholesale would ship error states.\n */\nexport function shouldDehydrateQuery(\n query: Parameters<typeof defaultShouldDehydrateQuery>[0]\n): boolean {\n return (\n !isProductPreviewQuery(query) &&\n (defaultShouldDehydrateQuery(query) || query.state.status === 'pending')\n );\n}\n\n/**\n * Remember a list/card product so `product.queries.detail(id)` can use it as\n * `placeholderData` while details load. No-op if details for this id are already\n * cached. Themes that fetch products outside `product.list` should call this.\n */\nexport function rememberProductPreview(product: Product): void {\n const queryClient = queryClientOrNull();\n if (!queryClient || product?.id == null) return;\n const id = String(product.id);\n if (queryClient.getQueryState(productDetailQueryKey(id))?.status === 'success') return;\n queryClient.setQueryData(productPreviewQueryKey(id), product);\n}\n\nfunction scopeFromQueryKey(queryKey: readonly unknown[]): ActiveScope | null | undefined {\n const last = queryKey[queryKey.length - 1];\n if (last == null || typeof last !== 'object' || !('scope' in last)) return undefined;\n return (last as { scope: ActiveScope | null }).scope;\n}\n\nfunction isSameScope(a: ActiveScope | null | undefined, b: ActiveScope | null): boolean {\n if (a === undefined) return false;\n if (a === b) return true;\n if (a == null || b == null) return a == null && b == null;\n return (\n a.id === b.id &&\n a.type === b.type &&\n a.allocation_id === b.allocation_id &&\n a.allocation_type === b.allocation_type\n );\n}\n\nconst LIST_QUERY_PREFIXES = [\n ['products', 'list'],\n ['wishlist', 'list'],\n] as const;\n\n/**\n * Rebuild the scoped preview index from hydrated list/wishlist queries (SSR\n * dehydrate drops preview keys). Subsequent lookups hit `productPreviewQueryKey`.\n */\nfunction findProductInScopedLists(\n queryClient: NonNullable<ReturnType<typeof queryClientOrNull>>,\n id: string\n): Product | undefined {\n const scope = getActiveScope();\n let found: Product | undefined;\n for (const prefix of LIST_QUERY_PREFIXES) {\n for (const [queryKey, data] of queryClient.getQueriesData<ProductsListResult>({\n queryKey: prefix,\n })) {\n if (!isSameScope(scopeFromQueryKey(queryKey), scope)) continue;\n for (const item of data?.items ?? []) {\n if (item?.id == null) continue;\n rememberProductPreview(item);\n if (!found && String(item.id) === id) found = item;\n }\n }\n }\n return found;\n}\n\n/**\n * List-card product for `placeholderData`. Prefers the preview key; if that was\n * dropped on SSR dehydrate, rebuilds it from the current-scope list/wishlist.\n */\nexport function getProductPreview(id: string): Product | undefined {\n const queryClient = queryClientOrNull();\n if (!queryClient) return undefined;\n const key = String(id);\n return (\n queryClient.getQueryData(productPreviewQueryKey(key)) ??\n findProductInScopedLists(queryClient, key)\n );\n}\n\nfunction rememberProductPreviews(items: Product[]): void {\n for (const item of items) rememberProductPreview(item);\n}\n\n/**\n * Search sends its words as `keyword` (a `sourceValue` string is still read there, as before);\n * every other source sends its ids as `source_value[]`, which the API requires as an array.\n */\nfunction appendSourceParams(\n searchParams: URLSearchParams,\n { source, sourceValue, keyword }: Pick<ProductsListParams, 'source' | 'sourceValue' | 'keyword'>\n): void {\n if (source === 'search') {\n const words = keyword ?? sourceValue;\n if (words !== undefined) searchParams.set('keyword', String(words));\n } else if (Array.isArray(sourceValue)) {\n sourceValue.forEach((val) => searchParams.append('source_value[]', String(val)));\n } else if (sourceValue !== undefined) {\n searchParams.append('source_value[]', String(sourceValue));\n }\n}\n\n/**\n * Sends an applied filter selection the way the SDK's `<salla-products-list>` does:\n * `filters[key]=v`, `filters[key][]=v` or `filters[key][sub]=v`.\n */\nfunction appendFilterParams(\n searchParams: URLSearchParams,\n filters?: Record<string, ProductListFilterValue>,\n parentKey = 'filters'\n): void {\n if (!filters) return;\n for (const [key, value] of Object.entries(filters)) {\n const fullKey = `${parentKey}[${key}]`;\n if (Array.isArray(value)) {\n value.forEach((item) => searchParams.append(`${fullKey}[]`, String(item)));\n } else if (value !== null && typeof value === 'object') {\n appendFilterParams(searchParams, value, fullKey);\n } else if (value !== undefined && value !== null) {\n searchParams.append(fullKey, String(value));\n }\n }\n}\n\n/** A `category_id` filter replaces the page's category as the list source (as in the SDK). */\nfunction categoryFilterIds(filters?: ProductListFilters): number[] | null {\n const raw = filters?.category_id;\n if (raw === undefined || raw === null) return null;\n const ids = Array.isArray(raw) ? raw : typeof raw === 'object' ? Object.values(raw) : [raw];\n return ids.map(Number);\n}\n\n// ===== API Functions =====\n\nexport const product = {\n find: async (id: string): Promise<Product> => {\n const endpoint = `products/${id}/details?with[]=images&with[]=category&with[]=rating&with[]=notify_availability&with[]=tags&with[]=brand&with[]=options&with[]=skus&with[]=skus_availability&with[]=included_products&with[]=bundle&with[]=sold_quantity`;\n const { data } = await api.get(endpoint).json<{ data: Product }>();\n return data;\n },\n\n findOrThrow: (id: string): Promise<Product> => orThrow(product.find(id)),\n\n /**\n * Fetch products list with pagination support\n * Used by native ProductsList component for SSR loaders\n *\n * API pattern: GET /products?source=wishlist&page=1\n */\n list: async (params: ProductsListParams): Promise<ProductsListResult> => {\n const {\n source,\n sourceValue,\n keyword,\n page,\n cursor,\n perPage = 16,\n sort,\n filterable,\n filters,\n signal,\n } = params;\n\n // Build URL with query parameters\n const searchParams = new URLSearchParams();\n searchParams.set('source', source);\n // Only send page when explicitly provided — cursor-based callers omit it entirely\n if (page !== undefined) searchParams.set('page', String(page));\n searchParams.set('per_page', String(perPage));\n\n appendSourceParams(searchParams, {\n source,\n sourceValue: (source === 'categories' && categoryFilterIds(filters)) || sourceValue,\n keyword,\n });\n appendFilterParams(searchParams, filters);\n\n // Add filterable parameter\n if (filterable !== undefined) {\n searchParams.set('filterable', filterable ? '1' : '0');\n }\n\n // Add sort parameter\n if (sort) {\n searchParams.set('sort', sort);\n }\n\n // Add cursor for cursor-based pagination\n if (cursor) {\n searchParams.set('cursor', cursor);\n }\n\n // Make the request\n const options: Record<string, unknown> = {};\n if (signal) options.signal = signal;\n\n const response = await api\n .get(`products?${searchParams.toString()}`, options as any)\n .json<ProductsListResponse>();\n\n const items = response.data ?? [];\n rememberProductPreviews(items);\n\n return {\n items,\n next: response.cursor?.next ?? null,\n filters: response.filters,\n };\n },\n\n queries: {\n detail: (id: string) =>\n queryOptions({\n // Stock and availability are resolved per branch allocation — same as the list.\n queryKey: productDetailQueryKey(id),\n queryFn: () => product.find(id),\n // List-card product, if one was remembered. Not written as the detail\n // cache entry — `queryFn` still hits products/{id}/details.\n placeholderData: () => getProductPreview(id),\n }),\n list: (params: Omit<ProductsListParams, 'signal'>) =>\n queryOptions({\n // Scope (branch) varies product availability — key must include it.\n queryKey: ['products', 'list', params, { scope: getActiveScope() }],\n queryFn: ({ signal }) => product.list({ ...params, signal }),\n }),\n },\n};\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { order } from './chunk-
|
|
1
|
+
import { order } from './chunk-YEY3SO23.js';
|
|
2
2
|
import { buildHreflangAlternates } from './chunk-TZ3E5BN4.js';
|
|
3
|
-
import { unauthorized, orUnauthorized } from './chunk-
|
|
4
|
-
import { RouteId } from './chunk-
|
|
3
|
+
import { unauthorized, orUnauthorized } from './chunk-I62RENKM.js';
|
|
4
|
+
import { RouteId } from './chunk-ZGHRSRDO.js';
|
|
5
5
|
import { getAuthToken } from './chunk-P3OPJL6I.js';
|
|
6
6
|
import { getTwilightContext } from './chunk-N2S25NXP.js';
|
|
7
7
|
import { lazy } from 'react';
|
|
@@ -51,9 +51,9 @@ async function orderSingleLoader({
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// src/routes/account/orders/index.tsx
|
|
54
|
-
var LazyOrdersPage = lazy(() => import('./OrdersPage-
|
|
54
|
+
var LazyOrdersPage = lazy(() => import('./OrdersPage-WI4OSGBF.js').then((m) => ({ default: m.OrdersPage })));
|
|
55
55
|
var LazyOrderSinglePage = lazy(
|
|
56
|
-
() => import('./OrderSinglePage-
|
|
56
|
+
() => import('./OrderSinglePage-7LIUMNRB.js').then((m) => ({ default: m.OrderSinglePage }))
|
|
57
57
|
);
|
|
58
58
|
var OrdersPage = LazyOrdersPage;
|
|
59
59
|
var OrderSinglePage = LazyOrderSinglePage;
|
|
@@ -105,5 +105,5 @@ var OrderSingle = {
|
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
export { OrderSingle, OrderSinglePage, Orders, OrdersPage, orderSingleLoader, ordersLoader };
|
|
108
|
-
//# sourceMappingURL=chunk-
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
108
|
+
//# sourceMappingURL=chunk-XFCJM6RN.js.map
|
|
109
|
+
//# sourceMappingURL=chunk-XFCJM6RN.js.map
|