@salla.sa/twilight-components 3.0.18 → 3.0.20
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-D2VNt6eb.js → Helper-C3MBaLHQ.js} +1 -1
- package/dist/cjs/delivery-promise-intent-5WTKLkFZ.js +71 -0
- package/dist/cjs/{filepond-DkCudLhG.js → filepond-DGt10gCq.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-poster-C-uxFWfW.js → filepond-plugin-file-poster-NSV7ClY6.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-size-BikXTQW2.js → filepond-plugin-file-validate-size-C08-fDj7.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-type-Drs7PouU.js → filepond-plugin-file-validate-type-CbbTh4qd.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-edit-hxr0h9kt.js → filepond-plugin-image-edit-CqqtsmjD.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-exif-orientation-CVZmWU_4.js → filepond-plugin-image-exif-orientation-D60HJIiL.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-preview-CBjPKx-d.js → filepond-plugin-image-preview-B7bWOXFm.js} +1 -1
- package/dist/cjs/helpers-wRMwEkLy.js +627 -0
- package/dist/cjs/{index-CTYg2zC6.js → index-U-OadFju.js} +14 -10
- package/dist/cjs/{intlTelInput-C9X0hKXV.js → intlTelInput-Cp6WJvPO.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 +164 -7
- 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 +13 -13
- 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 +435 -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 +4 -4
- 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 +5 -65
- 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 +1 -1
- package/dist/cjs/salla-free-shipping-tag.cjs.entry.js +1 -1
- package/dist/cjs/salla-fulfillment-methods.cjs.entry.js +1 -1
- package/dist/cjs/salla-gift-card-redeem_2.cjs.entry.js +2 -2
- package/dist/cjs/salla-gifting.cjs.entry.js +1 -1
- 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-mobile-update-modal.cjs.entry.js +188 -0
- package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +4 -4
- package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +6 -6
- package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +2 -2
- package/dist/cjs/salla-next-order-coupon.cjs.entry.js +1 -1
- package/dist/cjs/salla-notification-item_2.cjs.entry.js +3 -3
- package/dist/cjs/salla-offer-modal.cjs.entry.js +2 -2
- 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 +2 -2
- package/dist/cjs/salla-order-edit-item.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-edit-product-card.cjs.entry.js +2 -2
- package/dist/cjs/salla-order-edit.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-items.cjs.entry.js +2 -2
- package/dist/cjs/salla-order-options-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-payment.cjs.entry.js +2 -2
- package/dist/cjs/salla-order-rewards.cjs.entry.js +2 -2
- package/dist/cjs/salla-order-shipments.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-summary.cjs.entry.js +2 -2
- 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 +3 -3
- package/dist/cjs/salla-placeholder.cjs.entry.js +2 -2
- package/dist/cjs/salla-price-range.cjs.entry.js +1 -1
- package/dist/cjs/salla-product-card-embed.cjs.entry.js +2 -2
- package/dist/cjs/salla-product-card.cjs.entry.js +1 -1
- package/dist/cjs/salla-product-size-guide.cjs.entry.js +3 -3
- package/dist/cjs/salla-products-list.cjs.entry.js +9 -2
- 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 +33 -7
- package/dist/cjs/salla-rating-modal.cjs.entry.js +2 -2
- package/dist/cjs/salla-review-factors-tags.cjs.entry.js +2 -2
- 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 +3 -3
- package/dist/cjs/salla-search.cjs.entry.js +2 -2
- package/dist/cjs/salla-skeleton.cjs.entry.js +2 -2
- package/dist/cjs/salla-social-share.cjs.entry.js +2 -2
- package/dist/cjs/salla-social.cjs.entry.js +2 -2
- package/dist/cjs/salla-tab-content_3.cjs.entry.js +4 -4
- package/dist/cjs/salla-thank-you-header.cjs.entry.js +2 -2
- package/dist/cjs/salla-thank-you-page.cjs.entry.js +2 -2
- 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 +2 -2
- package/dist/cjs/salla-verify.cjs.entry.js +3 -3
- package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
- package/dist/cjs/salla-wishlist-actions.cjs.entry.js +2 -2
- package/dist/cjs/salla-wishlist-summary.cjs.entry.js +2 -2
- package/dist/cjs/twilight.cjs.js +2 -2
- package/dist/cjs/{vanilla-picker-BsLm8rHT.js → vanilla-picker-C-rN_NiT.js} +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/salla-bullet-delivery/api-service.js +156 -25
- package/dist/collection/components/salla-bullet-delivery/helpers.js +166 -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 +423 -101
- package/dist/collection/components/salla-login-modal/salla-login-modal.js +6 -1
- package/dist/collection/components/salla-mobile-update-modal/salla-mobile-update-modal.css +43 -0
- package/dist/collection/components/salla-mobile-update-modal/salla-mobile-update-modal.js +235 -0
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-cart.js +1 -1
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-details.js +2 -2
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-options-modal.js +4 -4
- package/dist/collection/components/salla-multiple-bundle-product/components/salla-multiple-bundle-product-slider.js +1 -1
- package/dist/collection/components/salla-multiple-bundle-product/salla-multiple-bundle-product.js +1 -1
- package/dist/collection/components/salla-notifications/salla-notification-item.js +1 -1
- package/dist/collection/components/salla-offer-modal/salla-offer-modal.js +1 -1
- package/dist/collection/components/salla-order-details/salla-order-details.js +1 -1
- package/dist/collection/components/salla-order-edit/salla-order-edit-product-card.js +1 -1
- package/dist/collection/components/salla-order-items/salla-order-items.js +1 -1
- package/dist/collection/components/salla-order-payment/salla-order-payment.js +1 -1
- package/dist/collection/components/salla-order-rewards/salla-order-rewards.js +1 -1
- package/dist/collection/components/salla-order-summary/salla-order-summary.js +1 -1
- package/dist/collection/components/salla-payments/salla-payments.js +2 -2
- package/dist/collection/components/salla-placeholder/salla-placeholder.js +1 -1
- package/dist/collection/components/salla-product-availability/salla-product-availability.js +1 -1
- package/dist/collection/components/salla-product-card-embed/salla-product-card-embed.js +1 -1
- package/dist/collection/components/salla-product-size-guide/salla-product-size-guide.js +2 -2
- package/dist/collection/components/salla-products-list/salla-products-list.js +7 -0
- package/dist/collection/components/salla-quantity-input/salla-quantity-input.js +1 -1
- package/dist/collection/components/salla-quick-buy/salla-quick-buy.js +91 -2
- package/dist/collection/components/salla-rating-modal/salla-rating-modal-v2.js +31 -5
- package/dist/collection/components/salla-review-card/salla-review-card.js +1 -1
- package/dist/collection/components/salla-review-factors-tags/salla-review-factors-tags.js +1 -1
- package/dist/collection/components/salla-reviews-page/salla-reviews-page.js +1 -1
- package/dist/collection/components/salla-search-product-card/salla-search-product-card.js +2 -2
- package/dist/collection/components/salla-searchable-dropdown/salla-searchable-dropdown.js +4 -4
- package/dist/collection/components/salla-skeleton/salla-skeleton.js +1 -1
- package/dist/collection/components/salla-social/salla-social.js +1 -1
- package/dist/collection/components/salla-social-share/salla-social-share.js +1 -1
- package/dist/collection/components/salla-tabs/salla-tab-content.js +1 -1
- package/dist/collection/components/salla-tabs/salla-tab-header.js +1 -1
- package/dist/collection/components/salla-tabs/salla-tabs.js +1 -1
- package/dist/collection/components/salla-tel-input/salla-tel-input.js +1 -1
- package/dist/collection/components/salla-thank-you-header/salla-thank-you-header.js +1 -1
- package/dist/collection/components/salla-thank-you-page/salla-thank-you-page.js +1 -1
- package/dist/collection/components/salla-tooltip/salla-tooltip.js +1 -1
- package/dist/collection/components/salla-user-settings/salla-user-settings.js +1 -1
- package/dist/collection/components/salla-verify/salla-verify.js +48 -2
- package/dist/collection/components/salla-wishlist-actions/salla-wishlist-actions.js +1 -1
- package/dist/components/delivery-promise-intent.js +67 -0
- package/dist/components/helpers.js +322 -40
- package/dist/components/index.js +2 -2
- package/dist/components/mail.js +2 -2
- package/dist/components/salla-bullet-delivery.js +436 -129
- package/dist/components/salla-contacts.js +2 -2
- package/dist/components/salla-delivery-promise.js +1 -62
- package/dist/components/salla-login-modal2.js +6 -1
- package/dist/components/salla-loyalty-point2.js +2 -2
- package/dist/components/salla-mobile-update-modal.d.ts +11 -0
- package/dist/components/salla-mobile-update-modal.js +241 -0
- package/dist/components/salla-multiple-bundle-product-cart2.js +1 -1
- package/dist/components/salla-multiple-bundle-product-details2.js +2 -2
- package/dist/components/salla-multiple-bundle-product-options-modal2.js +4 -4
- package/dist/components/salla-multiple-bundle-product-slider2.js +1 -1
- package/dist/components/salla-multiple-bundle-product.js +1 -1
- package/dist/components/salla-notification-item2.js +1 -1
- package/dist/components/salla-offer-modal.js +1 -1
- package/dist/components/salla-order-details.js +1 -1
- package/dist/components/salla-order-edit-product-card.js +1 -1
- package/dist/components/salla-order-items2.js +1 -1
- package/dist/components/salla-order-payment.js +1 -1
- package/dist/components/salla-order-rewards.js +1 -1
- package/dist/components/salla-order-summary.js +1 -1
- package/dist/components/salla-payments.js +2 -2
- package/dist/components/salla-placeholder2.js +1 -1
- package/dist/components/salla-product-availability2.js +1 -1
- package/dist/components/salla-product-card-embed.js +1 -1
- package/dist/components/salla-product-size-guide.js +2 -2
- package/dist/components/salla-products-list2.js +7 -0
- package/dist/components/salla-quantity-input2.js +1 -1
- package/dist/components/salla-quick-buy2.js +161 -4
- package/dist/components/salla-quick-order.js +2 -2
- package/dist/components/salla-rating-modal-v22.js +33 -7
- package/dist/components/salla-rating-modal2.js +2 -2
- package/dist/components/salla-review-card2.js +1 -1
- package/dist/components/salla-review-factors-tags2.js +1 -1
- package/dist/components/salla-reviews-page.js +1 -1
- package/dist/components/salla-search-product-card2.js +2 -2
- package/dist/components/salla-searchable-dropdown2.js +4 -4
- package/dist/components/salla-skeleton2.js +1 -1
- package/dist/components/salla-social-share2.js +4 -4
- package/dist/components/salla-social.js +1 -1
- package/dist/components/salla-tab-content2.js +1 -1
- package/dist/components/salla-tab-header2.js +1 -1
- package/dist/components/salla-tabs2.js +1 -1
- package/dist/components/salla-tel-input2.js +1 -1
- package/dist/components/salla-thank-you-header.js +1 -1
- package/dist/components/salla-thank-you-page.js +1 -1
- package/dist/components/salla-tooltip2.js +1 -1
- package/dist/components/salla-user-settings.js +1 -1
- package/dist/components/salla-verify.js +1 -321
- package/dist/components/salla-verify2.js +328 -0
- package/dist/components/salla-wishlist-actions.js +1 -1
- package/dist/docs.json +158 -2
- package/dist/esm/{Helper-C1T-oD4J.js → Helper-BKruFMBN.js} +1 -1
- package/dist/esm/delivery-promise-intent-C6pZjRut.js +67 -0
- package/dist/esm/{filepond-BoWJzHeN.js → filepond-Vl6a--vT.js} +1 -1
- package/dist/esm/{filepond-plugin-file-poster-B6MkMtuC.js → filepond-plugin-file-poster-CrQqmzd5.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-size-Dds_462B.js → filepond-plugin-file-validate-size-BrHjddJa.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-type-DrfGXNay.js → filepond-plugin-file-validate-type-BeMZq9Fl.js} +1 -1
- package/dist/esm/{filepond-plugin-image-edit-CN7eGg-7.js → filepond-plugin-image-edit-DW6JzY39.js} +1 -1
- package/dist/esm/{filepond-plugin-image-exif-orientation-CyhxK_6R.js → filepond-plugin-image-exif-orientation-gzIIB75B.js} +1 -1
- package/dist/esm/{filepond-plugin-image-preview-DdKqAzT9.js → filepond-plugin-image-preview-BwbtnJIU.js} +1 -1
- package/dist/esm/helpers-BVaKfTMx.js +591 -0
- package/dist/esm/{index-DgUQRYr2.js → index-CrXKQnBu.js} +14 -10
- package/dist/esm/{intlTelInput-SwlavcFB.js → intlTelInput-BkjSbnO6.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 +164 -7
- 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 +13 -13
- 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 +435 -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 +4 -4
- 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 +3 -63
- 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 +1 -1
- package/dist/esm/salla-free-shipping-tag.entry.js +1 -1
- package/dist/esm/salla-fulfillment-methods.entry.js +1 -1
- package/dist/esm/salla-gift-card-redeem_2.entry.js +2 -2
- package/dist/esm/salla-gifting.entry.js +1 -1
- 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-mobile-update-modal.entry.js +186 -0
- package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +4 -4
- package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +6 -6
- package/dist/esm/salla-multiple-bundle-product.entry.js +2 -2
- package/dist/esm/salla-next-order-coupon.entry.js +1 -1
- package/dist/esm/salla-notification-item_2.entry.js +3 -3
- package/dist/esm/salla-offer-modal.entry.js +2 -2
- 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 +2 -2
- package/dist/esm/salla-order-edit-item.entry.js +1 -1
- package/dist/esm/salla-order-edit-product-card.entry.js +2 -2
- package/dist/esm/salla-order-edit.entry.js +1 -1
- package/dist/esm/salla-order-items.entry.js +2 -2
- package/dist/esm/salla-order-options-modal.entry.js +1 -1
- package/dist/esm/salla-order-payment.entry.js +2 -2
- package/dist/esm/salla-order-rewards.entry.js +2 -2
- package/dist/esm/salla-order-shipments.entry.js +1 -1
- package/dist/esm/salla-order-summary.entry.js +2 -2
- 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 +3 -3
- package/dist/esm/salla-placeholder.entry.js +2 -2
- package/dist/esm/salla-price-range.entry.js +1 -1
- package/dist/esm/salla-product-card-embed.entry.js +2 -2
- package/dist/esm/salla-product-card.entry.js +1 -1
- package/dist/esm/salla-product-size-guide.entry.js +3 -3
- package/dist/esm/salla-products-list.entry.js +9 -2
- 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 +33 -7
- package/dist/esm/salla-rating-modal.entry.js +2 -2
- package/dist/esm/salla-review-factors-tags.entry.js +2 -2
- 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 +3 -3
- package/dist/esm/salla-search.entry.js +2 -2
- package/dist/esm/salla-skeleton.entry.js +2 -2
- package/dist/esm/salla-social-share.entry.js +2 -2
- package/dist/esm/salla-social.entry.js +2 -2
- package/dist/esm/salla-tab-content_3.entry.js +4 -4
- package/dist/esm/salla-thank-you-header.entry.js +2 -2
- package/dist/esm/salla-thank-you-page.entry.js +2 -2
- 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 +2 -2
- package/dist/esm/salla-verify.entry.js +3 -3
- package/dist/esm/salla-wallet.entry.js +1 -1
- package/dist/esm/salla-wishlist-actions.entry.js +2 -2
- package/dist/esm/salla-wishlist-summary.entry.js +2 -2
- package/dist/esm/twilight.js +3 -3
- package/dist/esm/{vanilla-picker-Buy50D7t.js → vanilla-picker-eSagUASw.js} +1 -1
- package/dist/twilight/p-0050dd2a.entry.js +4 -0
- package/dist/twilight/{p-3d8b77f7.entry.js → p-012ff05c.entry.js} +1 -1
- package/dist/twilight/{p-08a15c81.entry.js → p-02ce2139.entry.js} +1 -1
- package/dist/twilight/{p-b0d2e31f.entry.js → p-059aa8a9.entry.js} +1 -1
- package/dist/twilight/{p-0d795b58.entry.js → p-09798a10.entry.js} +1 -1
- package/dist/twilight/p-0af7555c.entry.js +4 -0
- package/dist/twilight/{p-bed68e52.entry.js → p-11075f15.entry.js} +1 -1
- package/dist/twilight/{p-6e52b649.entry.js → p-12b2b553.entry.js} +1 -1
- package/dist/twilight/{p-8c1d14f0.entry.js → p-14fb124b.entry.js} +1 -1
- package/dist/twilight/{p-9e0a9a5a.entry.js → p-1ca3525d.entry.js} +1 -1
- package/dist/twilight/{p-7f97335a.entry.js → p-1f54638c.entry.js} +1 -1
- package/dist/twilight/{p-5694edf1.entry.js → p-201c816d.entry.js} +1 -1
- package/dist/twilight/{p-92fd20a0.entry.js → p-203b2723.entry.js} +1 -1
- package/dist/twilight/{p-1af9db24.entry.js → p-224c35e6.entry.js} +1 -1
- package/dist/twilight/{p-6dccd40f.entry.js → p-22bd8281.entry.js} +1 -1
- package/dist/twilight/{p-d4fb9921.entry.js → p-25ac8744.entry.js} +1 -1
- package/dist/twilight/{p-0ba159db.entry.js → p-25b964c0.entry.js} +1 -1
- package/dist/twilight/{p-da0df10b.entry.js → p-2a469c80.entry.js} +1 -1
- package/dist/twilight/{p-26d2b28a.entry.js → p-2a6f93a8.entry.js} +1 -1
- package/dist/twilight/{p-7fd9dc36.entry.js → p-2b0f98fc.entry.js} +1 -1
- package/dist/twilight/{p-259c995a.entry.js → p-2e66576c.entry.js} +1 -1
- package/dist/twilight/{p-be6f8551.entry.js → p-2e8e7cf2.entry.js} +1 -1
- package/dist/twilight/{p-ee479819.entry.js → p-2f05393f.entry.js} +1 -1
- package/dist/twilight/{p-1960020c.entry.js → p-3054e1c1.entry.js} +1 -1
- package/dist/twilight/{p-70dfb2b4.entry.js → p-3295390b.entry.js} +1 -1
- package/dist/twilight/{p-a95b0dc1.entry.js → p-33678067.entry.js} +1 -1
- package/dist/twilight/{p-c4cf0b4d.entry.js → p-33c05de2.entry.js} +1 -1
- package/dist/twilight/{p-d0ff9a3e.entry.js → p-381a9e70.entry.js} +1 -1
- package/dist/twilight/{p-f9e5ed10.entry.js → p-38270121.entry.js} +1 -1
- package/dist/twilight/{p-027cbda6.entry.js → p-385bf37d.entry.js} +1 -1
- package/dist/twilight/{p-d0aeeb7f.entry.js → p-40ee2ca3.entry.js} +1 -1
- package/dist/twilight/{p-cb48a5ef.entry.js → p-43a3401b.entry.js} +1 -1
- package/dist/twilight/{p-9d15f22d.entry.js → p-4616033a.entry.js} +1 -1
- package/dist/twilight/p-484af8cc.entry.js +4 -0
- package/dist/twilight/{p-516e4edc.entry.js → p-4b6627f5.entry.js} +1 -1
- package/dist/twilight/p-4ed8ae08.entry.js +4 -0
- package/dist/twilight/{p-6af8a7b6.entry.js → p-4fb442c2.entry.js} +1 -1
- package/dist/twilight/{p-4b70e6c4.entry.js → p-516f9b83.entry.js} +1 -1
- package/dist/twilight/{p-d1204965.entry.js → p-56aebb36.entry.js} +1 -1
- package/dist/twilight/{p-6b5de500.entry.js → p-56fbe5ff.entry.js} +1 -1
- package/dist/twilight/{p-66ad7a30.entry.js → p-58af47e4.entry.js} +1 -1
- package/dist/twilight/{p-3f842f32.entry.js → p-616e6781.entry.js} +1 -1
- package/dist/twilight/{p-254cff9a.entry.js → p-62077080.entry.js} +1 -1
- package/dist/twilight/p-6427664a.entry.js +4 -0
- package/dist/twilight/{p-bb8b2c85.entry.js → p-65253725.entry.js} +1 -1
- package/dist/twilight/{p-fcb1009f.entry.js → p-6a05f69c.entry.js} +1 -1
- package/dist/twilight/{p-ac736b30.entry.js → p-6afa5aa8.entry.js} +1 -1
- package/dist/twilight/{p-f7a58656.entry.js → p-6ff116eb.entry.js} +1 -1
- package/dist/twilight/{p-f9587127.entry.js → p-710b19d2.entry.js} +1 -1
- package/dist/twilight/{p-84b0e7a9.entry.js → p-71297800.entry.js} +1 -1
- package/dist/twilight/{p-53735934.entry.js → p-7234a066.entry.js} +1 -1
- package/dist/twilight/{p-b1f808f5.entry.js → p-73af6a02.entry.js} +1 -1
- package/dist/twilight/{p-4ab5ee99.entry.js → p-7428deca.entry.js} +1 -1
- package/dist/twilight/{p-b5a45f87.entry.js → p-75b509cd.entry.js} +1 -1
- package/dist/twilight/{p-071aa0e7.entry.js → p-79e446b2.entry.js} +1 -1
- package/dist/twilight/{p-eaf0c514.entry.js → p-7a8c9411.entry.js} +1 -1
- package/dist/twilight/{p-5f6fee0e.entry.js → p-86533832.entry.js} +1 -1
- package/dist/twilight/p-8a4af12c.entry.js +4 -0
- package/dist/twilight/{p-9cf1cfd4.entry.js → p-8ddf6933.entry.js} +1 -1
- package/dist/twilight/{p-7b5f97e7.entry.js → p-93fe31b9.entry.js} +1 -1
- package/dist/twilight/{p-4891c565.entry.js → p-9c96a9e7.entry.js} +1 -1
- package/dist/twilight/{p-CBLWEyM9.js → p-BNr49RmW.js} +1 -1
- package/dist/twilight/{p-DMvhNbgN.js → p-BUzdlb7Q.js} +1 -1
- package/dist/twilight/p-BVaKfTMx.js +4 -0
- package/dist/twilight/{p-BK9YeXWp.js → p-BYWjrTuB.js} +1 -1
- package/dist/twilight/{p-CCwsxMbZ.js → p-Bo_J3Do4.js} +1 -1
- package/dist/twilight/{p-CgNJWeaK.js → p-ChxhrML8.js} +1 -1
- package/dist/twilight/p-CrXKQnBu.js +5 -0
- package/dist/twilight/{p-Y2ZIN9Ok.js → p-D1oKTNWQ.js} +1 -1
- package/dist/twilight/{p-De1tLqQF.js → p-DUNRPrqt.js} +1 -1
- package/dist/twilight/{p-BxQMWsr9.js → p-DUuRpwsl.js} +1 -1
- package/dist/twilight/{p-NqQdbGu6.js → p-DZR3BP63.js} +1 -1
- package/dist/twilight/{p-12a25415.entry.js → p-a52a3664.entry.js} +1 -1
- package/dist/twilight/{p-d346dabd.entry.js → p-a7114995.entry.js} +1 -1
- package/dist/twilight/{p-8c40278d.entry.js → p-aa7494cd.entry.js} +1 -1
- package/dist/twilight/{p-34148827.entry.js → p-ae5d26da.entry.js} +1 -1
- package/dist/twilight/{p-d1121b3f.entry.js → p-b5434bcc.entry.js} +1 -1
- package/dist/twilight/p-b9fabd92.entry.js +4 -0
- package/dist/twilight/{p-bed54154.entry.js → p-bac38ed2.entry.js} +1 -1
- package/dist/twilight/{p-cdeb9bcc.entry.js → p-bbcfcdb0.entry.js} +1 -1
- package/dist/twilight/{p-f7ab5825.entry.js → p-c097cfa1.entry.js} +1 -1
- package/dist/twilight/p-c13e7efb.entry.js +4 -0
- package/dist/twilight/{p-bfd5e263.entry.js → p-d0ea4c3a.entry.js} +1 -1
- package/dist/twilight/{p-a44670a9.entry.js → p-d0ec7ca7.entry.js} +1 -1
- package/dist/twilight/{p-fddf1997.entry.js → p-d31fbdea.entry.js} +1 -1
- package/dist/twilight/{p-37192614.entry.js → p-d482d43e.entry.js} +1 -1
- package/dist/twilight/{p-b3ada3d0.entry.js → p-d5368882.entry.js} +1 -1
- package/dist/twilight/{p-4a3fa153.entry.js → p-d5a2a231.entry.js} +1 -1
- package/dist/twilight/{p-e457e68f.entry.js → p-d6705759.entry.js} +1 -1
- package/dist/twilight/p-d7f2a028.entry.js +4 -0
- package/dist/twilight/{p-0418c2df.entry.js → p-d84dedaf.entry.js} +1 -1
- package/dist/twilight/{p-419d6d71.entry.js → p-d8d9ff09.entry.js} +1 -1
- package/dist/twilight/{p-361f6033.entry.js → p-d902ad13.entry.js} +1 -1
- package/dist/twilight/{p-481f52b1.entry.js → p-d941dc58.entry.js} +1 -1
- package/dist/twilight/{p-8766e236.entry.js → p-dd046bbd.entry.js} +1 -1
- package/dist/twilight/{p-23772523.entry.js → p-dd21db09.entry.js} +1 -1
- package/dist/twilight/{p-3a632c69.entry.js → p-dd83b424.entry.js} +1 -1
- package/dist/twilight/{p-aa35cf98.entry.js → p-e04fb844.entry.js} +1 -1
- package/dist/twilight/{p-6c3084c9.entry.js → p-e60d784c.entry.js} +1 -1
- package/dist/twilight/{p-d8955835.entry.js → p-e6cc7742.entry.js} +1 -1
- package/dist/twilight/{p-5e8d019e.entry.js → p-e853ac07.entry.js} +1 -1
- package/dist/twilight/{p-0f25fedd.entry.js → p-e9ecae21.entry.js} +1 -1
- package/dist/twilight/{p-6ba3808a.entry.js → p-ebe3d316.entry.js} +1 -1
- package/dist/twilight/{p-5bbf17dd.entry.js → p-ec2a45fb.entry.js} +1 -1
- package/dist/twilight/{p-a5b732b3.entry.js → p-ef216c0a.entry.js} +1 -1
- package/dist/twilight/{p-78a56dc6.entry.js → p-f3306980.entry.js} +1 -1
- package/dist/twilight/{p-d9a1bf08.entry.js → p-f65205d5.entry.js} +1 -1
- package/dist/twilight/{p-e9b03e9c.entry.js → p-f6e5cd28.entry.js} +1 -1
- package/dist/twilight/{p-af49191f.entry.js → p-f8cfc9f7.entry.js} +1 -1
- package/dist/twilight/{p-9e65451e.entry.js → p-faa0b9aa.entry.js} +1 -1
- package/dist/twilight/{p-9e042cce.entry.js → p-fb10df18.entry.js} +1 -1
- package/dist/twilight/{p-e38a6793.entry.js → p-fcb1cff7.entry.js} +1 -1
- package/dist/twilight/{p-487b4411.entry.js → p-ff3cb99b.entry.js} +1 -1
- package/dist/twilight/{p-ee65c489.entry.js → p-ff4680ea.entry.js} +1 -1
- package/dist/twilight/p-oL7bxwey.js +9 -0
- package/dist/twilight/p-q5NJ0uS-.js +4 -0
- 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 +68 -6
- package/dist/types/components/salla-bullet-delivery/icons.d.ts +14 -0
- package/dist/types/components/salla-bullet-delivery/interfaces.d.ts +40 -1
- package/dist/types/components/salla-bullet-delivery/salla-bullet-delivery.d.ts +73 -4
- package/dist/types/components/salla-mobile-update-modal/salla-mobile-update-modal.d.ts +44 -0
- package/dist/types/components/salla-quick-buy/salla-quick-buy.d.ts +18 -0
- package/dist/types/components/salla-rating-modal/salla-rating-modal-v2.d.ts +4 -0
- package/dist/types/components/salla-verify/salla-verify.d.ts +8 -0
- package/dist/types/components.d.ts +50 -0
- package/package.json +5 -5
- package/dist/cjs/helpers-8bMfm_mm.js +0 -329
- package/dist/esm/helpers-DqzaeXrL.js +0 -309
- package/dist/twilight/p-76584a5b.entry.js +0 -4
- package/dist/twilight/p-79822d99.entry.js +0 -4
- package/dist/twilight/p-Ca_SZn0u.js +0 -9
- package/dist/twilight/p-DgUQRYr2.js +0 -5
- package/dist/twilight/p-DqzaeXrL.js +0 -4
- package/dist/twilight/p-b9d67694.entry.js +0 -4
- package/dist/twilight/p-ba6dd59c.entry.js +0 -4
- package/dist/twilight/p-bac25e34.entry.js +0 -4
- package/dist/twilight/p-d1093a59.entry.js +0 -4
- package/dist/twilight/p-e24fbbb4.entry.js +0 -4
- package/dist/twilight/p-eefced26.entry.js +0 -4
|
@@ -2,22 +2,32 @@
|
|
|
2
2
|
* Crafted with ❤ by Salla
|
|
3
3
|
*/
|
|
4
4
|
import { h, Host, } from "@stencil/core";
|
|
5
|
-
import { bulletDeliveryAPI, clearApiCache, isSaudiArabia } from "./api-service";
|
|
5
|
+
import { bulletDeliveryAPI, CACHE_TTL, clearApiCache, clearBranchCache, isSaudiArabia } from "./api-service";
|
|
6
6
|
import { SelectorTracker, allocatedBranchIds, toCloseReason, } from "./selector-tracker";
|
|
7
|
-
import { filterBranches, findNearestBranch,
|
|
7
|
+
import { filterBranches, findNearestBranch, formatBranchClockTime, formatBranchDistance, getBranchWeekSchedule, getBranchCities, getBranchDirectionsHref, getBranchDiscount, getBranchDiscountRange, getBranchPhoneHref, getBranchReadinessLabel, getBranchReadyTodayTime, getBranchWhatsappHref, getIntentBranchId, getIntentCityId, getIntentCountryCode, getIntentCountryId, getIntentDistrictId, getIntentRegionId, getIntentSubtitle, groupBranchSchedule, hasSessionAddressIntent, isMapOriginIntent, isBranchAlwaysOpen, isBranchBusy, isBranchSelectable, isBranchVisible, requireRegionAndDistrictForSA, toCoordinate, } from "./helpers";
|
|
8
8
|
/* Location permission notice */
|
|
9
9
|
import { isLocationPermissionMissing, LocationPermissionNotice, requestLocationPermission, watchLocationPermission, } from "./location-permission-notice";
|
|
10
10
|
import { calculateLocationDistanceKm, LocationDistanceWarning, } from "./location-distance-warning";
|
|
11
11
|
const BRANCH_SEARCH_DEBOUNCE_MS = 1000;
|
|
12
|
+
/** Shorter queries are filtered locally; the branches API ignores them. */
|
|
13
|
+
const BRANCH_SEARCH_MIN_LENGTH = 2;
|
|
12
14
|
const GEOLOCATION_TIMEOUT = 10000;
|
|
15
|
+
/** GeolocationPositionError.PERMISSION_DENIED — inlined; the class is absent on the server. */
|
|
16
|
+
const GEO_PERMISSION_DENIED = 1;
|
|
17
|
+
/** Silent read for branch distances: a short wait, and a recent cached fix is good enough. */
|
|
18
|
+
const SILENT_GEOLOCATION_TIMEOUT = 5000;
|
|
19
|
+
const SILENT_GEOLOCATION_MAX_AGE = 10 * 60 * 1000;
|
|
20
|
+
/** Longest the branch list waits for that read; a later fix still serves the next list request. */
|
|
21
|
+
const BRANCH_LIST_LOCATION_WAIT = 1500;
|
|
22
|
+
/** Matches the `per_page` default of `bulletDeliveryAPI.getBranches`. */
|
|
23
|
+
const BRANCH_PAGE_SIZE = 20;
|
|
13
24
|
/** Final fallback center used only if `user.default_geo_location` is absent (Riyadh — matches checkout map-page). */
|
|
14
25
|
const DEFAULT_MAP_CENTER = { lat: 24.7756042, lng: 46.7360729 };
|
|
15
26
|
import GetDirections from "../../assets/svg/get-directions.svg";
|
|
16
|
-
import GPS from "../../assets/svg/gps.svg";
|
|
17
27
|
import Location from "../../assets/svg/location.svg";
|
|
18
28
|
import MiniMap from "../../assets/svg/mini-map.svg";
|
|
19
29
|
import Search from "../../assets/svg/search.svg";
|
|
20
|
-
import
|
|
30
|
+
import { BranchLocationIcon, LightningIcon, NotesIcon, PickupAvailabilityIcon, WorkingHoursIcon } from "./icons";
|
|
21
31
|
const DEBUG_KEY = 'salla-bullet-delivery-debug';
|
|
22
32
|
const OVERRIDE_IP_KEY = 'salla-bullet-delivery-override-ip';
|
|
23
33
|
function log(message, data) {
|
|
@@ -33,6 +43,8 @@ export class SallaBulletDelivery {
|
|
|
33
43
|
this.pendingCartSubmitResolver = null;
|
|
34
44
|
this.pendingCartSubmitPromise = null;
|
|
35
45
|
this.cartSubmitConfirmationPending = false;
|
|
46
|
+
/** Query the current branch list was searched with server-side; its results are not re-filtered locally. */
|
|
47
|
+
this.branchesServerQuery = '';
|
|
36
48
|
this.branchSearchDebounceTimer = null;
|
|
37
49
|
this.countrySearchTimer = null;
|
|
38
50
|
this.regionSearchTimer = null;
|
|
@@ -80,6 +92,8 @@ export class SallaBulletDelivery {
|
|
|
80
92
|
/** Identifies the latest reverse-geocode call so a resolved-but-superseded callback (same
|
|
81
93
|
* coordinates re-picked, or the map left) can be told apart from the current one. */
|
|
82
94
|
this.geocodeRequestId = 0;
|
|
95
|
+
/** Identifies the latest pickup-offer fetch so one from an earlier modal open is dropped. */
|
|
96
|
+
this.pickupDiscountRequestId = 0;
|
|
83
97
|
// Core state
|
|
84
98
|
this.activeTab = "address";
|
|
85
99
|
this.isLoggedIn = false;
|
|
@@ -102,9 +116,27 @@ export class SallaBulletDelivery {
|
|
|
102
116
|
this.selectedSessionAddress = false;
|
|
103
117
|
// Pickup state
|
|
104
118
|
this.branches = [];
|
|
119
|
+
/** Pickup offer range across the store's branches (INV-1416); null shows the default tab badge. */
|
|
120
|
+
this.pickupDiscountRange = null;
|
|
121
|
+
/** False until the offer lookup settles, so the tab never flashes the default badge before an offer. */
|
|
122
|
+
this.pickupDiscountResolved = false;
|
|
105
123
|
this.filteredBranches = [];
|
|
106
124
|
this.selectedBranch = null;
|
|
107
125
|
this.branchSearchQuery = "";
|
|
126
|
+
/** Cities that have branches in the selected country (from the unfiltered branch list). */
|
|
127
|
+
this.branchCities = [];
|
|
128
|
+
this.selectedBranchCity = null;
|
|
129
|
+
this.branchCitySearchQuery = '';
|
|
130
|
+
/** Branch whose weekly hours are expanded behind the chevron (one at a time). */
|
|
131
|
+
this.expandedScheduleBranchId = null;
|
|
132
|
+
/** Shopper's device location for branch distances (see getGrantedDeviceLocation). */
|
|
133
|
+
this.shopperLocation = null;
|
|
134
|
+
this.shopperLocationRequestId = 0;
|
|
135
|
+
this.nearestBranchRequestId = 0;
|
|
136
|
+
/** Bumped per branch-list request; overlapping city/search loads only apply the latest one. */
|
|
137
|
+
this.branchesRequestId = 0;
|
|
138
|
+
/** Shared country rows and city options expire with the API cache. */
|
|
139
|
+
this.allBranchCities = null;
|
|
108
140
|
// Loading states
|
|
109
141
|
this.loadingCountries = false;
|
|
110
142
|
this.loadingCities = false;
|
|
@@ -223,6 +255,13 @@ export class SallaBulletDelivery {
|
|
|
223
255
|
this.displayedDistricts = this.districts;
|
|
224
256
|
this.searchingDistricts = false;
|
|
225
257
|
};
|
|
258
|
+
this.handleBranchCitySelected = (item) => {
|
|
259
|
+
this.selectedBranchCity = item && item.id !== -1
|
|
260
|
+
? (this.branchCities.find((c) => String(c.id) === String(item.id)) ?? item)
|
|
261
|
+
: null;
|
|
262
|
+
this.selectedBranch = null;
|
|
263
|
+
void this.loadBranches();
|
|
264
|
+
};
|
|
226
265
|
this.handleMapLocationChanged = (event) => {
|
|
227
266
|
const detail = event.detail;
|
|
228
267
|
if (!detail?.position?.lat || !detail?.position?.lng)
|
|
@@ -447,6 +486,7 @@ export class SallaBulletDelivery {
|
|
|
447
486
|
}
|
|
448
487
|
// Reset state before opening
|
|
449
488
|
this.resetState();
|
|
489
|
+
void this.loadPickupDiscountRange();
|
|
450
490
|
if (!silent) {
|
|
451
491
|
// Open modal immediately — fields render right away with inline loading
|
|
452
492
|
this.modal.open();
|
|
@@ -498,20 +538,18 @@ export class SallaBulletDelivery {
|
|
|
498
538
|
}
|
|
499
539
|
}
|
|
500
540
|
// Load branches only when branch tab is active (lazy tab data)
|
|
501
|
-
// Use lat/lng from session storage if available for more accurate results
|
|
502
541
|
if (this.activeTab === "branch") {
|
|
503
|
-
const
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
else {
|
|
509
|
-
await this.loadBranches();
|
|
510
|
-
}
|
|
542
|
+
const loading = this.loadBranches();
|
|
543
|
+
const request = this.branchesRequestId;
|
|
544
|
+
await loading;
|
|
545
|
+
if (request !== this.branchesRequestId || this.activeTab !== 'branch' || this.branchSearchQuery.trim())
|
|
546
|
+
return;
|
|
511
547
|
// Auto-select preselected branch if provided
|
|
512
548
|
if (this.preselectedBranchId) {
|
|
513
|
-
this.preselectBranch(this.preselectedBranchId);
|
|
549
|
+
await this.preselectBranch(this.preselectedBranchId);
|
|
514
550
|
}
|
|
551
|
+
if (request !== this.branchesRequestId || this.activeTab !== 'branch' || this.branchSearchQuery.trim())
|
|
552
|
+
return;
|
|
515
553
|
}
|
|
516
554
|
// Prefill form data from session storage
|
|
517
555
|
await this.prefillFromSessionStorage();
|
|
@@ -564,6 +602,17 @@ export class SallaBulletDelivery {
|
|
|
564
602
|
});
|
|
565
603
|
}
|
|
566
604
|
resetState() {
|
|
605
|
+
clearBranchCache();
|
|
606
|
+
this.allBranchCities = null;
|
|
607
|
+
this.pickupDiscountRequestId++;
|
|
608
|
+
if (this.branchSearchDebounceTimer)
|
|
609
|
+
clearTimeout(this.branchSearchDebounceTimer);
|
|
610
|
+
++this.branchesRequestId;
|
|
611
|
+
this.loadingBranches = false;
|
|
612
|
+
++this.shopperLocationRequestId;
|
|
613
|
+
++this.nearestBranchRequestId;
|
|
614
|
+
this.loadingNearestBranch = false;
|
|
615
|
+
this.shopperLocation = null;
|
|
567
616
|
this.viewMode = "main";
|
|
568
617
|
this.mapLocationData = null;
|
|
569
618
|
this.mapCountryCode = null;
|
|
@@ -580,11 +629,16 @@ export class SallaBulletDelivery {
|
|
|
580
629
|
this.selectedSessionAddress = false;
|
|
581
630
|
this.selectedBranch = null;
|
|
582
631
|
this.branchSearchQuery = "";
|
|
632
|
+
this.branchCities = [];
|
|
633
|
+
this.selectedBranchCity = null;
|
|
634
|
+
this.expandedScheduleBranchId = null;
|
|
583
635
|
this.regions = [];
|
|
584
636
|
this.cities = [];
|
|
585
637
|
this.districts = [];
|
|
586
638
|
this.branches = [];
|
|
587
639
|
this.filteredBranches = [];
|
|
640
|
+
this.pickupDiscountRange = null;
|
|
641
|
+
this.pickupDiscountResolved = false;
|
|
588
642
|
this.newAddressForm = { ...SallaBulletDelivery.INITIAL_ADDRESS_FORM };
|
|
589
643
|
this.showCartWillBeClearedBanner = false;
|
|
590
644
|
this.allocationOutOfCoverageMessage = null;
|
|
@@ -988,16 +1042,63 @@ export class SallaBulletDelivery {
|
|
|
988
1042
|
});
|
|
989
1043
|
}
|
|
990
1044
|
async loadBranches() {
|
|
1045
|
+
const request = ++this.branchesRequestId;
|
|
1046
|
+
// A city change keeps the active search, so the server filters before picking the first page.
|
|
1047
|
+
const query = this.branchSearchQuery.trim();
|
|
991
1048
|
this.loadingBranches = true;
|
|
992
1049
|
try {
|
|
993
|
-
|
|
1050
|
+
const branches = await bulletDeliveryAPI.getBranches({
|
|
994
1051
|
country_id: this.selectedCountry?.id,
|
|
995
|
-
|
|
1052
|
+
city_id: this.selectedBranchCity?.id,
|
|
1053
|
+
query,
|
|
1054
|
+
...(await this.getListLocation()),
|
|
1055
|
+
});
|
|
1056
|
+
if (request !== this.branchesRequestId)
|
|
1057
|
+
return;
|
|
1058
|
+
this.branchesServerQuery = query.length >= BRANCH_SEARCH_MIN_LENGTH ? query : '';
|
|
1059
|
+
this.applyLoadedBranches(branches);
|
|
1060
|
+
// Search results hold only the matching branches, which would shrink the city options.
|
|
1061
|
+
if (query.length < BRANCH_SEARCH_MIN_LENGTH)
|
|
1062
|
+
void this.refreshBranchCities();
|
|
996
1063
|
}
|
|
997
1064
|
finally {
|
|
998
|
-
this.
|
|
1065
|
+
if (request === this.branchesRequestId)
|
|
1066
|
+
this.loadingBranches = false;
|
|
999
1067
|
}
|
|
1000
1068
|
}
|
|
1069
|
+
/** Reuse the country's city collection while keeping visible choices usable during loading. */
|
|
1070
|
+
refreshBranchCities() {
|
|
1071
|
+
if (!this.selectedBranchCity)
|
|
1072
|
+
this.branchCities = getBranchCities(this.branches);
|
|
1073
|
+
const countryId = this.selectedCountry?.id;
|
|
1074
|
+
if (!this.allBranchCities || this.allBranchCities.countryId !== countryId || Date.now() - this.allBranchCities.timestamp > CACHE_TTL) {
|
|
1075
|
+
const branches = bulletDeliveryAPI.getAllBranches(countryId, BRANCH_PAGE_SIZE);
|
|
1076
|
+
this.allBranchCities = {
|
|
1077
|
+
countryId,
|
|
1078
|
+
timestamp: Date.now(),
|
|
1079
|
+
branches,
|
|
1080
|
+
cities: branches.then((all) => getBranchCities(all)),
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
const pending = this.allBranchCities;
|
|
1084
|
+
return pending.cities.then((cities) => {
|
|
1085
|
+
if (this.allBranchCities !== pending || this.selectedCountry?.id !== countryId)
|
|
1086
|
+
return;
|
|
1087
|
+
if (!cities.length) {
|
|
1088
|
+
this.allBranchCities = null;
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
this.branchCities = cities;
|
|
1092
|
+
}).catch((error) => {
|
|
1093
|
+
if (this.allBranchCities === pending) {
|
|
1094
|
+
this.allBranchCities = null;
|
|
1095
|
+
if (this.selectedCountry?.id === countryId && Array.isArray(error?.branches)) {
|
|
1096
|
+
this.branchCities = getBranchCities([...this.branches, ...error.branches]);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
console.error('[BulletDelivery] Error fetching branch cities', error);
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1001
1102
|
/**
|
|
1002
1103
|
* Store a freshly fetched branch list and reconcile the current selection with it.
|
|
1003
1104
|
* `selectedBranch` is a snapshot from selection time: when the refreshed list carries the
|
|
@@ -1014,8 +1115,33 @@ export class SallaBulletDelivery {
|
|
|
1014
1115
|
}
|
|
1015
1116
|
this.filterBranches();
|
|
1016
1117
|
}
|
|
1118
|
+
/** Shares a fresh branch collection with the picker on each modal open. */
|
|
1119
|
+
async loadPickupDiscountRange() {
|
|
1120
|
+
if (!this.supportsPickup)
|
|
1121
|
+
return;
|
|
1122
|
+
const requestId = ++this.pickupDiscountRequestId;
|
|
1123
|
+
const { branches, complete } = await bulletDeliveryAPI.getBranchCollection(undefined, 60, { requireComplete: true });
|
|
1124
|
+
if (requestId !== this.pickupDiscountRequestId)
|
|
1125
|
+
return;
|
|
1126
|
+
this.pickupDiscountRange = complete ? getBranchDiscountRange(branches) : null;
|
|
1127
|
+
this.pickupDiscountResolved = true;
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* ar: "خصم 25%" / "خصم 5 – 25%" / "خصم 10 ر.س"; en: "25% discount" / "5 – 25% discount" / "10 SAR discount".
|
|
1131
|
+
* Money may carry the riyal-symbol SVG, so it renders as HTML.
|
|
1132
|
+
*/
|
|
1133
|
+
getPickupDiscountLabel(type, min, max = min) {
|
|
1134
|
+
const format = (amount) => type === 'percentage' ? String(Math.round(amount * 100) / 100) : salla.money(amount);
|
|
1135
|
+
const value = min === max ? format(min) : `${format(min)} – ${format(max)}`;
|
|
1136
|
+
const amount = type === 'percentage' ? `${value}%` : `${value} `;
|
|
1137
|
+
const fallback = this.isArabic ? `خصم ${amount}` : ` ${amount} discount`;
|
|
1138
|
+
return Salla.lang.getWithDefault('pages.checkout.pickup_discount', fallback, { amount });
|
|
1139
|
+
}
|
|
1017
1140
|
filterBranches() {
|
|
1018
|
-
|
|
1141
|
+
const query = this.branchSearchQuery.trim();
|
|
1142
|
+
this.filteredBranches = query && query === this.branchesServerQuery
|
|
1143
|
+
? this.branches
|
|
1144
|
+
: filterBranches(this.branches, query);
|
|
1019
1145
|
}
|
|
1020
1146
|
/**
|
|
1021
1147
|
* Prefill form fields from session storage
|
|
@@ -1040,7 +1166,7 @@ export class SallaBulletDelivery {
|
|
|
1040
1166
|
if (country) {
|
|
1041
1167
|
this.selectedCountry = country;
|
|
1042
1168
|
this.updateNewAddressForm({ country_id: Number(country.id) });
|
|
1043
|
-
this.preselectBranch(getIntentBranchId(intent));
|
|
1169
|
+
await this.preselectBranch(getIntentBranchId(intent));
|
|
1044
1170
|
}
|
|
1045
1171
|
}
|
|
1046
1172
|
}
|
|
@@ -1079,7 +1205,16 @@ export class SallaBulletDelivery {
|
|
|
1079
1205
|
}
|
|
1080
1206
|
}
|
|
1081
1207
|
applyCountryChange(newCountry) {
|
|
1208
|
+
++this.branchesRequestId;
|
|
1209
|
+
this.allBranchCities = null;
|
|
1210
|
+
this.loadingBranches = false;
|
|
1211
|
+
this.branches = [];
|
|
1212
|
+
this.filteredBranches = [];
|
|
1082
1213
|
this.selectedCountry = newCountry;
|
|
1214
|
+
this.selectedBranchCity = null;
|
|
1215
|
+
this.branchCities = [];
|
|
1216
|
+
this.branchCitySearchQuery = '';
|
|
1217
|
+
this.selectedBranch = null;
|
|
1083
1218
|
this.selectedRegion = null;
|
|
1084
1219
|
this.regions = [];
|
|
1085
1220
|
this.displayedRegions = [];
|
|
@@ -1199,19 +1334,11 @@ export class SallaBulletDelivery {
|
|
|
1199
1334
|
void this.loadBranches();
|
|
1200
1335
|
return;
|
|
1201
1336
|
}
|
|
1202
|
-
this.branchSearchDebounceTimer = setTimeout(
|
|
1203
|
-
|
|
1337
|
+
this.branchSearchDebounceTimer = setTimeout(() => {
|
|
1338
|
+
// Below the minimum, only reload when the list still holds an earlier server search.
|
|
1339
|
+
if (query.trim().length < BRANCH_SEARCH_MIN_LENGTH && !this.branchesServerQuery)
|
|
1204
1340
|
return;
|
|
1205
|
-
this.
|
|
1206
|
-
try {
|
|
1207
|
-
this.applyLoadedBranches(await bulletDeliveryAPI.getBranches({
|
|
1208
|
-
country_id: this.selectedCountry?.id,
|
|
1209
|
-
query,
|
|
1210
|
-
}));
|
|
1211
|
-
}
|
|
1212
|
-
finally {
|
|
1213
|
-
this.loadingBranches = false;
|
|
1214
|
-
}
|
|
1341
|
+
void this.loadBranches();
|
|
1215
1342
|
}, BRANCH_SEARCH_DEBOUNCE_MS);
|
|
1216
1343
|
}
|
|
1217
1344
|
clearSearchTimers() {
|
|
@@ -1238,13 +1365,23 @@ export class SallaBulletDelivery {
|
|
|
1238
1365
|
this.clearSearchTimers();
|
|
1239
1366
|
}
|
|
1240
1367
|
async loadBranchesWithLocation(lat, lng) {
|
|
1368
|
+
// Later list loads (city change, search) keep measuring from the device location.
|
|
1369
|
+
++this.shopperLocationRequestId;
|
|
1370
|
+
this.shopperLocation = { lat, lng };
|
|
1371
|
+
const request = ++this.branchesRequestId;
|
|
1241
1372
|
this.loadingBranches = true;
|
|
1242
1373
|
try {
|
|
1243
|
-
|
|
1374
|
+
const branches = await bulletDeliveryAPI.getBranches({
|
|
1244
1375
|
country_id: this.selectedCountry?.id,
|
|
1376
|
+
city_id: this.selectedBranchCity?.id,
|
|
1245
1377
|
lat,
|
|
1246
1378
|
lng,
|
|
1247
|
-
})
|
|
1379
|
+
});
|
|
1380
|
+
if (request !== this.branchesRequestId)
|
|
1381
|
+
return false;
|
|
1382
|
+
this.branchesServerQuery = '';
|
|
1383
|
+
this.applyLoadedBranches(branches);
|
|
1384
|
+
void this.refreshBranchCities();
|
|
1248
1385
|
// Auto-select country from first branch if no country is selected
|
|
1249
1386
|
if (!this.selectedCountry && this.branches.length > 0) {
|
|
1250
1387
|
const firstBranch = this.branches[0];
|
|
@@ -1258,9 +1395,11 @@ export class SallaBulletDelivery {
|
|
|
1258
1395
|
}
|
|
1259
1396
|
}
|
|
1260
1397
|
}
|
|
1398
|
+
return true;
|
|
1261
1399
|
}
|
|
1262
1400
|
finally {
|
|
1263
|
-
this.
|
|
1401
|
+
if (request === this.branchesRequestId)
|
|
1402
|
+
this.loadingBranches = false;
|
|
1264
1403
|
}
|
|
1265
1404
|
}
|
|
1266
1405
|
/** Locate nearest branch using device geolocation (branches tab only). */
|
|
@@ -1269,6 +1408,7 @@ export class SallaBulletDelivery {
|
|
|
1269
1408
|
this.locationError = Salla.lang.get("pages.checkout.current_location_not_supported");
|
|
1270
1409
|
return;
|
|
1271
1410
|
}
|
|
1411
|
+
const request = ++this.nearestBranchRequestId;
|
|
1272
1412
|
this.loadingNearestBranch = true;
|
|
1273
1413
|
this.locationError = "";
|
|
1274
1414
|
try {
|
|
@@ -1280,7 +1420,12 @@ export class SallaBulletDelivery {
|
|
|
1280
1420
|
});
|
|
1281
1421
|
});
|
|
1282
1422
|
const { latitude, longitude } = position.coords;
|
|
1283
|
-
|
|
1423
|
+
if (request !== this.nearestBranchRequestId)
|
|
1424
|
+
return;
|
|
1425
|
+
if (!await this.loadBranchesWithLocation(latitude, longitude))
|
|
1426
|
+
return;
|
|
1427
|
+
if (request !== this.nearestBranchRequestId)
|
|
1428
|
+
return;
|
|
1284
1429
|
const nearestBranch = findNearestBranch(this.branches, latitude, longitude);
|
|
1285
1430
|
if (nearestBranch) {
|
|
1286
1431
|
this.selectedBranch = nearestBranch;
|
|
@@ -1289,26 +1434,56 @@ export class SallaBulletDelivery {
|
|
|
1289
1434
|
}
|
|
1290
1435
|
}
|
|
1291
1436
|
catch (error) {
|
|
1437
|
+
if (request !== this.nearestBranchRequestId)
|
|
1438
|
+
return;
|
|
1292
1439
|
const geoError = error;
|
|
1293
1440
|
const code = typeof geoError?.code === "number" ? geoError.code : -1;
|
|
1294
|
-
this.locationError =
|
|
1441
|
+
this.locationError = this.geolocationErrorMessage(code);
|
|
1295
1442
|
}
|
|
1296
1443
|
finally {
|
|
1297
|
-
this.
|
|
1444
|
+
if (request === this.nearestBranchRequestId)
|
|
1445
|
+
this.loadingNearestBranch = false;
|
|
1298
1446
|
}
|
|
1299
1447
|
}
|
|
1448
|
+
geolocationErrorMessage(code) {
|
|
1449
|
+
if (code === GEO_PERMISSION_DENIED) {
|
|
1450
|
+
return Salla.lang.getWithDefault("pages.checkout.allow_location_permission_blocked_hint", this.isArabic
|
|
1451
|
+
? "مشاركة الموقع محجوبة لهذا المتجر في متصفحك. افتح إعدادات الموقع في المتصفح، اسمح بالوصول إلى الموقع، ثم أعد المحاولة."
|
|
1452
|
+
: "Location sharing is blocked for this store in your browser. Open your browser's location settings, allow location access, then try again.");
|
|
1453
|
+
}
|
|
1454
|
+
return Salla.lang.getWithDefault("pages.checkout.pickup_location_unavailable", this.isArabic ? "تعذَّر تحديد موقعك. حاول مرة أخرى." : "We couldn't detect your location. Try again.");
|
|
1455
|
+
}
|
|
1300
1456
|
handleBranchSelect(branch) {
|
|
1301
1457
|
this.selectedBranch = branch;
|
|
1302
1458
|
this.allocationOutOfCoverageMessage = null;
|
|
1303
1459
|
}
|
|
1460
|
+
toggleBranchSchedule(branchId) {
|
|
1461
|
+
this.expandedScheduleBranchId = this.expandedScheduleBranchId === branchId ? null : branchId;
|
|
1462
|
+
}
|
|
1304
1463
|
/**
|
|
1305
1464
|
* Restore a remembered / event-provided branch — but only one the list renders as selectable,
|
|
1306
1465
|
* so a branch that has closed since it was remembered is never silently preselected (INV-1407).
|
|
1307
1466
|
*/
|
|
1308
|
-
preselectBranch(branchId) {
|
|
1309
|
-
if (branchId == null)
|
|
1467
|
+
async preselectBranch(branchId) {
|
|
1468
|
+
if (branchId == null || this.selectedBranch)
|
|
1310
1469
|
return;
|
|
1311
|
-
|
|
1470
|
+
let branch = this.branches.find((b) => b.id === branchId);
|
|
1471
|
+
if (!branch && this.allBranchCities) {
|
|
1472
|
+
const pending = this.allBranchCities;
|
|
1473
|
+
const request = this.branchesRequestId;
|
|
1474
|
+
try {
|
|
1475
|
+
branch = (await pending.branches).find((b) => b.id === branchId);
|
|
1476
|
+
}
|
|
1477
|
+
catch {
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
if (request !== this.branchesRequestId || this.activeTab !== 'branch' || this.allBranchCities !== pending || pending.countryId !== this.selectedCountry?.id || this.selectedBranch || this.branchSearchQuery.trim())
|
|
1481
|
+
return;
|
|
1482
|
+
if (this.selectedBranchCity && String(branch?.city?.id) !== String(this.selectedBranchCity.id))
|
|
1483
|
+
return;
|
|
1484
|
+
if (branch && isBranchSelectable(branch))
|
|
1485
|
+
this.applyLoadedBranches([...this.branches, branch]);
|
|
1486
|
+
}
|
|
1312
1487
|
if (branch && isBranchSelectable(branch)) {
|
|
1313
1488
|
this.selectedBranch = branch;
|
|
1314
1489
|
}
|
|
@@ -1569,28 +1744,63 @@ export class SallaBulletDelivery {
|
|
|
1569
1744
|
}
|
|
1570
1745
|
/** Center shown before geolocation resolves — the customer's IP-based default (falls back to Riyadh). */
|
|
1571
1746
|
get mapInitialCenter() {
|
|
1747
|
+
return this.defaultGeoLocation ?? DEFAULT_MAP_CENTER;
|
|
1748
|
+
}
|
|
1749
|
+
/** Device location for a branch list request, waiting at most BRANCH_LIST_LOCATION_WAIT. */
|
|
1750
|
+
getListLocation() {
|
|
1751
|
+
const location = this.getGrantedDeviceLocation();
|
|
1752
|
+
if (this.shopperLocation || !navigator.geolocation || !navigator.permissions?.query)
|
|
1753
|
+
return location;
|
|
1754
|
+
return Promise.race([location, new Promise((resolve) => setTimeout(() => resolve({}), BRANCH_LIST_LOCATION_WAIT))]);
|
|
1755
|
+
}
|
|
1756
|
+
/**
|
|
1757
|
+
* Where branch distances (`distance_km`) are measured from: the shopper's real device location
|
|
1758
|
+
* only. It comes from "nearest to my location", or is read silently when location permission was
|
|
1759
|
+
* already granted (never prompting). Empty otherwise: `user.default_geo_location` and the Riyadh
|
|
1760
|
+
* map fallback are not where the shopper is, so they would show wrong distances.
|
|
1761
|
+
*/
|
|
1762
|
+
async getGrantedDeviceLocation() {
|
|
1763
|
+
if (this.shopperLocation)
|
|
1764
|
+
return this.shopperLocation;
|
|
1765
|
+
if (!navigator.geolocation || !navigator.permissions?.query)
|
|
1766
|
+
return {};
|
|
1767
|
+
const request = ++this.shopperLocationRequestId;
|
|
1768
|
+
try {
|
|
1769
|
+
const permission = await navigator.permissions.query({ name: 'geolocation' });
|
|
1770
|
+
if (request !== this.shopperLocationRequestId)
|
|
1771
|
+
return this.shopperLocation ?? {};
|
|
1772
|
+
if (permission.state !== 'granted')
|
|
1773
|
+
return {};
|
|
1774
|
+
const position = await new Promise((resolve, reject) => navigator.geolocation.getCurrentPosition(resolve, reject, {
|
|
1775
|
+
timeout: SILENT_GEOLOCATION_TIMEOUT,
|
|
1776
|
+
maximumAge: SILENT_GEOLOCATION_MAX_AGE,
|
|
1777
|
+
}));
|
|
1778
|
+
if (request !== this.shopperLocationRequestId)
|
|
1779
|
+
return this.shopperLocation ?? {};
|
|
1780
|
+
this.shopperLocation = { lat: position.coords.latitude, lng: position.coords.longitude };
|
|
1781
|
+
return this.shopperLocation;
|
|
1782
|
+
}
|
|
1783
|
+
catch {
|
|
1784
|
+
return {};
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
/** The customer's IP-based `user.default_geo_location`, or null when it is missing or invalid. */
|
|
1788
|
+
get defaultGeoLocation() {
|
|
1572
1789
|
const geo = salla.config.get('user.default_geo_location');
|
|
1573
1790
|
// Coerce defensively: config may arrive as strings, blank/whitespace, NaN, or out-of-range
|
|
1574
1791
|
// values. Reject blanks before coercion (Number('') === 0) and validate lat/lng ranges so we
|
|
1575
1792
|
// never feed (0,0) or an invalid point to the map; otherwise fall back to the default center.
|
|
1576
|
-
const lat =
|
|
1577
|
-
const lng =
|
|
1793
|
+
const lat = toCoordinate(geo?.lat);
|
|
1794
|
+
const lng = toCoordinate(geo?.lng);
|
|
1578
1795
|
const isValid = lat != null && lng != null &&
|
|
1579
1796
|
lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180;
|
|
1580
|
-
return isValid ? { lat, lng } :
|
|
1581
|
-
}
|
|
1582
|
-
/** Parse a config coordinate to a finite number, treating blank/whitespace strings as missing. */
|
|
1583
|
-
toCoordinate(value) {
|
|
1584
|
-
if (typeof value === 'string' && value.trim() === '')
|
|
1585
|
-
return null;
|
|
1586
|
-
if (value == null)
|
|
1587
|
-
return null;
|
|
1588
|
-
const num = Number(value);
|
|
1589
|
-
return Number.isFinite(num) ? num : null;
|
|
1797
|
+
return isValid ? { lat, lng } : null;
|
|
1590
1798
|
}
|
|
1591
1799
|
async handleTabChange(tab) {
|
|
1592
1800
|
if (this.tabChanging)
|
|
1593
1801
|
return;
|
|
1802
|
+
++this.branchesRequestId;
|
|
1803
|
+
this.loadingBranches = false;
|
|
1594
1804
|
this.tabChanging = true;
|
|
1595
1805
|
try {
|
|
1596
1806
|
this.activeTab = tab;
|
|
@@ -1622,24 +1832,25 @@ export class SallaBulletDelivery {
|
|
|
1622
1832
|
this.selectedCountry = this.countries[0];
|
|
1623
1833
|
}
|
|
1624
1834
|
}
|
|
1835
|
+
if (String(previousCountryId ?? '') !== String(this.selectedCountry?.id ?? '')) {
|
|
1836
|
+
this.allBranchCities = null;
|
|
1837
|
+
this.selectedBranchCity = null;
|
|
1838
|
+
this.branchCities = [];
|
|
1839
|
+
this.branchCitySearchQuery = '';
|
|
1840
|
+
this.selectedBranch = null;
|
|
1841
|
+
this.branches = [];
|
|
1842
|
+
this.filteredBranches = [];
|
|
1843
|
+
}
|
|
1625
1844
|
if (tab === "address" && this.needsMap)
|
|
1626
1845
|
this.fetchAddressToken();
|
|
1627
1846
|
// Load appropriate data when switching tabs if country is selected
|
|
1628
1847
|
if (this.selectedCountry) {
|
|
1629
1848
|
if (tab === "branch") {
|
|
1630
1849
|
// Load branches when switching to branch tab
|
|
1631
|
-
// Check session storage for lat/lng to get nearby branches
|
|
1632
1850
|
const savedIntent = this.getStoredIntent();
|
|
1633
|
-
|
|
1634
|
-
const intentLng = getIntentLongitude(savedIntent);
|
|
1635
|
-
if (intentLat != null && intentLng != null) {
|
|
1636
|
-
await this.loadBranchesWithLocation(intentLat, intentLng);
|
|
1637
|
-
}
|
|
1638
|
-
else {
|
|
1639
|
-
await this.loadBranches();
|
|
1640
|
-
}
|
|
1851
|
+
await this.loadBranches();
|
|
1641
1852
|
// Preselect branch from session storage if available
|
|
1642
|
-
this.preselectBranch(getIntentBranchId(savedIntent));
|
|
1853
|
+
void this.preselectBranch(getIntentBranchId(savedIntent));
|
|
1643
1854
|
}
|
|
1644
1855
|
else if (tab === "address") {
|
|
1645
1856
|
// Lazy-load saved addresses when switching to address tab (if not loaded yet).
|
|
@@ -1840,6 +2051,10 @@ export class SallaBulletDelivery {
|
|
|
1840
2051
|
? { id: addr.district.id, name: addr.district.name }
|
|
1841
2052
|
: undefined,
|
|
1842
2053
|
short_address: addr.short_address,
|
|
2054
|
+
street: addr.street,
|
|
2055
|
+
local: addr.local,
|
|
2056
|
+
lat: addr.lat,
|
|
2057
|
+
lng: addr.lng,
|
|
1843
2058
|
};
|
|
1844
2059
|
}
|
|
1845
2060
|
buildIntentBranch() {
|
|
@@ -2143,10 +2358,17 @@ export class SallaBulletDelivery {
|
|
|
2143
2358
|
(this.activeTab === "address"
|
|
2144
2359
|
? Salla.lang.get("pages.checkout.address_out_of_coverage")
|
|
2145
2360
|
: Salla.lang.get("pages.checkout.failed_to_set_pickup"));
|
|
2146
|
-
this.allocationOutOfCoverageMessage = `${errorMessage}.`;
|
|
2361
|
+
this.allocationOutOfCoverageMessage = /[.!؟?]$/.test(errorMessage.trim()) ? errorMessage : `${errorMessage}.`;
|
|
2147
2362
|
this.trackSelectorResult("failed", previousIntent, []);
|
|
2148
2363
|
this.confirmBtn?.stop();
|
|
2149
2364
|
this.confirming = false;
|
|
2365
|
+
// A rejected branch may have turned busy or closed: drop it (the reload may hide it) and
|
|
2366
|
+
// reload so the list shows its current state.
|
|
2367
|
+
if (this.activeTab === "branch") {
|
|
2368
|
+
this.selectedBranch = null;
|
|
2369
|
+
clearApiCache();
|
|
2370
|
+
void this.loadBranches();
|
|
2371
|
+
}
|
|
2150
2372
|
return;
|
|
2151
2373
|
}
|
|
2152
2374
|
// Process successful allocation response
|
|
@@ -2312,6 +2534,19 @@ export class SallaBulletDelivery {
|
|
|
2312
2534
|
wrapper.append(info, btn);
|
|
2313
2535
|
return wrapper;
|
|
2314
2536
|
}
|
|
2537
|
+
/**
|
|
2538
|
+
* A branch pickup offer (INV-1416) replaces the default "save delivery fees" badge; only one shows,
|
|
2539
|
+
* and neither until the offer lookup settles.
|
|
2540
|
+
*/
|
|
2541
|
+
renderPickupTabBadge() {
|
|
2542
|
+
if (!this.pickupDiscountResolved)
|
|
2543
|
+
return null;
|
|
2544
|
+
const range = this.pickupDiscountRange;
|
|
2545
|
+
if (range) {
|
|
2546
|
+
return (h("span", { class: "s-bullet-delivery-tab-badge s-bullet-delivery-discount-badge", dir: this.isArabic ? 'rtl' : 'ltr', innerHTML: this.getPickupDiscountLabel(range.type, range.min, range.max) }));
|
|
2547
|
+
}
|
|
2548
|
+
return (h("span", { class: "s-bullet-delivery-tab-badge" }, h("span", { class: "s-bullet-delivery-tab-badge-icon", innerHTML: LightningIcon, "aria-hidden": "true" }), Salla.lang.getWithDefault("pages.checkout.save_delivery_fees", "وفّر رسوم التوصيل")));
|
|
2549
|
+
}
|
|
2315
2550
|
renderTabs() {
|
|
2316
2551
|
// Show tabs only when pickup is supported; otherwise delivery-only view with no tabs.
|
|
2317
2552
|
// The pickup tab is gated by this same `supportsPickup` check, while the delivery
|
|
@@ -2321,10 +2556,10 @@ export class SallaBulletDelivery {
|
|
|
2321
2556
|
return (h("div", { class: "s-bullet-delivery-tabs" }, this.isSupportsDelivery && (h("button", { type: "button", class: {
|
|
2322
2557
|
"s-bullet-delivery-tab": true,
|
|
2323
2558
|
"s-bullet-delivery-tab--active": this.activeTab === "address",
|
|
2324
|
-
}, onClick: () => this.handleTabChange("address") }, h("span",
|
|
2559
|
+
}, onClick: () => this.handleTabChange("address") }, h("span", null, Salla.lang.get("mobile_app.strings.delivery")))), h("button", { type: "button", class: {
|
|
2325
2560
|
"s-bullet-delivery-tab": true,
|
|
2326
2561
|
"s-bullet-delivery-tab--active": this.activeTab === "branch",
|
|
2327
|
-
}, onClick: () => this.handleTabChange("branch") }, h("span",
|
|
2562
|
+
}, onClick: () => this.handleTabChange("branch") }, h("span", null, Salla.lang.get("mobile_app.strings.pickup")), this.renderPickupTabBadge())));
|
|
2328
2563
|
}
|
|
2329
2564
|
renderAlert(message) {
|
|
2330
2565
|
return (h("div", { class: "s-bullet-delivery-allocation-out-of-coverage", role: "alert" }, h("span", { class: "s-bullet-delivery-allocation-out-of-coverage-icon", "aria-hidden": "true" }, h("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", role: "img", "aria-hidden": "true" }, h("title", null, "Information"), h("circle", { cx: "10", cy: "10", r: "9", stroke: "currentColor", "stroke-width": "1.5", fill: "currentColor" }), h("text", { x: "10", y: "14", "text-anchor": "middle", fill: "white", "font-size": "12", "font-weight": "bold" }, "i"))), h("span", { class: "s-bullet-delivery-allocation-out-of-coverage-text", style: { textAlign: this.isRTL ? 'right' : 'left' } }, message)));
|
|
@@ -2348,8 +2583,9 @@ export class SallaBulletDelivery {
|
|
|
2348
2583
|
}
|
|
2349
2584
|
return this.renderAlert(`${message} ${Salla.lang.getWithDefault('pages.cart.choose_another_address', 'Choose another address')}`);
|
|
2350
2585
|
}
|
|
2351
|
-
|
|
2352
|
-
|
|
2586
|
+
/** `showLabel` is off in the pickup filter panel, where the selects sit label-less side by side. */
|
|
2587
|
+
renderCountrySelect(showLabel = true) {
|
|
2588
|
+
return (h("div", { class: "s-bullet-delivery-field" }, h("salla-searchable-dropdown", { label: showLabel ? Salla.lang.get("blocks.buy_as_gift.receiver_country") : undefined, placeholder: Salla.lang.get("pages.checkout.select_country"), items: this.displayedCountries, selectedItem: this.selectedCountry, loading: this.loadingCountries, searching: this.searchingCountries, disabled: this.countries.length <= 1, required: true, inputId: "bullet-delivery-country", searchQuery: this.countrySearchQuery, clientSearch: true, onItemSelected: (e) => this.handleCountrySelected(e.detail), onSearchInput: (e) => this.handleCountrySearch(e.detail), onDropdownClosed: () => this.handleCountryDropdownClosed() })));
|
|
2353
2589
|
}
|
|
2354
2590
|
/** Region select (SA only): shown when SA is selected; city and district disabled until region selected. */
|
|
2355
2591
|
renderRegionSelect() {
|
|
@@ -2594,66 +2830,146 @@ export class SallaBulletDelivery {
|
|
|
2594
2830
|
return (h("form", { onSubmit: handleSubmit }, this.renderGuestDeliveryForm(), h("div", { class: "s-bullet-delivery-form-actions s-bullet-delivery-form-actions--single", style: { padding: '24px' } }, h("salla-button", { type: "submit", loading: this.confirming, disabled: !canSubmit || this.confirming, width: "wide" }, submitLabel), !this.isLoggedIn && (h("button", { type: "button", class: "s-bullet-delivery-login-prompt", onClick: () => this.handleLogin() }, Salla.lang.get('pages.checkout.login_to_use_saved_addresses'))))));
|
|
2595
2831
|
}
|
|
2596
2832
|
renderBranchSearch() {
|
|
2597
|
-
return (h("div", { class: "s-bullet-delivery-branch-search" }, h("div", { class: "s-bullet-delivery-search-row" }, h("div", { class: "s-bullet-delivery-search s-bullet-delivery-branch-search-wrap" }, h("span", { class: "s-bullet-delivery-search-icon s-bullet-delivery-branch-search-icon", innerHTML: Search, "aria-hidden": "true" }), h("input", { type: "text", class: "s-bullet-delivery-branch-search-input form-input", placeholder: Salla.lang.
|
|
2833
|
+
return (h("div", { class: "s-bullet-delivery-branch-search" }, h("div", { class: "s-bullet-delivery-search-row" }, h("div", { class: "s-bullet-delivery-search s-bullet-delivery-branch-search-wrap" }, h("span", { class: "s-bullet-delivery-search-icon s-bullet-delivery-branch-search-icon", innerHTML: Search, "aria-hidden": "true" }), h("input", { type: "text", class: "s-bullet-delivery-branch-search-input form-input", placeholder: Salla.lang.getWithDefault("pages.checkout.search_for_country_city_or_branch", this.isArabic ? "ابحث عن دولة أو مدينة أو فرع" : "Search for a country, city or branch"), value: this.branchSearchQuery, onInput: (e) => this.handleBranchSearch(e), autocomplete: "off" })), h("button", { type: "button", class: {
|
|
2598
2834
|
"s-bullet-delivery-location-btn": true,
|
|
2599
2835
|
"s-bullet-delivery-location-btn--full": true,
|
|
2600
2836
|
"s-bullet-delivery-location-btn--loading": this.loadingNearestBranch,
|
|
2601
|
-
}, onClick: () => this.handleFindNearestBranch(), disabled: this.loadingNearestBranch }, this.loadingNearestBranch ? (h("span", { class: "s-bullet-delivery-location-icon", "aria-hidden": "true" }, h("salla-skeleton", { height: "
|
|
2602
|
-
}
|
|
2603
|
-
/** Renders a branch's `preparation_time_range` as a localized "from - to <unit>" label. */
|
|
2604
|
-
getPreparationTimeLabel(range) {
|
|
2605
|
-
if (!range)
|
|
2606
|
-
return null;
|
|
2607
|
-
const unitKeys = {
|
|
2608
|
-
hour: 'pages.checkout.preparation_time_hours',
|
|
2609
|
-
minute: 'pages.checkout.preparation_time_minutes',
|
|
2610
|
-
day: 'pages.checkout.preparation_time_days',
|
|
2611
|
-
};
|
|
2612
|
-
const key = unitKeys[range.from.unit];
|
|
2613
|
-
if (!key)
|
|
2614
|
-
return null;
|
|
2615
|
-
return Salla.lang
|
|
2616
|
-
.getWithDefault(key, 'من {from} إلى {to} دقائق')
|
|
2617
|
-
?.replace('{from}', String(range.from.value))
|
|
2618
|
-
?.replace('{to}', String(range.to.value));
|
|
2837
|
+
}, onClick: () => this.handleFindNearestBranch(), disabled: this.loadingNearestBranch, "aria-label": Salla.lang.get("pages.checkout.nearest_to_my_location") }, this.loadingNearestBranch ? (h("span", { class: "s-bullet-delivery-location-icon", "aria-hidden": "true" }, h("salla-skeleton", { height: "16px", width: "16px" }))) : (h("span", { class: "s-bullet-delivery-location-icon", innerHTML: Location, "aria-hidden": "true" })), h("span", { class: "s-bullet-delivery-location-label" }, Salla.lang.get("pages.checkout.nearest_to_my_location")))), this.locationError && this.activeTab === "branch" && (h("span", { class: "s-bullet-delivery-error" }, this.locationError))));
|
|
2619
2838
|
}
|
|
2620
2839
|
renderBranchList() {
|
|
2621
2840
|
if (this.loadingBranches) {
|
|
2622
2841
|
return (h("div", { class: "s-bullet-delivery-branches-wrap" }, h("div", { class: "s-bullet-delivery-branches-loading" }, [1, 2, 3, 4].map((v) => (h("div", { key: v, class: "s-bullet-delivery-branch-skeleton" }, h("salla-skeleton", { class: "s-bullet-delivery-branch-skeleton-radio", type: "circle", height: "16px", width: "16px" }), h("div", { class: "s-bullet-delivery-branch-skeleton-icon" }, h("salla-skeleton", { height: "34px", width: "34px" })), h("div", { class: "s-bullet-delivery-branch-skeleton-content" }, h("salla-skeleton", { class: "s-bullet-delivery-branch-skeleton-title", height: "12px", width: "124px" })), h("salla-skeleton", { class: "s-bullet-delivery-branch-skeleton-time", height: "12px", width: "88px" }), h("div", { class: "s-bullet-delivery-branch-skeleton-map" }, h("salla-skeleton", { height: "32px", width: "32px" }))))))));
|
|
2623
2842
|
}
|
|
2624
|
-
|
|
2843
|
+
const branches = this.filteredBranches.filter(isBranchVisible);
|
|
2844
|
+
if (branches.length === 0) {
|
|
2625
2845
|
return (h("salla-placeholder", { alignment: "center", class: "s-bullet-delivery-placeholder" }, h("span", { slot: "title" }, Salla.lang.get("pages.checkout.no_pickup_branches_found"))));
|
|
2626
2846
|
}
|
|
2627
|
-
return (h("div", { class: "s-bullet-delivery-branches-wrap" }, h("ul", { class: "s-bullet-delivery-branches-list s-scrollbar" },
|
|
2847
|
+
return (h("div", { class: "s-bullet-delivery-branches-wrap" }, h("ul", { class: "s-bullet-delivery-branches-list s-scrollbar", role: "listbox" }, branches.map(branch => {
|
|
2628
2848
|
const selectable = isBranchSelectable(branch);
|
|
2629
|
-
const
|
|
2849
|
+
const isSelected = this.selectedBranch?.id === branch.id;
|
|
2630
2850
|
const locationText = [branch.country?.name, branch.city?.name, branch.district?.name]
|
|
2631
2851
|
.filter(Boolean)
|
|
2632
|
-
.join('
|
|
2633
|
-
const
|
|
2852
|
+
.join('، ');
|
|
2853
|
+
const distance = formatBranchDistance(branch.distance_km);
|
|
2854
|
+
// Closed but taking orders: the opening-time readiness replaces the range.
|
|
2855
|
+
const readinessLabel = getBranchReadinessLabel(branch) ?? this.getReadyTodayLabel(branch);
|
|
2856
|
+
const preparationLabel = readinessLabel ? null : this.getPreparationShortLabel(branch.preparation_time_range);
|
|
2857
|
+
const scheduleGroups = groupBranchSchedule(getBranchWeekSchedule(branch));
|
|
2858
|
+
// An always-open branch has no hours worth listing, so it gets no working-hours dropdown.
|
|
2859
|
+
const hasSchedule = scheduleGroups.length > 0 && !isBranchAlwaysOpen(branch);
|
|
2860
|
+
const scheduleOpen = hasSchedule && this.expandedScheduleBranchId === branch.id;
|
|
2861
|
+
const phoneHref = getBranchPhoneHref(branch);
|
|
2862
|
+
const whatsappHref = getBranchWhatsappHref(branch);
|
|
2863
|
+
const directionsHref = getBranchDirectionsHref(branch);
|
|
2864
|
+
const discount = getBranchDiscount(branch);
|
|
2634
2865
|
return (h("li", { key: branch.id, class: {
|
|
2635
2866
|
's-bullet-delivery-branch-item': true,
|
|
2636
|
-
's-bullet-delivery-branch-item--selected':
|
|
2867
|
+
's-bullet-delivery-branch-item--selected': isSelected,
|
|
2637
2868
|
's-bullet-delivery-branch-item--disabled': !selectable,
|
|
2638
|
-
}, tabIndex: selectable ? 0 : -1, role: "option", "aria-disabled": !selectable, onClick: () => selectable && this.handleBranchSelect(branch), onKeyDown: e => {
|
|
2869
|
+
}, tabIndex: selectable ? 0 : -1, role: "option", "aria-selected": isSelected, "aria-disabled": !selectable, onClick: () => selectable && this.handleBranchSelect(branch), onKeyDown: e => {
|
|
2870
|
+
if (e.target !== e.currentTarget)
|
|
2871
|
+
return;
|
|
2639
2872
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
2640
2873
|
e.preventDefault();
|
|
2641
2874
|
if (selectable)
|
|
2642
2875
|
this.handleBranchSelect(branch);
|
|
2643
2876
|
}
|
|
2644
|
-
} }, h("input", { type: "radio", name: "branch", class: "s-bullet-delivery-radio", checked:
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2877
|
+
} }, h("input", { type: "radio", name: "branch", class: "s-bullet-delivery-radio s-bullet-delivery-branch-radio", checked: isSelected, disabled: !selectable, tabIndex: -1 }), h("div", { class: "s-bullet-delivery-branch-body" }, h("p", { class: "s-bullet-delivery-branch-name" }, h("span", null, branch.name), discount ? (h("span", { class: "s-bullet-delivery-discount-badge", dir: this.isArabic ? 'rtl' : 'ltr', innerHTML: this.getPickupDiscountLabel(discount.type, discount.amount) })) : null), locationText ? (h("span", { class: "s-bullet-delivery-branch-meta s-bullet-delivery-branch-location" }, h("span", { class: "s-bullet-delivery-branch-meta-icon", innerHTML: BranchLocationIcon, "aria-hidden": "true" }), h("span", null, locationText))) : null, isSelected && branch.pickup_instructions ? (h("span", { class: "s-bullet-delivery-branch-meta s-bullet-delivery-branch-instructions" }, h("span", { class: "s-bullet-delivery-branch-meta-icon", innerHTML: NotesIcon, "aria-hidden": "true" }), h("span", null, branch.pickup_instructions))) : null, h("div", { class: "s-bullet-delivery-branch-meta-row" }, distance || readinessLabel || preparationLabel ? (h("div", { class: "s-bullet-delivery-branch-pills" }, distance ? (h("span", { class: "s-bullet-delivery-branch-meta s-bullet-delivery-branch-pill s-bullet-delivery-branch-distance" }, h("i", { class: "sicon-location" }), h("span", null, this.renderDistanceLabel(distance)))) : null, readinessLabel ? (h("span", { class: "s-bullet-delivery-branch-meta s-bullet-delivery-branch-pill s-bullet-delivery-branch-prep" }, h("span", { class: "s-bullet-delivery-branch-meta-icon", innerHTML: PickupAvailabilityIcon, "aria-hidden": "true" }), h("span", { class: "s-bullet-delivery-branch-meta-value" }, readinessLabel))) : preparationLabel ? (h("span", { class: "s-bullet-delivery-branch-meta s-bullet-delivery-branch-pill s-bullet-delivery-branch-prep" }, h("span", { class: "s-bullet-delivery-branch-meta-icon", innerHTML: PickupAvailabilityIcon, "aria-hidden": "true" }), h("span", null, h("span", { class: "s-bullet-delivery-branch-meta-label" }, Salla.lang.getWithDefault('pages.checkout.pickup_branch_ready_in', 'Pickup available after:'), ' '), h("span", { class: "s-bullet-delivery-branch-meta-value" }, preparationLabel)))) : null)) : null, h("hr", { class: "s-bullet-delivery-branch-divider" }), this.renderBranchOpenStatus(branch, hasSchedule, scheduleOpen)), scheduleOpen && (h("div", { class: "s-bullet-delivery-branch-schedule" }, scheduleGroups.map((group, index) => (h("div", { key: index, class: "s-bullet-delivery-branch-schedule-day" }, h("span", { class: "s-bullet-delivery-branch-schedule-days" }, group.days.length > 1
|
|
2878
|
+
? `${group.days[0]} - ${group.days[group.days.length - 1]}`
|
|
2879
|
+
: group.days[0]), h("span", { class: "s-bullet-delivery-branch-schedule-times" }, group.times
|
|
2880
|
+
.map(t => `${this.formatClock(t.start)} - ${this.formatClock(t.end)}`)
|
|
2881
|
+
.join(this.isArabic ? '، ' : ', ')))))))), h("div", { class: "s-bullet-delivery-branch-actions" }, phoneHref && (h("a", { href: phoneHref, class: "s-bullet-delivery-branch-action", title: Salla.lang.getWithDefault('pages.checkout.branch_call', 'اتصال'), onClick: e => e.stopPropagation() }, h("i", { class: "sicon-phone" }))), whatsappHref && (h("a", { href: whatsappHref, target: "_blank", rel: "noopener noreferrer", class: "s-bullet-delivery-branch-action", title: Salla.lang.getWithDefault('pages.checkout.branch_whatsapp', 'واتساب'), onClick: e => e.stopPropagation() }, h("i", { class: "sicon-whatsapp2" }))), directionsHref && (h("a", { href: directionsHref, target: "_blank", rel: "noopener noreferrer", class: "s-bullet-delivery-branch-action s-bullet-delivery-branch-map-link", title: Salla.lang.get('common.elements.open_in_google_maps'), onClick: e => e.stopPropagation() }, h("span", { class: "s-bullet-delivery-branch-map-link-icon", innerHTML: GetDirections.replace(/mask0_25437_34440/g, `mask0_branch_${branch.id}`), "aria-hidden": "true" }), h("span", { class: "sr-only" }, Salla.lang.get('common.elements.open_in_google_maps')))))));
|
|
2649
2882
|
}))));
|
|
2650
2883
|
}
|
|
2884
|
+
/** "يبعد عنك: ~" stays muted; the distance and its unit read as the value, as in checkout. */
|
|
2885
|
+
renderDistanceLabel(distance) {
|
|
2886
|
+
const template = Salla.lang.getWithDefault('pages.checkout.branch_distance_from_you', 'يبعد عنك: ~ {distance} كم');
|
|
2887
|
+
const index = template.indexOf('{distance}');
|
|
2888
|
+
if (index === -1)
|
|
2889
|
+
return template;
|
|
2890
|
+
return [
|
|
2891
|
+
h("span", { class: "s-bullet-delivery-branch-meta-label" }, template.slice(0, index)),
|
|
2892
|
+
h("span", { class: "s-bullet-delivery-branch-meta-value" }, template.slice(index).replace('{distance}', distance)),
|
|
2893
|
+
];
|
|
2894
|
+
}
|
|
2895
|
+
get isArabic() {
|
|
2896
|
+
return (Salla.lang.getLocale?.() ?? document.documentElement.lang) === 'ar';
|
|
2897
|
+
}
|
|
2898
|
+
formatClock(time) {
|
|
2899
|
+
return formatBranchClockTime(time, this.isArabic ? 'ar' : 'en');
|
|
2900
|
+
}
|
|
2901
|
+
/** "جاهز اليوم 10:00 ص" for a branch that is closed now and opens later today. */
|
|
2902
|
+
getReadyTodayLabel(branch) {
|
|
2903
|
+
const time = getBranchReadyTodayTime(branch);
|
|
2904
|
+
return time
|
|
2905
|
+
? `${Salla.lang.getWithDefault('pages.checkout.pickup_branch_ready_today_at', 'جاهز اليوم')} ${this.formatClock(time)}`
|
|
2906
|
+
: null;
|
|
2907
|
+
}
|
|
2908
|
+
/** "15-30 د" — compact preparation range for the card's meta row. */
|
|
2909
|
+
getPreparationShortLabel(range) {
|
|
2910
|
+
if (!range?.from || !range?.to)
|
|
2911
|
+
return null;
|
|
2912
|
+
const unitKeys = {
|
|
2913
|
+
minute: ['pages.checkout.preparation_time_minute_short', 'د'],
|
|
2914
|
+
hour: ['pages.checkout.preparation_time_hour_short', 'س'],
|
|
2915
|
+
day: ['pages.checkout.preparation_time_day_short', 'يوم'],
|
|
2916
|
+
};
|
|
2917
|
+
const unit = (u) => (unitKeys[u] ? Salla.lang.getWithDefault(unitKeys[u][0], unitKeys[u][1]) : null);
|
|
2918
|
+
const fromUnit = unit(range.from.unit);
|
|
2919
|
+
const toUnit = unit(range.to.unit);
|
|
2920
|
+
if (!fromUnit || !toUnit)
|
|
2921
|
+
return null;
|
|
2922
|
+
return range.from.unit === range.to.unit
|
|
2923
|
+
? `${range.from.value}-${range.to.value} ${toUnit}`
|
|
2924
|
+
: `${range.from.value} ${fromUnit} - ${range.to.value} ${toUnit}`;
|
|
2925
|
+
}
|
|
2926
|
+
/**
|
|
2927
|
+
* Busy, always-open, or the backend's `open_status_line` ("مفتوح - يغلق عند 11:00 م"), which reads
|
|
2928
|
+
* the hours on the branch's clock. Without that line, `is_open` gives a bare open/closed label.
|
|
2929
|
+
*/
|
|
2930
|
+
renderBranchOpenStatus(branch, hasSchedule, scheduleOpen) {
|
|
2931
|
+
const toggle = hasSchedule && (h("button", { type: "button", class: "s-bullet-delivery-branch-schedule-toggle", "aria-expanded": scheduleOpen ? 'true' : 'false', "aria-label": Salla.lang.getWithDefault('pages.checkout.pickup_show_weekly_hours', 'عرض ساعات العمل الأسبوعية'), onClick: e => {
|
|
2932
|
+
e.stopPropagation();
|
|
2933
|
+
this.toggleBranchSchedule(branch.id);
|
|
2934
|
+
} }, h("i", { class: { 'sicon-keyboard_arrow_down': true, 'is-expanded': scheduleOpen } })));
|
|
2935
|
+
if (isBranchBusy(branch)) {
|
|
2936
|
+
return (h("span", { class: "s-bullet-delivery-branch-meta s-bullet-delivery-branch-open-status" }, h("span", { class: "s-bullet-delivery-branch-meta-icon", innerHTML: WorkingHoursIcon, "aria-hidden": "true" }), h("span", { class: "s-bullet-delivery-pickup-status--busy" }, Salla.lang.getWithDefault('pages.checkout.pickup_branch_busy', 'مشغول، لا يستقبل طلبات')), toggle));
|
|
2937
|
+
}
|
|
2938
|
+
const alwaysOpen = isBranchAlwaysOpen(branch);
|
|
2939
|
+
const line = branch.pickup_readiness?.open_status_line;
|
|
2940
|
+
if (!alwaysOpen && line) {
|
|
2941
|
+
return (h("span", { class: "s-bullet-delivery-branch-meta s-bullet-delivery-branch-open-status" }, h("span", { class: "s-bullet-delivery-branch-meta-icon", innerHTML: WorkingHoursIcon, "aria-hidden": "true" }), h("span", null, line), toggle));
|
|
2942
|
+
}
|
|
2943
|
+
if (!alwaysOpen && !hasSchedule)
|
|
2944
|
+
return null;
|
|
2945
|
+
if (!alwaysOpen && typeof branch.is_open !== 'boolean') {
|
|
2946
|
+
return h("span", { class: "s-bullet-delivery-branch-meta s-bullet-delivery-branch-open-status" }, toggle);
|
|
2947
|
+
}
|
|
2948
|
+
const isOpen = alwaysOpen || branch.is_open;
|
|
2949
|
+
const label = alwaysOpen
|
|
2950
|
+
? Salla.lang.getWithDefault('pages.checkout.pickup_branch_always_open', 'مفتوح دائمًا 24/7')
|
|
2951
|
+
: isOpen
|
|
2952
|
+
? Salla.lang.getWithDefault('pages.checkout.pickup_branch_open', 'مفتوح')
|
|
2953
|
+
: Salla.lang.getWithDefault('pages.checkout.pickup_branch_closed', 'مغلق');
|
|
2954
|
+
return (h("span", { class: "s-bullet-delivery-branch-meta s-bullet-delivery-branch-open-status" }, h("span", { class: "s-bullet-delivery-branch-meta-icon", innerHTML: WorkingHoursIcon, "aria-hidden": "true" }), h("span", { class: isOpen ? 's-bullet-delivery-pickup-status--open' : 's-bullet-delivery-pickup-status--closed' }, label), toggle));
|
|
2955
|
+
}
|
|
2651
2956
|
renderPickupTab() {
|
|
2652
2957
|
return (h("div", { class: {
|
|
2653
2958
|
"s-bullet-delivery-content": true,
|
|
2654
2959
|
"s-bullet-delivery-content--active": this.activeTab === "branch",
|
|
2655
2960
|
"s-hidden": this.activeTab !== "branch",
|
|
2656
|
-
} }, this.renderCountrySelect(), this.renderBranchSearch(), this.renderBranchList()));
|
|
2961
|
+
} }, h("div", { class: "s-bullet-delivery-pickup-filters" }, h("div", { class: "s-bullet-delivery-pickup-filters-row" }, this.renderCountrySelect(false), this.renderBranchCitySelect()), this.renderBranchSearch()), this.renderBranchList()));
|
|
2962
|
+
}
|
|
2963
|
+
/** City filter for the pickup list; options come from the branches themselves, so none is empty. */
|
|
2964
|
+
renderBranchCitySelect() {
|
|
2965
|
+
return (h("div", { class: "s-bullet-delivery-field" }, h("salla-searchable-dropdown", { placeholder: Salla.lang.get("pages.checkout.select_city"), items: [{ id: -1, name: Salla.lang.getWithDefault('pages.checkout.all_cities', this.isArabic ? 'كل المدن' : 'All cities') }, ...this.branchCities], selectedItem: this.selectedBranchCity, loading: this.loadingBranches && this.branchCities.length === 0, disabled: this.branchCities.length === 0 && !this.selectedBranchCity, inputId: "bullet-delivery-branch-city", searchQuery: this.branchCitySearchQuery, clientSearch: true, onItemSelected: (e) => {
|
|
2966
|
+
this.branchCitySearchQuery = '';
|
|
2967
|
+
this.handleBranchCitySelected(e.detail);
|
|
2968
|
+
}, onSearchInput: (e) => {
|
|
2969
|
+
this.branchCitySearchQuery = e.detail;
|
|
2970
|
+
}, onDropdownClosed: () => {
|
|
2971
|
+
this.branchCitySearchQuery = '';
|
|
2972
|
+
} })));
|
|
2657
2973
|
}
|
|
2658
2974
|
/** Add-address form: map + confirm card in one screen, or dropdown fallback. */
|
|
2659
2975
|
renderAddAddressForm() {
|
|
@@ -2695,7 +3011,7 @@ export class SallaBulletDelivery {
|
|
|
2695
3011
|
return (h("div", { class: "s-bullet-delivery-footer" }, h("salla-button", { ref: (btn) => {
|
|
2696
3012
|
this.confirmBtn = btn;
|
|
2697
3013
|
}, disabled: this.isConfirmDisabled(), onClick: () => this.handleConfirm(), "loader-position": "center", width: "wide" }, this.activeTab === "branch"
|
|
2698
|
-
? Salla.lang.
|
|
3014
|
+
? Salla.lang.getWithDefault("pages.checkout.confirm_receipt_from_the_branch", "تأكيد الإستلام من الفرع")
|
|
2699
3015
|
: Salla.lang.get("pages.checkout.confirm_address")), showAddAddressInFooter && (h("salla-button", { onClick: () => this.handleAddNewAddress(), width: "wide", shape: "link" }, Salla.lang.get("pages.checkout.add_new_address"))), !this.isLoggedIn && (h("salla-button", { shape: "link", onClick: () => this.handleLogin() }, Salla.lang.get("pages.checkout.login_to_use_saved_addresses")))));
|
|
2700
3016
|
}
|
|
2701
3017
|
renderMainView() {
|
|
@@ -2881,7 +3197,7 @@ export class SallaBulletDelivery {
|
|
|
2881
3197
|
this.handleModalVisibility(Boolean(event.detail));
|
|
2882
3198
|
}, class: "s-bullet-delivery-modal", width: "sm", "data-testid": "salla-bullet-delivery-modal" }, h("div", { class: "s-bullet-delivery-inner" }, h("div", { class: "s-bullet-delivery-header" }, h("h2", { class: "s-bullet-delivery-title" }, this.activeTab === 'address'
|
|
2883
3199
|
? Salla.lang.get('blocks.home.add_address_for_order_delivery')
|
|
2884
|
-
: Salla.lang.
|
|
3200
|
+
: Salla.lang.getWithDefault('blocks.home.choose_pickup_branch_title', this.isArabic ? 'اختر فرع استلام طلبك' : 'Choose your pickup branch')), h("p", { class: "s-bullet-delivery-subtitle" }, this.activeTab === 'address'
|
|
2885
3201
|
? Salla.lang.get('blocks.home.products_available_for_delivery_shown_while_shopping')
|
|
2886
3202
|
: Salla.lang.get('blocks.home.choose_branch_for_order_pickup_description'))), this.renderTabs(), this.viewMode === 'main' && this.renderMainView(), this.viewMode === 'add-address' && this.renderAddAddressForm()))));
|
|
2887
3203
|
}
|
|
@@ -3040,9 +3356,15 @@ export class SallaBulletDelivery {
|
|
|
3040
3356
|
"selectedSavedAddress": {},
|
|
3041
3357
|
"selectedSessionAddress": {},
|
|
3042
3358
|
"branches": {},
|
|
3359
|
+
"pickupDiscountRange": {},
|
|
3360
|
+
"pickupDiscountResolved": {},
|
|
3043
3361
|
"filteredBranches": {},
|
|
3044
3362
|
"selectedBranch": {},
|
|
3045
3363
|
"branchSearchQuery": {},
|
|
3364
|
+
"branchCities": {},
|
|
3365
|
+
"selectedBranchCity": {},
|
|
3366
|
+
"branchCitySearchQuery": {},
|
|
3367
|
+
"expandedScheduleBranchId": {},
|
|
3046
3368
|
"loadingCountries": {},
|
|
3047
3369
|
"loadingCities": {},
|
|
3048
3370
|
"loadingDistricts": {},
|