@salla.sa/twilight-components 2.14.370 → 2.14.372
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/{filepond-DNoOQ518.js → filepond-D6hNdSue.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-poster-CX52qbRW.js → filepond-plugin-file-poster-DOSqy8V3.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-size-Dxk9m3Lt.js → filepond-plugin-file-validate-size-l4VLpkoL.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-type-DQMxc1IT.js → filepond-plugin-file-validate-type-KYY5p5gt.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-edit-BLW3ytTq.js → filepond-plugin-image-edit-BzaiZ8lY.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-exif-orientation-BgndLkUA.js → filepond-plugin-image-exif-orientation-Dp_AVLHw.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-preview-z85khFfc.js → filepond-plugin-image-preview-Cu_XtCoc.js} +1 -1
- package/dist/cjs/{index-BNCWtQwH.js → index-BmCJSRO7.js} +1 -1
- package/dist/cjs/{index-Uv2p8S16.js → index-D2SICJqL.js} +6 -2
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/location-DIyESLuI.js +16 -0
- package/dist/cjs/salla-accordion-body_3.cjs.entry.js +5 -11
- package/dist/cjs/salla-accordion_6.cjs.entry.js +2 -2
- package/dist/cjs/salla-add-product-button_4.cjs.entry.js +3 -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-apps-icons.cjs.entry.js +1 -1
- package/dist/cjs/salla-booking-field_7.cjs.entry.js +17 -17
- package/dist/cjs/salla-bullet-delivery.cjs.entry.js +1980 -0
- package/dist/cjs/salla-cart-item-offers_2.cjs.entry.js +17 -5
- package/dist/cjs/salla-comment-form_8.cjs.entry.js +8 -8
- 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 +12 -7
- package/dist/cjs/salla-count-down_2.cjs.entry.js +7 -7
- package/dist/cjs/salla-custom-fields.cjs.entry.js +1 -1
- package/dist/cjs/salla-filters-widget.cjs.entry.js +3 -3
- package/dist/cjs/salla-filters.cjs.entry.js +2 -2
- package/dist/cjs/salla-gifting.cjs.entry.js +3 -3
- package/dist/cjs/salla-hook.cjs.entry.js +2 -2
- package/dist/cjs/salla-infinite-scroll.cjs.entry.js +1 -1
- package/dist/cjs/salla-installment.cjs.entry.js +1 -1
- package/dist/cjs/salla-list-tile.cjs.entry.js +2 -2
- package/dist/cjs/salla-localization-modal.cjs.entry.js +2 -2
- package/dist/cjs/salla-login-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +2 -2
- package/dist/cjs/salla-loyalty-program.cjs.entry.js +2 -2
- package/dist/cjs/salla-loyalty.cjs.entry.js +1 -1
- package/dist/cjs/salla-maintenance-alert.cjs.entry.js +2 -2
- 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 +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-notification-item.cjs.entry.js +2 -2
- package/dist/cjs/salla-notifications.cjs.entry.js +1 -1
- 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-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-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 +1 -1
- 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 +3 -3
- package/dist/cjs/salla-product-size-guide.cjs.entry.js +3 -3
- package/dist/cjs/salla-products-list.cjs.entry.js +1 -1
- package/dist/cjs/salla-products-slider.cjs.entry.js +1 -1
- package/dist/cjs/salla-progress-bar.cjs.entry.js +1 -1
- package/dist/cjs/salla-quick-order.cjs.entry.js +1 -1
- package/dist/cjs/salla-rating-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-scopes.cjs.entry.js +2 -2
- package/dist/cjs/salla-search.cjs.entry.js +4 -4
- package/dist/cjs/salla-skeleton.cjs.entry.js +2 -2
- package/dist/cjs/salla-slider.cjs.entry.js +1 -1
- 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-tiered-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-tooltip.cjs.entry.js +2 -2
- 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 +1 -1
- package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
- package/dist/cjs/twilight.cjs.js +2 -2
- package/dist/cjs/{vanilla-picker-CnB9AyA4.js → vanilla-picker-W3JKfO-o.js} +1 -1
- package/dist/collection/assets/svg/get-directions.svg +6 -0
- package/dist/collection/assets/svg/gps.svg +17 -0
- package/dist/collection/assets/svg/location.svg +8 -4
- package/dist/collection/assets/svg/marker.svg +28 -0
- package/dist/collection/assets/svg/mini-google-map.svg +33 -0
- package/dist/collection/assets/svg/mini-map.svg +31 -0
- package/dist/collection/assets/svg/store3.svg +12 -0
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/salla-bullet-delivery/api-service.js +135 -0
- package/dist/collection/components/salla-bullet-delivery/helpers.js +125 -0
- package/dist/collection/components/salla-bullet-delivery/interfaces.js +1 -0
- package/dist/collection/components/salla-bullet-delivery/salla-bullet-delivery.css +23 -0
- package/dist/collection/components/salla-bullet-delivery/salla-bullet-delivery.js +1827 -0
- package/dist/collection/components/salla-cart-summary/salla-cart-summary.js +16 -4
- package/dist/collection/components/salla-color-picker/salla-color-picker.js +1 -1
- package/dist/collection/components/salla-comment-form/salla-comment-form.js +1 -1
- package/dist/collection/components/salla-comments/salla-comment-item.js +3 -3
- package/dist/collection/components/salla-conditional-fields/salla-conditional-fields.js +1 -1
- package/dist/collection/components/salla-cookies-bar/salla-cookies-bar.js +16 -69
- package/dist/collection/components/salla-count-down/salla-count-down.js +1 -1
- package/dist/collection/components/salla-datetime-picker/salla-datetime-picker.js +1 -1
- package/dist/collection/components/salla-file-upload/salla-file-upload.js +2 -2
- package/dist/collection/components/salla-filters/salla-filters.js +1 -1
- package/dist/collection/components/salla-filters-widget/salla-filters-widget.js +2 -2
- package/dist/collection/components/salla-gifting/salla-gifting.js +2 -2
- package/dist/collection/components/salla-hook/salla-hook.js +1 -1
- package/dist/collection/components/salla-list-tile/salla-list-tile.js +1 -1
- package/dist/collection/components/salla-loading/salla-loading.js +1 -1
- package/dist/collection/components/salla-localization-modal/salla-localization-modal.js +1 -1
- package/dist/collection/components/salla-loyalty/salla-loyalty-prize-item.js +1 -1
- package/dist/collection/components/salla-loyalty-program/salla-loyalty-program.js +1 -1
- package/dist/collection/components/salla-maintenance-alert/salla-maintenance-alert.js +1 -1
- package/dist/collection/components/salla-map/salla-map.js +3 -3
- 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-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-price-range/salla-price-range.js +2 -2
- package/dist/collection/components/salla-product-availability/salla-product-availability.js +1 -1
- package/dist/collection/components/salla-product-card/salla-product-card.js +5 -5
- package/dist/collection/components/salla-product-size-guide/salla-product-size-guide.js +2 -2
- package/dist/collection/components/salla-quantity-input/salla-quantity-input.js +1 -1
- package/dist/collection/components/salla-quick-buy/salla-quick-buy.js +1 -1
- package/dist/collection/components/salla-review-card/salla-review-card.js +1 -1
- package/dist/collection/components/salla-reviews/salla-reviews.js +1 -1
- package/dist/collection/components/salla-reviews-page/salla-reviews-page.js +1 -1
- package/dist/collection/components/salla-scopes/salla-scopes.js +1 -1
- package/dist/collection/components/salla-search/salla-search.js +3 -3
- 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-tooltip/salla-tooltip.js +1 -1
- package/dist/collection/components/salla-user-settings/salla-user-settings.js +1 -1
- package/dist/components/index.js +2 -2
- package/dist/components/location.js +14 -0
- package/dist/components/salla-bullet-delivery.d.ts +11 -0
- package/dist/components/salla-bullet-delivery.js +2060 -0
- package/dist/components/salla-cart-summary.js +16 -4
- package/dist/components/salla-color-picker2.js +1 -1
- package/dist/components/salla-comment-form2.js +1 -1
- package/dist/components/salla-comment-item2.js +3 -3
- package/dist/components/salla-conditional-fields2.js +1 -1
- package/dist/components/salla-cookies-bar.js +15 -9
- package/dist/components/salla-count-down2.js +1 -1
- package/dist/components/salla-datetime-picker2.js +1 -1
- package/dist/components/salla-file-upload2.js +2 -2
- package/dist/components/salla-filters-widget2.js +2 -2
- package/dist/components/salla-filters.js +1 -1
- package/dist/components/salla-gifting.js +2 -2
- package/dist/components/salla-hook.js +1 -1
- package/dist/components/salla-list-tile2.js +1 -1
- package/dist/components/salla-loading2.js +1 -1
- package/dist/components/salla-localization-modal.js +1 -1
- package/dist/components/salla-loyalty-prize-item.js +1 -1
- package/dist/components/salla-loyalty-program.js +1 -1
- package/dist/components/salla-maintenance-alert.js +1 -1
- package/dist/components/salla-map2.js +4 -10
- 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-summary.js +1 -1
- package/dist/components/salla-payments.js +2 -2
- package/dist/components/salla-placeholder2.js +1 -1
- package/dist/components/salla-price-range2.js +2 -2
- package/dist/components/salla-product-availability2.js +1 -1
- package/dist/components/salla-product-card2.js +5 -5
- package/dist/components/salla-product-size-guide.js +2 -2
- package/dist/components/salla-quantity-input.js +1 -1
- package/dist/components/salla-quick-buy2.js +1 -1
- package/dist/components/salla-review-card2.js +1 -1
- package/dist/components/salla-reviews-page.js +1 -1
- package/dist/components/salla-reviews.js +1 -1
- package/dist/components/salla-scopes.js +1 -1
- package/dist/components/salla-search.js +3 -3
- package/dist/components/salla-skeleton2.js +1 -1
- package/dist/components/salla-social-share.js +1 -1
- 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-tooltip2.js +1 -1
- package/dist/components/salla-user-settings.js +1 -1
- package/dist/esm/{filepond-BhRqbCAg.js → filepond-CVt8gG7K.js} +1 -1
- package/dist/esm/{filepond-plugin-file-poster-Czu5ACER.js → filepond-plugin-file-poster-ByDhiu8k.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-size-BZbSUj1B.js → filepond-plugin-file-validate-size-C46KRc5n.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-type-DKYfoXoT.js → filepond-plugin-file-validate-type-7wK_W1ju.js} +1 -1
- package/dist/esm/{filepond-plugin-image-edit-WuB5nx6B.js → filepond-plugin-image-edit-BbFosret.js} +1 -1
- package/dist/esm/{filepond-plugin-image-exif-orientation-noX6t0j9.js → filepond-plugin-image-exif-orientation-DXsWsxNp.js} +1 -1
- package/dist/esm/{filepond-plugin-image-preview-Czg9NDfH.js → filepond-plugin-image-preview-BZoHvyw-.js} +1 -1
- package/dist/esm/{index-De4u_OiV.js → index-SkTHIgsP.js} +6 -2
- package/dist/esm/{index-Dtrxto6J.js → index-x1gUeQbQ.js} +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/location-BO5AoBAP.js +14 -0
- package/dist/esm/salla-accordion-body_3.entry.js +5 -11
- package/dist/esm/salla-accordion_6.entry.js +2 -2
- package/dist/esm/salla-add-product-button_4.entry.js +3 -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-apps-icons.entry.js +1 -1
- package/dist/esm/salla-booking-field_7.entry.js +17 -17
- package/dist/esm/salla-bullet-delivery.entry.js +1978 -0
- package/dist/esm/salla-cart-item-offers_2.entry.js +17 -5
- package/dist/esm/salla-comment-form_8.entry.js +8 -8
- 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 +12 -7
- package/dist/esm/salla-count-down_2.entry.js +7 -7
- package/dist/esm/salla-custom-fields.entry.js +1 -1
- package/dist/esm/salla-filters-widget.entry.js +3 -3
- package/dist/esm/salla-filters.entry.js +2 -2
- package/dist/esm/salla-gifting.entry.js +3 -3
- package/dist/esm/salla-hook.entry.js +2 -2
- package/dist/esm/salla-infinite-scroll.entry.js +1 -1
- package/dist/esm/salla-installment.entry.js +1 -1
- package/dist/esm/salla-list-tile.entry.js +2 -2
- package/dist/esm/salla-localization-modal.entry.js +2 -2
- package/dist/esm/salla-login-modal.entry.js +1 -1
- package/dist/esm/salla-loyalty-prize-item.entry.js +2 -2
- package/dist/esm/salla-loyalty-program.entry.js +2 -2
- package/dist/esm/salla-loyalty.entry.js +1 -1
- package/dist/esm/salla-maintenance-alert.entry.js +2 -2
- 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 +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-notification-item.entry.js +2 -2
- package/dist/esm/salla-notifications.entry.js +1 -1
- package/dist/esm/salla-offer-modal.entry.js +2 -2
- package/dist/esm/salla-offer.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-summary.entry.js +2 -2
- package/dist/esm/salla-order-totals-card.entry.js +1 -1
- package/dist/esm/salla-orders.entry.js +1 -1
- 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 +3 -3
- package/dist/esm/salla-product-size-guide.entry.js +3 -3
- package/dist/esm/salla-products-list.entry.js +1 -1
- package/dist/esm/salla-products-slider.entry.js +1 -1
- package/dist/esm/salla-progress-bar.entry.js +1 -1
- package/dist/esm/salla-quick-order.entry.js +1 -1
- package/dist/esm/salla-rating-modal.entry.js +1 -1
- package/dist/esm/salla-scopes.entry.js +2 -2
- package/dist/esm/salla-search.entry.js +4 -4
- package/dist/esm/salla-skeleton.entry.js +2 -2
- package/dist/esm/salla-slider.entry.js +1 -1
- 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-tiered-offer.entry.js +1 -1
- package/dist/esm/salla-tooltip.entry.js +2 -2
- 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 +1 -1
- package/dist/esm/salla-wallet.entry.js +1 -1
- package/dist/esm/twilight.js +3 -3
- package/dist/esm/{vanilla-picker-rbpgRFmW.js → vanilla-picker-CBzZiD3g.js} +1 -1
- package/dist/twilight/{p-40ff5179.entry.js → p-001b7ef6.entry.js} +1 -1
- package/dist/twilight/{p-eaa6e008.entry.js → p-07fdc902.entry.js} +1 -1
- package/dist/twilight/{p-d0c47c31.entry.js → p-0ad3a828.entry.js} +1 -1
- package/dist/twilight/{p-09feb665.entry.js → p-0b53d638.entry.js} +1 -1
- package/dist/twilight/{p-8006c4fb.entry.js → p-13b496e7.entry.js} +1 -1
- package/dist/twilight/{p-7f3f771a.entry.js → p-18e52d0e.entry.js} +1 -1
- package/dist/twilight/{p-c3706c8f.entry.js → p-1e8fbd9f.entry.js} +1 -1
- package/dist/twilight/{p-dfadafad.entry.js → p-236372e3.entry.js} +1 -1
- package/dist/twilight/{p-5654e5ee.entry.js → p-27e70f37.entry.js} +1 -1
- package/dist/twilight/{p-884cb4c5.entry.js → p-2820ce1d.entry.js} +1 -1
- package/dist/twilight/{p-6ff50966.entry.js → p-2ab48cac.entry.js} +1 -1
- package/dist/twilight/{p-295915a0.entry.js → p-2f692fcf.entry.js} +1 -1
- package/dist/twilight/{p-69c58d83.entry.js → p-301c2f68.entry.js} +1 -1
- package/dist/twilight/{p-bac83103.entry.js → p-3243737f.entry.js} +1 -1
- package/dist/twilight/{p-8edd8051.entry.js → p-35024791.entry.js} +1 -1
- package/dist/twilight/{p-11408fba.entry.js → p-3bf9141e.entry.js} +1 -1
- package/dist/twilight/{p-5744d83c.entry.js → p-3eaa8925.entry.js} +1 -1
- package/dist/twilight/{p-67840827.entry.js → p-3fe97989.entry.js} +1 -1
- package/dist/twilight/{p-55447584.entry.js → p-409f7136.entry.js} +1 -1
- package/dist/twilight/{p-5e1573ea.entry.js → p-463e4f76.entry.js} +1 -1
- package/dist/twilight/{p-f86cd123.entry.js → p-4cf58a9c.entry.js} +1 -1
- package/dist/twilight/{p-b5dc631b.entry.js → p-4fa45c6a.entry.js} +1 -1
- package/dist/twilight/p-504b5014.entry.js +4 -0
- package/dist/twilight/{p-4a76e050.entry.js → p-511ca10b.entry.js} +1 -1
- package/dist/twilight/{p-0dd6679c.entry.js → p-51de8331.entry.js} +1 -1
- package/dist/twilight/{p-d3680fb2.entry.js → p-53b2e08f.entry.js} +1 -1
- package/dist/twilight/{p-ab3aa0c4.entry.js → p-53cc3cef.entry.js} +1 -1
- package/dist/twilight/{p-bcc2be67.entry.js → p-5905a86a.entry.js} +1 -1
- package/dist/twilight/{p-db533685.entry.js → p-59db4c52.entry.js} +1 -1
- package/dist/twilight/{p-a2b26070.entry.js → p-5b9bc272.entry.js} +1 -1
- package/dist/twilight/{p-f63ba8ce.entry.js → p-5bf0ced8.entry.js} +1 -1
- package/dist/twilight/{p-Db-E_0Rj.js → p-5dujJcuF.js} +1 -1
- package/dist/twilight/{p-55789c14.entry.js → p-6036b492.entry.js} +1 -1
- package/dist/twilight/p-6837da63.entry.js +4 -0
- package/dist/twilight/{p-7f999201.entry.js → p-75769c80.entry.js} +1 -1
- package/dist/twilight/p-7d72642b.entry.js +4 -0
- package/dist/twilight/p-861be114.entry.js +4 -0
- package/dist/twilight/p-86982850.entry.js +4 -0
- package/dist/twilight/p-8b505e2a.entry.js +4 -0
- package/dist/twilight/{p-a63d0e39.entry.js → p-8e97544e.entry.js} +1 -1
- package/dist/twilight/{p-8eaf241e.entry.js → p-94f73964.entry.js} +1 -1
- package/dist/twilight/{p-d6536ce3.entry.js → p-9d497735.entry.js} +1 -1
- package/dist/twilight/{p-6a0df26c.entry.js → p-9ebe9909.entry.js} +1 -1
- package/dist/twilight/{p-Btrb7IoM.js → p-BF4uw95J.js} +1 -1
- package/dist/twilight/p-BO5AoBAP.js +4 -0
- package/dist/twilight/{p-Wi2aT09S.js → p-BgZuVAWD.js} +1 -1
- package/dist/twilight/{p-B-3IShme.js → p-Cp0TiBtU.js} +1 -1
- package/dist/twilight/{p-B9mALQjv.js → p-DICe9yRT.js} +1 -1
- package/dist/twilight/{p-BcUTU-HF.js → p-DPmKuJIj.js} +2 -2
- package/dist/twilight/{p-CbQiaV8S.js → p-D_zRqCzR.js} +1 -1
- package/dist/twilight/{p-BFLhXraR.js → p-DcBxzAOm.js} +2 -2
- package/dist/twilight/{p-C4_JENkr.js → p-Dr5NxBjb.js} +1 -1
- package/dist/twilight/{p-De4u_OiV.js → p-SkTHIgsP.js} +1 -1
- package/dist/twilight/p-a473108d.entry.js +4 -0
- package/dist/twilight/{p-0d942f6b.entry.js → p-a9e61f29.entry.js} +1 -1
- package/dist/twilight/p-acc5aba0.entry.js +4 -0
- package/dist/twilight/{p-0743ad3f.entry.js → p-afb92112.entry.js} +1 -1
- package/dist/twilight/{p-0f8d378c.entry.js → p-b3fad8c9.entry.js} +1 -1
- package/dist/twilight/{p-3190dbfb.entry.js → p-b8b9c8c0.entry.js} +1 -1
- package/dist/twilight/{p-810d7f34.entry.js → p-bc174ca1.entry.js} +1 -1
- package/dist/twilight/{p-b7047136.entry.js → p-bdb38d1b.entry.js} +1 -1
- package/dist/twilight/{p-b1aaa74b.entry.js → p-c1bdca57.entry.js} +1 -1
- package/dist/twilight/{p-a1588d0d.entry.js → p-c9179f5b.entry.js} +1 -1
- package/dist/twilight/{p-948e44b1.entry.js → p-d100ac0c.entry.js} +1 -1
- package/dist/twilight/{p-fba6d1c9.entry.js → p-d45adf75.entry.js} +1 -1
- package/dist/twilight/{p-edec367c.entry.js → p-d5c633e3.entry.js} +1 -1
- package/dist/twilight/{p-0361337c.entry.js → p-d95a2fee.entry.js} +1 -1
- package/dist/twilight/{p-ad9f616f.entry.js → p-d969b269.entry.js} +1 -1
- package/dist/twilight/{p-f894c79f.entry.js → p-db479d0a.entry.js} +1 -1
- package/dist/twilight/{p-77bd2500.entry.js → p-e100b798.entry.js} +1 -1
- package/dist/twilight/{p-72941677.entry.js → p-e1222500.entry.js} +1 -1
- package/dist/twilight/{p-cc9f3079.entry.js → p-e452b815.entry.js} +1 -1
- package/dist/twilight/{p-665ea882.entry.js → p-e5758e7c.entry.js} +1 -1
- package/dist/twilight/p-e975235b.entry.js +4 -0
- package/dist/twilight/{p-96d0ca21.entry.js → p-ebb88e7b.entry.js} +1 -1
- package/dist/twilight/{p-e7a71145.entry.js → p-ec8e267b.entry.js} +1 -1
- package/dist/twilight/{p-619fdc7f.entry.js → p-f0ad1125.entry.js} +1 -1
- package/dist/twilight/{p-4bdf1e1b.entry.js → p-f64f5502.entry.js} +1 -1
- package/dist/twilight/{p-16cdf1aa.entry.js → p-f89add85.entry.js} +1 -1
- package/dist/twilight/twilight.esm.js +1 -1
- package/dist/types/components/salla-bullet-delivery/api-service.d.ts +61 -0
- package/dist/types/components/salla-bullet-delivery/helpers.d.ts +39 -0
- package/dist/types/components/salla-bullet-delivery/interfaces.d.ts +297 -0
- package/dist/types/components/salla-bullet-delivery/salla-bullet-delivery.d.ts +202 -0
- package/dist/types/components/salla-cart-summary/salla-cart-summary.d.ts +2 -1
- package/dist/types/components/salla-cookies-bar/salla-cookies-bar.d.ts +5 -9
- package/dist/types/components.d.ts +57 -26
- package/package.json +5 -5
- package/dist/twilight/p-4970483c.entry.js +0 -4
- package/dist/twilight/p-4e52bc62.entry.js +0 -4
- package/dist/twilight/p-61619fec.entry.js +0 -4
- package/dist/twilight/p-a90a0bb7.entry.js +0 -4
- package/dist/twilight/p-b9dfbb9f.entry.js +0 -4
- package/dist/twilight/p-c8aa07fd.entry.js +0 -4
- package/dist/twilight/p-fae39494.entry.js +0 -4
- package/dist/twilight/p-fde5d559.entry.js +0 -4
|
@@ -0,0 +1,1827 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Crafted with ❤ by Salla
|
|
3
|
+
*/
|
|
4
|
+
import { h, Host, } from "@stencil/core";
|
|
5
|
+
import { bulletDeliveryAPI, isSaudiArabia } from "./api-service";
|
|
6
|
+
import { findNearestBranch, filterBranches, formatWorkingHoursDisplay, getBranchFirstSlot, findMatchingAddress, getGeolocationErrorMessage, getIntentSubtitle, getIntentCountryId, getIntentCountryCode, getIntentRegionId, getIntentCityId, getIntentDistrictId, getIntentBranchId, getIntentLatitude, getIntentLongitude, hasSessionAddressIntent, requireRegionAndDistrictForSA, buildAddressLocationPayloadFromSelection, } from "./helpers";
|
|
7
|
+
const BRANCH_SEARCH_DEBOUNCE_MS = 1000;
|
|
8
|
+
const GEOLOCATION_TIMEOUT = 10000;
|
|
9
|
+
import Store from "../../assets/svg/store3.svg";
|
|
10
|
+
import Search from "../../assets/svg/search.svg";
|
|
11
|
+
import Location from "../../assets/svg/location.svg";
|
|
12
|
+
import GPS from "../../assets/svg/gps.svg";
|
|
13
|
+
import MiniMap from "../../assets/svg/mini-map.svg";
|
|
14
|
+
import ArrowRight from "../../assets/svg/keyboard_arrow_right.svg";
|
|
15
|
+
import ArrowLeft from "../../assets/svg/keyboard_arrow_left.svg";
|
|
16
|
+
import GetDirections from "../../assets/svg/get-directions.svg";
|
|
17
|
+
/**
|
|
18
|
+
* @slot footer - The bottom section of the component for custom actions.
|
|
19
|
+
*/
|
|
20
|
+
export class SallaBulletDelivery {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.confirming = false;
|
|
23
|
+
this.branchSearchDebounceTimer = null;
|
|
24
|
+
this.componentReady = false;
|
|
25
|
+
this.pendingOpen = false;
|
|
26
|
+
this.tabChanging = false;
|
|
27
|
+
this.intentStorageKey = "bullet_delivery_intent";
|
|
28
|
+
this.sessionShownKey = "bullet_delivery_shown_this_session";
|
|
29
|
+
this.cartItemAddedEvent = "cart::item.added";
|
|
30
|
+
this.cartItemAddedHandler = null;
|
|
31
|
+
this.useCartEventApi = false;
|
|
32
|
+
this.bulletDeliveryOpenHandler = (eventData) => {
|
|
33
|
+
this.preselectedAddressId = eventData?.preselected_address_id;
|
|
34
|
+
this.preselectedBranchId = eventData?.preselected_branch_id;
|
|
35
|
+
this.open();
|
|
36
|
+
};
|
|
37
|
+
this.closeHandler = null;
|
|
38
|
+
this.guestLoginSyncHandler = null;
|
|
39
|
+
/** True after saved addresses have been loaded (lazy: only when address tab is shown). */
|
|
40
|
+
this.savedAddressesLoaded = false;
|
|
41
|
+
// Core state
|
|
42
|
+
this.loading = true;
|
|
43
|
+
this.activeTab = "address";
|
|
44
|
+
this.isLoggedIn = false;
|
|
45
|
+
this.viewMode = "main";
|
|
46
|
+
// Location data
|
|
47
|
+
this.countries = [];
|
|
48
|
+
this.regions = [];
|
|
49
|
+
this.cities = [];
|
|
50
|
+
this.districts = [];
|
|
51
|
+
this.loadingRegions = false;
|
|
52
|
+
this.selectedCountry = null;
|
|
53
|
+
this.selectedRegion = null;
|
|
54
|
+
this.selectedCity = null;
|
|
55
|
+
this.selectedDistrict = null;
|
|
56
|
+
this.districtName = "";
|
|
57
|
+
// Saved addresses state
|
|
58
|
+
this.savedAddresses = [];
|
|
59
|
+
this.selectedSavedAddress = null;
|
|
60
|
+
/** True when user selected the session address (guest address from before login, not yet saved) */
|
|
61
|
+
this.selectedSessionAddress = false;
|
|
62
|
+
// Pickup state
|
|
63
|
+
this.branches = [];
|
|
64
|
+
this.filteredBranches = [];
|
|
65
|
+
this.selectedBranch = null;
|
|
66
|
+
this.branchSearchQuery = "";
|
|
67
|
+
// Loading states
|
|
68
|
+
this.loadingCities = false;
|
|
69
|
+
this.loadingDistricts = false;
|
|
70
|
+
this.loadingBranches = false;
|
|
71
|
+
this.loadingNearestBranch = false;
|
|
72
|
+
this.locationError = "";
|
|
73
|
+
this.savingAddress = false;
|
|
74
|
+
this.loadingSavedAddresses = false;
|
|
75
|
+
this.showCartWillBeClearedBanner = false;
|
|
76
|
+
/** Shown when scopes/allocation returns 422 (address outside delivery coverage). Only on delivery tab. */
|
|
77
|
+
this.allocationOutOfCoverageMessage = null;
|
|
78
|
+
this.newAddressForm = {
|
|
79
|
+
...SallaBulletDelivery.INITIAL_ADDRESS_FORM,
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Submit add-address form: create address via API then switch back to list.
|
|
83
|
+
*/
|
|
84
|
+
this.handleSubmitAddAddress = async (e) => {
|
|
85
|
+
e.preventDefault();
|
|
86
|
+
if (this.savingAddress)
|
|
87
|
+
return;
|
|
88
|
+
if (!this.selectedCountry || !this.selectedCity)
|
|
89
|
+
return;
|
|
90
|
+
if (!requireRegionAndDistrictForSA(this.selectedCountry?.code, this.selectedRegion?.id, this.selectedDistrict?.id ?? (this.districtName?.trim() || null)))
|
|
91
|
+
return;
|
|
92
|
+
this.savingAddress = true;
|
|
93
|
+
try {
|
|
94
|
+
const payload = this.buildAddressLocationPayload();
|
|
95
|
+
const { success, address } = await bulletDeliveryAPI.saveAddressLocation(payload);
|
|
96
|
+
if (success) {
|
|
97
|
+
await this.loadSavedAddresses();
|
|
98
|
+
const latest = address ?? this.savedAddresses[0] ?? null;
|
|
99
|
+
if (latest?.is_in_coverage) {
|
|
100
|
+
this.selectedSessionAddress = false;
|
|
101
|
+
this.selectedSavedAddress = latest;
|
|
102
|
+
}
|
|
103
|
+
this.addressCreated.emit({ address: latest });
|
|
104
|
+
this.viewMode = "main";
|
|
105
|
+
this.districtName = "";
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
Salla.notify?.error(Salla.lang.get("common.errors.error_occurred"));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
console.error("SallaBulletDelivery: Error saving address", error);
|
|
113
|
+
Salla.notify?.error(Salla.lang.get("common.errors.error_occurred"));
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
this.savingAddress = false;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/** Whether to show delivery + pickup tabs. From store.settings.bullet_delivery.supports_pickup */
|
|
121
|
+
get supportsPickup() {
|
|
122
|
+
return !!Salla.config.get("store.settings.bullet_delivery.supports_pickup");
|
|
123
|
+
}
|
|
124
|
+
/** The modal opening strategy: 'first_visit' | 'on_cart_click' | 'after_add_to_cart' */
|
|
125
|
+
get openingType() {
|
|
126
|
+
return Salla.config.get("store.settings.bullet_delivery.settings.type");
|
|
127
|
+
}
|
|
128
|
+
/** Whether the modal is required (cannot be closed/skipped). From store.settings.bullet_delivery.settings.is_required */
|
|
129
|
+
get isRequired() {
|
|
130
|
+
return !!Salla.config.get("store.settings.bullet_delivery.settings.is_required");
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Opens the bullet delivery modal
|
|
134
|
+
*/
|
|
135
|
+
async open() {
|
|
136
|
+
// If component is not ready yet, mark as pending and return
|
|
137
|
+
if (!this.componentReady || !this.modal) {
|
|
138
|
+
this.pendingOpen = true;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// Reset state and set loading before opening
|
|
142
|
+
this.resetState();
|
|
143
|
+
this.loading = true;
|
|
144
|
+
// Open modal immediately to show skeleton/loading state
|
|
145
|
+
this.modal.open();
|
|
146
|
+
try {
|
|
147
|
+
// Check login status
|
|
148
|
+
const userType = Salla.config.get("user.type");
|
|
149
|
+
this.isLoggedIn = userType !== "guest";
|
|
150
|
+
const savedIntent = this.getStoredIntent();
|
|
151
|
+
// When opening from a stored intent, treat its IDs as preselected targets
|
|
152
|
+
if (savedIntent?.type === "address" && savedIntent.address_id) {
|
|
153
|
+
this.preselectedAddressId = savedIntent.address_id;
|
|
154
|
+
}
|
|
155
|
+
if (savedIntent?.type === "branch" && savedIntent.branch_id) {
|
|
156
|
+
this.preselectedBranchId = savedIntent.branch_id;
|
|
157
|
+
}
|
|
158
|
+
const hasStoredAddressIds = !this.isLoggedIn &&
|
|
159
|
+
savedIntent?.type === "address" &&
|
|
160
|
+
getIntentCountryId(savedIntent) != null &&
|
|
161
|
+
getIntentCityId(savedIntent) != null;
|
|
162
|
+
// Set default tab first so we can lazy-load tab-specific data.
|
|
163
|
+
if (this.supportsPickup &&
|
|
164
|
+
savedIntent?.type &&
|
|
165
|
+
(savedIntent.type === "address" || savedIntent.type === "branch")) {
|
|
166
|
+
this.activeTab = savedIntent.type;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
this.activeTab = "address";
|
|
170
|
+
}
|
|
171
|
+
// Load countries always; load saved addresses only when address tab is active (lazy tab data).
|
|
172
|
+
await Promise.all([
|
|
173
|
+
this.loadCountries(hasStoredAddressIds),
|
|
174
|
+
this.isLoggedIn && this.activeTab === "address"
|
|
175
|
+
? this.loadSavedAddresses().then(() => {
|
|
176
|
+
this.savedAddressesLoaded = true;
|
|
177
|
+
})
|
|
178
|
+
: Promise.resolve(),
|
|
179
|
+
]);
|
|
180
|
+
// Auto-select preselected address if provided
|
|
181
|
+
if (this.isLoggedIn && this.preselectedAddressId) {
|
|
182
|
+
const address = this.savedAddresses.find((a) => a.id === this.preselectedAddressId);
|
|
183
|
+
if (address) {
|
|
184
|
+
this.selectedSessionAddress = false;
|
|
185
|
+
this.selectedSavedAddress = address;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Load branches only when branch tab is active (lazy tab data)
|
|
189
|
+
// Use lat/lng from session storage if available for more accurate results
|
|
190
|
+
if (this.activeTab === "branch") {
|
|
191
|
+
const intentLat = getIntentLatitude(savedIntent);
|
|
192
|
+
const intentLng = getIntentLongitude(savedIntent);
|
|
193
|
+
if (intentLat != null && intentLng != null) {
|
|
194
|
+
await this.loadBranchesWithLocation(intentLat, intentLng);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
await this.loadBranches();
|
|
198
|
+
}
|
|
199
|
+
// Auto-select preselected branch if provided
|
|
200
|
+
if (this.preselectedBranchId) {
|
|
201
|
+
const branch = this.branches.find((b) => b.id === this.preselectedBranchId);
|
|
202
|
+
if (branch) {
|
|
203
|
+
this.selectedBranch = branch;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Prefill form data from session storage
|
|
208
|
+
await this.prefillFromSessionStorage();
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
console.error("SallaBulletDelivery: Error loading data", e);
|
|
212
|
+
}
|
|
213
|
+
finally {
|
|
214
|
+
// Only hide loading after all data is loaded and UI is ready
|
|
215
|
+
this.loading = false;
|
|
216
|
+
this.modal?.stopLoading();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Closes the bullet delivery modal
|
|
221
|
+
*/
|
|
222
|
+
async close() {
|
|
223
|
+
this.bulletDeliveryClosed.emit();
|
|
224
|
+
return this.modal?.close();
|
|
225
|
+
}
|
|
226
|
+
resetState() {
|
|
227
|
+
this.viewMode = "main";
|
|
228
|
+
this.selectedCountry = null;
|
|
229
|
+
this.selectedRegion = null;
|
|
230
|
+
this.selectedCity = null;
|
|
231
|
+
this.selectedDistrict = null;
|
|
232
|
+
this.districtName = "";
|
|
233
|
+
this.selectedSavedAddress = null;
|
|
234
|
+
this.selectedSessionAddress = false;
|
|
235
|
+
this.selectedBranch = null;
|
|
236
|
+
this.branchSearchQuery = "";
|
|
237
|
+
this.regions = [];
|
|
238
|
+
this.cities = [];
|
|
239
|
+
this.districts = [];
|
|
240
|
+
this.branches = [];
|
|
241
|
+
this.filteredBranches = [];
|
|
242
|
+
this.newAddressForm = { ...SallaBulletDelivery.INITIAL_ADDRESS_FORM };
|
|
243
|
+
// Reset new state variables
|
|
244
|
+
this.showCartWillBeClearedBanner = false;
|
|
245
|
+
this.allocationOutOfCoverageMessage = null;
|
|
246
|
+
this.locationError = "";
|
|
247
|
+
this.savedAddressesLoaded = false;
|
|
248
|
+
this.loadingSavedAddresses = false;
|
|
249
|
+
}
|
|
250
|
+
getIntentStorage() {
|
|
251
|
+
const rememberLastSession = Boolean(Salla.config.get("store.settings.bullet_delivery.settings.remember_last_session"));
|
|
252
|
+
return Salla.storage[rememberLastSession ? "store" : "session"];
|
|
253
|
+
}
|
|
254
|
+
getStoredIntent() {
|
|
255
|
+
return this.getIntentStorage().get(this.intentStorageKey);
|
|
256
|
+
}
|
|
257
|
+
setStoredIntent(intent) {
|
|
258
|
+
this.getIntentStorage().set(this.intentStorageKey, intent);
|
|
259
|
+
}
|
|
260
|
+
removeStoredIntent() {
|
|
261
|
+
this.getIntentStorage().remove(this.intentStorageKey);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Single prefill flow: load geography from stored intent and set selected location + form.
|
|
265
|
+
* Assumes this.countries is already loaded. No-op if no intent or no city in intent.
|
|
266
|
+
*/
|
|
267
|
+
async prefillAddressFromStoredIntent() {
|
|
268
|
+
const intent = this.getStoredIntent();
|
|
269
|
+
if (!intent || intent.type !== "address" || getIntentCityId(intent) == null)
|
|
270
|
+
return;
|
|
271
|
+
const countryId = getIntentCountryId(intent);
|
|
272
|
+
if (!countryId)
|
|
273
|
+
return;
|
|
274
|
+
const country = this.countries.find((c) => String(c.id) === String(countryId));
|
|
275
|
+
if (!country)
|
|
276
|
+
return;
|
|
277
|
+
this.selectedCountry = country;
|
|
278
|
+
this.updateNewAddressForm({ country_id: Number(country.id) });
|
|
279
|
+
const isSA = isSaudiArabia(country.code);
|
|
280
|
+
const cityId = getIntentCityId(intent);
|
|
281
|
+
const regionId = getIntentRegionId(intent);
|
|
282
|
+
const districtId = getIntentDistrictId(intent);
|
|
283
|
+
const districtName = intent.address_details?.district?.name;
|
|
284
|
+
const [regions, cities, districts] = await Promise.all([
|
|
285
|
+
isSA ? bulletDeliveryAPI.getRegions(country.id) : Promise.resolve([]),
|
|
286
|
+
bulletDeliveryAPI.getCities(country.id, isSA && regionId != null ? regionId : undefined),
|
|
287
|
+
cityId != null
|
|
288
|
+
? bulletDeliveryAPI.getDistricts(Number(cityId))
|
|
289
|
+
: Promise.resolve([]),
|
|
290
|
+
]);
|
|
291
|
+
if (isSA)
|
|
292
|
+
this.regions = regions;
|
|
293
|
+
this.cities = cities;
|
|
294
|
+
this.districts = districts;
|
|
295
|
+
this.loadingCities = false;
|
|
296
|
+
this.loadingRegions = false;
|
|
297
|
+
this.loadingDistricts = false;
|
|
298
|
+
if (isSA && regionId != null) {
|
|
299
|
+
const region = this.regions.find((r) => String(r.id) === String(regionId));
|
|
300
|
+
if (region) {
|
|
301
|
+
this.selectedRegion = region;
|
|
302
|
+
this.updateNewAddressForm({ region_id: region.id });
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (cityId != null && this.cities.length > 0) {
|
|
306
|
+
const city = this.cities.find((c) => String(c.id) === String(cityId));
|
|
307
|
+
if (city) {
|
|
308
|
+
this.selectedCity = city;
|
|
309
|
+
this.updateNewAddressForm({ city_id: city.id, city });
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (this.districts.length > 0) {
|
|
313
|
+
const district = this.findPrefillDistrict(districtId, districtName);
|
|
314
|
+
if (district) {
|
|
315
|
+
this.updateNewAddressForm({ district_id: district.id, district });
|
|
316
|
+
this.selectedDistrict = district;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
updateNewAddressForm(partial) {
|
|
321
|
+
this.newAddressForm = { ...this.newAddressForm, ...partial };
|
|
322
|
+
}
|
|
323
|
+
/** Whether allocation completed successfully this session (modal won't auto-open again). */
|
|
324
|
+
hasBeenShownThisSession() {
|
|
325
|
+
return !!Salla.storage.session.get(this.sessionShownKey);
|
|
326
|
+
}
|
|
327
|
+
/** Mark allocation as completed this session (called only after allocateScope succeeds). */
|
|
328
|
+
markShownThisSession() {
|
|
329
|
+
Salla.storage.session.set(this.sessionShownKey, true);
|
|
330
|
+
}
|
|
331
|
+
async loadCountries(skipEagerSubFetch = false) {
|
|
332
|
+
const forBranch = this.activeTab === "branch";
|
|
333
|
+
this.countries = await bulletDeliveryAPI.getCountries(forBranch);
|
|
334
|
+
// Preselect country from bullet_delivery.customer_location.country (SA | EG | ...)
|
|
335
|
+
const configCountryCode = Salla.config.get("store.settings.bullet_delivery.customer_location.country");
|
|
336
|
+
const countryToSelect = configCountryCode && this.countries.length > 0
|
|
337
|
+
? this.countries.find((c) => String(c.code).toUpperCase() ===
|
|
338
|
+
String(configCountryCode).toUpperCase())
|
|
339
|
+
: null;
|
|
340
|
+
if (countryToSelect) {
|
|
341
|
+
this.selectedCountry = countryToSelect;
|
|
342
|
+
this.updateNewAddressForm({
|
|
343
|
+
country_id: Number(this.selectedCountry.id),
|
|
344
|
+
});
|
|
345
|
+
// Skip eager sub-fetches when stored intent IDs exist — prefillFromSessionStorage
|
|
346
|
+
// will fire regions/cities/districts in parallel using the stored IDs directly.
|
|
347
|
+
if (!skipEagerSubFetch) {
|
|
348
|
+
if (isSaudiArabia(this.selectedCountry.code)) {
|
|
349
|
+
await this.loadRegions(this.selectedCountry.id);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
await this.loadCities(this.selectedCountry.id);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
async loadCities(countryId, regionId) {
|
|
358
|
+
this.loadingCities = true;
|
|
359
|
+
this.cities = [];
|
|
360
|
+
this.districts = [];
|
|
361
|
+
this.selectedCity = null;
|
|
362
|
+
this.selectedDistrict = null;
|
|
363
|
+
this.districtName = "";
|
|
364
|
+
try {
|
|
365
|
+
this.cities = await bulletDeliveryAPI.getCities(countryId, regionId);
|
|
366
|
+
}
|
|
367
|
+
finally {
|
|
368
|
+
this.loadingCities = false;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
async loadDistricts(cityId) {
|
|
372
|
+
this.loadingDistricts = true;
|
|
373
|
+
this.districts = [];
|
|
374
|
+
this.selectedDistrict = null;
|
|
375
|
+
this.districtName = "";
|
|
376
|
+
try {
|
|
377
|
+
this.districts = await bulletDeliveryAPI.getDistricts(cityId);
|
|
378
|
+
}
|
|
379
|
+
finally {
|
|
380
|
+
this.loadingDistricts = false;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
findPrefillDistrict(districtId, districtName) {
|
|
384
|
+
if (this.districts.length === 0) {
|
|
385
|
+
return undefined;
|
|
386
|
+
}
|
|
387
|
+
if (districtId != null) {
|
|
388
|
+
const byId = this.districts.find((d) => String(d.id) === String(districtId));
|
|
389
|
+
if (byId) {
|
|
390
|
+
return byId;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
const normalizedName = districtName?.trim().toLowerCase();
|
|
394
|
+
if (!normalizedName) {
|
|
395
|
+
return undefined;
|
|
396
|
+
}
|
|
397
|
+
return this.districts.find((d) => {
|
|
398
|
+
const arName = d.name?.trim().toLowerCase();
|
|
399
|
+
const enName = d.name_en?.trim().toLowerCase();
|
|
400
|
+
return arName === normalizedName || enName === normalizedName;
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
async loadBranches() {
|
|
404
|
+
this.loadingBranches = true;
|
|
405
|
+
try {
|
|
406
|
+
this.branches = await bulletDeliveryAPI.getBranches({
|
|
407
|
+
country_id: this.selectedCountry?.id,
|
|
408
|
+
});
|
|
409
|
+
this.filterBranches();
|
|
410
|
+
}
|
|
411
|
+
finally {
|
|
412
|
+
this.loadingBranches = false;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
filterBranches() {
|
|
416
|
+
this.filteredBranches = filterBranches(this.branches, this.branchSearchQuery);
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Prefill form fields from session storage
|
|
420
|
+
*/
|
|
421
|
+
async prefillFromSessionStorage() {
|
|
422
|
+
try {
|
|
423
|
+
const intent = this.getStoredIntent();
|
|
424
|
+
if (!intent) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
// Prefill address tab for guest users (from stored address_details IDs only)
|
|
428
|
+
if (this.activeTab === "address" &&
|
|
429
|
+
intent.type === "address" &&
|
|
430
|
+
!this.isLoggedIn) {
|
|
431
|
+
await this.prefillAddressFromStoredIntent();
|
|
432
|
+
}
|
|
433
|
+
// Prefill branch tab
|
|
434
|
+
if (this.activeTab === "branch" && intent.type === "branch") {
|
|
435
|
+
const countryId = getIntentCountryId(intent);
|
|
436
|
+
if (countryId != null) {
|
|
437
|
+
const country = this.countries.find((c) => String(c.id) === String(countryId));
|
|
438
|
+
if (country) {
|
|
439
|
+
this.selectedCountry = country;
|
|
440
|
+
this.updateNewAddressForm({ country_id: Number(country.id) });
|
|
441
|
+
const branchId = getIntentBranchId(intent);
|
|
442
|
+
if (branchId != null && this.branches.length > 0) {
|
|
443
|
+
const branch = this.branches.find((b) => b.id === branchId);
|
|
444
|
+
if (branch) {
|
|
445
|
+
this.selectedBranch = branch;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
catch (error) {
|
|
453
|
+
console.error("[BulletDelivery] Error prefilling from session storage:", error);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
async loadSavedAddresses() {
|
|
457
|
+
this.savedAddresses = await bulletDeliveryAPI.getSavedAddresses();
|
|
458
|
+
// If session address exists (guest intent before login), select it by default
|
|
459
|
+
const intent = this.getStoredIntent();
|
|
460
|
+
const hasSessionAddress = hasSessionAddressIntent(intent);
|
|
461
|
+
if (hasSessionAddress) {
|
|
462
|
+
this.selectedSessionAddress = true;
|
|
463
|
+
this.selectedSavedAddress = null;
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
// Select default address if available and valid
|
|
467
|
+
const defaultAddress = this.savedAddresses.find((a) => a.is_default && a.is_in_coverage !== false);
|
|
468
|
+
if (defaultAddress) {
|
|
469
|
+
this.selectedSavedAddress = defaultAddress;
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
// Select first valid address
|
|
473
|
+
const validAddress = this.savedAddresses.find((a) => a.is_in_coverage !== false);
|
|
474
|
+
if (validAddress) {
|
|
475
|
+
this.selectedSavedAddress = validAddress;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
applyCountryChange(newCountry) {
|
|
481
|
+
this.selectedCountry = newCountry;
|
|
482
|
+
this.selectedRegion = null;
|
|
483
|
+
this.regions = [];
|
|
484
|
+
this.cities = [];
|
|
485
|
+
this.districts = [];
|
|
486
|
+
this.selectedCity = null;
|
|
487
|
+
this.selectedDistrict = null;
|
|
488
|
+
this.districtName = "";
|
|
489
|
+
this.allocationOutOfCoverageMessage = null;
|
|
490
|
+
if (this.selectedCountry) {
|
|
491
|
+
this.updateNewAddressForm({
|
|
492
|
+
country_id: Number(this.selectedCountry.id),
|
|
493
|
+
region_id: undefined,
|
|
494
|
+
city_id: undefined,
|
|
495
|
+
district_id: undefined,
|
|
496
|
+
city: undefined,
|
|
497
|
+
district: undefined,
|
|
498
|
+
});
|
|
499
|
+
if (this.activeTab === "branch") {
|
|
500
|
+
this.loadBranches();
|
|
501
|
+
}
|
|
502
|
+
else if (isSaudiArabia(this.selectedCountry.code)) {
|
|
503
|
+
this.loadRegions(this.selectedCountry.id);
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
this.loadCities(this.selectedCountry.id);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
async loadRegions(countryId) {
|
|
511
|
+
this.loadingRegions = true;
|
|
512
|
+
this.regions = [];
|
|
513
|
+
this.selectedRegion = null;
|
|
514
|
+
this.cities = [];
|
|
515
|
+
this.districts = [];
|
|
516
|
+
this.selectedCity = null;
|
|
517
|
+
this.selectedDistrict = null;
|
|
518
|
+
this.districtName = "";
|
|
519
|
+
try {
|
|
520
|
+
this.regions = await bulletDeliveryAPI.getRegions(countryId);
|
|
521
|
+
}
|
|
522
|
+
finally {
|
|
523
|
+
this.loadingRegions = false;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* AC7: Guest-to-Registered Sync
|
|
528
|
+
* Syncs guest session location to user profile on login
|
|
529
|
+
*/
|
|
530
|
+
async handleGuestToRegisteredSync() {
|
|
531
|
+
try {
|
|
532
|
+
// Check if user is now logged in
|
|
533
|
+
const userId = Salla.config.get("user.id");
|
|
534
|
+
if (!userId)
|
|
535
|
+
return;
|
|
536
|
+
// Get the guest session location from session storage
|
|
537
|
+
const guestIntent = this.getStoredIntent();
|
|
538
|
+
if (!guestIntent || guestIntent.type !== "address") {
|
|
539
|
+
// No guest address intent to sync, or it's a branch intent
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
// Get user's saved addresses
|
|
543
|
+
const userAddresses = await bulletDeliveryAPI.getSavedAddresses();
|
|
544
|
+
const matchingAddress = findMatchingAddress(guestIntent, userAddresses);
|
|
545
|
+
if (matchingAddress) {
|
|
546
|
+
await this.setAddressAsActive(matchingAddress.id);
|
|
547
|
+
const updatedIntent = {
|
|
548
|
+
...guestIntent,
|
|
549
|
+
address_id: matchingAddress.id,
|
|
550
|
+
address_details: this.buildIntentAddressFromSaved(matchingAddress),
|
|
551
|
+
};
|
|
552
|
+
this.setStoredIntent(updatedIntent);
|
|
553
|
+
}
|
|
554
|
+
else if (getIntentCityId(guestIntent)) {
|
|
555
|
+
// No match - create new address from guest session data
|
|
556
|
+
const newAddress = await this.createAddressFromGuestSession(guestIntent);
|
|
557
|
+
if (newAddress) {
|
|
558
|
+
const updatedIntent = {
|
|
559
|
+
...guestIntent,
|
|
560
|
+
address_id: newAddress.id,
|
|
561
|
+
address_details: this.buildIntentAddressFromSaved(newAddress),
|
|
562
|
+
};
|
|
563
|
+
this.setStoredIntent(updatedIntent);
|
|
564
|
+
this.addressCreated.emit({ address: newAddress });
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
// Emit event to notify that sync is complete
|
|
568
|
+
Salla.event.emit("bullet-delivery::guest-synced", {
|
|
569
|
+
guest_intent: guestIntent,
|
|
570
|
+
matched_address_id: matchingAddress?.id,
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
catch (error) {
|
|
574
|
+
console.error("SallaBulletDelivery: Error syncing guest session to user profile", error);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Set an address as active/last used
|
|
579
|
+
*/
|
|
580
|
+
async setAddressAsActive(addressId) {
|
|
581
|
+
try {
|
|
582
|
+
// Call API to mark address as default/active
|
|
583
|
+
await Salla.address?.api?.setDefault?.(addressId);
|
|
584
|
+
}
|
|
585
|
+
catch (error) {
|
|
586
|
+
// If setDefault API doesn't exist, just update local state
|
|
587
|
+
console.warn("SallaBulletDelivery: Could not set address as default", error);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Create a new address from guest session: only country, city and district IDs (no street, etc.).
|
|
592
|
+
* Uses address/location API; after fetch we return the newly created address from the list.
|
|
593
|
+
*/
|
|
594
|
+
async createAddressFromGuestSession(guestIntent) {
|
|
595
|
+
const countryId = getIntentCountryId(guestIntent);
|
|
596
|
+
const cityId = getIntentCityId(guestIntent);
|
|
597
|
+
if (!countryId || !cityId)
|
|
598
|
+
return null;
|
|
599
|
+
const isSA = isSaudiArabia(getIntentCountryCode(guestIntent));
|
|
600
|
+
const districtName = guestIntent.address_details?.district?.name ?? "";
|
|
601
|
+
const payload = {
|
|
602
|
+
country_id: countryId,
|
|
603
|
+
region_id: getIntentRegionId(guestIntent),
|
|
604
|
+
city_id: cityId,
|
|
605
|
+
district_id: getIntentDistrictId(guestIntent),
|
|
606
|
+
description: districtName,
|
|
607
|
+
};
|
|
608
|
+
if (isSA) {
|
|
609
|
+
payload.local = districtName;
|
|
610
|
+
}
|
|
611
|
+
try {
|
|
612
|
+
const { success, address } = await bulletDeliveryAPI.saveAddressLocation(payload);
|
|
613
|
+
if (!success)
|
|
614
|
+
return null;
|
|
615
|
+
if (address)
|
|
616
|
+
return address;
|
|
617
|
+
const addresses = await bulletDeliveryAPI.getSavedAddresses();
|
|
618
|
+
const districtId = getIntentDistrictId(guestIntent);
|
|
619
|
+
const newAddress = addresses.find((a) => (a.city_id ?? a.city?.id) === cityId &&
|
|
620
|
+
(a.district_id ?? a.district?.id) === districtId) ??
|
|
621
|
+
addresses[0] ??
|
|
622
|
+
null;
|
|
623
|
+
return newAddress;
|
|
624
|
+
}
|
|
625
|
+
catch (error) {
|
|
626
|
+
console.error("SallaBulletDelivery: Could not create address from guest session", error);
|
|
627
|
+
return null;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
emitHeaderContextUpdate(result, address, branch) {
|
|
631
|
+
let locationText = "";
|
|
632
|
+
if (result.type === "address") {
|
|
633
|
+
if (address) {
|
|
634
|
+
locationText =
|
|
635
|
+
address.district?.name && address.city?.name
|
|
636
|
+
? `${address.district.name}، ${address.city.name}`
|
|
637
|
+
: (address.city?.name ?? "");
|
|
638
|
+
}
|
|
639
|
+
else if (this.selectedCity) {
|
|
640
|
+
locationText = this.selectedDistrict
|
|
641
|
+
? `${this.selectedDistrict.name}، ${this.selectedCity.name}`
|
|
642
|
+
: this.selectedCity.name;
|
|
643
|
+
}
|
|
644
|
+
else if (result.address_details) {
|
|
645
|
+
const parts = [
|
|
646
|
+
result.address_details.district?.name,
|
|
647
|
+
result.address_details.city.name,
|
|
648
|
+
result.address_details.country.name,
|
|
649
|
+
].filter(Boolean);
|
|
650
|
+
locationText =
|
|
651
|
+
parts.join("، ") || result.address_details.short_address || "";
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
else if (branch) {
|
|
655
|
+
locationText = branch.name;
|
|
656
|
+
}
|
|
657
|
+
else if (result.branch_details) {
|
|
658
|
+
locationText = result.branch_details.city ?? result.branch_details.name;
|
|
659
|
+
}
|
|
660
|
+
// Build display text with prefix (e.g., "Delivering to: Riyadh" or "Pickup from: Branch Name")
|
|
661
|
+
const prefix = result.type === "address"
|
|
662
|
+
? Salla.lang.get("mobile_app.strings.delivery")
|
|
663
|
+
: Salla.lang.get("mobile_app.strings.pickup");
|
|
664
|
+
const displayText = locationText ? `${prefix}: ${locationText}` : "";
|
|
665
|
+
this.headerContextUpdate.emit({
|
|
666
|
+
type: result.type,
|
|
667
|
+
display_text: displayText,
|
|
668
|
+
country_code: result.country_code,
|
|
669
|
+
city: this.selectedCity?.name ?? result.address_details?.city?.name,
|
|
670
|
+
district: this.selectedDistrict?.name ?? result.address_details?.district?.name,
|
|
671
|
+
branch_name: branch?.name ?? result.branch_details?.name,
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
handleBranchSearch(event) {
|
|
675
|
+
const input = event.target;
|
|
676
|
+
const query = input.value;
|
|
677
|
+
this.branchSearchQuery = query;
|
|
678
|
+
if (this.branchSearchDebounceTimer)
|
|
679
|
+
clearTimeout(this.branchSearchDebounceTimer);
|
|
680
|
+
if (!query?.trim()) {
|
|
681
|
+
this.branchSearchQuery = "";
|
|
682
|
+
void this.loadBranches();
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
this.branchSearchDebounceTimer = setTimeout(async () => {
|
|
686
|
+
if (query.trim().length < 2)
|
|
687
|
+
return;
|
|
688
|
+
this.loadingBranches = true;
|
|
689
|
+
try {
|
|
690
|
+
this.branches = await bulletDeliveryAPI.getBranches({
|
|
691
|
+
country_id: this.selectedCountry?.id,
|
|
692
|
+
query,
|
|
693
|
+
});
|
|
694
|
+
this.filterBranches();
|
|
695
|
+
}
|
|
696
|
+
finally {
|
|
697
|
+
this.loadingBranches = false;
|
|
698
|
+
}
|
|
699
|
+
}, BRANCH_SEARCH_DEBOUNCE_MS);
|
|
700
|
+
}
|
|
701
|
+
async loadBranchesWithLocation(lat, lng) {
|
|
702
|
+
this.loadingBranches = true;
|
|
703
|
+
try {
|
|
704
|
+
this.branches = await bulletDeliveryAPI.getBranches({
|
|
705
|
+
country_id: this.selectedCountry?.id,
|
|
706
|
+
lat,
|
|
707
|
+
lng,
|
|
708
|
+
});
|
|
709
|
+
this.filterBranches();
|
|
710
|
+
// Auto-select country from first branch if no country is selected
|
|
711
|
+
if (!this.selectedCountry && this.branches.length > 0) {
|
|
712
|
+
const firstBranch = this.branches[0];
|
|
713
|
+
if (firstBranch.country) {
|
|
714
|
+
const matchingCountry = this.countries.find((c) => c.id === firstBranch.country.id);
|
|
715
|
+
if (matchingCountry) {
|
|
716
|
+
this.selectedCountry = matchingCountry;
|
|
717
|
+
this.updateNewAddressForm({
|
|
718
|
+
country_id: Number(matchingCountry.id),
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
finally {
|
|
725
|
+
this.loadingBranches = false;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
/** Locate nearest branch using device geolocation (branches tab only). */
|
|
729
|
+
async handleFindNearestBranch() {
|
|
730
|
+
if (!navigator.geolocation) {
|
|
731
|
+
this.locationError = Salla.lang.get("pages.checkout.current_location_not_supported");
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
this.loadingNearestBranch = true;
|
|
735
|
+
this.locationError = "";
|
|
736
|
+
try {
|
|
737
|
+
const position = await new Promise((resolve, reject) => {
|
|
738
|
+
navigator.geolocation.getCurrentPosition(resolve, reject, {
|
|
739
|
+
enableHighAccuracy: true,
|
|
740
|
+
timeout: GEOLOCATION_TIMEOUT,
|
|
741
|
+
maximumAge: 0,
|
|
742
|
+
});
|
|
743
|
+
});
|
|
744
|
+
const { latitude, longitude } = position.coords;
|
|
745
|
+
await this.loadBranchesWithLocation(latitude, longitude);
|
|
746
|
+
const nearestBranch = findNearestBranch(this.branches, latitude, longitude);
|
|
747
|
+
if (nearestBranch) {
|
|
748
|
+
this.selectedBranch = nearestBranch;
|
|
749
|
+
this.branchSearchQuery = "";
|
|
750
|
+
this.filterBranches();
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
catch (error) {
|
|
754
|
+
const geoError = error;
|
|
755
|
+
const code = typeof geoError?.code === "number" ? geoError.code : -1;
|
|
756
|
+
this.locationError = getGeolocationErrorMessage(code);
|
|
757
|
+
}
|
|
758
|
+
finally {
|
|
759
|
+
this.loadingNearestBranch = false;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
handleBranchSelect(branch) {
|
|
763
|
+
this.selectedBranch = branch;
|
|
764
|
+
}
|
|
765
|
+
handleSavedAddressSelect(address) {
|
|
766
|
+
if (address.is_in_coverage === false) {
|
|
767
|
+
// Show toast notification for out of coverage address
|
|
768
|
+
Salla.notify?.error(Salla.lang.get("pages.checkout.shipping_not_available"));
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
this.selectedSavedAddress = address;
|
|
772
|
+
this.selectedSessionAddress = false;
|
|
773
|
+
}
|
|
774
|
+
handleSessionAddressSelect() {
|
|
775
|
+
this.selectedSessionAddress = true;
|
|
776
|
+
this.selectedSavedAddress = null;
|
|
777
|
+
}
|
|
778
|
+
/** Show delete confirmation UI for this address (do not call API yet). */
|
|
779
|
+
/**
|
|
780
|
+
* Switch to add-address form (unified form). Preselects country from session when present.
|
|
781
|
+
*/
|
|
782
|
+
async handleAddNewAddress() {
|
|
783
|
+
this.viewMode = "add-address";
|
|
784
|
+
const intent = this.getStoredIntent();
|
|
785
|
+
const sessionCountryId = getIntentCountryId(intent);
|
|
786
|
+
if (sessionCountryId && this.countries.length > 0) {
|
|
787
|
+
const country = this.countries.find((c) => c.id === sessionCountryId);
|
|
788
|
+
if (country) {
|
|
789
|
+
this.selectedCountry = country;
|
|
790
|
+
this.updateNewAddressForm({ country_id: Number(country.id) });
|
|
791
|
+
if (isSaudiArabia(country.code)) {
|
|
792
|
+
await this.loadRegions(country.id);
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
await this.loadCities(country.id);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
handleBackToAddressList() {
|
|
801
|
+
this.viewMode = "main";
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* Build address/location payload from guest-form state (same fields as add-address).
|
|
805
|
+
*/
|
|
806
|
+
buildAddressLocationPayload() {
|
|
807
|
+
const districtName = this.selectedDistrict?.name ?? this.districtName?.trim() ?? "";
|
|
808
|
+
return buildAddressLocationPayloadFromSelection({
|
|
809
|
+
countryId: this.selectedCountry?.id ?? 0,
|
|
810
|
+
countryCode: this.selectedCountry?.code,
|
|
811
|
+
regionId: this.selectedRegion?.id,
|
|
812
|
+
cityId: this.selectedCity?.id,
|
|
813
|
+
districtId: this.selectedDistrict?.id,
|
|
814
|
+
description: districtName,
|
|
815
|
+
});
|
|
816
|
+
}
|
|
817
|
+
async handleTabChange(tab) {
|
|
818
|
+
if (this.tabChanging)
|
|
819
|
+
return;
|
|
820
|
+
this.tabChanging = true;
|
|
821
|
+
try {
|
|
822
|
+
this.activeTab = tab;
|
|
823
|
+
this.showCartWillBeClearedBanner = false;
|
|
824
|
+
this.allocationOutOfCoverageMessage = null;
|
|
825
|
+
// Reload countries with for_branch=1 for pickup tab, for_branch=0 for delivery tab
|
|
826
|
+
const forBranch = tab === "branch";
|
|
827
|
+
this.countries = await bulletDeliveryAPI.getCountries(forBranch);
|
|
828
|
+
const previousCountryId = this.selectedCountry?.id;
|
|
829
|
+
if (previousCountryId !== undefined && previousCountryId !== null) {
|
|
830
|
+
this.selectedCountry =
|
|
831
|
+
this.countries.find((c) => c.id === previousCountryId) || null;
|
|
832
|
+
}
|
|
833
|
+
// Load appropriate data when switching tabs if country is selected
|
|
834
|
+
if (this.selectedCountry) {
|
|
835
|
+
if (tab === "branch") {
|
|
836
|
+
// Load branches when switching to branch tab
|
|
837
|
+
// Check session storage for lat/lng to get nearby branches
|
|
838
|
+
const savedIntent = this.getStoredIntent();
|
|
839
|
+
const intentLat = getIntentLatitude(savedIntent);
|
|
840
|
+
const intentLng = getIntentLongitude(savedIntent);
|
|
841
|
+
if (intentLat != null && intentLng != null) {
|
|
842
|
+
await this.loadBranchesWithLocation(intentLat, intentLng);
|
|
843
|
+
}
|
|
844
|
+
else {
|
|
845
|
+
await this.loadBranches();
|
|
846
|
+
}
|
|
847
|
+
// Preselect branch from session storage if available
|
|
848
|
+
const branchId = getIntentBranchId(savedIntent);
|
|
849
|
+
if (branchId != null && this.branches.length > 0) {
|
|
850
|
+
const branch = this.branches.find((b) => b.id === branchId);
|
|
851
|
+
if (branch) {
|
|
852
|
+
this.selectedBranch = branch;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
else if (tab === "address") {
|
|
857
|
+
// Lazy-load saved addresses when switching to address tab (if not loaded yet).
|
|
858
|
+
if (this.isLoggedIn && !this.savedAddressesLoaded) {
|
|
859
|
+
this.loadingSavedAddresses = true;
|
|
860
|
+
try {
|
|
861
|
+
await this.loadSavedAddresses();
|
|
862
|
+
this.savedAddressesLoaded = true;
|
|
863
|
+
}
|
|
864
|
+
finally {
|
|
865
|
+
this.loadingSavedAddresses = false;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
if (!this.isLoggedIn) {
|
|
869
|
+
const savedIntent = this.getStoredIntent();
|
|
870
|
+
if (savedIntent && getIntentCityId(savedIntent)) {
|
|
871
|
+
await this.prefillAddressFromStoredIntent();
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
finally {
|
|
878
|
+
this.tabChanging = false;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
isConfirmDisabled() {
|
|
882
|
+
if (this.activeTab === "branch") {
|
|
883
|
+
return !this.selectedBranch;
|
|
884
|
+
}
|
|
885
|
+
if (this.activeTab === "address") {
|
|
886
|
+
if (this.isLoggedIn && this.selectedSessionAddress) {
|
|
887
|
+
return false; // Session address selected - confirm will save then allocate
|
|
888
|
+
}
|
|
889
|
+
if (this.isLoggedIn && this.selectedSavedAddress) {
|
|
890
|
+
return this.selectedSavedAddress.is_in_coverage === false;
|
|
891
|
+
}
|
|
892
|
+
// Guest: require country + city; for SA require region + district
|
|
893
|
+
if (!this.selectedCountry || !this.selectedCity)
|
|
894
|
+
return true;
|
|
895
|
+
return !requireRegionAndDistrictForSA(this.selectedCountry?.code, this.selectedRegion?.id, this.selectedDistrict?.id ?? (this.districtName?.trim() || null));
|
|
896
|
+
}
|
|
897
|
+
return false;
|
|
898
|
+
}
|
|
899
|
+
handleLogin() {
|
|
900
|
+
Salla.event.dispatch("bullet-delivery::close");
|
|
901
|
+
Salla.event.dispatch("login::open");
|
|
902
|
+
}
|
|
903
|
+
buildIntentAddress() {
|
|
904
|
+
if (this.activeTab !== "address" ||
|
|
905
|
+
!this.selectedCountry ||
|
|
906
|
+
!this.selectedCity) {
|
|
907
|
+
return undefined;
|
|
908
|
+
}
|
|
909
|
+
const country = {
|
|
910
|
+
id: this.selectedCountry.id,
|
|
911
|
+
name: this.selectedCountry.name,
|
|
912
|
+
code: this.selectedCountry.code,
|
|
913
|
+
};
|
|
914
|
+
const city = {
|
|
915
|
+
id: this.selectedCity.id,
|
|
916
|
+
name: this.selectedCity.name,
|
|
917
|
+
};
|
|
918
|
+
const region = this.selectedRegion
|
|
919
|
+
? {
|
|
920
|
+
id: this.selectedRegion.id,
|
|
921
|
+
name: this.selectedRegion.name,
|
|
922
|
+
code: this.selectedRegion.code,
|
|
923
|
+
}
|
|
924
|
+
: undefined;
|
|
925
|
+
const district = this.selectedDistrict
|
|
926
|
+
? { id: this.selectedDistrict.id, name: this.selectedDistrict.name }
|
|
927
|
+
: this.districtName
|
|
928
|
+
? { id: 0, name: this.districtName }
|
|
929
|
+
: undefined;
|
|
930
|
+
const short_address = this.selectedSavedAddress?.short_address;
|
|
931
|
+
return {
|
|
932
|
+
country,
|
|
933
|
+
region,
|
|
934
|
+
city,
|
|
935
|
+
district,
|
|
936
|
+
short_address,
|
|
937
|
+
};
|
|
938
|
+
}
|
|
939
|
+
buildIntentAddressFromSaved(addr) {
|
|
940
|
+
return {
|
|
941
|
+
country: {
|
|
942
|
+
id: addr.country?.id ?? addr.country_id ?? 0,
|
|
943
|
+
name: addr.country?.name ?? "",
|
|
944
|
+
code: addr.country?.code,
|
|
945
|
+
},
|
|
946
|
+
region: addr.region
|
|
947
|
+
? { id: addr.region.id, name: addr.region.name, code: addr.region.code }
|
|
948
|
+
: undefined,
|
|
949
|
+
city: {
|
|
950
|
+
id: addr.city?.id ?? addr.city_id ?? 0,
|
|
951
|
+
name: addr.city?.name ?? "",
|
|
952
|
+
},
|
|
953
|
+
district: addr.district
|
|
954
|
+
? { id: addr.district.id, name: addr.district.name }
|
|
955
|
+
: undefined,
|
|
956
|
+
short_address: addr.short_address,
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
buildIntentBranch() {
|
|
960
|
+
if (this.activeTab !== "branch" || !this.selectedBranch)
|
|
961
|
+
return undefined;
|
|
962
|
+
const b = this.selectedBranch;
|
|
963
|
+
const lat = b.location?.lat != null ? Number(b.location.lat) : undefined;
|
|
964
|
+
const lng = b.location?.lng != null ? Number(b.location.lng) : undefined;
|
|
965
|
+
return {
|
|
966
|
+
id: b.id,
|
|
967
|
+
name: b.name,
|
|
968
|
+
city: b.city?.name,
|
|
969
|
+
latitude: lat,
|
|
970
|
+
longitude: lng,
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
async handleConfirm() {
|
|
974
|
+
if (this.isConfirmDisabled() || this.confirming)
|
|
975
|
+
return;
|
|
976
|
+
this.confirming = true;
|
|
977
|
+
this.confirmBtn?.load();
|
|
978
|
+
let scheduledRedirect = false;
|
|
979
|
+
try {
|
|
980
|
+
const result = {
|
|
981
|
+
type: this.activeTab,
|
|
982
|
+
country_id: Number(this.selectedCountry?.id) || 0,
|
|
983
|
+
country_code: this.selectedCountry?.code || "",
|
|
984
|
+
};
|
|
985
|
+
let selectedAddress;
|
|
986
|
+
let selectedBranchData;
|
|
987
|
+
let usedSessionAddress = false;
|
|
988
|
+
if (this.activeTab === "address") {
|
|
989
|
+
if (this.isLoggedIn && this.selectedSessionAddress) {
|
|
990
|
+
usedSessionAddress = true;
|
|
991
|
+
const savedAddress = await this.saveSessionAddressToProfile();
|
|
992
|
+
if (!savedAddress) {
|
|
993
|
+
Salla.notify?.error(Salla.lang.get("common.errors.error_occurred"));
|
|
994
|
+
this.confirmBtn?.stop();
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
997
|
+
result.address_id = savedAddress.id;
|
|
998
|
+
selectedAddress = savedAddress;
|
|
999
|
+
this.selectedSessionAddress = false;
|
|
1000
|
+
this.selectedSavedAddress = savedAddress;
|
|
1001
|
+
result.address_details = this.buildIntentAddressFromSaved(savedAddress);
|
|
1002
|
+
}
|
|
1003
|
+
else if (this.isLoggedIn && this.selectedSavedAddress) {
|
|
1004
|
+
result.address_id = this.selectedSavedAddress.id;
|
|
1005
|
+
selectedAddress = this.selectedSavedAddress;
|
|
1006
|
+
result.address_details = this.buildIntentAddressFromSaved(this.selectedSavedAddress);
|
|
1007
|
+
}
|
|
1008
|
+
else {
|
|
1009
|
+
result.address_details = this.buildIntentAddress();
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
else {
|
|
1013
|
+
result.branch_details = this.buildIntentBranch();
|
|
1014
|
+
result.branch_id = this.selectedBranch?.id;
|
|
1015
|
+
selectedBranchData = this.selectedBranch || undefined;
|
|
1016
|
+
}
|
|
1017
|
+
// Build scope allocation payload based on scenario
|
|
1018
|
+
let allocationPayload;
|
|
1019
|
+
if (this.activeTab === "address") {
|
|
1020
|
+
if (this.isLoggedIn && this.selectedSavedAddress) {
|
|
1021
|
+
// Case 2: Logged-in user with saved address
|
|
1022
|
+
allocationPayload = {
|
|
1023
|
+
type: "address",
|
|
1024
|
+
address_id: String(this.selectedSavedAddress.id),
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
else {
|
|
1028
|
+
// Case 1: Guest user or logged-in user without saved address
|
|
1029
|
+
allocationPayload = {
|
|
1030
|
+
type: "address",
|
|
1031
|
+
country_id: String(this.selectedCountry?.id || 0),
|
|
1032
|
+
city_id: String(this.selectedCity?.id || ""),
|
|
1033
|
+
};
|
|
1034
|
+
if (isSaudiArabia(this.selectedCountry?.code ?? '')) {
|
|
1035
|
+
if (this.selectedRegion?.id) {
|
|
1036
|
+
allocationPayload.region_id = String(this.selectedRegion.id);
|
|
1037
|
+
}
|
|
1038
|
+
allocationPayload.district_id = String(this.selectedDistrict?.id || "");
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
else {
|
|
1043
|
+
// Case 3: Pickup
|
|
1044
|
+
allocationPayload = {
|
|
1045
|
+
type: "branch",
|
|
1046
|
+
branch_id: String(this.selectedBranch?.id || ""),
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
// Make API call to allocate scope
|
|
1050
|
+
const allocationResult = await bulletDeliveryAPI.allocateScope(allocationPayload);
|
|
1051
|
+
if (!allocationResult.success) {
|
|
1052
|
+
console.error("BulletDelivery: Scope allocation failed", allocationResult.error);
|
|
1053
|
+
const errorMessage = allocationResult.error ||
|
|
1054
|
+
(this.activeTab === "address"
|
|
1055
|
+
? Salla.lang.get("pages.checkout.address_out_of_coverage")
|
|
1056
|
+
: Salla.lang.get("pages.checkout.failed_to_set_pickup"));
|
|
1057
|
+
Salla.notify?.error(errorMessage);
|
|
1058
|
+
this.allocationOutOfCoverageMessage = errorMessage;
|
|
1059
|
+
this.confirmBtn?.stop();
|
|
1060
|
+
this.confirming = false;
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
// Process successful allocation response
|
|
1064
|
+
let allocatedScopeId;
|
|
1065
|
+
if (allocationResult.data) {
|
|
1066
|
+
const allocationData = allocationResult.data;
|
|
1067
|
+
allocatedScopeId = allocationData.id;
|
|
1068
|
+
const allocationType = allocationData?.allocation?.type;
|
|
1069
|
+
const allocationBranchId = allocationData?.allocation?.branch_id;
|
|
1070
|
+
// Set headers via Salla.api.setHeader
|
|
1071
|
+
if (allocationType) {
|
|
1072
|
+
Salla.api.setHeader("s-scope-allocation-type", allocationType);
|
|
1073
|
+
}
|
|
1074
|
+
if (allocationBranchId) {
|
|
1075
|
+
Salla.api.setHeader("s-scope-allocation-id", String(allocationBranchId));
|
|
1076
|
+
}
|
|
1077
|
+
// Persist allocation data in scope storage (single source of truth for all components)
|
|
1078
|
+
const existingScope = Salla.config.get("store.scope", Salla.storage.get("scope")) || {};
|
|
1079
|
+
Salla.storage.set("scope", {
|
|
1080
|
+
...existingScope,
|
|
1081
|
+
id: allocatedScopeId,
|
|
1082
|
+
allocation_type: allocationType,
|
|
1083
|
+
allocation_id: allocationBranchId
|
|
1084
|
+
? String(allocationBranchId)
|
|
1085
|
+
: undefined,
|
|
1086
|
+
});
|
|
1087
|
+
// Store headers in result object for persistence after page reload
|
|
1088
|
+
result.allocation_headers = {
|
|
1089
|
+
"s-scope-allocation-type": allocationType,
|
|
1090
|
+
"s-scope-allocation-id": allocationBranchId
|
|
1091
|
+
? String(allocationBranchId)
|
|
1092
|
+
: undefined,
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
// After allocation success: mark session so we don't show modal again this session
|
|
1096
|
+
this.markShownThisSession();
|
|
1097
|
+
// After allocation success: update session storage for guest prefill on next visit
|
|
1098
|
+
// When session address was confirmed, remove intent so logout shows a reset form
|
|
1099
|
+
if (usedSessionAddress) {
|
|
1100
|
+
this.removeStoredIntent();
|
|
1101
|
+
}
|
|
1102
|
+
else {
|
|
1103
|
+
this.setStoredIntent(result);
|
|
1104
|
+
}
|
|
1105
|
+
if (allocatedScopeId) {
|
|
1106
|
+
await bulletDeliveryAPI.setDeliveryScope(allocatedScopeId);
|
|
1107
|
+
}
|
|
1108
|
+
this.bulletDeliveryConfirmed.emit({
|
|
1109
|
+
...result,
|
|
1110
|
+
address: selectedAddress,
|
|
1111
|
+
branch: selectedBranchData,
|
|
1112
|
+
});
|
|
1113
|
+
// Emit header context update for global header sync
|
|
1114
|
+
this.emitHeaderContextUpdate(result, selectedAddress, selectedBranchData);
|
|
1115
|
+
scheduledRedirect = true;
|
|
1116
|
+
setTimeout(() => {
|
|
1117
|
+
this.confirmBtn?.stop();
|
|
1118
|
+
this.close();
|
|
1119
|
+
this.confirming = false;
|
|
1120
|
+
if (allocatedScopeId) {
|
|
1121
|
+
const scope = Salla.storage.get("scope") || {};
|
|
1122
|
+
let url = Salla.helpers.addParamToUrl("scope", allocatedScopeId);
|
|
1123
|
+
if (scope.allocation_id) {
|
|
1124
|
+
url = Salla.helpers.addParamToUrl("allocation_id", scope.allocation_id, url);
|
|
1125
|
+
}
|
|
1126
|
+
if (scope.allocation_type) {
|
|
1127
|
+
url = Salla.helpers.addParamToUrl("allocation_type", scope.allocation_type, url);
|
|
1128
|
+
}
|
|
1129
|
+
window.location.replace(url);
|
|
1130
|
+
}
|
|
1131
|
+
else {
|
|
1132
|
+
window.location.reload();
|
|
1133
|
+
}
|
|
1134
|
+
}, 500);
|
|
1135
|
+
}
|
|
1136
|
+
finally {
|
|
1137
|
+
if (!scheduledRedirect) {
|
|
1138
|
+
this.confirming = false;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
getCartViewConfig(intent) {
|
|
1143
|
+
if (!intent || !Salla.url.is_page("cart"))
|
|
1144
|
+
return null;
|
|
1145
|
+
const isBranch = intent.type === "branch";
|
|
1146
|
+
const isAddress = intent.type === "address";
|
|
1147
|
+
if ((isBranch && !this.supportsPickup) || (!isBranch && !isAddress))
|
|
1148
|
+
return null;
|
|
1149
|
+
return {
|
|
1150
|
+
title: isBranch
|
|
1151
|
+
? Salla.lang.get("pages.checkout.pickup_option")
|
|
1152
|
+
: Salla.lang.get("pages.checkout.delivery_option"),
|
|
1153
|
+
subtitle: getIntentSubtitle(intent, Salla.lang.get("common.elements.to"), ""),
|
|
1154
|
+
buttonText: Salla.lang.get("common.elements.edit"),
|
|
1155
|
+
isAddress,
|
|
1156
|
+
intent,
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
/** Creates the cart view DOM for mounting into cart.items.start hook */
|
|
1160
|
+
createCartViewElement() {
|
|
1161
|
+
const intent = this.getStoredIntent();
|
|
1162
|
+
const config = this.getCartViewConfig(intent);
|
|
1163
|
+
if (!config)
|
|
1164
|
+
return null;
|
|
1165
|
+
const { title, subtitle, buttonText, intent: configIntent } = config;
|
|
1166
|
+
const openPayload = configIntent.type === "branch"
|
|
1167
|
+
? { preselected_branch_id: getIntentBranchId(configIntent) }
|
|
1168
|
+
: { preselected_address_id: configIntent.address_id };
|
|
1169
|
+
const icon = document.createElement("span");
|
|
1170
|
+
icon.className =
|
|
1171
|
+
"s-bullet-delivery-cart-view-icon s-bullet-delivery-tab-icon";
|
|
1172
|
+
icon.setAttribute("aria-hidden", "true");
|
|
1173
|
+
icon.innerHTML = Location;
|
|
1174
|
+
const titleEl = document.createElement("span");
|
|
1175
|
+
titleEl.className = "s-bullet-delivery-cart-view-title";
|
|
1176
|
+
titleEl.textContent = title;
|
|
1177
|
+
const subtitleEl = document.createElement("span");
|
|
1178
|
+
subtitleEl.className = "s-bullet-delivery-cart-view-subtitle";
|
|
1179
|
+
subtitleEl.textContent = subtitle;
|
|
1180
|
+
const text = document.createElement("div");
|
|
1181
|
+
text.className = "s-bullet-delivery-cart-view-text";
|
|
1182
|
+
text.append(titleEl, subtitleEl);
|
|
1183
|
+
const info = document.createElement("div");
|
|
1184
|
+
info.className = "s-bullet-delivery-cart-view-info";
|
|
1185
|
+
info.append(icon, text);
|
|
1186
|
+
const btn = document.createElement("salla-button");
|
|
1187
|
+
btn.className = "s-bullet-delivery-cart-view-button";
|
|
1188
|
+
btn.setAttribute("fill", "outline");
|
|
1189
|
+
btn.setAttribute("color", "primary");
|
|
1190
|
+
btn.textContent = buttonText;
|
|
1191
|
+
btn.addEventListener("click", () => Salla.event.emit("bullet-delivery::open", openPayload));
|
|
1192
|
+
const wrapper = document.createElement("div");
|
|
1193
|
+
wrapper.className = "s-bullet-delivery-cart-view";
|
|
1194
|
+
wrapper.append(info, btn);
|
|
1195
|
+
return wrapper;
|
|
1196
|
+
}
|
|
1197
|
+
renderSkeleton() {
|
|
1198
|
+
return (h("div", { slot: "loading", class: "s-bullet-delivery-skeleton" }, h("div", { class: "s-bullet-delivery-skeleton-header" }, h("salla-skeleton", { class: "s-bullet-delivery-skeleton-title", height: "28px", width: "68%" }), h("salla-skeleton", { class: "s-bullet-delivery-skeleton-subtitle", height: "18px", width: "84%" })), h("div", { class: {
|
|
1199
|
+
"s-bullet-delivery-skeleton-tabs": true,
|
|
1200
|
+
"s-bullet-delivery-skeleton-tabs--single": !this.supportsPickup,
|
|
1201
|
+
} }, h("div", { class: "s-bullet-delivery-skeleton-tab" }, h("salla-skeleton", { class: "s-bullet-delivery-skeleton-tab-icon", height: "32px", width: "32px" }), h("salla-skeleton", { class: "s-bullet-delivery-skeleton-tab-label", height: "18px", width: "92px" })), this.supportsPickup && (h("div", { class: "s-bullet-delivery-skeleton-tab" }, h("salla-skeleton", { class: "s-bullet-delivery-skeleton-tab-icon", height: "32px", width: "32px" }), h("salla-skeleton", { class: "s-bullet-delivery-skeleton-tab-label", height: "18px", width: "84px" })))), h("div", { class: "s-bullet-delivery-skeleton-content" }, h("div", { class: "s-bullet-delivery-skeleton-field" }, h("salla-skeleton", { class: "s-bullet-delivery-skeleton-field-label", height: "16px", width: "96px" }), h("salla-skeleton", { class: "s-bullet-delivery-skeleton-field-control", height: "56px", width: "100%" })), h("div", { class: "s-bullet-delivery-skeleton-field" }, h("salla-skeleton", { class: "s-bullet-delivery-skeleton-field-label", height: "16px", width: "104px" }), h("salla-skeleton", { class: "s-bullet-delivery-skeleton-field-control", height: "56px", width: "100%" })), h("div", { class: "s-bullet-delivery-skeleton-field" }, h("salla-skeleton", { class: "s-bullet-delivery-skeleton-field-label", height: "16px", width: "88px" }), h("salla-skeleton", { class: "s-bullet-delivery-skeleton-field-control", height: "56px", width: "100%" }))), h("div", { class: "s-bullet-delivery-skeleton-footer" }, h("salla-skeleton", { height: "52px", width: "100%" }))));
|
|
1202
|
+
}
|
|
1203
|
+
renderTabs() {
|
|
1204
|
+
// Show tabs only when pickup is supported; otherwise delivery-only view with no tabs
|
|
1205
|
+
if (!this.supportsPickup)
|
|
1206
|
+
return null;
|
|
1207
|
+
return (h("div", { class: "s-bullet-delivery-tabs" }, h("button", { type: "button", class: {
|
|
1208
|
+
"s-bullet-delivery-tab": true,
|
|
1209
|
+
"s-bullet-delivery-tab--active": this.activeTab === "address",
|
|
1210
|
+
}, onClick: () => this.handleTabChange("address") }, h("span", { class: "s-bullet-delivery-tab-icon", innerHTML: Location, "aria-hidden": "true" }), h("span", null, Salla.lang.get("mobile_app.strings.delivery"))), h("button", { type: "button", class: {
|
|
1211
|
+
"s-bullet-delivery-tab": true,
|
|
1212
|
+
"s-bullet-delivery-tab--active": this.activeTab === "branch",
|
|
1213
|
+
}, onClick: () => this.handleTabChange("branch") }, h("span", { class: "s-bullet-delivery-tab-icon", innerHTML: Store, "aria-hidden": "true" }), h("span", null, Salla.lang.get("mobile_app.strings.pickup")))));
|
|
1214
|
+
}
|
|
1215
|
+
renderAlert(message) {
|
|
1216
|
+
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" }, message)));
|
|
1217
|
+
}
|
|
1218
|
+
renderAllocationOutOfCoverageAlert() {
|
|
1219
|
+
const message = this.allocationOutOfCoverageMessage ||
|
|
1220
|
+
Salla.lang.get("pages.checkout.shipping_not_available");
|
|
1221
|
+
return this.renderAlert(message);
|
|
1222
|
+
}
|
|
1223
|
+
renderCountrySelect() {
|
|
1224
|
+
return (h("div", { class: "s-bullet-delivery-field" }, h("label", { class: "s-bullet-delivery-label", htmlFor: "bullet-delivery-country" }, Salla.lang.get("blocks.buy_as_gift.receiver_country"), h("span", { class: "text-red-500" }, " *")), h("select", { id: "bullet-delivery-country", class: "form-input", onChange: (e) => {
|
|
1225
|
+
const select = e.target;
|
|
1226
|
+
const countryId = Number.parseInt(select.value);
|
|
1227
|
+
const country = this.countries.find((c) => c.id === countryId);
|
|
1228
|
+
// A "switch" means the user already had a country and picked a different one
|
|
1229
|
+
const isCountrySwitch = this.selectedCountry &&
|
|
1230
|
+
country &&
|
|
1231
|
+
this.selectedCountry.code !== country.code;
|
|
1232
|
+
// Show the info banner whenever a country is changed to a different one
|
|
1233
|
+
this.showCartWillBeClearedBanner = !!isCountrySwitch;
|
|
1234
|
+
this.applyCountryChange(country || null);
|
|
1235
|
+
} }, h("option", { value: "", disabled: true, selected: !this.selectedCountry }, Salla.lang.get("pages.checkout.select_country")), this.countries.map((country) => (h("option", { key: country.id, value: country.id, selected: this.selectedCountry?.id === country.id }, country.name))))));
|
|
1236
|
+
}
|
|
1237
|
+
renderSelectLoader() {
|
|
1238
|
+
return (h("span", { class: "s-bullet-delivery-select-loader", "aria-hidden": "true" }, h("salla-loading", { size: "16", width: "3" })));
|
|
1239
|
+
}
|
|
1240
|
+
renderLoadingLabel(label, htmlFor, isLoading = false, isRequired = true) {
|
|
1241
|
+
return (h("label", { class: "s-bullet-delivery-label", htmlFor: htmlFor }, h("span", { class: "s-bullet-delivery-label-content" }, h("span", null, label, isRequired && h("span", { class: "text-red-500" }, " *")), isLoading && this.renderSelectLoader())));
|
|
1242
|
+
}
|
|
1243
|
+
/** Region select (SA only): shown when SA is selected; city and district disabled until region selected. */
|
|
1244
|
+
renderRegionSelect() {
|
|
1245
|
+
const isSA = isSaudiArabia(this.selectedCountry?.code ?? '');
|
|
1246
|
+
if (!isSA || !this.selectedCountry)
|
|
1247
|
+
return null;
|
|
1248
|
+
return (h("div", { class: "s-bullet-delivery-field" }, this.renderLoadingLabel(Salla.lang.get("pages.checkout.region_field"), "bullet-delivery-region", this.loadingRegions), h("select", { id: "bullet-delivery-region", class: "form-input", disabled: this.loadingRegions || this.regions.length === 0, onChange: (e) => {
|
|
1249
|
+
const select = e.target;
|
|
1250
|
+
const regionId = Number.parseInt(select.value);
|
|
1251
|
+
const region = this.regions.find((r) => r.id === regionId);
|
|
1252
|
+
this.selectedRegion = region || null;
|
|
1253
|
+
this.updateNewAddressForm({
|
|
1254
|
+
region_id: region?.id,
|
|
1255
|
+
city_id: undefined,
|
|
1256
|
+
district_id: undefined,
|
|
1257
|
+
city: undefined,
|
|
1258
|
+
district: undefined,
|
|
1259
|
+
});
|
|
1260
|
+
if (region && this.selectedCountry) {
|
|
1261
|
+
this.loadCities(this.selectedCountry.id, region.id);
|
|
1262
|
+
}
|
|
1263
|
+
} }, h("option", { value: "", disabled: true, selected: !this.selectedRegion }, Salla.lang.get("pages.checkout.select_region")), this.regions.map((region) => (h("option", { key: region.id, value: region.id, selected: this.selectedRegion?.id === region.id }, region.name))))));
|
|
1264
|
+
}
|
|
1265
|
+
renderCityDistrictSelects() {
|
|
1266
|
+
// Guest form: region + district only for SA; other countries get country + city only
|
|
1267
|
+
const isSA = isSaudiArabia(this.selectedCountry?.code ?? '');
|
|
1268
|
+
const showDistrict = isSA;
|
|
1269
|
+
const showDistrictInput = showDistrict &&
|
|
1270
|
+
this.selectedCity &&
|
|
1271
|
+
!this.loadingDistricts &&
|
|
1272
|
+
this.districts.length === 0;
|
|
1273
|
+
// For SA: city disabled until region selected; for non-SA: city disabled until country selected
|
|
1274
|
+
const cityDisabled = !this.selectedCountry ||
|
|
1275
|
+
(isSA && !this.selectedRegion) ||
|
|
1276
|
+
this.loadingCities ||
|
|
1277
|
+
this.cities.length === 0;
|
|
1278
|
+
const districtDisabled = !this.selectedCountry ||
|
|
1279
|
+
(isSA && !this.selectedRegion) ||
|
|
1280
|
+
!this.selectedCity ||
|
|
1281
|
+
this.loadingDistricts;
|
|
1282
|
+
return (h("div", { class: "s-bullet-delivery-field-row" }, h("div", { class: "s-bullet-delivery-field" }, this.renderLoadingLabel(Salla.lang.get("blocks.buy_as_gift.receiver_city"), "bullet-delivery-city", this.loadingCities), h("select", { id: "bullet-delivery-city", class: "form-input", disabled: cityDisabled, onChange: (e) => {
|
|
1283
|
+
const select = e.target;
|
|
1284
|
+
const cityId = Number.parseInt(select.value);
|
|
1285
|
+
const city = this.cities.find((c) => c.id === cityId);
|
|
1286
|
+
this.selectedCity = city || null;
|
|
1287
|
+
this.selectedDistrict = null;
|
|
1288
|
+
this.districtName = "";
|
|
1289
|
+
if (city) {
|
|
1290
|
+
this.updateNewAddressForm({ city: city, district: undefined });
|
|
1291
|
+
if (showDistrict) {
|
|
1292
|
+
this.loadDistricts(city.id);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
} }, h("option", { value: "", disabled: true, selected: !this.selectedCity }, Salla.lang.get("pages.checkout.select_city")), this.cities.map((city) => (h("option", { key: city.id, value: city.id, selected: this.selectedCity?.id === city.id }, city.name))))), showDistrict && (h("div", { class: "s-bullet-delivery-field" }, this.renderLoadingLabel(Salla.lang.get("pages.checkout.district_field"), "bullet-delivery-district", this.loadingDistricts && !showDistrictInput), showDistrictInput ? (h("input", { id: "bullet-delivery-district", type: "text", class: "form-input", placeholder: Salla.lang.get("pages.checkout.select_district"), value: this.districtName, disabled: districtDisabled, onInput: (e) => {
|
|
1296
|
+
const input = e.target;
|
|
1297
|
+
this.districtName = input.value;
|
|
1298
|
+
this.updateNewAddressForm({ district: undefined });
|
|
1299
|
+
} })) : (h("select", { id: "bullet-delivery-district", class: "form-input", disabled: districtDisabled || this.districts.length === 0, onChange: (e) => {
|
|
1300
|
+
const select = e.target;
|
|
1301
|
+
const districtId = Number.parseInt(select.value);
|
|
1302
|
+
const district = this.districts.find((d) => d.id === districtId);
|
|
1303
|
+
this.selectedDistrict = district || null;
|
|
1304
|
+
this.districtName = "";
|
|
1305
|
+
if (district) {
|
|
1306
|
+
this.updateNewAddressForm({ district });
|
|
1307
|
+
}
|
|
1308
|
+
} }, h("option", { value: "", disabled: true, selected: !this.selectedDistrict }, Salla.lang.get("pages.checkout.select_district")), this.districts.map((district) => {
|
|
1309
|
+
const langCode = Salla.config.get("user.language_code");
|
|
1310
|
+
const label = langCode === "ar"
|
|
1311
|
+
? district.name
|
|
1312
|
+
: (district.name_en ?? district.name);
|
|
1313
|
+
return (h("option", { key: district.id, value: district.id, selected: this.selectedDistrict?.id === district.id }, label));
|
|
1314
|
+
})))))));
|
|
1315
|
+
}
|
|
1316
|
+
renderSavedAddressesEmptyState() {
|
|
1317
|
+
return (h("div", { class: "s-bullet-delivery-saved-addresses-empty" }, h("div", { class: "s-bullet-delivery-saved-addresses-empty-icon", "aria-hidden": "true" }, h("svg", { width: "28", height: "28", viewBox: "0 0 28 29", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("title", null, "No Saved Adresses"), h("path", { d: "M20.16 0C21.4613 0 22.6773 0.341333 23.808 1.024C24.9387 1.70667 25.8347 2.61333 26.496 3.744C27.1787 4.91733 27.52 6.18667 27.52 7.552C27.52 9.45067 26.8267 11.232 25.44 12.896C24.4587 14.0907 23.0827 15.2427 21.312 16.352H21.28C20.9387 16.5653 20.5653 16.672 20.16 16.672C19.7547 16.672 19.3813 16.5653 19.04 16.352H19.008C17.2373 15.2213 15.8613 14.0693 14.88 12.896C13.4933 11.232 12.8 9.45067 12.8 7.552C12.8 6.18667 13.1413 4.91733 13.824 3.744C14.4853 2.61333 15.3813 1.70667 16.512 1.024C17.6427 0.341333 18.8587 0 20.16 0ZM11.488 1.984C9.67467 2.368 8.04267 3.14667 6.592 4.32C5.14133 5.49333 4.01067 6.92267 3.2 8.608C2.34667 10.3573 1.92 12.224 1.92 14.208C1.92 14.72 1.952 15.2427 2.016 15.776L2.08 15.744C2.57067 15.488 2.94933 15.3067 3.216 15.2C3.48267 15.0933 3.73867 15.0933 3.984 15.2C4.22933 15.3067 4.4 15.488 4.496 15.744C4.592 16 4.58667 16.256 4.48 16.512C4.37333 16.768 4.19733 16.9493 3.952 17.056C3.70667 17.1627 3.36 17.3227 2.912 17.536L2.656 17.664C2.57067 17.7067 2.48533 17.7387 2.4 17.76C2.89067 19.4667 3.70133 20.9973 4.832 22.352C5.96267 23.7067 7.296 24.7573 8.832 25.504C10.432 26.272 12.1173 26.656 13.888 26.656C15.4667 26.656 16.9813 26.3467 18.432 25.728C19.8187 25.1307 21.0667 24.288 22.176 23.2C21.92 23.0507 21.7653 22.8373 21.712 22.56C21.6587 22.2827 21.7013 22.0267 21.84 21.792C21.9787 21.5573 22.176 21.408 22.432 21.344C22.8373 21.2587 23.2 21.12 23.52 20.928C23.6907 20.8427 23.8613 20.8 24.032 20.8C24.8 19.5413 25.3333 18.176 25.632 16.704C25.6747 16.4267 25.808 16.2133 26.032 16.064C26.256 15.9147 26.496 15.8667 26.752 15.92C27.008 15.9733 27.2107 16.1173 27.36 16.352C27.5093 16.5867 27.552 16.832 27.488 17.088C27.0613 19.2853 26.1973 21.264 24.896 23.024C23.5947 24.784 22.0053 26.1547 20.128 27.136C18.1653 28.16 16.0853 28.672 13.888 28.672C11.3707 28.672 9.03467 28.0107 6.88 26.688C4.78933 25.408 3.12533 23.68 1.888 21.504C0.629333 19.264 0 16.832 0 14.208C0 11.904 0.490667 9.73867 1.472 7.712C2.41067 5.74933 3.728 4.09067 5.424 2.736C7.12 1.38133 9.01333 0.48 11.104 0.032C11.36 -0.032 11.6 0.0106667 11.824 0.16C12.048 0.309333 12.1867 0.522667 12.24 0.8C12.2933 1.07733 12.2453 1.328 12.096 1.552C11.9467 1.776 11.744 1.92 11.488 1.984ZM14.72 7.552C14.72 8.96 15.2533 10.304 16.32 11.584C17.1733 12.5867 18.3893 13.6 19.968 14.624C20.032 14.6453 20.096 14.656 20.16 14.656C20.224 14.656 20.288 14.6453 20.352 14.624C21.9307 13.6213 23.1467 12.608 24 11.584C25.0667 10.304 25.6 8.96 25.6 7.552C25.6 6.57067 25.3547 5.65333 24.864 4.8C24.3733 3.94667 23.7067 3.26933 22.864 2.768C22.0213 2.26667 21.12 2.016 20.16 2.016C19.2 2.016 18.2987 2.26667 17.456 2.768C16.6133 3.26933 15.9467 3.94667 15.456 4.8C14.9653 5.65333 14.72 6.57067 14.72 7.552ZM17.28 7.68C17.28 6.848 17.5627 6.13867 18.128 5.552C18.6933 4.96533 19.3707 4.672 20.16 4.672C20.9493 4.672 21.6267 4.96533 22.192 5.552C22.7573 6.13867 23.04 6.848 23.04 7.68C23.04 8.512 22.7573 9.216 22.192 9.792C21.6267 10.368 20.9493 10.656 20.16 10.656C19.3707 10.656 18.6933 10.368 18.128 9.792C17.5627 9.216 17.28 8.512 17.28 7.68ZM6.752 14.688C7.62667 14.7733 8.53333 15.0293 9.472 15.456C9.70667 15.5627 9.87733 15.744 9.984 16C10.0907 16.256 10.0907 16.512 9.984 16.768C9.87733 17.024 9.70133 17.2 9.456 17.296C9.21067 17.392 8.97067 17.3867 8.736 17.28C7.94667 16.9387 7.22133 16.736 6.56 16.672C6.28267 16.6293 6.064 16.5013 5.904 16.288C5.744 16.0747 5.68 15.8293 5.712 15.552C5.744 15.2747 5.86133 15.0507 6.064 14.88C6.26667 14.7093 6.496 14.6453 6.752 14.688ZM17.6 20.544C18.304 20.864 18.976 21.0987 19.616 21.248C19.872 21.312 20.0693 21.4613 20.208 21.696C20.3467 21.9307 20.3893 22.1813 20.336 22.448C20.2827 22.7147 20.144 22.9227 19.92 23.072C19.696 23.2213 19.4453 23.264 19.168 23.2C18.4213 23.0293 17.632 22.752 16.8 22.368C16.5653 22.2613 16.4 22.08 16.304 21.824C16.208 21.568 16.2133 21.312 16.32 21.056C16.4267 20.8 16.6027 20.624 16.848 20.528C17.0933 20.432 17.344 20.4373 17.6 20.544ZM12.832 17.44C13.0027 17.568 13.248 17.7493 13.568 17.984L14.496 18.688C14.7093 18.8587 14.8373 19.0773 14.88 19.344C14.9227 19.6107 14.8693 19.856 14.72 20.08C14.5707 20.304 14.368 20.4427 14.112 20.496C13.856 20.5493 13.6107 20.5013 13.376 20.352L11.744 19.072C11.5307 18.9227 11.4027 18.7093 11.36 18.432C11.3173 18.1547 11.3707 17.904 11.52 17.68C11.6693 17.456 11.872 17.3227 12.128 17.28C12.384 17.2373 12.6187 17.2907 12.832 17.44ZM20.16 8.672C20.416 8.672 20.64 8.576 20.832 8.384C21.024 8.192 21.12 7.95733 21.12 7.68C21.12 7.40267 21.024 7.16267 20.832 6.96C20.64 6.75733 20.416 6.656 20.16 6.656C19.904 6.656 19.68 6.75733 19.488 6.96C19.296 7.16267 19.2 7.40267 19.2 7.68C19.2 7.95733 19.296 8.192 19.488 8.384C19.68 8.576 19.904 8.672 20.16 8.672Z", fill: "#666666" }))), h("p", { class: "s-bullet-delivery-saved-addresses-empty-title" }, Salla.lang.get("pages.checkout.no_saved_addresses")), h("p", { class: "s-bullet-delivery-saved-addresses-empty-desc" }, Salla.lang.get("pages.checkout.add_address_simplify_shipping")), h("salla-button", { onClick: () => this.handleAddNewAddress(), onKeyUp: () => this.handleAddNewAddress() }, Salla.lang.get("pages.checkout.add_new_address"))));
|
|
1318
|
+
}
|
|
1319
|
+
/**
|
|
1320
|
+
* Save session address (guest intent) to user profile. Returns the newly saved address or null.
|
|
1321
|
+
*/
|
|
1322
|
+
async saveSessionAddressToProfile() {
|
|
1323
|
+
const intent = this.getStoredIntent();
|
|
1324
|
+
const countryId = getIntentCountryId(intent);
|
|
1325
|
+
const cityId = getIntentCityId(intent);
|
|
1326
|
+
const districtId = getIntentDistrictId(intent);
|
|
1327
|
+
if (!intent || intent.type !== "address" || !countryId || !cityId)
|
|
1328
|
+
return null;
|
|
1329
|
+
const countryCode = getIntentCountryCode(intent);
|
|
1330
|
+
if (isSaudiArabia(countryCode) && !districtId)
|
|
1331
|
+
return null;
|
|
1332
|
+
const isSA = isSaudiArabia(countryCode);
|
|
1333
|
+
const districtName = intent.address_details?.district?.name ?? "";
|
|
1334
|
+
const payload = {
|
|
1335
|
+
country_id: countryId,
|
|
1336
|
+
region_id: getIntentRegionId(intent),
|
|
1337
|
+
city_id: cityId,
|
|
1338
|
+
district_id: districtId,
|
|
1339
|
+
description: districtName,
|
|
1340
|
+
};
|
|
1341
|
+
if (isSA) {
|
|
1342
|
+
payload.local = districtName;
|
|
1343
|
+
}
|
|
1344
|
+
try {
|
|
1345
|
+
const { success, address } = await bulletDeliveryAPI.saveAddressLocation(payload);
|
|
1346
|
+
if (!success)
|
|
1347
|
+
return null;
|
|
1348
|
+
const savedAddress = address ?? null;
|
|
1349
|
+
if (savedAddress) {
|
|
1350
|
+
this.addressCreated.emit({ address: savedAddress });
|
|
1351
|
+
}
|
|
1352
|
+
return savedAddress;
|
|
1353
|
+
}
|
|
1354
|
+
catch (error) {
|
|
1355
|
+
console.error("SallaBulletDelivery: Error saving session address", error);
|
|
1356
|
+
return null;
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
renderSavedAddresses() {
|
|
1360
|
+
if (!this.isLoggedIn)
|
|
1361
|
+
return null;
|
|
1362
|
+
if (this.loadingSavedAddresses) {
|
|
1363
|
+
return (h("div", null, h("salla-loading", { size: "md" })));
|
|
1364
|
+
}
|
|
1365
|
+
const intent = this.getStoredIntent();
|
|
1366
|
+
const hasSessionAddress = hasSessionAddressIntent(intent);
|
|
1367
|
+
const sessionAddressTitle = hasSessionAddress && intent?.address_details
|
|
1368
|
+
? [
|
|
1369
|
+
intent.address_details.district?.name,
|
|
1370
|
+
intent.address_details.city.name,
|
|
1371
|
+
intent.address_details.country.name,
|
|
1372
|
+
]
|
|
1373
|
+
.filter(Boolean)
|
|
1374
|
+
.join("، ") ||
|
|
1375
|
+
[
|
|
1376
|
+
intent.address_details.country.id,
|
|
1377
|
+
intent.address_details.city.id,
|
|
1378
|
+
].join(", ")
|
|
1379
|
+
: "";
|
|
1380
|
+
if (this.savedAddresses.length === 0 && !hasSessionAddress) {
|
|
1381
|
+
return this.renderSavedAddressesEmptyState();
|
|
1382
|
+
}
|
|
1383
|
+
return (h("div", { class: "s-bullet-delivery-addresses-list s-scrollbar" }, hasSessionAddress &&
|
|
1384
|
+
this.renderAddressRow({
|
|
1385
|
+
key: "session-address",
|
|
1386
|
+
line1: sessionAddressTitle,
|
|
1387
|
+
line2: "",
|
|
1388
|
+
selected: this.selectedSessionAddress,
|
|
1389
|
+
onClick: () => this.handleSessionAddressSelect(),
|
|
1390
|
+
}), this.savedAddresses.map((address) => {
|
|
1391
|
+
const addrLine1 = address.formatted?.address_one ?? address.short_address ?? "";
|
|
1392
|
+
const line1 = [address.building_number, address.street]
|
|
1393
|
+
.filter(Boolean)
|
|
1394
|
+
.join("، ") || addrLine1;
|
|
1395
|
+
const districtName = address.district?.name ?? "";
|
|
1396
|
+
const cityName = address.city?.name ?? "";
|
|
1397
|
+
const line2 = this.isRTL && districtName
|
|
1398
|
+
? `${Salla.lang.get("pages.checkout.district_field")} ${districtName}، ${cityName}`
|
|
1399
|
+
: [districtName, cityName].filter(Boolean).join("، ");
|
|
1400
|
+
const inCoverage = address.is_in_coverage !== false;
|
|
1401
|
+
return this.renderAddressRow({
|
|
1402
|
+
key: String(address.id),
|
|
1403
|
+
line1,
|
|
1404
|
+
line2,
|
|
1405
|
+
selected: this.selectedSavedAddress?.id === address.id,
|
|
1406
|
+
disabled: !inCoverage,
|
|
1407
|
+
onClick: () => inCoverage && this.handleSavedAddressSelect(address),
|
|
1408
|
+
});
|
|
1409
|
+
})));
|
|
1410
|
+
}
|
|
1411
|
+
renderAddressRow(options) {
|
|
1412
|
+
const { key, line1, line2, selected, disabled = false, onClick } = options;
|
|
1413
|
+
return (h("button", { key: key, class: {
|
|
1414
|
+
"s-bullet-delivery-address-item": true,
|
|
1415
|
+
"s-bullet-delivery-address-item--selected": selected,
|
|
1416
|
+
"s-bullet-delivery-address-item--disabled": disabled,
|
|
1417
|
+
}, type: "button", onClick: disabled ? undefined : onClick, onKeyDown: (e) => {
|
|
1418
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1419
|
+
e.preventDefault();
|
|
1420
|
+
if (!disabled)
|
|
1421
|
+
onClick();
|
|
1422
|
+
}
|
|
1423
|
+
} }, h("input", { type: "radio", name: "saved_address", class: "s-bullet-delivery-radio", checked: selected, disabled: disabled, onClick: (e) => e.stopPropagation() }), h("span", { class: "s-bullet-delivery-address-map-icon", innerHTML: MiniMap, "aria-hidden": "true" }), h("div", { class: "s-bullet-delivery-address-content" }, h("div", { class: "s-bullet-delivery-address-lines" }, h("span", { class: "s-bullet-delivery-address-line1" }, line1), h("span", { class: "s-bullet-delivery-address-line2" }, line2)))));
|
|
1424
|
+
}
|
|
1425
|
+
renderGuestDeliveryForm() {
|
|
1426
|
+
const isSA = isSaudiArabia(this.selectedCountry?.code ?? '');
|
|
1427
|
+
return [
|
|
1428
|
+
this.renderCountrySelect(),
|
|
1429
|
+
isSA ? this.renderRegionSelect() : null,
|
|
1430
|
+
this.renderCityDistrictSelects(),
|
|
1431
|
+
];
|
|
1432
|
+
}
|
|
1433
|
+
renderDeliveryTab() {
|
|
1434
|
+
return (h("div", { class: {
|
|
1435
|
+
"s-bullet-delivery-content": true,
|
|
1436
|
+
"s-bullet-delivery-content--active": this.activeTab === "address",
|
|
1437
|
+
"s-hidden": this.activeTab !== "address",
|
|
1438
|
+
} }, this.isLoggedIn
|
|
1439
|
+
? this.renderSavedAddresses()
|
|
1440
|
+
: this.renderGuestDeliveryForm()));
|
|
1441
|
+
}
|
|
1442
|
+
renderBranchSearch() {
|
|
1443
|
+
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.get("pages.checkout.search_for_city_or_branch"), value: this.branchSearchQuery, onInput: (e) => this.handleBranchSearch(e), autocomplete: "off" })), h("button", { type: "button", class: {
|
|
1444
|
+
"s-bullet-delivery-location-btn": true,
|
|
1445
|
+
"s-bullet-delivery-location-btn--full": true,
|
|
1446
|
+
"s-bullet-delivery-location-btn--loading": this.loadingNearestBranch,
|
|
1447
|
+
}, onClick: () => this.handleFindNearestBranch(), disabled: this.loadingNearestBranch }, this.loadingNearestBranch ? (h("salla-loading", { size: "sm" })) : (h("span", { class: "s-bullet-delivery-location-icon", innerHTML: GPS, "aria-hidden": "true" })), h("span", null, Salla.lang.get("pages.checkout.nearest_to_my_location")))), this.locationError && this.activeTab === "branch" && (h("span", { class: "s-bullet-delivery-error" }, this.locationError))));
|
|
1448
|
+
}
|
|
1449
|
+
renderBranchList() {
|
|
1450
|
+
if (this.loadingBranches) {
|
|
1451
|
+
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" }))))))));
|
|
1452
|
+
}
|
|
1453
|
+
if (this.filteredBranches.length === 0) {
|
|
1454
|
+
return (h("salla-placeholder", { alignment: "center", class: "s-bullet-delivery-placeholder" }, h("span", { slot: "title" }, Salla.lang.get("pages.checkout.no_pickup_branches_found"))));
|
|
1455
|
+
}
|
|
1456
|
+
return (h("div", { class: "s-bullet-delivery-branches-wrap" }, h("ul", { class: "s-bullet-delivery-branches-list s-scrollbar" }, this.filteredBranches.map((branch) => (h("li", { key: branch.id, class: {
|
|
1457
|
+
"s-bullet-delivery-branch-item": true,
|
|
1458
|
+
"s-bullet-delivery-branch-item--selected": this.selectedBranch?.id === branch.id,
|
|
1459
|
+
"s-bullet-delivery-branch-item--disabled": branch.is_open === false,
|
|
1460
|
+
}, tabIndex: branch.is_open === false ? -1 : 0, role: "option", "aria-disabled": branch.is_open === false, onClick: () => branch.is_open !== false && this.handleBranchSelect(branch), onKeyDown: (e) => {
|
|
1461
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1462
|
+
e.preventDefault();
|
|
1463
|
+
if (branch.is_open !== false)
|
|
1464
|
+
this.handleBranchSelect(branch);
|
|
1465
|
+
}
|
|
1466
|
+
} }, h("input", { type: "radio", name: "branch", class: "s-bullet-delivery-radio", checked: this.selectedBranch?.id === branch.id, disabled: branch.is_open === false }), h("span", { class: "s-bullet-delivery-branch-icon", "aria-hidden": "true" }, h("span", { innerHTML: Store })), h("div", { class: "s-bullet-delivery-branch-info" }, h("span", { class: "s-bullet-delivery-branch-name" }, branch.name), branch.preparation_time ? (h("span", { class: "s-bullet-delivery-branch-prep" }, `${Salla.lang.get("pages.checkout.processing_time")}: ${branch.preparation_time} ${Salla.lang.get("pages.checkout.hour")}`)) : null), (() => {
|
|
1467
|
+
const slot = getBranchFirstSlot(branch.working_hours);
|
|
1468
|
+
return slot ? (h("span", { class: "s-bullet-delivery-branch-time" }, formatWorkingHoursDisplay(slot.from, slot.to, Salla.config.get("user.language_code") ||
|
|
1469
|
+
"ar", Salla.lang.get("pages.checkout.until")))) : null;
|
|
1470
|
+
})(), branch.location?.lat != null && branch.location?.lng != null && (h("a", { href: `https://www.google.com/maps?q=${branch.location.lat},${branch.location.lng}`, target: "_blank", rel: "noopener noreferrer", class: "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"))))))))));
|
|
1471
|
+
}
|
|
1472
|
+
renderPickupTab() {
|
|
1473
|
+
return (h("div", { class: {
|
|
1474
|
+
"s-bullet-delivery-content": true,
|
|
1475
|
+
"s-bullet-delivery-content--active": this.activeTab === "branch",
|
|
1476
|
+
"s-hidden": this.activeTab !== "branch",
|
|
1477
|
+
} }, this.renderCountrySelect(), this.renderBranchSearch(), this.renderBranchList()));
|
|
1478
|
+
}
|
|
1479
|
+
/** Add-address form: same fields as guest form (country, region, city, district) only. */
|
|
1480
|
+
renderAddAddressForm() {
|
|
1481
|
+
const title = Salla.lang.get("pages.checkout.add_new_address");
|
|
1482
|
+
const isSA = isSaudiArabia(this.selectedCountry?.code ?? '');
|
|
1483
|
+
const canSubmit = this.selectedCountry &&
|
|
1484
|
+
this.selectedCity &&
|
|
1485
|
+
(!isSA || this.selectedRegion) &&
|
|
1486
|
+
(!isSA ||
|
|
1487
|
+
!!this.selectedDistrict ||
|
|
1488
|
+
!!(this.districtName && this.districtName.trim().length > 0));
|
|
1489
|
+
const submitLabel = this.savingAddress
|
|
1490
|
+
? Salla.lang.get("pages.checkout.loading")
|
|
1491
|
+
: Salla.lang.get("pages.checkout.confirm_address");
|
|
1492
|
+
return (h("div", { class: "s-bullet-delivery-add-address" }, h("div", { class: "s-bullet-delivery-add-address-header" }, h("button", { type: "button", class: "s-bullet-delivery-add-address-title", onClick: () => this.handleBackToAddressList(), onKeyDown: (e) => e.key === "Enter" && this.handleBackToAddressList() }, h("span", { innerHTML: this.isRTL ? ArrowRight : ArrowLeft, "aria-hidden": "true" }), h("span", { class: "s-bullet-delivery-add-address-title-text" }, title))), h("form", { class: "s-bullet-delivery-add-address-form", onSubmit: (e) => this.handleSubmitAddAddress(e) }, this.renderGuestDeliveryForm(), h("div", { class: "s-bullet-delivery-form-actions s-bullet-delivery-form-actions--single" }, h("salla-button", { type: "submit", loading: this.savingAddress, disabled: !canSubmit || this.savingAddress, class: "s-bullet-delivery-add-address-submit" }, submitLabel)))));
|
|
1493
|
+
}
|
|
1494
|
+
renderFooter() {
|
|
1495
|
+
const showAddAddressInFooter = this.activeTab === "address" && this.isLoggedIn;
|
|
1496
|
+
return (h("div", { class: "s-bullet-delivery-footer" }, h("salla-button", { ref: (btn) => {
|
|
1497
|
+
this.confirmBtn = btn;
|
|
1498
|
+
}, disabled: this.isConfirmDisabled(), onClick: () => this.handleConfirm(), "loader-position": "center", width: "wide" }, this.activeTab === "branch"
|
|
1499
|
+
? Salla.lang.get("pages.checkout.confirm_receipt_from_the_branch")
|
|
1500
|
+
: 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")))));
|
|
1501
|
+
}
|
|
1502
|
+
renderMainView() {
|
|
1503
|
+
const isAddressEmptyState = this.isLoggedIn &&
|
|
1504
|
+
this.activeTab === "address" &&
|
|
1505
|
+
this.savedAddresses.length === 0 &&
|
|
1506
|
+
!hasSessionAddressIntent(this.getStoredIntent());
|
|
1507
|
+
const activeTabView = this.activeTab === "branch" && this.supportsPickup
|
|
1508
|
+
? this.renderPickupTab()
|
|
1509
|
+
: this.renderDeliveryTab();
|
|
1510
|
+
return (h("div", null, h("div", { class: "s-bullet-delivery-header" }, h("h2", { class: "s-bullet-delivery-title" }, Salla.lang.get("blocks.home.select_the_receiving_method")), h("p", { class: "s-bullet-delivery-subtitle" }, Salla.lang.get("pages.checkout.delivery_pickup_availability_hint"))), this.renderTabs(), this.showCartWillBeClearedBanner &&
|
|
1511
|
+
this.renderAlert(Salla.lang.get("blocks.scope.empty_cart_warning")), this.allocationOutOfCoverageMessage &&
|
|
1512
|
+
this.renderAllocationOutOfCoverageAlert(), activeTabView, !isAddressEmptyState && this.renderFooter()));
|
|
1513
|
+
}
|
|
1514
|
+
handleAfterAddToCart() {
|
|
1515
|
+
if (this.openingType !== "after_add_to_cart")
|
|
1516
|
+
return;
|
|
1517
|
+
if (this.hasBeenShownThisSession())
|
|
1518
|
+
return;
|
|
1519
|
+
if (this.modal?.isOpen?.())
|
|
1520
|
+
return;
|
|
1521
|
+
this.open();
|
|
1522
|
+
}
|
|
1523
|
+
overrideScopeSwitchUI() {
|
|
1524
|
+
const intent = this.getStoredIntent();
|
|
1525
|
+
if (!intent)
|
|
1526
|
+
return;
|
|
1527
|
+
const scopesTriggerButton = Array.from(document.querySelectorAll('[onclick*="scopes"]')).find((el) => /scopes/.test(el.getAttribute("onclick") || ""));
|
|
1528
|
+
if (!scopesTriggerButton)
|
|
1529
|
+
return;
|
|
1530
|
+
scopesTriggerButton.onclick = () => {
|
|
1531
|
+
this.open();
|
|
1532
|
+
};
|
|
1533
|
+
const isBranch = intent.type === "branch";
|
|
1534
|
+
const truncate = (str, max) => str && str.length > max ? `${str.slice(0, max)}...` : (str ?? "");
|
|
1535
|
+
const labelText = isBranch
|
|
1536
|
+
? `${Salla.lang.get("mobile_app.strings.pickup")} ${Salla.lang.get("common.elements.from")} ${truncate(intent.branch_details?.name, 20)}`
|
|
1537
|
+
: `${Salla.lang.get("mobile_app.strings.delivery")} ${Salla.lang.get("common.elements.to")} ${truncate(intent.address_details?.city?.name, 10)}`;
|
|
1538
|
+
const spanLabel = scopesTriggerButton.querySelector('span:not([class*="sicon"]):not([class*="icon"])');
|
|
1539
|
+
if (spanLabel) {
|
|
1540
|
+
spanLabel.textContent = labelText;
|
|
1541
|
+
}
|
|
1542
|
+
else {
|
|
1543
|
+
// Replace bare text nodes (e.g. " متجر السعودية") directly on the button
|
|
1544
|
+
for (const node of Array.from(scopesTriggerButton.childNodes)) {
|
|
1545
|
+
if (node.nodeType === Node.TEXT_NODE && node.textContent?.trim()) {
|
|
1546
|
+
node.textContent = ` ${labelText}`;
|
|
1547
|
+
break;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
async componentWillLoad() {
|
|
1553
|
+
await Salla.onReady();
|
|
1554
|
+
Salla.event.on("bullet-delivery::open", this.bulletDeliveryOpenHandler);
|
|
1555
|
+
this.closeHandler = this.close.bind(this);
|
|
1556
|
+
Salla.event.on("bullet-delivery::close", this.closeHandler);
|
|
1557
|
+
// Listen for successful login to sync guest session to user profile (AC7)
|
|
1558
|
+
this.guestLoginSyncHandler = this.handleGuestToRegisteredSync.bind(this);
|
|
1559
|
+
Salla.event.on("login::success", this.guestLoginSyncHandler);
|
|
1560
|
+
Salla.event.on("auth::logged-in", this.guestLoginSyncHandler);
|
|
1561
|
+
this.isRTL = Salla.config.get("theme.is_rtl");
|
|
1562
|
+
// Listen for add-to-cart events for 'after_add_to_cart' opening strategy (after salla is ready)
|
|
1563
|
+
this.cartItemAddedHandler = () => this.handleAfterAddToCart();
|
|
1564
|
+
if (typeof Salla.cart?.event?.onItemAdded === "function") {
|
|
1565
|
+
this.useCartEventApi = true;
|
|
1566
|
+
Salla.cart.event.onItemAdded(this.cartItemAddedHandler);
|
|
1567
|
+
}
|
|
1568
|
+
else {
|
|
1569
|
+
Salla.event.on(this.cartItemAddedEvent, this.cartItemAddedHandler);
|
|
1570
|
+
}
|
|
1571
|
+
try {
|
|
1572
|
+
this.overrideScopeSwitchUI();
|
|
1573
|
+
}
|
|
1574
|
+
catch (e) {
|
|
1575
|
+
console.warn("SallaBulletDelivery: overrideScopeSwitchUI failed", e);
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
render() {
|
|
1579
|
+
return (h(Host, { key: '5a933828333aab1fdc02d2a6429c6ff6813ac906', class: "s-bullet-delivery" }, h("salla-modal", { key: '47d9e05fa3d391f4ac9e83318a869460fac54c5b', ref: (modal) => {
|
|
1580
|
+
this.modal = modal;
|
|
1581
|
+
}, isClosable: !this.isRequired, class: "s-bullet-delivery-modal", isLoading: this.loading, width: "sm" }, this.loading ? (this.renderSkeleton()) : (h("div", { class: "s-bullet-delivery-inner" }, this.viewMode === "main" && this.renderMainView(), this.viewMode === "add-address" && this.renderAddAddressForm())))));
|
|
1582
|
+
}
|
|
1583
|
+
componentDidLoad() {
|
|
1584
|
+
// Mark component as ready
|
|
1585
|
+
this.componentReady = true;
|
|
1586
|
+
// Handle pending open request (if event was emitted before component was ready)
|
|
1587
|
+
if (this.pendingOpen) {
|
|
1588
|
+
this.pendingOpen = false;
|
|
1589
|
+
this.open();
|
|
1590
|
+
return;
|
|
1591
|
+
}
|
|
1592
|
+
// Strategy-based auto-open logic
|
|
1593
|
+
switch (this.openingType) {
|
|
1594
|
+
case "first_visit":
|
|
1595
|
+
// Open once per session when component mounts (per-session behaviour)
|
|
1596
|
+
if (!this.hasBeenShownThisSession()) {
|
|
1597
|
+
this.open();
|
|
1598
|
+
}
|
|
1599
|
+
break;
|
|
1600
|
+
case "on_cart_click":
|
|
1601
|
+
// Open automatically when user is on the cart page
|
|
1602
|
+
if (Salla.url.is_page("cart")) {
|
|
1603
|
+
Salla.storage.session.get(this.sessionShownKey) !== true &&
|
|
1604
|
+
this.open();
|
|
1605
|
+
}
|
|
1606
|
+
break;
|
|
1607
|
+
case "after_add_to_cart":
|
|
1608
|
+
// Handled reactively via cart::item.added event listener
|
|
1609
|
+
break;
|
|
1610
|
+
default:
|
|
1611
|
+
break;
|
|
1612
|
+
}
|
|
1613
|
+
// Mount cart view into cart.items.start hook
|
|
1614
|
+
const cartViewEl = this.createCartViewElement();
|
|
1615
|
+
if (cartViewEl && typeof salla?.hooks?.mount === "function") {
|
|
1616
|
+
Salla.hooks.mount("cart:items.start", cartViewEl).catch(() => {
|
|
1617
|
+
// Hook may not exist on this page; ignore
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
disconnectedCallback() {
|
|
1622
|
+
this.componentReady = false;
|
|
1623
|
+
Salla.event.off("bullet-delivery::open", this.bulletDeliveryOpenHandler);
|
|
1624
|
+
if (this.closeHandler) {
|
|
1625
|
+
Salla.event.off("bullet-delivery::close", this.closeHandler);
|
|
1626
|
+
this.closeHandler = null;
|
|
1627
|
+
}
|
|
1628
|
+
if (this.guestLoginSyncHandler) {
|
|
1629
|
+
Salla.event.off("login::success", this.guestLoginSyncHandler);
|
|
1630
|
+
Salla.event.off("auth::logged-in", this.guestLoginSyncHandler);
|
|
1631
|
+
this.guestLoginSyncHandler = null;
|
|
1632
|
+
}
|
|
1633
|
+
if (this.cartItemAddedHandler) {
|
|
1634
|
+
if (this.useCartEventApi && typeof Salla.cart?.event?.offItemAdded === "function") {
|
|
1635
|
+
Salla.cart.event.offItemAdded(this.cartItemAddedHandler);
|
|
1636
|
+
}
|
|
1637
|
+
else {
|
|
1638
|
+
Salla.event.off(this.cartItemAddedEvent, this.cartItemAddedHandler);
|
|
1639
|
+
}
|
|
1640
|
+
this.cartItemAddedHandler = null;
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
static get is() { return "salla-bullet-delivery"; }
|
|
1644
|
+
static get originalStyleUrls() {
|
|
1645
|
+
return {
|
|
1646
|
+
"$": ["salla-bullet-delivery.scss"]
|
|
1647
|
+
};
|
|
1648
|
+
}
|
|
1649
|
+
static get styleUrls() {
|
|
1650
|
+
return {
|
|
1651
|
+
"$": ["salla-bullet-delivery.css"]
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1654
|
+
static get states() {
|
|
1655
|
+
return {
|
|
1656
|
+
"loading": {},
|
|
1657
|
+
"activeTab": {},
|
|
1658
|
+
"isLoggedIn": {},
|
|
1659
|
+
"viewMode": {},
|
|
1660
|
+
"countries": {},
|
|
1661
|
+
"regions": {},
|
|
1662
|
+
"cities": {},
|
|
1663
|
+
"districts": {},
|
|
1664
|
+
"loadingRegions": {},
|
|
1665
|
+
"selectedCountry": {},
|
|
1666
|
+
"selectedRegion": {},
|
|
1667
|
+
"selectedCity": {},
|
|
1668
|
+
"selectedDistrict": {},
|
|
1669
|
+
"districtName": {},
|
|
1670
|
+
"savedAddresses": {},
|
|
1671
|
+
"selectedSavedAddress": {},
|
|
1672
|
+
"selectedSessionAddress": {},
|
|
1673
|
+
"branches": {},
|
|
1674
|
+
"filteredBranches": {},
|
|
1675
|
+
"selectedBranch": {},
|
|
1676
|
+
"branchSearchQuery": {},
|
|
1677
|
+
"loadingCities": {},
|
|
1678
|
+
"loadingDistricts": {},
|
|
1679
|
+
"loadingBranches": {},
|
|
1680
|
+
"loadingNearestBranch": {},
|
|
1681
|
+
"locationError": {},
|
|
1682
|
+
"savingAddress": {},
|
|
1683
|
+
"loadingSavedAddresses": {},
|
|
1684
|
+
"showCartWillBeClearedBanner": {},
|
|
1685
|
+
"allocationOutOfCoverageMessage": {},
|
|
1686
|
+
"newAddressForm": {}
|
|
1687
|
+
};
|
|
1688
|
+
}
|
|
1689
|
+
static get events() {
|
|
1690
|
+
return [{
|
|
1691
|
+
"method": "bulletDeliveryConfirmed",
|
|
1692
|
+
"name": "bulletDeliveryConfirmed",
|
|
1693
|
+
"bubbles": true,
|
|
1694
|
+
"cancelable": true,
|
|
1695
|
+
"composed": true,
|
|
1696
|
+
"docs": {
|
|
1697
|
+
"tags": [],
|
|
1698
|
+
"text": "Emitted when the user confirms their selection"
|
|
1699
|
+
},
|
|
1700
|
+
"complexType": {
|
|
1701
|
+
"original": "BulletDeliveryConfirmedEvent",
|
|
1702
|
+
"resolved": "BulletDeliveryConfirmedEvent",
|
|
1703
|
+
"references": {
|
|
1704
|
+
"BulletDeliveryConfirmedEvent": {
|
|
1705
|
+
"location": "import",
|
|
1706
|
+
"path": "./interfaces",
|
|
1707
|
+
"id": "src/components/salla-bullet-delivery/interfaces.ts::BulletDeliveryConfirmedEvent"
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
}, {
|
|
1712
|
+
"method": "bulletDeliveryClosed",
|
|
1713
|
+
"name": "bulletDeliveryClosed",
|
|
1714
|
+
"bubbles": true,
|
|
1715
|
+
"cancelable": true,
|
|
1716
|
+
"composed": true,
|
|
1717
|
+
"docs": {
|
|
1718
|
+
"tags": [],
|
|
1719
|
+
"text": "Emitted when the modal is closed"
|
|
1720
|
+
},
|
|
1721
|
+
"complexType": {
|
|
1722
|
+
"original": "void",
|
|
1723
|
+
"resolved": "void",
|
|
1724
|
+
"references": {}
|
|
1725
|
+
}
|
|
1726
|
+
}, {
|
|
1727
|
+
"method": "addressCreated",
|
|
1728
|
+
"name": "addressCreated",
|
|
1729
|
+
"bubbles": true,
|
|
1730
|
+
"cancelable": true,
|
|
1731
|
+
"composed": true,
|
|
1732
|
+
"docs": {
|
|
1733
|
+
"tags": [],
|
|
1734
|
+
"text": "Emitted when a new address is created"
|
|
1735
|
+
},
|
|
1736
|
+
"complexType": {
|
|
1737
|
+
"original": "AddressCreatedEvent",
|
|
1738
|
+
"resolved": "AddressCreatedEvent",
|
|
1739
|
+
"references": {
|
|
1740
|
+
"AddressCreatedEvent": {
|
|
1741
|
+
"location": "import",
|
|
1742
|
+
"path": "./interfaces",
|
|
1743
|
+
"id": "src/components/salla-bullet-delivery/interfaces.ts::AddressCreatedEvent"
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
}, {
|
|
1748
|
+
"method": "headerContextUpdate",
|
|
1749
|
+
"name": "headerContextUpdate",
|
|
1750
|
+
"bubbles": true,
|
|
1751
|
+
"cancelable": true,
|
|
1752
|
+
"composed": true,
|
|
1753
|
+
"docs": {
|
|
1754
|
+
"tags": [],
|
|
1755
|
+
"text": "Emitted to sync with the global header (Delivering to: [location])"
|
|
1756
|
+
},
|
|
1757
|
+
"complexType": {
|
|
1758
|
+
"original": "HeaderContextUpdateEvent",
|
|
1759
|
+
"resolved": "HeaderContextUpdateEvent",
|
|
1760
|
+
"references": {
|
|
1761
|
+
"HeaderContextUpdateEvent": {
|
|
1762
|
+
"location": "import",
|
|
1763
|
+
"path": "./interfaces",
|
|
1764
|
+
"id": "src/components/salla-bullet-delivery/interfaces.ts::HeaderContextUpdateEvent"
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
}];
|
|
1769
|
+
}
|
|
1770
|
+
static get methods() {
|
|
1771
|
+
return {
|
|
1772
|
+
"open": {
|
|
1773
|
+
"complexType": {
|
|
1774
|
+
"signature": "() => Promise<void>",
|
|
1775
|
+
"parameters": [],
|
|
1776
|
+
"references": {
|
|
1777
|
+
"Promise": {
|
|
1778
|
+
"location": "global",
|
|
1779
|
+
"id": "global::Promise"
|
|
1780
|
+
}
|
|
1781
|
+
},
|
|
1782
|
+
"return": "Promise<void>"
|
|
1783
|
+
},
|
|
1784
|
+
"docs": {
|
|
1785
|
+
"text": "Opens the bullet delivery modal",
|
|
1786
|
+
"tags": []
|
|
1787
|
+
}
|
|
1788
|
+
},
|
|
1789
|
+
"close": {
|
|
1790
|
+
"complexType": {
|
|
1791
|
+
"signature": "() => Promise<HTMLElement>",
|
|
1792
|
+
"parameters": [],
|
|
1793
|
+
"references": {
|
|
1794
|
+
"Promise": {
|
|
1795
|
+
"location": "global",
|
|
1796
|
+
"id": "global::Promise"
|
|
1797
|
+
},
|
|
1798
|
+
"HTMLElement": {
|
|
1799
|
+
"location": "global",
|
|
1800
|
+
"id": "global::HTMLElement"
|
|
1801
|
+
}
|
|
1802
|
+
},
|
|
1803
|
+
"return": "Promise<HTMLElement>"
|
|
1804
|
+
},
|
|
1805
|
+
"docs": {
|
|
1806
|
+
"text": "Closes the bullet delivery modal",
|
|
1807
|
+
"tags": []
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
};
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
/**
|
|
1814
|
+
* SA add-address view: 'confirmed' = selected address box + description + confirm, 'full' = all form fields (after Edit).
|
|
1815
|
+
*/
|
|
1816
|
+
// Unified form state (guest and add address)
|
|
1817
|
+
SallaBulletDelivery.INITIAL_ADDRESS_FORM = {
|
|
1818
|
+
country_id: 0,
|
|
1819
|
+
is_default: false,
|
|
1820
|
+
city_id: undefined,
|
|
1821
|
+
district_id: undefined,
|
|
1822
|
+
street: undefined,
|
|
1823
|
+
building_number: undefined,
|
|
1824
|
+
additional_number: undefined,
|
|
1825
|
+
postal_code: undefined,
|
|
1826
|
+
description: undefined,
|
|
1827
|
+
};
|