@salla.sa/twilight-components 3.0.17 → 3.0.19
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/cjs/{Helper-DSYelC4c.js → Helper-DqKJCL8G.js} +1 -1
- package/dist/cjs/{filepond-l9D0Yv7b.js → filepond-Byu0lc8z.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-poster-8SrbLptI.js → filepond-plugin-file-poster-qwx7lYZ-.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-size-DGD6oJy0.js → filepond-plugin-file-validate-size-C-n0P4TT.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-type-BIvrhp3w.js → filepond-plugin-file-validate-type-C8VOOXdT.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-edit-4xKikdXG.js → filepond-plugin-image-edit-B9KG763Y.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-exif-orientation-C3BvwxQh.js → filepond-plugin-image-exif-orientation-Czt4pYzU.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-preview-CBq_GY0V.js → filepond-plugin-image-preview-BFm1Zl0o.js} +1 -1
- package/dist/cjs/free-shipping-timer-6QBe5BNS.js +156 -0
- package/dist/cjs/helpers-NV7wgP50.js +602 -0
- package/dist/cjs/{index-BAwxpXnB.js → index-CFW798jX.js} +2 -2
- package/dist/cjs/{intlTelInput-xw-HaAEN.js → intlTelInput-CLa2B89b.js} +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/salla-accordion-body_2.cjs.entry.js +1 -1
- package/dist/cjs/salla-accordion_6.cjs.entry.js +2 -2
- package/dist/cjs/salla-add-product-button_5.cjs.entry.js +46 -3
- package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
- package/dist/cjs/salla-alert_2.cjs.entry.js +1 -1
- package/dist/cjs/salla-app-install-alert.cjs.entry.js +1 -1
- package/dist/cjs/salla-applied-filters.cjs.entry.js +2 -2
- package/dist/cjs/salla-apps-icons.cjs.entry.js +1 -1
- package/dist/cjs/salla-attachment-view_9.cjs.entry.js +11 -11
- package/dist/cjs/salla-badge.cjs.entry.js +1 -1
- package/dist/cjs/salla-basket-gap.cjs.entry.js +1 -1
- package/dist/cjs/salla-bullet-delivery_3.cjs.entry.js +590 -134
- package/dist/cjs/salla-cart-coupons.cjs.entry.js +1 -1
- package/dist/cjs/salla-cart-item-offers_2.cjs.entry.js +1 -1
- package/dist/cjs/salla-cart-summary-card.cjs.entry.js +1 -1
- package/dist/cjs/salla-cashback-banner.cjs.entry.js +1 -1
- package/dist/cjs/salla-comment-factors.cjs.entry.js +1 -1
- package/dist/cjs/salla-comment-form_9.cjs.entry.js +2 -2
- package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-contacts.cjs.entry.js +1 -1
- package/dist/cjs/salla-cookies-bar.cjs.entry.js +1 -1
- package/dist/cjs/salla-count-down.cjs.entry.js +1 -1
- package/dist/cjs/salla-custom-fields.cjs.entry.js +1 -1
- package/dist/cjs/salla-delivery-promise.cjs.entry.js +2 -2
- package/dist/cjs/salla-edit-order-button.cjs.entry.js +1 -1
- package/dist/cjs/salla-filters-widget.cjs.entry.js +2 -2
- package/dist/cjs/salla-filters.cjs.entry.js +2 -2
- package/dist/cjs/salla-free-shipping-banner.cjs.entry.js +95 -9
- package/dist/cjs/salla-free-shipping-tag.cjs.entry.js +18 -5
- package/dist/cjs/salla-fulfillment-methods.cjs.entry.js +1 -1
- package/dist/cjs/salla-gift-card-redeem_2.cjs.entry.js +1 -1
- package/dist/cjs/salla-gifting.cjs.entry.js +13 -6
- package/dist/cjs/salla-hook.cjs.entry.js +1 -1
- package/dist/cjs/salla-infinite-scroll.cjs.entry.js +2 -2
- package/dist/cjs/salla-installment.cjs.entry.js +1 -1
- package/dist/cjs/salla-list-tile.cjs.entry.js +1 -1
- package/dist/cjs/salla-localization-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-login-modal.cjs.entry.js +7 -2
- package/dist/cjs/salla-loyalty-banner_10.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-exchange-product-card.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-points-banner.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-points-history.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty.cjs.entry.js +1 -1
- package/dist/cjs/salla-maintenance-alert.cjs.entry.js +1 -1
- package/dist/cjs/salla-map_3.cjs.entry.js +1 -1
- package/dist/cjs/salla-menu.cjs.entry.js +1 -1
- package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
- package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +1 -1
- package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +1 -1
- package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +1 -1
- package/dist/cjs/salla-next-order-coupon.cjs.entry.js +1 -1
- package/dist/cjs/salla-notification-item_2.cjs.entry.js +2 -2
- package/dist/cjs/salla-offer-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-branch.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-cancel.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-details.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-edit-item.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-edit-product-card.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-edit.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-items.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-options-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-payment.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-rewards.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-shipments.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-summary.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
- package/dist/cjs/salla-orders.cjs.entry.js +2 -2
- package/dist/cjs/salla-payments.cjs.entry.js +1 -1
- package/dist/cjs/salla-placeholder.cjs.entry.js +1 -1
- package/dist/cjs/salla-price-range.cjs.entry.js +1 -1
- package/dist/cjs/salla-product-card-embed.cjs.entry.js +1 -1
- package/dist/cjs/salla-product-card.cjs.entry.js +1 -1
- package/dist/cjs/salla-product-size-guide.cjs.entry.js +1 -1
- package/dist/cjs/salla-products-list.cjs.entry.js +13 -5
- package/dist/cjs/salla-products-slider.cjs.entry.js +2 -2
- package/dist/cjs/salla-quick-order.cjs.entry.js +1 -1
- package/dist/cjs/salla-rating-modal-v2.cjs.entry.js +7 -4
- package/dist/cjs/salla-rating-modal.cjs.entry.js +2 -2
- package/dist/cjs/salla-review-factors-tags.cjs.entry.js +1 -1
- package/dist/cjs/salla-review-order-item.cjs.entry.js +1 -1
- package/dist/cjs/salla-scopes.cjs.entry.js +1 -1
- package/dist/cjs/salla-search-product-card.cjs.entry.js +1 -1
- package/dist/cjs/salla-search.cjs.entry.js +2 -2
- package/dist/cjs/salla-skeleton.cjs.entry.js +1 -1
- package/dist/cjs/salla-social-share.cjs.entry.js +1 -1
- package/dist/cjs/salla-social.cjs.entry.js +1 -1
- package/dist/cjs/salla-tab-content_3.cjs.entry.js +1 -1
- package/dist/cjs/salla-thank-you-header.cjs.entry.js +1 -1
- package/dist/cjs/salla-thank-you-page.cjs.entry.js +1 -1
- package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
- package/dist/cjs/salla-user-menu.cjs.entry.js +1 -1
- package/dist/cjs/salla-user-profile.cjs.entry.js +1 -1
- package/dist/cjs/salla-user-settings.cjs.entry.js +1 -1
- package/dist/cjs/salla-verify.cjs.entry.js +1 -1
- package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
- package/dist/cjs/salla-wishlist-actions.cjs.entry.js +1 -1
- package/dist/cjs/salla-wishlist-summary.cjs.entry.js +2 -2
- package/dist/cjs/twilight.cjs.js +2 -2
- package/dist/cjs/{vanilla-picker-Cm_uNdps.js → vanilla-picker-Vx_7G7bs.js} +1 -1
- package/dist/collection/components/salla-bullet-delivery/api-service.js +156 -25
- package/dist/collection/components/salla-bullet-delivery/helpers.js +143 -15
- package/dist/collection/components/salla-bullet-delivery/icons.js +17 -0
- package/dist/collection/components/salla-bullet-delivery/salla-bullet-delivery.css +490 -52
- package/dist/collection/components/salla-bullet-delivery/salla-bullet-delivery.js +489 -106
- package/dist/collection/components/salla-bullet-delivery/selector-tracker.js +106 -0
- package/dist/collection/components/salla-free-shipping-banner/salla-free-shipping-banner.css +18 -4
- package/dist/collection/components/salla-free-shipping-banner/salla-free-shipping-banner.js +94 -11
- package/dist/collection/components/salla-free-shipping-tag/salla-free-shipping-tag.css +6 -0
- package/dist/collection/components/salla-free-shipping-tag/salla-free-shipping-tag.js +18 -2
- package/dist/collection/components/salla-gifting/salla-gifting.css +16 -1
- package/dist/collection/components/salla-gifting/salla-gifting.js +11 -4
- package/dist/collection/components/salla-login-modal/salla-login-modal.js +6 -1
- package/dist/collection/components/salla-products-list/salla-products-list.js +11 -3
- package/dist/collection/components/salla-quick-buy/salla-quick-buy.js +44 -1
- package/dist/collection/components/salla-rating-modal/salla-rating-modal-v2.js +5 -2
- package/dist/collection/shared/free-shipping-timer.js +130 -0
- package/dist/components/free-shipping-timer.js +150 -0
- package/dist/components/helpers.js +299 -40
- package/dist/components/index.js +2 -2
- package/dist/components/salla-bullet-delivery.js +595 -133
- package/dist/components/salla-free-shipping-banner.js +95 -8
- package/dist/components/salla-free-shipping-tag.js +17 -3
- package/dist/components/salla-gifting.js +12 -5
- package/dist/components/salla-login-modal2.js +6 -1
- package/dist/components/salla-products-list2.js +11 -3
- package/dist/components/salla-quick-buy2.js +44 -1
- package/dist/components/salla-rating-modal-v22.js +5 -2
- package/dist/docs.json +25 -5
- package/dist/esm/{Helper-POCi7J93.js → Helper-I0CAizv1.js} +1 -1
- package/dist/esm/{filepond-Ct76xW02.js → filepond-DTUYXV0J.js} +1 -1
- package/dist/esm/{filepond-plugin-file-poster-C1OkzGRs.js → filepond-plugin-file-poster-DydZjneT.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-size-gdd-69cO.js → filepond-plugin-file-validate-size-nbsCU2t9.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-type-BaZ2QTzl.js → filepond-plugin-file-validate-type-Cl5B_DIy.js} +1 -1
- package/dist/esm/{filepond-plugin-image-edit-CsoNvf0i.js → filepond-plugin-image-edit-bzskFyFR.js} +1 -1
- package/dist/esm/{filepond-plugin-image-exif-orientation-BHDSe3nH.js → filepond-plugin-image-exif-orientation-MBDuxLaX.js} +1 -1
- package/dist/esm/{filepond-plugin-image-preview-CD_S17z3.js → filepond-plugin-image-preview-N6wzEryW.js} +1 -1
- package/dist/esm/free-shipping-timer-CnTwkF6y.js +150 -0
- package/dist/esm/helpers-Cnh7Qptl.js +568 -0
- package/dist/esm/{index-DmGAR42j.js → index-C9zdeQFI.js} +2 -2
- package/dist/esm/{intlTelInput-D76Q4XFx.js → intlTelInput-B5L9nYtO.js} +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/salla-accordion-body_2.entry.js +1 -1
- package/dist/esm/salla-accordion_6.entry.js +2 -2
- package/dist/esm/salla-add-product-button_5.entry.js +46 -3
- package/dist/esm/salla-advertisement.entry.js +1 -1
- package/dist/esm/salla-alert_2.entry.js +1 -1
- package/dist/esm/salla-app-install-alert.entry.js +1 -1
- package/dist/esm/salla-applied-filters.entry.js +2 -2
- package/dist/esm/salla-apps-icons.entry.js +1 -1
- package/dist/esm/salla-attachment-view_9.entry.js +11 -11
- package/dist/esm/salla-badge.entry.js +1 -1
- package/dist/esm/salla-basket-gap.entry.js +1 -1
- package/dist/esm/salla-bullet-delivery_3.entry.js +590 -134
- package/dist/esm/salla-cart-coupons.entry.js +1 -1
- package/dist/esm/salla-cart-item-offers_2.entry.js +1 -1
- package/dist/esm/salla-cart-summary-card.entry.js +1 -1
- package/dist/esm/salla-cashback-banner.entry.js +1 -1
- package/dist/esm/salla-comment-factors.entry.js +1 -1
- package/dist/esm/salla-comment-form_9.entry.js +2 -2
- package/dist/esm/salla-conditional-offer.entry.js +1 -1
- package/dist/esm/salla-contacts.entry.js +1 -1
- package/dist/esm/salla-cookies-bar.entry.js +1 -1
- package/dist/esm/salla-count-down.entry.js +1 -1
- package/dist/esm/salla-custom-fields.entry.js +1 -1
- package/dist/esm/salla-delivery-promise.entry.js +2 -2
- package/dist/esm/salla-edit-order-button.entry.js +1 -1
- package/dist/esm/salla-filters-widget.entry.js +2 -2
- package/dist/esm/salla-filters.entry.js +2 -2
- package/dist/esm/salla-free-shipping-banner.entry.js +94 -8
- package/dist/esm/salla-free-shipping-tag.entry.js +17 -4
- package/dist/esm/salla-fulfillment-methods.entry.js +1 -1
- package/dist/esm/salla-gift-card-redeem_2.entry.js +1 -1
- package/dist/esm/salla-gifting.entry.js +13 -6
- package/dist/esm/salla-hook.entry.js +1 -1
- package/dist/esm/salla-infinite-scroll.entry.js +2 -2
- package/dist/esm/salla-installment.entry.js +1 -1
- package/dist/esm/salla-list-tile.entry.js +1 -1
- package/dist/esm/salla-localization-modal.entry.js +1 -1
- package/dist/esm/salla-login-modal.entry.js +7 -2
- package/dist/esm/salla-loyalty-banner_10.entry.js +1 -1
- package/dist/esm/salla-loyalty-exchange-product-card.entry.js +1 -1
- package/dist/esm/salla-loyalty-points-banner.entry.js +1 -1
- package/dist/esm/salla-loyalty-points-history.entry.js +1 -1
- package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
- package/dist/esm/salla-loyalty.entry.js +1 -1
- package/dist/esm/salla-maintenance-alert.entry.js +1 -1
- package/dist/esm/salla-map_3.entry.js +1 -1
- package/dist/esm/salla-menu.entry.js +1 -1
- package/dist/esm/salla-metadata.entry.js +1 -1
- package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +1 -1
- package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +1 -1
- package/dist/esm/salla-multiple-bundle-product.entry.js +1 -1
- package/dist/esm/salla-next-order-coupon.entry.js +1 -1
- package/dist/esm/salla-notification-item_2.entry.js +2 -2
- package/dist/esm/salla-offer-modal.entry.js +1 -1
- package/dist/esm/salla-offer.entry.js +1 -1
- package/dist/esm/salla-order-branch.entry.js +1 -1
- package/dist/esm/salla-order-cancel.entry.js +1 -1
- package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
- package/dist/esm/salla-order-details-options.entry.js +1 -1
- package/dist/esm/salla-order-details.entry.js +1 -1
- package/dist/esm/salla-order-edit-item.entry.js +1 -1
- package/dist/esm/salla-order-edit-product-card.entry.js +1 -1
- package/dist/esm/salla-order-edit.entry.js +1 -1
- package/dist/esm/salla-order-items.entry.js +1 -1
- package/dist/esm/salla-order-options-modal.entry.js +1 -1
- package/dist/esm/salla-order-payment.entry.js +1 -1
- package/dist/esm/salla-order-rewards.entry.js +1 -1
- package/dist/esm/salla-order-shipments.entry.js +1 -1
- package/dist/esm/salla-order-summary.entry.js +1 -1
- package/dist/esm/salla-order-totals-card.entry.js +1 -1
- package/dist/esm/salla-orders.entry.js +2 -2
- package/dist/esm/salla-payments.entry.js +1 -1
- package/dist/esm/salla-placeholder.entry.js +1 -1
- package/dist/esm/salla-price-range.entry.js +1 -1
- package/dist/esm/salla-product-card-embed.entry.js +1 -1
- package/dist/esm/salla-product-card.entry.js +1 -1
- package/dist/esm/salla-product-size-guide.entry.js +1 -1
- package/dist/esm/salla-products-list.entry.js +13 -5
- package/dist/esm/salla-products-slider.entry.js +2 -2
- package/dist/esm/salla-quick-order.entry.js +1 -1
- package/dist/esm/salla-rating-modal-v2.entry.js +7 -4
- package/dist/esm/salla-rating-modal.entry.js +2 -2
- package/dist/esm/salla-review-factors-tags.entry.js +1 -1
- package/dist/esm/salla-review-order-item.entry.js +1 -1
- package/dist/esm/salla-scopes.entry.js +1 -1
- package/dist/esm/salla-search-product-card.entry.js +1 -1
- package/dist/esm/salla-search.entry.js +2 -2
- package/dist/esm/salla-skeleton.entry.js +1 -1
- package/dist/esm/salla-social-share.entry.js +1 -1
- package/dist/esm/salla-social.entry.js +1 -1
- package/dist/esm/salla-tab-content_3.entry.js +1 -1
- package/dist/esm/salla-thank-you-header.entry.js +1 -1
- package/dist/esm/salla-thank-you-page.entry.js +1 -1
- package/dist/esm/salla-tiered-offer.entry.js +1 -1
- package/dist/esm/salla-trust-badges.entry.js +1 -1
- package/dist/esm/salla-user-menu.entry.js +1 -1
- package/dist/esm/salla-user-profile.entry.js +1 -1
- package/dist/esm/salla-user-settings.entry.js +1 -1
- package/dist/esm/salla-verify.entry.js +1 -1
- package/dist/esm/salla-wallet.entry.js +1 -1
- package/dist/esm/salla-wishlist-actions.entry.js +1 -1
- package/dist/esm/salla-wishlist-summary.entry.js +2 -2
- package/dist/esm/twilight.js +3 -3
- package/dist/esm/{vanilla-picker-BlIXJyvJ.js → vanilla-picker-CAeu4f87.js} +1 -1
- package/dist/twilight/{p-84d725d4.entry.js → p-01d5cd61.entry.js} +1 -1
- package/dist/twilight/{p-60f4357f.entry.js → p-0213fde4.entry.js} +1 -1
- package/dist/twilight/{p-8f0af317.entry.js → p-036fbfc0.entry.js} +1 -1
- package/dist/twilight/{p-90d4129f.entry.js → p-0add41ce.entry.js} +1 -1
- package/dist/twilight/{p-fed66bcb.entry.js → p-0b0d4942.entry.js} +1 -1
- package/dist/twilight/{p-86ca22d5.entry.js → p-17bcbf9b.entry.js} +1 -1
- package/dist/twilight/{p-b66df976.entry.js → p-1867f7d4.entry.js} +1 -1
- package/dist/twilight/p-194ff38c.entry.js +4 -0
- package/dist/twilight/{p-4057b692.entry.js → p-20f9c62f.entry.js} +1 -1
- package/dist/twilight/{p-783c6346.entry.js → p-252748d9.entry.js} +1 -1
- package/dist/twilight/{p-3d5e862c.entry.js → p-290ce0bc.entry.js} +1 -1
- package/dist/twilight/{p-d68625f7.entry.js → p-2b930157.entry.js} +1 -1
- package/dist/twilight/{p-184ea04c.entry.js → p-2e4e15c5.entry.js} +1 -1
- package/dist/twilight/p-2e6537a3.entry.js +4 -0
- package/dist/twilight/{p-2a3e2404.entry.js → p-30d64bd1.entry.js} +1 -1
- package/dist/twilight/{p-5d4fadd2.entry.js → p-32495dd2.entry.js} +1 -1
- package/dist/twilight/{p-cd7029fc.entry.js → p-32d9da31.entry.js} +1 -1
- package/dist/twilight/{p-7e854633.entry.js → p-32f100f8.entry.js} +1 -1
- package/dist/twilight/{p-dc3ff1f0.entry.js → p-386b3dcd.entry.js} +1 -1
- package/dist/twilight/{p-e8090773.entry.js → p-3a4e86d1.entry.js} +1 -1
- package/dist/twilight/{p-a0a57259.entry.js → p-3b766a79.entry.js} +1 -1
- package/dist/twilight/{p-a5d2ad5e.entry.js → p-3b7a45ec.entry.js} +1 -1
- package/dist/twilight/{p-33ff7967.entry.js → p-3bb0e184.entry.js} +1 -1
- package/dist/twilight/{p-8b39a9f7.entry.js → p-3cc6ca6c.entry.js} +1 -1
- package/dist/twilight/{p-0a794d6f.entry.js → p-4070f808.entry.js} +1 -1
- package/dist/twilight/{p-d2c1457e.entry.js → p-412fb721.entry.js} +1 -1
- package/dist/twilight/{p-fce39869.entry.js → p-427c13b6.entry.js} +1 -1
- package/dist/twilight/{p-49195cb6.entry.js → p-45e0a5d0.entry.js} +1 -1
- package/dist/twilight/{p-cd866be6.entry.js → p-4d615f9f.entry.js} +1 -1
- package/dist/twilight/{p-4f794057.entry.js → p-4d7fc363.entry.js} +1 -1
- package/dist/twilight/{p-9eb92980.entry.js → p-5009f654.entry.js} +1 -1
- package/dist/twilight/{p-f4411a04.entry.js → p-50853b76.entry.js} +1 -1
- package/dist/twilight/{p-b9695308.entry.js → p-550ad1a6.entry.js} +1 -1
- package/dist/twilight/{p-4839d408.entry.js → p-575014c4.entry.js} +1 -1
- package/dist/twilight/{p-f10b887a.entry.js → p-5aee5e44.entry.js} +1 -1
- package/dist/twilight/{p-622bfb21.entry.js → p-619c709c.entry.js} +1 -1
- package/dist/twilight/{p-74f206cf.entry.js → p-6d572fe0.entry.js} +1 -1
- package/dist/twilight/{p-26fec98c.entry.js → p-6f84c662.entry.js} +1 -1
- package/dist/twilight/{p-4a1aa85f.entry.js → p-703b9253.entry.js} +1 -1
- package/dist/twilight/{p-509ad773.entry.js → p-73dea22d.entry.js} +1 -1
- package/dist/twilight/{p-6c7cae8a.entry.js → p-74285af9.entry.js} +1 -1
- package/dist/twilight/{p-31260fae.entry.js → p-777d28f6.entry.js} +1 -1
- package/dist/twilight/{p-4702959a.entry.js → p-7db6ccfe.entry.js} +1 -1
- package/dist/twilight/{p-e89a1905.entry.js → p-7db8d545.entry.js} +1 -1
- package/dist/twilight/{p-0c6a024f.entry.js → p-7fa4d0b6.entry.js} +1 -1
- package/dist/twilight/{p-2e8f95d0.entry.js → p-825c5b73.entry.js} +1 -1
- package/dist/twilight/{p-e5545546.entry.js → p-8262e669.entry.js} +1 -1
- package/dist/twilight/{p-bab5d057.entry.js → p-86d55a6b.entry.js} +1 -1
- package/dist/twilight/{p-0225f396.entry.js → p-8712f7c7.entry.js} +1 -1
- package/dist/twilight/{p-a53e2c74.entry.js → p-8948b58c.entry.js} +1 -1
- package/dist/twilight/{p-37b68ef3.entry.js → p-8b8cf457.entry.js} +1 -1
- package/dist/twilight/{p-8e8e40bc.entry.js → p-8c2992e7.entry.js} +1 -1
- package/dist/twilight/{p-eb160c2e.entry.js → p-8c548259.entry.js} +1 -1
- package/dist/twilight/{p-5d775867.entry.js → p-8eb3fd92.entry.js} +1 -1
- package/dist/twilight/p-908716fb.entry.js +4 -0
- package/dist/twilight/{p-62ba0971.entry.js → p-90a59027.entry.js} +1 -1
- package/dist/twilight/{p-ae9c0abe.entry.js → p-9683535f.entry.js} +1 -1
- package/dist/twilight/{p-89cff0c8.entry.js → p-982e9124.entry.js} +1 -1
- package/dist/twilight/{p-a17784e6.entry.js → p-995b898f.entry.js} +1 -1
- package/dist/twilight/{p-3a3d4cb7.entry.js → p-99cb3dba.entry.js} +1 -1
- package/dist/twilight/{p-6757344a.entry.js → p-9a0218a6.entry.js} +1 -1
- package/dist/twilight/{p-7d337f25.entry.js → p-9cf31ff4.entry.js} +1 -1
- package/dist/twilight/{p-d495cce0.entry.js → p-9d1a5007.entry.js} +1 -1
- package/dist/twilight/{p-57b93850.entry.js → p-9e429047.entry.js} +1 -1
- package/dist/twilight/{p-40083f25.entry.js → p-9e542951.entry.js} +1 -1
- package/dist/twilight/{p-Dhq3oJAe.js → p-BcT9tEVW.js} +1 -1
- package/dist/twilight/{p-Dza6OBFg.js → p-Bgu5gtOF.js} +1 -1
- package/dist/twilight/p-C9zdeQFI.js +5 -0
- package/dist/twilight/{p-BbZqYBfp.js → p-CSGj1pY-.js} +1 -1
- package/dist/twilight/{p-Nyk6-1lq.js → p-CWWgpQ8Q.js} +1 -1
- package/dist/twilight/{p-BwzmoZpm.js → p-Cfz9xit3.js} +1 -1
- package/dist/twilight/{p-iCJI7qYe.js → p-CmYSalnM.js} +1 -1
- package/dist/twilight/p-CnTwkF6y.js +4 -0
- package/dist/twilight/p-Cnh7Qptl.js +4 -0
- package/dist/twilight/{p-DVWVl151.js → p-Dav_R_d2.js} +1 -1
- package/dist/twilight/{p-B7rn1taO.js → p-JGEddAgs.js} +1 -1
- package/dist/twilight/{p-CAc7tX2K.js → p-RflSBQNB.js} +1 -1
- package/dist/twilight/{p-De2wEjqS.js → p-Xgbueas7.js} +1 -1
- package/dist/twilight/{p-64d49f5d.entry.js → p-a070cce0.entry.js} +1 -1
- package/dist/twilight/p-a0bfedad.entry.js +4 -0
- package/dist/twilight/{p-bf29daf3.entry.js → p-a22d9931.entry.js} +1 -1
- package/dist/twilight/{p-2153c6fd.entry.js → p-a3959219.entry.js} +1 -1
- package/dist/twilight/p-a3ca61af.entry.js +4 -0
- package/dist/twilight/{p-0e1248c4.entry.js → p-a55b5c44.entry.js} +1 -1
- package/dist/twilight/{p-24423a8d.entry.js → p-a5fc8358.entry.js} +1 -1
- package/dist/twilight/{p-66f6d722.entry.js → p-aabcd09f.entry.js} +1 -1
- package/dist/twilight/{p-4c801f91.entry.js → p-ad00021e.entry.js} +1 -1
- package/dist/twilight/{p-fae2a8d0.entry.js → p-ade9a68c.entry.js} +1 -1
- package/dist/twilight/{p-83ccad19.entry.js → p-b5e0065a.entry.js} +1 -1
- package/dist/twilight/{p-2a8d6e7e.entry.js → p-bbb09d92.entry.js} +1 -1
- package/dist/twilight/{p-f034968b.entry.js → p-c2df20f8.entry.js} +1 -1
- package/dist/twilight/{p-b38c38fe.entry.js → p-c4274188.entry.js} +1 -1
- package/dist/twilight/{p-d63ce284.entry.js → p-c5e2c781.entry.js} +1 -1
- package/dist/twilight/{p-07450aed.entry.js → p-c64b2b22.entry.js} +1 -1
- package/dist/twilight/{p-14752d03.entry.js → p-c92cc92f.entry.js} +1 -1
- package/dist/twilight/{p-d6c5bf2a.entry.js → p-cb54adac.entry.js} +1 -1
- package/dist/twilight/{p-7750bace.entry.js → p-ce1e45a3.entry.js} +1 -1
- package/dist/twilight/{p-e4d90663.entry.js → p-d0acd7ff.entry.js} +1 -1
- package/dist/twilight/{p-f9b9af72.entry.js → p-d0f903ac.entry.js} +1 -1
- package/dist/twilight/{p-7df4ee74.entry.js → p-d57b49ff.entry.js} +1 -1
- package/dist/twilight/p-db3efb27.entry.js +4 -0
- package/dist/twilight/{p-e81c4521.entry.js → p-db73d0bf.entry.js} +1 -1
- package/dist/twilight/{p-bfb70998.entry.js → p-e20d5e75.entry.js} +1 -1
- package/dist/twilight/{p-1982520c.entry.js → p-e223beca.entry.js} +1 -1
- package/dist/twilight/{p-20939237.entry.js → p-e37da59f.entry.js} +1 -1
- package/dist/twilight/p-e3991836.entry.js +4 -0
- package/dist/twilight/{p-fe413496.entry.js → p-e455709f.entry.js} +1 -1
- package/dist/twilight/{p-cc2c52bb.entry.js → p-e921b2d1.entry.js} +1 -1
- package/dist/twilight/{p-acd48ae7.entry.js → p-ec356e5a.entry.js} +1 -1
- package/dist/twilight/{p-7a985c8c.entry.js → p-eeefc285.entry.js} +1 -1
- package/dist/twilight/{p-120b4694.entry.js → p-f3b12754.entry.js} +1 -1
- package/dist/twilight/{p-c3c99d9e.entry.js → p-f6279a13.entry.js} +1 -1
- package/dist/twilight/{p-b819de23.entry.js → p-f83efc62.entry.js} +1 -1
- package/dist/twilight/{p-8b43035f.entry.js → p-fa622715.entry.js} +1 -1
- package/dist/twilight/{p-b87ea253.entry.js → p-faf00404.entry.js} +1 -1
- package/dist/twilight/twilight.esm.js +1 -1
- package/dist/types/components/salla-bullet-delivery/api-service.d.ts +23 -7
- package/dist/types/components/salla-bullet-delivery/helpers.d.ts +61 -6
- package/dist/types/components/salla-bullet-delivery/icons.d.ts +14 -0
- package/dist/types/components/salla-bullet-delivery/interfaces.d.ts +36 -1
- package/dist/types/components/salla-bullet-delivery/salla-bullet-delivery.d.ts +82 -3
- package/dist/types/components/salla-bullet-delivery/selector-tracker.d.ts +30 -0
- package/dist/types/components/salla-free-shipping-banner/salla-free-shipping-banner.d.ts +19 -5
- package/dist/types/components/salla-free-shipping-tag/salla-free-shipping-tag.d.ts +6 -1
- package/dist/types/components/salla-gifting/salla-gifting.d.ts +1 -0
- package/dist/types/components/salla-quick-buy/salla-quick-buy.d.ts +6 -0
- package/dist/types/components/salla-rating-modal/salla-rating-modal-v2.d.ts +1 -0
- package/dist/types/components.d.ts +11 -25
- package/dist/types/shared/free-shipping-timer.d.ts +36 -0
- package/package.json +5 -5
- package/dist/cjs/free-shipping-DkIKD6ch.js +0 -31
- package/dist/cjs/helpers-8bMfm_mm.js +0 -329
- package/dist/components/free-shipping.js +0 -29
- package/dist/esm/free-shipping-Brg4wsgg.js +0 -29
- package/dist/esm/helpers-DqzaeXrL.js +0 -309
- package/dist/twilight/p-12a8aed8.entry.js +0 -4
- package/dist/twilight/p-4f443e36.entry.js +0 -4
- package/dist/twilight/p-5b81a3d9.entry.js +0 -4
- package/dist/twilight/p-93f26336.entry.js +0 -4
- package/dist/twilight/p-Brg4wsgg.js +0 -4
- package/dist/twilight/p-DmGAR42j.js +0 -5
- package/dist/twilight/p-DqzaeXrL.js +0 -4
- package/dist/twilight/p-c7c868b4.entry.js +0 -4
- package/dist/twilight/p-d5a2ba68.entry.js +0 -4
- package/dist/twilight/p-f8ff074f.entry.js +0 -4
|
@@ -20,7 +20,9 @@ async function withApiErrorHandling(fn, fallback, logLabel) {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
const apiCache = new Map();
|
|
23
|
-
const CACHE_TTL = 5 * 60 * 1000;
|
|
23
|
+
export const CACHE_TTL = 5 * 60 * 1000;
|
|
24
|
+
let branchCacheGeneration = 0;
|
|
25
|
+
const resolvedBranchPages = new WeakMap();
|
|
24
26
|
function getCached(key) {
|
|
25
27
|
const entry = apiCache.get(key);
|
|
26
28
|
if (!entry || Date.now() - entry.timestamp > CACHE_TTL) {
|
|
@@ -32,6 +34,47 @@ function getCached(key) {
|
|
|
32
34
|
function setCache(key, data) {
|
|
33
35
|
apiCache.set(key, { data, timestamp: Date.now() });
|
|
34
36
|
}
|
|
37
|
+
function getCountryBranches(branches, countryId) {
|
|
38
|
+
if (!branches || countryId == null)
|
|
39
|
+
return branches;
|
|
40
|
+
if (branches.some(branch => branch.country?.id == null))
|
|
41
|
+
return null;
|
|
42
|
+
const matches = branches.filter(branch => String(branch.country?.id) === String(countryId));
|
|
43
|
+
return matches.length ? matches : null;
|
|
44
|
+
}
|
|
45
|
+
function getBranchPage({ query, lat, lng, country_id, city_id, page, per_page = 20 }, cachePage = true) {
|
|
46
|
+
const params = { per_page };
|
|
47
|
+
if (query && query.trim().length >= 2)
|
|
48
|
+
params.query = query;
|
|
49
|
+
if (lat)
|
|
50
|
+
params.lat = Number(lat).toFixed(6);
|
|
51
|
+
if (lng)
|
|
52
|
+
params.lng = Number(lng).toFixed(6);
|
|
53
|
+
if (country_id)
|
|
54
|
+
params.country_id = country_id;
|
|
55
|
+
if (city_id)
|
|
56
|
+
params.city_id = city_id;
|
|
57
|
+
if (page && page > 1)
|
|
58
|
+
params.page = page;
|
|
59
|
+
const cacheKey = `branches_${JSON.stringify(params)}`;
|
|
60
|
+
const cached = cachePage ? getCached(cacheKey) : null;
|
|
61
|
+
if (cached)
|
|
62
|
+
return cached;
|
|
63
|
+
const request = (async () => {
|
|
64
|
+
const res = await salla.api.request('branches', { params });
|
|
65
|
+
if (!Array.isArray(res?.data))
|
|
66
|
+
throw new Error('Invalid branches response');
|
|
67
|
+
return { branches: res.data, perPage: per_page, pagination: res.pagination };
|
|
68
|
+
})();
|
|
69
|
+
if (cachePage)
|
|
70
|
+
setCache(cacheKey, request);
|
|
71
|
+
void request.then(page => { resolvedBranchPages.set(request, page); }, () => { });
|
|
72
|
+
void request.catch(() => {
|
|
73
|
+
if (apiCache.get(cacheKey)?.data === request)
|
|
74
|
+
apiCache.delete(cacheKey);
|
|
75
|
+
});
|
|
76
|
+
return request;
|
|
77
|
+
}
|
|
35
78
|
/** Uses country code from API (e.g. 'SA'). */
|
|
36
79
|
export const isSaudiArabia = (countryCode) => String(countryCode).toUpperCase() === 'SA';
|
|
37
80
|
/**
|
|
@@ -141,30 +184,105 @@ export const bulletDeliveryAPI = {
|
|
|
141
184
|
return Array.isArray(data) ? data : [];
|
|
142
185
|
}, [], 'Error fetching user addresses');
|
|
143
186
|
},
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
187
|
+
/** Complete country rows for the city picker; incomplete reads remain retryable. */
|
|
188
|
+
async getAllBranches(country_id, per_page = 20) {
|
|
189
|
+
const collection = await this.getBranchCollection(country_id, per_page, { maxPages: Number.POSITIVE_INFINITY });
|
|
190
|
+
if (!collection.complete)
|
|
191
|
+
throw Object.assign(new Error('Incomplete branch city collection'), { branches: collection.branches });
|
|
192
|
+
return collection.branches;
|
|
193
|
+
},
|
|
194
|
+
/** Keeps loaded branches separate from whether the collection is complete. */
|
|
195
|
+
async getBranchCollection(country_id, per_page = 20, { maxPages = 10, requireComplete = false } = {}) {
|
|
196
|
+
const generation = branchCacheGeneration;
|
|
197
|
+
const cacheKey = `branches_all_${JSON.stringify([country_id ?? null, per_page, maxPages, requireComplete])}`;
|
|
198
|
+
const cached = Number.isFinite(maxPages) ? getCached(cacheKey) : null;
|
|
199
|
+
if (cached)
|
|
200
|
+
return cached;
|
|
201
|
+
const storeBranches = country_id != null ? getCached('branches_all') : null;
|
|
202
|
+
if (country_id == null)
|
|
203
|
+
setCache('branches_first', getBranchPage({ per_page, page: 1 }));
|
|
204
|
+
const partial = { branches: [], complete: false };
|
|
205
|
+
const request = withApiErrorHandling(async () => {
|
|
206
|
+
const sharedFirstPage = storeBranches ? getCached('branches_first') : null;
|
|
207
|
+
const first = sharedFirstPage ? resolvedBranchPages.get(sharedFirstPage) : null;
|
|
208
|
+
if (storeBranches && getCountryBranches(first?.branches ?? null, country_id)) {
|
|
209
|
+
const collection = await storeBranches;
|
|
210
|
+
if (generation !== branchCacheGeneration)
|
|
211
|
+
return { branches: [], complete: false };
|
|
212
|
+
const branches = collection.complete ? getCountryBranches(collection.branches, country_id) : null;
|
|
213
|
+
if (branches)
|
|
214
|
+
return { branches, complete: true };
|
|
215
|
+
}
|
|
216
|
+
for (let page = 1; page <= maxPages; page++) {
|
|
217
|
+
const { branches, pagination } = await getBranchPage({ country_id, per_page, page }, Number.isFinite(maxPages) || page === 1);
|
|
218
|
+
if (generation !== branchCacheGeneration)
|
|
219
|
+
return { branches: [], complete: false };
|
|
220
|
+
const currentPage = Number(pagination?.currentPage ?? page);
|
|
221
|
+
const totalPages = Number(pagination?.totalPages);
|
|
222
|
+
if (page === 1 && totalPages === 0 && !branches.length)
|
|
223
|
+
return { branches: [], complete: true };
|
|
224
|
+
if (pagination && (currentPage !== page || !Number.isInteger(totalPages) || totalPages < page)) {
|
|
225
|
+
throw new Error('Invalid branches pagination');
|
|
226
|
+
}
|
|
227
|
+
partial.branches.push(...branches);
|
|
228
|
+
if (pagination) {
|
|
229
|
+
if (requireComplete && totalPages > maxPages)
|
|
230
|
+
return partial;
|
|
231
|
+
if (page === totalPages)
|
|
232
|
+
return { branches: partial.branches, complete: true };
|
|
233
|
+
if (!branches.length)
|
|
234
|
+
throw new Error('Incomplete branches response');
|
|
235
|
+
}
|
|
236
|
+
else if (branches.length < per_page) {
|
|
237
|
+
return { branches: partial.branches, complete: true };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return partial;
|
|
241
|
+
}, partial, 'Error fetching all branches');
|
|
242
|
+
setCache(cacheKey, request);
|
|
243
|
+
if (country_id == null)
|
|
244
|
+
setCache('branches_all', request);
|
|
245
|
+
void request.then(collection => {
|
|
246
|
+
if (collection.complete) {
|
|
247
|
+
if (generation === branchCacheGeneration && apiCache.get('branches_all')?.data === request) {
|
|
248
|
+
setCache('branches_complete', collection.branches);
|
|
249
|
+
}
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (apiCache.get(cacheKey)?.data === request)
|
|
253
|
+
apiCache.delete(cacheKey);
|
|
254
|
+
if (apiCache.get('branches_all')?.data === request)
|
|
255
|
+
apiCache.delete('branches_all');
|
|
256
|
+
});
|
|
257
|
+
return request;
|
|
258
|
+
},
|
|
259
|
+
async getBranches(filters = {}) {
|
|
260
|
+
const generation = branchCacheGeneration;
|
|
261
|
+
const hasSearchParams = (filters.query && filters.query.trim().length >= 2) || filters.lat || filters.lng || filters.city_id;
|
|
262
|
+
const perPage = filters.per_page ?? 20;
|
|
263
|
+
const offset = ((filters.page ?? 1) - 1) * perPage;
|
|
264
|
+
if (!hasSearchParams) {
|
|
265
|
+
const branches = getCountryBranches(getCached('branches_complete'), filters.country_id);
|
|
266
|
+
if (branches) {
|
|
267
|
+
return branches.slice(offset, offset + perPage);
|
|
268
|
+
}
|
|
269
|
+
const firstPage = getCached('branches_first');
|
|
270
|
+
if (firstPage) {
|
|
271
|
+
const result = resolvedBranchPages.get(firstPage);
|
|
272
|
+
if (generation !== branchCacheGeneration)
|
|
273
|
+
return [];
|
|
274
|
+
if (result) {
|
|
275
|
+
const first = getCountryBranches(result.branches, filters.country_id);
|
|
276
|
+
const complete = result.pagination
|
|
277
|
+
? Number(result.pagination.totalPages) === 1
|
|
278
|
+
: result.branches.length < result.perPage;
|
|
279
|
+
if (first && (first.length >= offset + perPage || complete)) {
|
|
280
|
+
return first.slice(offset, offset + perPage);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
151
284
|
}
|
|
152
|
-
|
|
153
|
-
const params = { per_page };
|
|
154
|
-
if (query?.trim().length >= 2)
|
|
155
|
-
params.query = query;
|
|
156
|
-
if (lat)
|
|
157
|
-
params.lat = lat;
|
|
158
|
-
if (lng)
|
|
159
|
-
params.lng = lng;
|
|
160
|
-
if (country_id)
|
|
161
|
-
params.country_id = country_id;
|
|
162
|
-
const res = await salla.api.request("branches", { params });
|
|
163
|
-
return (Array.isArray(res?.data) ? res.data : []);
|
|
164
|
-
}, [], 'Error fetching branches');
|
|
165
|
-
if (cacheKey && result.length > 0)
|
|
166
|
-
setCache(cacheKey, result);
|
|
167
|
-
return result;
|
|
285
|
+
return withApiErrorHandling(async () => (await getBranchPage(filters)).branches, [], 'Error fetching branches');
|
|
168
286
|
},
|
|
169
287
|
async saveAddressLocation(payload) {
|
|
170
288
|
return withApiErrorHandling(async () => {
|
|
@@ -182,7 +300,12 @@ export const bulletDeliveryAPI = {
|
|
|
182
300
|
}, false, 'Error setting delivery scope');
|
|
183
301
|
},
|
|
184
302
|
async allocateScope(payload) {
|
|
185
|
-
|
|
303
|
+
// A field reason (e.g. branch_id "not accepting orders") is more useful than the generic "invalid fields" message.
|
|
304
|
+
const errMsg = (d) => {
|
|
305
|
+
const body = d;
|
|
306
|
+
const fieldReason = Object.values(body?.error?.fields ?? {}).flat().find((m) => typeof m === 'string' && m.trim());
|
|
307
|
+
return fieldReason ?? body?.error?.message ?? body?.message ?? 'Failed to allocate scope';
|
|
308
|
+
};
|
|
186
309
|
try {
|
|
187
310
|
const response = await salla.api.withoutNotifier(() => salla.api.request("scopes/allocation", payload, 'post'));
|
|
188
311
|
// SDK resolves with { data } and throws on non-2xx; any resolved value is success
|
|
@@ -203,6 +326,14 @@ export const bulletDeliveryAPI = {
|
|
|
203
326
|
},
|
|
204
327
|
};
|
|
205
328
|
export function clearApiCache() {
|
|
329
|
+
branchCacheGeneration++;
|
|
206
330
|
apiCache.clear();
|
|
207
331
|
}
|
|
332
|
+
export function clearBranchCache() {
|
|
333
|
+
branchCacheGeneration++;
|
|
334
|
+
for (const key of apiCache.keys()) {
|
|
335
|
+
if (key.startsWith('branches_'))
|
|
336
|
+
apiCache.delete(key);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
208
339
|
export default bulletDeliveryAPI;
|
|
@@ -31,13 +31,153 @@ export const isBranchSelectable = (branch) => {
|
|
|
31
31
|
const selectable = branch.pickup_readiness?.selectable;
|
|
32
32
|
return typeof selectable === 'boolean' ? selectable : branch.is_open !== false;
|
|
33
33
|
};
|
|
34
|
-
/**
|
|
34
|
+
/** Backend readiness label ("استلمه غدًا", "جاهز {date}") when pickup is not today; null otherwise. */
|
|
35
|
+
export const getBranchReadinessLabel = (branch) => {
|
|
36
|
+
const readiness = branch?.pickup_readiness;
|
|
37
|
+
return readiness?.label && ['tomorrow', 'later'].includes(readiness.state) ? readiness.label : null;
|
|
38
|
+
};
|
|
39
|
+
/** Branch-clock "HH:mm" a branch that is closed now becomes ready at later today; null otherwise. */
|
|
40
|
+
export const getBranchReadyTodayTime = (branch) => {
|
|
41
|
+
const readiness = branch?.pickup_readiness;
|
|
42
|
+
if (readiness?.state !== 'same_day' || branch?.is_open !== false)
|
|
43
|
+
return null;
|
|
44
|
+
return readiness.ready_at?.match(/T(\d{2}:\d{2})/)?.[1] ?? null;
|
|
45
|
+
};
|
|
46
|
+
/** Busy branches (stock at the merchant's stop-orders threshold) stay listed but dimmed and unselectable. */
|
|
47
|
+
export const isBranchBusy = (branch) => branch?.pickup_readiness?.state === 'orders_paused';
|
|
48
|
+
/** Distinct cities of a branch list, in first-seen order (the API lists nearest first). */
|
|
49
|
+
export const getBranchCities = (branches) => {
|
|
50
|
+
const seen = new Set();
|
|
51
|
+
const cities = [];
|
|
52
|
+
for (const { city } of branches) {
|
|
53
|
+
if (!city?.id || seen.has(String(city.id)))
|
|
54
|
+
continue;
|
|
55
|
+
seen.add(String(city.id));
|
|
56
|
+
cities.push({ id: city.id, name: city.name });
|
|
57
|
+
}
|
|
58
|
+
return cities;
|
|
59
|
+
};
|
|
60
|
+
/** "3.52" / "12" — at most two decimals, as the checkout picker shows it; '' when the distance is unknown. */
|
|
61
|
+
export const formatBranchDistance = (km) => {
|
|
62
|
+
if (km == null || Number.isNaN(Number(km)))
|
|
63
|
+
return '';
|
|
64
|
+
return String(Math.round(Number(km) * 100) / 100);
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Readiness states the picker hides outright instead of showing as a disabled card: closed and not
|
|
68
|
+
* taking pickup orders at all. Busy/out-of-stock stay visible-but-disabled so the shopper sees why
|
|
69
|
+
* (same rule as the checkout picker, INV-1414).
|
|
70
|
+
*/
|
|
71
|
+
const HIDDEN_READINESS_STATES = ['closed', 'unavailable'];
|
|
72
|
+
export const isBranchVisible = (branch) => !!branch && !HIDDEN_READINESS_STATES.includes(branch.pickup_readiness?.state);
|
|
73
|
+
/** The branch's pickup offer (INV-1416); null when it has none, or a zero one, so "خصم 0%" never shows. */
|
|
74
|
+
export const getBranchDiscount = (branch) => {
|
|
75
|
+
const type = branch?.discount?.type;
|
|
76
|
+
const amount = Number(branch?.discount?.amount);
|
|
77
|
+
if ((type !== 'percentage' && type !== 'fixed_amount') || !(amount > 0))
|
|
78
|
+
return null;
|
|
79
|
+
return { type, amount };
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Min–max pickup offer across the listed branches, for the pickup tab badge; null when none has one.
|
|
83
|
+
* Branches the picker hides are left out so the tab never advertises an offer the shopper can't pick.
|
|
84
|
+
* A percentage and a fixed amount can't share one range, so percentages win when both are set.
|
|
85
|
+
*/
|
|
86
|
+
export const getBranchDiscountRange = (branches) => {
|
|
87
|
+
const discounts = branches.filter(isBranchVisible).map(getBranchDiscount).filter((d) => !!d);
|
|
88
|
+
if (!discounts.length)
|
|
89
|
+
return null;
|
|
90
|
+
const type = discounts.some(d => d.type === 'percentage') ? 'percentage' : 'fixed_amount';
|
|
91
|
+
const amounts = discounts.filter(d => d.type === type).map(d => d.amount);
|
|
92
|
+
return { type, min: Math.min(...amounts), max: Math.max(...amounts) };
|
|
93
|
+
};
|
|
94
|
+
/** The storefront's working_hours and ready_at use 24h "HH:mm"; null for anything else. */
|
|
95
|
+
export const parseBranchTime = (time) => {
|
|
96
|
+
const match = String(time ?? '').trim().match(/^(\d{1,2}):(\d{2})(?::\d{2})?$/);
|
|
97
|
+
if (!match || Number(match[1]) > 24)
|
|
98
|
+
return null;
|
|
99
|
+
return { hours: Number(match[1]) % 24, minutes: Number(match[2]) };
|
|
100
|
+
};
|
|
101
|
+
/** Date#getDay() keys for the day names the storefront API may send (Arabic or English). */
|
|
102
|
+
const DAY_KEYS = {
|
|
103
|
+
sunday: 0, 'الاحد': 0,
|
|
104
|
+
monday: 1, 'الاثنين': 1,
|
|
105
|
+
tuesday: 2, 'الثلاثاء': 2,
|
|
106
|
+
wednesday: 3, 'الاربعاء': 3,
|
|
107
|
+
thursday: 4, 'الخميس': 4,
|
|
108
|
+
friday: 5, 'الجمعة': 5,
|
|
109
|
+
saturday: 6, 'السبت': 6,
|
|
110
|
+
};
|
|
111
|
+
const dayKeyFromName = (name) => DAY_KEYS[String(name ?? '').trim().toLowerCase().replace(/[أإآ]/g, 'ا')];
|
|
112
|
+
/**
|
|
113
|
+
* The storefront's `working_hours` (`{ name, times: [{ from, to }] }`, 24h times) as weekly
|
|
114
|
+
* schedule rows for the hours dropdown.
|
|
115
|
+
*/
|
|
116
|
+
export const getBranchWeekSchedule = (branch) => (branch.working_hours || [])
|
|
117
|
+
.filter(day => day?.name)
|
|
118
|
+
.map(day => ({
|
|
119
|
+
day_key: dayKeyFromName(day.name),
|
|
120
|
+
day: day.name,
|
|
121
|
+
times: (day.times || []).map(t => ({ start: t.from, end: t.to })),
|
|
122
|
+
}));
|
|
123
|
+
export const isBranchAlwaysOpen = (branch) => !!branch.always_open;
|
|
124
|
+
/**
|
|
125
|
+
* "11:00 م" / "11:00 PM". ar-SA's ICU pattern puts the day period first, which the bidi algorithm
|
|
126
|
+
* scrambles inside RTL text, so the parts are joined in a fixed "h:mm period" order instead.
|
|
127
|
+
*/
|
|
128
|
+
export const formatBranchClockTime = (time, locale) => {
|
|
129
|
+
const parsed = parseBranchTime(time);
|
|
130
|
+
if (!parsed)
|
|
131
|
+
return '';
|
|
132
|
+
const date = new Date(Date.UTC(2000, 0, 1, parsed.hours, parsed.minutes));
|
|
133
|
+
const parts = new Intl.DateTimeFormat(locale === 'ar' ? 'ar-SA-u-nu-latn' : 'en', {
|
|
134
|
+
timeZone: 'UTC',
|
|
135
|
+
hour: '2-digit',
|
|
136
|
+
minute: '2-digit',
|
|
137
|
+
hour12: true,
|
|
138
|
+
}).formatToParts(date);
|
|
139
|
+
const get = (type) => parts.find(p => p.type === type)?.value ?? '';
|
|
140
|
+
return `${get('hour')}:${get('minute')} ${get('dayPeriod')}`;
|
|
141
|
+
};
|
|
142
|
+
const sameTimes = (a, b) => a.length === b.length && a.every((t, i) => t.start === b[i].start && t.end === b[i].end);
|
|
143
|
+
/** Consecutive days with identical hours collapse into one row; the largest groups come first. */
|
|
144
|
+
export const groupBranchSchedule = (weekSchedule) => {
|
|
145
|
+
const groups = [];
|
|
146
|
+
const days = [...(weekSchedule || [])].filter(s => s.times?.length).sort((a, b) => (a.day_key ?? 0) - (b.day_key ?? 0));
|
|
147
|
+
for (const day of days) {
|
|
148
|
+
const last = groups[groups.length - 1];
|
|
149
|
+
if (last && day.day_key === last.lastDayKey + 1 && sameTimes(last.times, day.times)) {
|
|
150
|
+
last.days.push(day.day);
|
|
151
|
+
last.lastDayKey = day.day_key;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
groups.push({ days: [day.day], times: day.times, lastDayKey: day.day_key ?? 0 });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return groups.sort((a, b) => b.days.length - a.days.length).map(({ days, times }) => ({ days, times }));
|
|
158
|
+
};
|
|
159
|
+
/** Keeps the digits and a leading "+" the merchant typed; drops spaces, dashes and brackets. */
|
|
160
|
+
const cleanPhone = (value) => String(value ?? '').trim().replace(/[^\d+]/g, '');
|
|
161
|
+
export const getBranchPhoneHref = (branch) => {
|
|
162
|
+
const phone = cleanPhone(branch.contacts?.phone);
|
|
163
|
+
return phone ? `tel:${phone}` : null;
|
|
164
|
+
};
|
|
165
|
+
/** wa.me wants the international number as bare digits ("+966…" / "00966…" → "966…"). */
|
|
166
|
+
export const getBranchWhatsappHref = (branch) => {
|
|
167
|
+
const digits = cleanPhone(branch.contacts?.whatsapp).replace(/^\+/, '').replace(/^00/, '').replace(/\D/g, '');
|
|
168
|
+
return digits ? `https://wa.me/${digits}` : null;
|
|
169
|
+
};
|
|
170
|
+
export const getBranchDirectionsHref = (branch) => branch.location?.lat != null && branch.location?.lng != null
|
|
171
|
+
? `https://www.google.com/maps?q=${branch.location.lat},${branch.location.lng}`
|
|
172
|
+
: null;
|
|
173
|
+
/** Nearest selectable branch by distance; single pass O(n). */
|
|
35
174
|
export function findNearestBranch(branches, userLat, userLon) {
|
|
36
175
|
let nearest = null;
|
|
37
176
|
let minD = Number.POSITIVE_INFINITY;
|
|
38
177
|
for (const b of branches) {
|
|
39
178
|
const lat = b.location?.lat != null ? Number(b.location.lat) : Number.NaN;
|
|
40
179
|
const lng = b.location?.lng != null ? Number(b.location.lng) : Number.NaN;
|
|
180
|
+
// Closed branches that still take orders are selectable too, so gate on selectability, not is_open.
|
|
41
181
|
if (Number.isNaN(lat) || Number.isNaN(lng) || !isBranchSelectable(b))
|
|
42
182
|
continue;
|
|
43
183
|
const d = calculateDistance(userLat, userLon, lat, lng);
|
|
@@ -61,11 +201,12 @@ export function formatWorkingHoursDisplay(from, to, locale, untilLabel) {
|
|
|
61
201
|
const t = String(to).trim();
|
|
62
202
|
return !f || !t ? '' : f === '00:00' ? `${untilLabel} ${formatTimeTo12h(t, locale)}` : `${formatTimeTo12h(f, locale)} - ${formatTimeTo12h(t, locale)}`;
|
|
63
203
|
}
|
|
204
|
+
/** Matches the fields the branches API searches: branch, city and country names (either language). */
|
|
64
205
|
export const filterBranches = (branches, searchQuery) => {
|
|
65
206
|
if (!searchQuery)
|
|
66
207
|
return branches;
|
|
67
208
|
const q = searchQuery.toLowerCase();
|
|
68
|
-
return branches.filter((b) => b.name.
|
|
209
|
+
return branches.filter((b) => [b.name, b.city?.name, b.city?.name_en, b.country?.name, b.country?.name_en].some((name) => name?.toLowerCase().includes(q)));
|
|
69
210
|
};
|
|
70
211
|
export const getIntentSubtitle = (intent, toAddress, fromBranch) => {
|
|
71
212
|
if (intent.type === 'branch') {
|
|
@@ -85,9 +226,6 @@ export const getIntentRegionId = (i) => idFrom(i?.address_details?.region?.id);
|
|
|
85
226
|
export const getIntentCityId = (i) => idFrom(i?.address_details?.city?.id);
|
|
86
227
|
export const getIntentDistrictId = (i) => idFrom(i?.address_details?.district?.id);
|
|
87
228
|
export const getIntentBranchId = (i) => i?.branch_details?.id;
|
|
88
|
-
/** Intent coordinates (branch tab only; address flow no longer uses coordinates). */
|
|
89
|
-
export const getIntentLatitude = (i) => i?.branch_details?.latitude;
|
|
90
|
-
export const getIntentLongitude = (i) => i?.branch_details?.longitude;
|
|
91
229
|
export const isMapOriginIntent = (i) => !!i && i.type === 'address' && i.address_details?.lat != null && i.address_details?.lng != null;
|
|
92
230
|
export const hasSessionAddressIntent = (intent) => {
|
|
93
231
|
if (!intent || intent.type !== 'address' || intent.address_id)
|
|
@@ -120,13 +258,3 @@ export function buildAddressLocationPayloadFromSelection(options) {
|
|
|
120
258
|
...(shortAddress && { short_address: shortAddress }),
|
|
121
259
|
};
|
|
122
260
|
}
|
|
123
|
-
// Geolocation error codes - fallback constants for non-browser environments
|
|
124
|
-
const GEO_ERROR_PERMISSION_DENIED = typeof GeolocationPositionError !== 'undefined' ? GeolocationPositionError.PERMISSION_DENIED : 1;
|
|
125
|
-
const GEO_ERROR_POSITION_UNAVAILABLE = typeof GeolocationPositionError !== 'undefined' ? GeolocationPositionError.POSITION_UNAVAILABLE : 2;
|
|
126
|
-
const GEO_ERROR_TIMEOUT = typeof GeolocationPositionError !== 'undefined' ? GeolocationPositionError.TIMEOUT : 3;
|
|
127
|
-
const GEO_ERROR_MESSAGES = {
|
|
128
|
-
[GEO_ERROR_PERMISSION_DENIED]: 'Location permission denied',
|
|
129
|
-
[GEO_ERROR_POSITION_UNAVAILABLE]: 'Location unavailable',
|
|
130
|
-
[GEO_ERROR_TIMEOUT]: 'Location timeout',
|
|
131
|
-
};
|
|
132
|
-
export const getGeolocationErrorMessage = (errorCode) => GEO_ERROR_MESSAGES[errorCode] ?? 'An error occurred while detecting location';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Crafted with ❤ by Salla
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Inline icons shared with the checkout pickup picker (Checkout-Module INV-1414), kept byte-identical
|
|
6
|
+
* so both surfaces render the same glyphs.
|
|
7
|
+
*/
|
|
8
|
+
/** Checkout `LightningIcon.vue` — the "save delivery fees" pickup-tab badge. */
|
|
9
|
+
export const LightningIcon = `<svg width="7" height="10" viewBox="0 0 7 10" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.41015 0.036C5.73815 0.084 5.96415 0.222 6.08815 0.45C6.21215 0.678 6.21415 0.952 6.09415 1.272C6.03815 1.432 5.89415 1.72 5.66215 2.136L5.13415 3.108C5.03015 3.308 4.96215 3.44 4.93015 3.504C4.91415 3.544 4.90215 3.576 4.89415 3.6C4.89415 3.656 4.91815 3.7 4.96615 3.732C4.99015 3.74 5.02615 3.748 5.07415 3.756H5.51815C5.79815 3.756 5.99015 3.76 6.09415 3.768C6.30215 3.784 6.45815 3.832 6.56215 3.912C6.70615 4.008 6.81215 4.138 6.88015 4.302C6.94815 4.466 6.97015 4.636 6.94615 4.812C6.93015 4.948 6.85815 5.1 6.73015 5.268C6.66615 5.356 6.53815 5.508 6.34615 5.724L3.65815 8.82C3.35415 9.172 3.14815 9.398 3.04015 9.498C2.93215 9.598 2.83415 9.664 2.74615 9.696C2.58615 9.768 2.43415 9.766 2.29015 9.69C2.14615 9.614 2.05415 9.488 2.01415 9.312C1.99815 9.208 1.99615 9.08 2.00815 8.928C2.02015 8.776 2.07415 8.472 2.17015 8.016L2.50615 6.432C2.57815 6.104 2.61815 5.888 2.62615 5.784C2.63415 5.728 2.62215 5.686 2.59015 5.658C2.55815 5.63 2.52615 5.612 2.49415 5.604C2.39815 5.588 2.18615 5.58 1.85815 5.58H1.60615C1.19815 5.58 0.918154 5.568 0.766154 5.544C0.462154 5.504 0.246154 5.38 0.118154 5.172C-0.00984615 4.964 -0.0338462 4.704 0.0461538 4.392C0.0861538 4.24 0.190154 3.968 0.358154 3.576L1.25815 1.464C1.41015 1.112 1.51815 0.872 1.58215 0.744C1.71015 0.512 1.85815 0.34 2.02615 0.228C2.19415 0.116 2.40215 0.048 2.65015 0.024C2.79415 0.008 3.05415 0 3.43015 0H4.47415C4.93815 0 5.25015 0.012 5.41015 0.036Z" fill="white"/></svg>`;
|
|
10
|
+
/** Pickup-instructions line on the branch card (design-provided). */
|
|
11
|
+
export const NotesIcon = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.58709 4.67775L11.769 5.52554M7.90501 7.20895L9.49598 7.63284M7.98415 11.9777L8.62054 12.1472C10.4205 12.6268 11.3205 12.8666 12.0295 12.4595C12.7385 12.0525 12.9797 11.1576 13.462 9.36777L14.1441 6.83657C14.6264 5.04674 14.8675 4.15183 14.4582 3.44681C14.0488 2.7418 13.1488 2.50201 11.3489 2.02242L10.7125 1.85287C8.91249 1.37328 8.0125 1.13349 7.30349 1.54053C6.59447 1.94757 6.35332 2.84249 5.87102 4.63231L5.18894 7.16351C4.70664 8.95334 4.46549 9.84825 4.87484 10.5533C5.28419 11.2583 6.18418 11.4981 7.98415 11.9777Z" stroke="#555555" stroke-width="1.125" stroke-linecap="round"/><path d="M8.00016 13.964L7.36527 14.1369C5.56952 14.6259 4.67164 14.8704 3.96429 14.4554C3.25694 14.0404 3.01636 13.1279 2.53519 11.303L1.85471 8.72211C1.37354 6.89717 1.13295 5.98471 1.54134 5.26586C1.89461 4.64404 2.66683 4.66668 3.66683 4.66661" stroke="#555555" stroke-width="1.125" stroke-linecap="round"/></svg>`;
|
|
12
|
+
/** Pickup-availability (preparation time) line on the branch card (design-provided). */
|
|
13
|
+
export const PickupAvailabilityIcon = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="8.00016" cy="8.00004" r="6.66667" stroke="#555555" stroke-width="1.125"/><path d="M8 5.33337V8.00004L9.33333 9.33337" stroke="#555555" stroke-width="1.125" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
14
|
+
/** Working-hours (open/closed status) line on the branch card (design-provided). */
|
|
15
|
+
export const WorkingHoursIcon = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.00014 14.6667C4.31824 14.6667 1.3335 11.6819 1.3335 8.00004C1.3335 4.31814 4.31826 1.33337 8.00016 1.33337C10.9853 1.33337 13.484 3.2953 14.3335 6.00004H12.6668" stroke="#666666" stroke-width="1.125" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 5.33337V8.00004L9.33333 9.33337" stroke="#666666" stroke-width="1.125" stroke-linecap="round" stroke-linejoin="round"/><path d="M14.6367 8.66667C14.6565 8.44724 14.6667 8.22486 14.6667 8M10 14.6667C10.2277 14.5917 10.4502 14.5043 10.6667 14.4052M13.8604 11.3333C13.989 11.0856 14.1036 10.8288 14.2034 10.5641M12.1283 13.4862C12.358 13.2961 12.5754 13.0905 12.7792 12.871" stroke="#666666" stroke-width="1.125" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
|
16
|
+
/** Location (country, city, district) line on the branch card (design-provided). */
|
|
17
|
+
export const BranchLocationIcon = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="8.00016" cy="4.66667" r="2.66667" stroke="#555555" stroke-width="1.125"/><path d="M8 7.33337L8 12" stroke="#555555" stroke-width="1.125" stroke-linecap="round"/><path d="M11.3332 12.6666C11.3332 13.403 9.84079 14 7.99984 14C6.15889 14 4.6665 13.403 4.6665 12.6666" stroke="#555555" stroke-width="1.125" stroke-linecap="round"/></svg>`;
|