@salla.sa/twilight-components 2.14.384 → 2.14.386
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-CJUBlGWZ.js → filepond-Dz0w3b0-.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-poster-DzfdX-da.js → filepond-plugin-file-poster-Bc2hFAJm.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-size-aKEs_A1i.js → filepond-plugin-file-validate-size-D-ntIPdx.js} +1 -1
- package/dist/cjs/{filepond-plugin-file-validate-type-BBQOuEjF.js → filepond-plugin-file-validate-type-1TnSvBgD.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-edit-Ce6fwF2W.js → filepond-plugin-image-edit-DGi3QY5x.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-exif-orientation-BcFGamVd.js → filepond-plugin-image-exif-orientation-CzMQBbqX.js} +1 -1
- package/dist/cjs/{filepond-plugin-image-preview-DktpahDI.js → filepond-plugin-image-preview-D555a4un.js} +1 -1
- package/dist/cjs/{index-CfgN9bup.js → index--a5myRaH.js} +1 -1
- package/dist/cjs/{index-Dc8V4JzY.js → index-Oy30xVAt.js} +2 -2
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/salla-accordion-body_3.cjs.entry.js +1 -1
- package/dist/cjs/salla-accordion_6.cjs.entry.js +1 -1
- package/dist/cjs/salla-add-product-button_4.cjs.entry.js +1 -1
- 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 +10 -10
- package/dist/cjs/salla-bullet-delivery.cjs.entry.js +248 -188
- package/dist/cjs/salla-cart-item-offers_2.cjs.entry.js +1 -1
- package/dist/cjs/salla-comment-form_8.cjs.entry.js +1 -1
- package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-contacts.cjs.entry.js +1 -1
- package/dist/cjs/salla-cookies-bar.cjs.entry.js +1 -1
- package/dist/cjs/salla-count-down_2.cjs.entry.js +1 -1
- package/dist/cjs/salla-custom-fields.cjs.entry.js +1 -1
- package/dist/cjs/salla-filters-widget.cjs.entry.js +1 -1
- package/dist/cjs/salla-filters.cjs.entry.js +1 -1
- package/dist/cjs/salla-gifting.cjs.entry.js +1 -1
- package/dist/cjs/salla-hook.cjs.entry.js +1 -1
- package/dist/cjs/salla-infinite-scroll.cjs.entry.js +1 -1
- package/dist/cjs/salla-installment.cjs.entry.js +1 -1
- package/dist/cjs/salla-list-tile.cjs.entry.js +1 -1
- package/dist/cjs/salla-localization-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-login-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty-program.cjs.entry.js +1 -1
- package/dist/cjs/salla-loyalty.cjs.entry.js +1 -1
- package/dist/cjs/salla-maintenance-alert.cjs.entry.js +1 -1
- package/dist/cjs/salla-menu.cjs.entry.js +1 -1
- package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
- package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +1 -1
- package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +1 -1
- package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +1 -1
- package/dist/cjs/salla-notification-item.cjs.entry.js +1 -1
- package/dist/cjs/salla-notifications.cjs.entry.js +1 -1
- package/dist/cjs/salla-offer-modal.cjs.entry.js +1 -1
- package/dist/cjs/salla-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-details.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-summary.cjs.entry.js +1 -1
- package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
- package/dist/cjs/salla-orders.cjs.entry.js +1 -1
- package/dist/cjs/salla-payments.cjs.entry.js +1 -1
- package/dist/cjs/salla-placeholder.cjs.entry.js +1 -1
- package/dist/cjs/salla-price-range.cjs.entry.js +1 -1
- package/dist/cjs/salla-product-size-guide.cjs.entry.js +1 -1
- 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 +1 -1
- package/dist/cjs/salla-search.cjs.entry.js +1 -1
- package/dist/cjs/salla-skeleton.cjs.entry.js +1 -1
- package/dist/cjs/salla-slider.cjs.entry.js +1 -1
- package/dist/cjs/salla-social-share.cjs.entry.js +1 -1
- package/dist/cjs/salla-social.cjs.entry.js +1 -1
- package/dist/cjs/salla-tab-content_3.cjs.entry.js +1 -1
- package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
- package/dist/cjs/salla-tooltip.cjs.entry.js +1 -1
- package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
- package/dist/cjs/salla-user-menu.cjs.entry.js +1 -1
- package/dist/cjs/salla-user-profile.cjs.entry.js +1 -1
- package/dist/cjs/salla-user-settings.cjs.entry.js +1 -1
- package/dist/cjs/salla-verify.cjs.entry.js +1 -1
- package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
- package/dist/cjs/twilight.cjs.js +1 -1
- package/dist/cjs/{vanilla-picker-DR583jAq.js → vanilla-picker-BjBHEsil.js} +1 -1
- package/dist/collection/components/salla-bullet-delivery/helpers.js +4 -20
- package/dist/collection/components/salla-bullet-delivery/salla-bullet-delivery.js +244 -168
- package/dist/components/index.js +2 -2
- package/dist/components/salla-bullet-delivery.js +247 -187
- package/dist/esm/{filepond-BWifXQjU.js → filepond-BXxeKj-9.js} +1 -1
- package/dist/esm/{filepond-plugin-file-poster-Cwfa6rZE.js → filepond-plugin-file-poster-B5BTs5Ly.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-size-BrX587rP.js → filepond-plugin-file-validate-size-_PyCg3tk.js} +1 -1
- package/dist/esm/{filepond-plugin-file-validate-type-CR3s_l2K.js → filepond-plugin-file-validate-type-uSrSfAxF.js} +1 -1
- package/dist/esm/{filepond-plugin-image-edit-DcaaNA7K.js → filepond-plugin-image-edit-Cke6iTN3.js} +1 -1
- package/dist/esm/{filepond-plugin-image-exif-orientation-BhT9UmOS.js → filepond-plugin-image-exif-orientation-DKLDaeeL.js} +1 -1
- package/dist/esm/{filepond-plugin-image-preview-nWsxKqF2.js → filepond-plugin-image-preview-KfxXXS81.js} +1 -1
- package/dist/esm/{index-DHu5e7PE.js → index-B2mHcqWp.js} +1 -1
- package/dist/esm/{index-CSCx8X8V.js → index-D4I5TLtE.js} +2 -2
- package/dist/esm/loader.js +2 -2
- package/dist/esm/salla-accordion-body_3.entry.js +1 -1
- package/dist/esm/salla-accordion_6.entry.js +1 -1
- package/dist/esm/salla-add-product-button_4.entry.js +1 -1
- 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 +10 -10
- package/dist/esm/salla-bullet-delivery.entry.js +248 -188
- package/dist/esm/salla-cart-item-offers_2.entry.js +1 -1
- package/dist/esm/salla-comment-form_8.entry.js +1 -1
- package/dist/esm/salla-conditional-offer.entry.js +1 -1
- package/dist/esm/salla-contacts.entry.js +1 -1
- package/dist/esm/salla-cookies-bar.entry.js +1 -1
- package/dist/esm/salla-count-down_2.entry.js +1 -1
- package/dist/esm/salla-custom-fields.entry.js +1 -1
- package/dist/esm/salla-filters-widget.entry.js +1 -1
- package/dist/esm/salla-filters.entry.js +1 -1
- package/dist/esm/salla-gifting.entry.js +1 -1
- package/dist/esm/salla-hook.entry.js +1 -1
- package/dist/esm/salla-infinite-scroll.entry.js +1 -1
- package/dist/esm/salla-installment.entry.js +1 -1
- package/dist/esm/salla-list-tile.entry.js +1 -1
- package/dist/esm/salla-localization-modal.entry.js +1 -1
- package/dist/esm/salla-login-modal.entry.js +1 -1
- package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
- package/dist/esm/salla-loyalty-program.entry.js +1 -1
- package/dist/esm/salla-loyalty.entry.js +1 -1
- package/dist/esm/salla-maintenance-alert.entry.js +1 -1
- package/dist/esm/salla-menu.entry.js +1 -1
- package/dist/esm/salla-metadata.entry.js +1 -1
- package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +1 -1
- package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +1 -1
- package/dist/esm/salla-multiple-bundle-product.entry.js +1 -1
- package/dist/esm/salla-notification-item.entry.js +1 -1
- package/dist/esm/salla-notifications.entry.js +1 -1
- package/dist/esm/salla-offer-modal.entry.js +1 -1
- 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 +1 -1
- package/dist/esm/salla-order-summary.entry.js +1 -1
- package/dist/esm/salla-order-totals-card.entry.js +1 -1
- package/dist/esm/salla-orders.entry.js +1 -1
- package/dist/esm/salla-payments.entry.js +1 -1
- package/dist/esm/salla-placeholder.entry.js +1 -1
- package/dist/esm/salla-price-range.entry.js +1 -1
- package/dist/esm/salla-product-size-guide.entry.js +1 -1
- 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 +1 -1
- package/dist/esm/salla-search.entry.js +1 -1
- package/dist/esm/salla-skeleton.entry.js +1 -1
- package/dist/esm/salla-slider.entry.js +1 -1
- package/dist/esm/salla-social-share.entry.js +1 -1
- package/dist/esm/salla-social.entry.js +1 -1
- package/dist/esm/salla-tab-content_3.entry.js +1 -1
- package/dist/esm/salla-tiered-offer.entry.js +1 -1
- package/dist/esm/salla-tooltip.entry.js +1 -1
- package/dist/esm/salla-trust-badges.entry.js +1 -1
- package/dist/esm/salla-user-menu.entry.js +1 -1
- package/dist/esm/salla-user-profile.entry.js +1 -1
- package/dist/esm/salla-user-settings.entry.js +1 -1
- package/dist/esm/salla-verify.entry.js +1 -1
- package/dist/esm/salla-wallet.entry.js +1 -1
- package/dist/esm/twilight.js +2 -2
- package/dist/esm/{vanilla-picker-CQ4dQJev.js → vanilla-picker-CM1O2U8w.js} +1 -1
- package/dist/twilight/{p-713d20a2.entry.js → p-0127cd6e.entry.js} +1 -1
- package/dist/twilight/{p-47740515.entry.js → p-0476b736.entry.js} +1 -1
- package/dist/twilight/{p-3c669bb0.entry.js → p-0537ad3e.entry.js} +1 -1
- package/dist/twilight/{p-fcf342fd.entry.js → p-06e10077.entry.js} +1 -1
- package/dist/twilight/{p-b9496c6c.entry.js → p-08c37adc.entry.js} +1 -1
- package/dist/twilight/{p-58a203ef.entry.js → p-0e82b9cd.entry.js} +1 -1
- package/dist/twilight/{p-cc499b03.entry.js → p-12e9e619.entry.js} +1 -1
- package/dist/twilight/{p-4ba25464.entry.js → p-15732417.entry.js} +1 -1
- package/dist/twilight/{p-f58f83a1.entry.js → p-15c7e73a.entry.js} +1 -1
- package/dist/twilight/{p-7eb215ae.entry.js → p-181da663.entry.js} +1 -1
- package/dist/twilight/{p-eff84a35.entry.js → p-283727c3.entry.js} +1 -1
- package/dist/twilight/{p-76293bed.entry.js → p-28665675.entry.js} +1 -1
- package/dist/twilight/{p-c7f7c0fc.entry.js → p-29da0820.entry.js} +1 -1
- package/dist/twilight/{p-7c46f469.entry.js → p-2c5880fe.entry.js} +1 -1
- package/dist/twilight/{p-b851cdcd.entry.js → p-30bdeebc.entry.js} +1 -1
- package/dist/twilight/{p-b56db8c8.entry.js → p-33727c81.entry.js} +1 -1
- package/dist/twilight/{p-b4013078.entry.js → p-35bab511.entry.js} +1 -1
- package/dist/twilight/{p-f2b2e290.entry.js → p-37996e21.entry.js} +1 -1
- package/dist/twilight/{p-c8e6b463.entry.js → p-3a67bf02.entry.js} +1 -1
- package/dist/twilight/{p-c819a24b.entry.js → p-3cf6308d.entry.js} +1 -1
- package/dist/twilight/{p-20695fed.entry.js → p-408f439d.entry.js} +1 -1
- package/dist/twilight/{p-0bd2951c.entry.js → p-48db8cc1.entry.js} +1 -1
- package/dist/twilight/{p-d880213f.entry.js → p-4b34c403.entry.js} +1 -1
- package/dist/twilight/{p-759ea776.entry.js → p-4d80d014.entry.js} +1 -1
- package/dist/twilight/{p-55f08b09.entry.js → p-4ede0af7.entry.js} +1 -1
- package/dist/twilight/{p-ec07da81.entry.js → p-4f5c85b6.entry.js} +1 -1
- package/dist/twilight/{p-ddf4eb18.entry.js → p-503a0362.entry.js} +1 -1
- package/dist/twilight/{p-74fb528f.entry.js → p-5338f5de.entry.js} +1 -1
- package/dist/twilight/{p-54bdfaa1.entry.js → p-5bc80a29.entry.js} +1 -1
- package/dist/twilight/{p-e1baac53.entry.js → p-5bc914c3.entry.js} +1 -1
- package/dist/twilight/{p-7effdd10.entry.js → p-653b2dac.entry.js} +1 -1
- package/dist/twilight/{p-612e7ad0.entry.js → p-6a8ae21b.entry.js} +1 -1
- package/dist/twilight/{p-1d296b1e.entry.js → p-6b66894c.entry.js} +1 -1
- package/dist/twilight/{p-9d9fd6ea.entry.js → p-6c1eb2aa.entry.js} +1 -1
- package/dist/twilight/{p-0e364b43.entry.js → p-70799a42.entry.js} +1 -1
- package/dist/twilight/{p-2abc4a24.entry.js → p-72ebeb8b.entry.js} +1 -1
- package/dist/twilight/{p-c8c92bd6.entry.js → p-7424ba6e.entry.js} +1 -1
- package/dist/twilight/{p-bfdce729.entry.js → p-7a874935.entry.js} +1 -1
- package/dist/twilight/{p-4fd0fc2a.entry.js → p-7ac9fe96.entry.js} +1 -1
- package/dist/twilight/{p-27f38623.entry.js → p-7b18c9e0.entry.js} +1 -1
- package/dist/twilight/{p-d969e5f8.entry.js → p-89635370.entry.js} +1 -1
- package/dist/twilight/{p-54a45b62.entry.js → p-90dc7be8.entry.js} +1 -1
- package/dist/twilight/{p-e1d3b456.entry.js → p-91f1e6df.entry.js} +1 -1
- package/dist/twilight/{p-eb7a8a3f.entry.js → p-95afe7b9.entry.js} +1 -1
- package/dist/twilight/{p-2598b0e2.entry.js → p-9ac3d8e7.entry.js} +1 -1
- package/dist/twilight/{p-211ecdf8.entry.js → p-9b68f4f7.entry.js} +1 -1
- package/dist/twilight/{p-67440334.entry.js → p-9cf8788e.entry.js} +1 -1
- package/dist/twilight/{p-CNaBlSvx.js → p-BbjmfFRJ.js} +1 -1
- package/dist/twilight/{p-PTrxhb6X.js → p-BjbWnZaV.js} +1 -1
- package/dist/twilight/{p-jh2tazFy.js → p-Bm_ows1a.js} +1 -1
- package/dist/twilight/{p-CGbcJTo7.js → p-D339DoJY.js} +2 -2
- package/dist/twilight/{p-CSCx8X8V.js → p-D4I5TLtE.js} +1 -1
- package/dist/twilight/p-D_Ov4zes.js +9 -0
- package/dist/twilight/{p-CQE3hxmT.js → p-Dr8Bgm1u.js} +1 -1
- package/dist/twilight/{p-DVkH3hdE.js → p-OQFknQfe.js} +1 -1
- package/dist/twilight/{p-CrmdYuCr.js → p-Q1_LG8_l.js} +1 -1
- package/dist/twilight/{p-C3V6igTx.js → p-Ym28Ytut.js} +1 -1
- package/dist/twilight/{p-cdba6449.entry.js → p-a2b440ae.entry.js} +1 -1
- package/dist/twilight/{p-621ddaae.entry.js → p-a32e417b.entry.js} +1 -1
- package/dist/twilight/{p-8d8f3c5a.entry.js → p-a348dd40.entry.js} +1 -1
- package/dist/twilight/{p-71393e6a.entry.js → p-a56efe37.entry.js} +1 -1
- package/dist/twilight/{p-3ae26c18.entry.js → p-a751f592.entry.js} +1 -1
- package/dist/twilight/{p-bd7a418e.entry.js → p-ba723c9d.entry.js} +1 -1
- package/dist/twilight/{p-7818157c.entry.js → p-bd3ed9f5.entry.js} +1 -1
- package/dist/twilight/{p-cef440b0.entry.js → p-c3c51233.entry.js} +1 -1
- package/dist/twilight/{p-d0c9709f.entry.js → p-c52ad0b1.entry.js} +1 -1
- package/dist/twilight/{p-db802523.entry.js → p-cfa77298.entry.js} +1 -1
- package/dist/twilight/{p-2f4597e6.entry.js → p-d0e38089.entry.js} +1 -1
- package/dist/twilight/{p-c4bea50f.entry.js → p-d4035f22.entry.js} +1 -1
- package/dist/twilight/{p-375f007b.entry.js → p-d6dccd1f.entry.js} +1 -1
- package/dist/twilight/{p-3584002e.entry.js → p-d8510bea.entry.js} +1 -1
- package/dist/twilight/p-dbb2069c.entry.js +4 -0
- package/dist/twilight/{p-a1cd434a.entry.js → p-e8601f3e.entry.js} +1 -1
- package/dist/twilight/{p-69e3c48a.entry.js → p-e8b67cc3.entry.js} +1 -1
- package/dist/twilight/{p-d2992ac9.entry.js → p-ebc8b253.entry.js} +1 -1
- package/dist/twilight/{p-a22e6e33.entry.js → p-f5004752.entry.js} +1 -1
- package/dist/twilight/{p-8f0f02dc.entry.js → p-f8693f42.entry.js} +1 -1
- package/dist/twilight/{p-d51c988f.entry.js → p-fe2adfd8.entry.js} +1 -1
- package/dist/twilight/twilight.esm.js +1 -1
- package/dist/types/components/salla-bullet-delivery/helpers.d.ts +1 -3
- package/dist/types/components/salla-bullet-delivery/salla-bullet-delivery.d.ts +19 -16
- package/package.json +5 -5
- package/dist/twilight/p-1OAIxNJF.js +0 -9
- package/dist/twilight/p-916ea128.entry.js +0 -4
|
@@ -53,25 +53,6 @@ export const filterBranches = (branches, searchQuery) => {
|
|
|
53
53
|
const q = searchQuery.toLowerCase();
|
|
54
54
|
return branches.filter((b) => b.name.toLowerCase().includes(q) || b.city?.name?.toLowerCase().includes(q));
|
|
55
55
|
};
|
|
56
|
-
/** Match saved address to guest intent by city/district (and optional street). */
|
|
57
|
-
export function findMatchingAddress(guestIntent, userAddresses) {
|
|
58
|
-
const cityId = getIntentCityId(guestIntent);
|
|
59
|
-
const districtId = getIntentDistrictId(guestIntent);
|
|
60
|
-
return userAddresses.find((addr) => {
|
|
61
|
-
const addrCity = addr.city?.id ?? addr.city_id;
|
|
62
|
-
const addrDistrict = addr.district?.id ?? addr.district_id;
|
|
63
|
-
if (cityId == null || addrCity !== cityId)
|
|
64
|
-
return false;
|
|
65
|
-
if (districtId != null) {
|
|
66
|
-
if (addrDistrict !== districtId)
|
|
67
|
-
return false;
|
|
68
|
-
if (guestIntent.street && addr.street)
|
|
69
|
-
return guestIntent.street.toLowerCase() === addr.street.toLowerCase();
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
return true;
|
|
73
|
-
}) ?? null;
|
|
74
|
-
}
|
|
75
56
|
export const getIntentSubtitle = (intent, toAddress, fromBranch) => {
|
|
76
57
|
if (intent.type === 'branch') {
|
|
77
58
|
const loc = intent.branch_details?.city ?? intent.branch_details?.name;
|
|
@@ -100,7 +81,10 @@ export const hasSessionAddressIntent = (intent) => {
|
|
|
100
81
|
const city = getIntentCityId(intent);
|
|
101
82
|
const d = getIntentDistrictId(intent);
|
|
102
83
|
const code = getIntentCountryCode(intent);
|
|
103
|
-
|
|
84
|
+
const hasDistrictId = d != null && Number(d) !== 0;
|
|
85
|
+
const hasDistrictName = Boolean(intent.address_details?.district?.name?.trim());
|
|
86
|
+
const districtOk = !isSaudiArabia(code) || hasDistrictId || hasDistrictName;
|
|
87
|
+
return !!(c && city && districtOk);
|
|
104
88
|
};
|
|
105
89
|
export const requireRegionAndDistrictForSA = (countryCode, regionId, districtIdOrName) => !countryCode || !isSaudiArabia(countryCode)
|
|
106
90
|
? true
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { h, Host, } from "@stencil/core";
|
|
5
5
|
import { bulletDeliveryAPI, isSaudiArabia } from "./api-service";
|
|
6
|
-
import { findNearestBranch, filterBranches, formatWorkingHoursDisplay, getBranchFirstSlot,
|
|
6
|
+
import { findNearestBranch, filterBranches, formatWorkingHoursDisplay, getBranchFirstSlot, getGeolocationErrorMessage, getIntentSubtitle, getIntentCountryId, getIntentCountryCode, getIntentRegionId, getIntentCityId, getIntentDistrictId, getIntentBranchId, getIntentLatitude, getIntentLongitude, hasSessionAddressIntent, requireRegionAndDistrictForSA, buildAddressLocationPayloadFromSelection, } from "./helpers";
|
|
7
7
|
const BRANCH_SEARCH_DEBOUNCE_MS = 1000;
|
|
8
8
|
const GEOLOCATION_TIMEOUT = 10000;
|
|
9
9
|
import Store from "../../assets/svg/store3.svg";
|
|
@@ -20,22 +20,33 @@ import GetDirections from "../../assets/svg/get-directions.svg";
|
|
|
20
20
|
export class SallaBulletDelivery {
|
|
21
21
|
constructor() {
|
|
22
22
|
this.confirming = false;
|
|
23
|
+
this.pendingCartSubmitResolver = null;
|
|
24
|
+
this.pendingCartSubmitPromise = null;
|
|
25
|
+
this.cartSubmitConfirmationPending = false;
|
|
23
26
|
this.branchSearchDebounceTimer = null;
|
|
24
27
|
this.componentReady = false;
|
|
25
28
|
this.pendingOpen = false;
|
|
26
29
|
this.tabChanging = false;
|
|
27
30
|
this.intentStorageKey = "bullet_delivery_intent";
|
|
28
|
-
this.sessionShownKey = "
|
|
31
|
+
this.sessionShownKey = "bullet_delivery_shown";
|
|
32
|
+
this.incompleteIntentPromptKey = "bullet_delivery_incomplete_intent_prompted";
|
|
29
33
|
this.cartItemAddedEvent = "cart::item.added";
|
|
30
34
|
this.cartItemAddedHandler = null;
|
|
35
|
+
this.cartSubmittingHandler = null;
|
|
31
36
|
this.useCartEventApi = false;
|
|
37
|
+
this.authLoggedInHandler = null;
|
|
38
|
+
this.authLoggedOutHandler = null;
|
|
39
|
+
this.loginClosedHandler = null;
|
|
40
|
+
this.hasExplicitPreselectedIdsForOpen = false;
|
|
32
41
|
this.bulletDeliveryOpenHandler = (eventData) => {
|
|
33
42
|
this.preselectedAddressId = eventData?.preselected_address_id;
|
|
34
43
|
this.preselectedBranchId = eventData?.preselected_branch_id;
|
|
44
|
+
this.hasExplicitPreselectedIdsForOpen =
|
|
45
|
+
eventData?.preselected_address_id != null ||
|
|
46
|
+
eventData?.preselected_branch_id != null;
|
|
35
47
|
this.open();
|
|
36
48
|
};
|
|
37
49
|
this.closeHandler = null;
|
|
38
|
-
this.guestLoginSyncHandler = null;
|
|
39
50
|
/** True after saved addresses have been loaded (lazy: only when address tab is shown). */
|
|
40
51
|
this.savedAddressesLoaded = false;
|
|
41
52
|
// Core state
|
|
@@ -144,17 +155,9 @@ export class SallaBulletDelivery {
|
|
|
144
155
|
// Open modal immediately to show skeleton/loading state
|
|
145
156
|
this.modal.open();
|
|
146
157
|
try {
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
this.
|
|
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
|
+
this.isLoggedIn = !this.isGuestUser();
|
|
159
|
+
const savedIntent = this.cleanStaleGuestAddressIdIfNeeded(this.getStoredIntent());
|
|
160
|
+
this.applyPreselectedIdsFromIntent(savedIntent);
|
|
158
161
|
const hasStoredAddressIds = !this.isLoggedIn &&
|
|
159
162
|
savedIntent?.type === "address" &&
|
|
160
163
|
getIntentCountryId(savedIntent) != null &&
|
|
@@ -214,12 +217,17 @@ export class SallaBulletDelivery {
|
|
|
214
217
|
// Only hide loading after all data is loaded and UI is ready
|
|
215
218
|
this.loading = false;
|
|
216
219
|
this.modal?.stopLoading();
|
|
220
|
+
this.overrideScopeSwitchUI();
|
|
217
221
|
}
|
|
218
222
|
}
|
|
219
223
|
/**
|
|
220
224
|
* Closes the bullet delivery modal
|
|
221
225
|
*/
|
|
222
226
|
async close() {
|
|
227
|
+
// If submit flow is waiting and user dismissed the modal, release the pending gate.
|
|
228
|
+
if (this.cartSubmitConfirmationPending && !this.confirming) {
|
|
229
|
+
this.resolvePendingCartSubmit();
|
|
230
|
+
}
|
|
223
231
|
this.bulletDeliveryClosed.emit();
|
|
224
232
|
return this.modal?.close();
|
|
225
233
|
}
|
|
@@ -251,14 +259,87 @@ export class SallaBulletDelivery {
|
|
|
251
259
|
const rememberLastSession = Boolean(Salla.config.get("store.settings.bullet_delivery.settings.remember_last_session"));
|
|
252
260
|
return Salla.storage[rememberLastSession ? "store" : "session"];
|
|
253
261
|
}
|
|
262
|
+
getShownStorage() {
|
|
263
|
+
// Always session-scoped. `remember_last_session` applies to intent persistence only.
|
|
264
|
+
return Salla.storage.session;
|
|
265
|
+
}
|
|
254
266
|
getStoredIntent() {
|
|
255
267
|
return this.getIntentStorage().get(this.intentStorageKey);
|
|
256
268
|
}
|
|
269
|
+
isGuestUser() {
|
|
270
|
+
return String(Salla.config.get("user.type") ?? "guest") === "guest";
|
|
271
|
+
}
|
|
272
|
+
cleanStaleGuestAddressIdIfNeeded(intent) {
|
|
273
|
+
if (!this.isGuestUser() || intent?.type !== "address" || !intent.address_id)
|
|
274
|
+
return intent;
|
|
275
|
+
const cleaned = {
|
|
276
|
+
...intent,
|
|
277
|
+
address_id: undefined,
|
|
278
|
+
};
|
|
279
|
+
this.setStoredIntent(cleaned);
|
|
280
|
+
return cleaned;
|
|
281
|
+
}
|
|
282
|
+
applyPreselectedIdsFromIntent(intent) {
|
|
283
|
+
if (this.hasExplicitPreselectedIdsForOpen) {
|
|
284
|
+
this.hasExplicitPreselectedIdsForOpen = false;
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
this.preselectedAddressId = undefined;
|
|
288
|
+
this.preselectedBranchId = undefined;
|
|
289
|
+
if (this.isGuestUser()) {
|
|
290
|
+
if (intent?.type === "branch" && intent.branch_id) {
|
|
291
|
+
this.preselectedBranchId = intent.branch_id;
|
|
292
|
+
}
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
if (intent?.type === "address" && intent.address_id) {
|
|
296
|
+
this.preselectedAddressId = intent.address_id;
|
|
297
|
+
}
|
|
298
|
+
else if (intent?.type === "branch" && intent.branch_id) {
|
|
299
|
+
this.preselectedBranchId = intent.branch_id;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
hasIncompleteUserAddressIntent() {
|
|
303
|
+
if (this.isGuestUser())
|
|
304
|
+
return false;
|
|
305
|
+
const intent = this.getStoredIntent();
|
|
306
|
+
if (!intent || intent.type !== "address" || intent.address_id || !intent.address_details)
|
|
307
|
+
return false;
|
|
308
|
+
// Intent is an address without address_id; consider it "incomplete"
|
|
309
|
+
// only when it represents a valid session-style address.
|
|
310
|
+
return hasSessionAddressIntent(intent);
|
|
311
|
+
}
|
|
312
|
+
hasCompleteIntentForLoggedInUser() {
|
|
313
|
+
if (this.isGuestUser())
|
|
314
|
+
return false;
|
|
315
|
+
const intent = this.getStoredIntent();
|
|
316
|
+
if (!intent)
|
|
317
|
+
return false;
|
|
318
|
+
if (intent.type === "address")
|
|
319
|
+
return !!intent.address_id;
|
|
320
|
+
if (intent.type === "branch")
|
|
321
|
+
return !!intent.branch_id;
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
shouldPromptIncompleteIntentThisSession() {
|
|
325
|
+
const storage = this.getShownStorage();
|
|
326
|
+
return (this.hasIncompleteUserAddressIntent() &&
|
|
327
|
+
storage.get(this.incompleteIntentPromptKey) !== true);
|
|
328
|
+
}
|
|
329
|
+
markIncompleteIntentPrompted() {
|
|
330
|
+
this.getShownStorage().set(this.incompleteIntentPromptKey, true);
|
|
331
|
+
}
|
|
257
332
|
setStoredIntent(intent) {
|
|
258
333
|
this.getIntentStorage().set(this.intentStorageKey, intent);
|
|
334
|
+
this.overrideScopeSwitchUI();
|
|
259
335
|
}
|
|
260
|
-
|
|
261
|
-
|
|
336
|
+
clearBulletDeliveryStoredData() {
|
|
337
|
+
// Clear all bullet-delivery keys from both scopes to avoid stale state across auth transitions.
|
|
338
|
+
Salla.storage.session.remove(this.intentStorageKey);
|
|
339
|
+
Salla.storage.store.remove(this.intentStorageKey);
|
|
340
|
+
Salla.storage.session.remove(this.sessionShownKey);
|
|
341
|
+
Salla.storage.session.remove(this.incompleteIntentPromptKey);
|
|
342
|
+
this.overrideScopeSwitchUI();
|
|
262
343
|
}
|
|
263
344
|
/**
|
|
264
345
|
* Single prefill flow: load geography from stored intent and set selected location + form.
|
|
@@ -316,17 +397,23 @@ export class SallaBulletDelivery {
|
|
|
316
397
|
this.selectedDistrict = district;
|
|
317
398
|
}
|
|
318
399
|
}
|
|
400
|
+
// When district is captured as free text (or couldn't be matched), keep it in the text input state.
|
|
401
|
+
if (!this.selectedDistrict && districtName) {
|
|
402
|
+
this.districtName = districtName;
|
|
403
|
+
}
|
|
319
404
|
}
|
|
320
405
|
updateNewAddressForm(partial) {
|
|
321
406
|
this.newAddressForm = { ...this.newAddressForm, ...partial };
|
|
322
407
|
}
|
|
323
408
|
/** Whether allocation completed successfully this session (modal won't auto-open again). */
|
|
324
409
|
hasBeenShownThisSession() {
|
|
325
|
-
|
|
410
|
+
const storage = this.getShownStorage();
|
|
411
|
+
return storage.get(this.sessionShownKey) === true;
|
|
326
412
|
}
|
|
327
413
|
/** Mark allocation as completed this session (called only after allocateScope succeeds). */
|
|
328
414
|
markShownThisSession() {
|
|
329
|
-
|
|
415
|
+
const storage = this.getShownStorage();
|
|
416
|
+
storage.set(this.sessionShownKey, true);
|
|
330
417
|
}
|
|
331
418
|
async loadCountries(skipEagerSubFetch = false) {
|
|
332
419
|
const forBranch = this.activeTab === "branch";
|
|
@@ -523,110 +610,6 @@ export class SallaBulletDelivery {
|
|
|
523
610
|
this.loadingRegions = false;
|
|
524
611
|
}
|
|
525
612
|
}
|
|
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
613
|
emitHeaderContextUpdate(result, address, branch) {
|
|
631
614
|
let locationText = "";
|
|
632
615
|
if (result.type === "address") {
|
|
@@ -897,8 +880,21 @@ export class SallaBulletDelivery {
|
|
|
897
880
|
return false;
|
|
898
881
|
}
|
|
899
882
|
handleLogin() {
|
|
883
|
+
// Keep bullet-delivery flow in-place and avoid full page reload after login.
|
|
884
|
+
Salla.auth.setCanRedirect(false);
|
|
900
885
|
Salla.event.dispatch("bullet-delivery::close");
|
|
901
|
-
Salla.event.dispatch("login::open")
|
|
886
|
+
Salla.event.dispatch("login::open", Salla.url.is_page("cart")
|
|
887
|
+
? { withoutReload: true, source: "cart-submit" }
|
|
888
|
+
: { withoutReload: true, source: "bullet-delivery" });
|
|
889
|
+
}
|
|
890
|
+
resolvePendingCartSubmit() {
|
|
891
|
+
if (!this.pendingCartSubmitResolver)
|
|
892
|
+
return;
|
|
893
|
+
const resolve = this.pendingCartSubmitResolver;
|
|
894
|
+
this.pendingCartSubmitResolver = null;
|
|
895
|
+
this.pendingCartSubmitPromise = null;
|
|
896
|
+
this.cartSubmitConfirmationPending = false;
|
|
897
|
+
resolve();
|
|
902
898
|
}
|
|
903
899
|
buildIntentAddress() {
|
|
904
900
|
if (this.activeTab !== "address" ||
|
|
@@ -984,10 +980,8 @@ export class SallaBulletDelivery {
|
|
|
984
980
|
};
|
|
985
981
|
let selectedAddress;
|
|
986
982
|
let selectedBranchData;
|
|
987
|
-
let usedSessionAddress = false;
|
|
988
983
|
if (this.activeTab === "address") {
|
|
989
984
|
if (this.isLoggedIn && this.selectedSessionAddress) {
|
|
990
|
-
usedSessionAddress = true;
|
|
991
985
|
const savedAddress = await this.saveSessionAddressToProfile();
|
|
992
986
|
if (!savedAddress) {
|
|
993
987
|
Salla.notify?.error(Salla.lang.get("common.errors.error_occurred"));
|
|
@@ -1094,14 +1088,9 @@ export class SallaBulletDelivery {
|
|
|
1094
1088
|
}
|
|
1095
1089
|
// After allocation success: mark session so we don't show modal again this session
|
|
1096
1090
|
this.markShownThisSession();
|
|
1097
|
-
// After allocation success:
|
|
1098
|
-
//
|
|
1099
|
-
|
|
1100
|
-
this.removeStoredIntent();
|
|
1101
|
-
}
|
|
1102
|
-
else {
|
|
1103
|
-
this.setStoredIntent(result);
|
|
1104
|
-
}
|
|
1091
|
+
// After allocation success: persist latest intent so switch UI can always reflect
|
|
1092
|
+
// the selected address/branch once confirmed.
|
|
1093
|
+
this.setStoredIntent(result);
|
|
1105
1094
|
if (allocatedScopeId) {
|
|
1106
1095
|
await bulletDeliveryAPI.setDeliveryScope(allocatedScopeId);
|
|
1107
1096
|
}
|
|
@@ -1117,6 +1106,10 @@ export class SallaBulletDelivery {
|
|
|
1117
1106
|
this.confirmBtn?.stop();
|
|
1118
1107
|
this.close();
|
|
1119
1108
|
this.confirming = false;
|
|
1109
|
+
if (this.cartSubmitConfirmationPending) {
|
|
1110
|
+
this.resolvePendingCartSubmit();
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1120
1113
|
if (allocatedScopeId) {
|
|
1121
1114
|
const scope = Salla.storage.get("scope") || {};
|
|
1122
1115
|
let url = Salla.helpers.addParamToUrl("scope", allocatedScopeId);
|
|
@@ -1235,7 +1228,7 @@ export class SallaBulletDelivery {
|
|
|
1235
1228
|
} }, 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
1229
|
}
|
|
1237
1230
|
renderSelectLoader() {
|
|
1238
|
-
return (h("span", { class: "s-bullet-delivery-select-loader", "aria-hidden": "true" }, h("salla-
|
|
1231
|
+
return (h("span", { class: "s-bullet-delivery-select-loader", "aria-hidden": "true" }, h("salla-skeleton", { height: "16px", width: "16px" })));
|
|
1239
1232
|
}
|
|
1240
1233
|
renderLoadingLabel(label, htmlFor, isLoading = false, isRequired = true) {
|
|
1241
1234
|
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())));
|
|
@@ -1360,22 +1353,17 @@ export class SallaBulletDelivery {
|
|
|
1360
1353
|
if (!this.isLoggedIn)
|
|
1361
1354
|
return null;
|
|
1362
1355
|
if (this.loadingSavedAddresses) {
|
|
1363
|
-
return (h("div",
|
|
1356
|
+
return (h("div", { class: "s-bullet-delivery-addresses-list s-scrollbar" }, [1, 2, 3].map((v) => (h("div", { key: v, class: "s-bullet-delivery-address-item s-bullet-delivery-address-item--skeleton" }, h("salla-skeleton", { class: "s-bullet-delivery-skel-radio", height: "18px", width: "18px" }), h("salla-skeleton", { class: "s-bullet-delivery-skel-map", height: "36px", width: "36px" }), h("div", { class: "s-bullet-delivery-address-content" }, h("div", { class: "s-bullet-delivery-address-lines" }, h("salla-skeleton", { height: "18px", width: "72%" }), h("salla-skeleton", { height: "16px", width: "56%" }))))))));
|
|
1364
1357
|
}
|
|
1365
1358
|
const intent = this.getStoredIntent();
|
|
1366
1359
|
const hasSessionAddress = hasSessionAddressIntent(intent);
|
|
1367
|
-
const
|
|
1368
|
-
? [
|
|
1369
|
-
intent.address_details.district?.name,
|
|
1370
|
-
intent.address_details.city.name,
|
|
1371
|
-
intent.address_details.country.name,
|
|
1372
|
-
]
|
|
1360
|
+
const sessionLine1 = hasSessionAddress && intent?.address_details
|
|
1361
|
+
? [intent.address_details.city?.name, intent.address_details.country?.name]
|
|
1373
1362
|
.filter(Boolean)
|
|
1374
|
-
.join("، ") ||
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
].join(", ")
|
|
1363
|
+
.join("، ") || ""
|
|
1364
|
+
: "";
|
|
1365
|
+
const sessionLine2 = hasSessionAddress && intent?.address_details
|
|
1366
|
+
? (intent.address_details.district?.name ?? "").trim()
|
|
1379
1367
|
: "";
|
|
1380
1368
|
if (this.savedAddresses.length === 0 && !hasSessionAddress) {
|
|
1381
1369
|
return this.renderSavedAddressesEmptyState();
|
|
@@ -1383,8 +1371,8 @@ export class SallaBulletDelivery {
|
|
|
1383
1371
|
return (h("div", { class: "s-bullet-delivery-addresses-list s-scrollbar" }, hasSessionAddress &&
|
|
1384
1372
|
this.renderAddressRow({
|
|
1385
1373
|
key: "session-address",
|
|
1386
|
-
line1:
|
|
1387
|
-
line2:
|
|
1374
|
+
line1: sessionLine1,
|
|
1375
|
+
line2: sessionLine2,
|
|
1388
1376
|
selected: this.selectedSessionAddress,
|
|
1389
1377
|
onClick: () => this.handleSessionAddressSelect(),
|
|
1390
1378
|
}), this.savedAddresses.map((address) => {
|
|
@@ -1399,7 +1387,7 @@ export class SallaBulletDelivery {
|
|
|
1399
1387
|
]
|
|
1400
1388
|
.filter(Boolean)
|
|
1401
1389
|
.join("، ");
|
|
1402
|
-
const line2 = (
|
|
1390
|
+
const line2 = (address.formatted?.address_two || builtLine2) ?? "";
|
|
1403
1391
|
const inCoverage = address.is_in_coverage !== false;
|
|
1404
1392
|
return this.renderAddressRow({
|
|
1405
1393
|
key: String(address.id),
|
|
@@ -1447,7 +1435,7 @@ export class SallaBulletDelivery {
|
|
|
1447
1435
|
"s-bullet-delivery-location-btn": true,
|
|
1448
1436
|
"s-bullet-delivery-location-btn--full": true,
|
|
1449
1437
|
"s-bullet-delivery-location-btn--loading": this.loadingNearestBranch,
|
|
1450
|
-
}, onClick: () => this.handleFindNearestBranch(), disabled: this.loadingNearestBranch }, this.loadingNearestBranch ? (h("salla-
|
|
1438
|
+
}, onClick: () => this.handleFindNearestBranch(), disabled: this.loadingNearestBranch }, this.loadingNearestBranch ? (h("span", { class: "s-bullet-delivery-location-icon", "aria-hidden": "true" }, h("salla-skeleton", { height: "18px", width: "18px" }))) : (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))));
|
|
1451
1439
|
}
|
|
1452
1440
|
renderBranchList() {
|
|
1453
1441
|
if (this.loadingBranches) {
|
|
@@ -1517,10 +1505,14 @@ export class SallaBulletDelivery {
|
|
|
1517
1505
|
handleAfterAddToCart() {
|
|
1518
1506
|
if (this.openingType !== "after_add_to_cart")
|
|
1519
1507
|
return;
|
|
1520
|
-
|
|
1508
|
+
const canOpenForIncompleteIntent = this.shouldPromptIncompleteIntentThisSession();
|
|
1509
|
+
if (this.hasBeenShownThisSession() && !canOpenForIncompleteIntent)
|
|
1521
1510
|
return;
|
|
1522
1511
|
if (this.modal?.hasAttribute?.("visible"))
|
|
1523
1512
|
return;
|
|
1513
|
+
if (canOpenForIncompleteIntent) {
|
|
1514
|
+
this.markIncompleteIntentPrompted();
|
|
1515
|
+
}
|
|
1524
1516
|
this.open();
|
|
1525
1517
|
}
|
|
1526
1518
|
overrideScopeSwitchUI() {
|
|
@@ -1528,13 +1520,17 @@ export class SallaBulletDelivery {
|
|
|
1528
1520
|
const btn = document.querySelector('[onclick*="scopes"]');
|
|
1529
1521
|
if (!btn)
|
|
1530
1522
|
return;
|
|
1523
|
+
const hasIntentWithType = !!intent && (intent.type === "address" || intent.type === "branch");
|
|
1524
|
+
if (!hasIntentWithType) {
|
|
1525
|
+
btn.style.display = "none";
|
|
1526
|
+
btn.onclick = () => this.open();
|
|
1527
|
+
return;
|
|
1528
|
+
}
|
|
1531
1529
|
const trunc = (s, max) => s && s.length > max ? `${s.slice(0, max)}...` : (s ?? "");
|
|
1532
|
-
const label =
|
|
1533
|
-
? Salla.lang.get("common.
|
|
1534
|
-
:
|
|
1535
|
-
|
|
1536
|
-
: `${Salla.lang.get("mobile_app.strings.delivery")} ${Salla.lang.get("common.elements.to")} ${trunc(intent.address_details?.city?.name, 10)}`;
|
|
1537
|
-
btn.style.display = intent ? "" : "none";
|
|
1530
|
+
const label = intent.type === "branch"
|
|
1531
|
+
? `${Salla.lang.get("mobile_app.strings.pickup")} ${Salla.lang.get("common.elements.from")} ${trunc(intent.branch_details?.name, 20)}`
|
|
1532
|
+
: `${Salla.lang.get("mobile_app.strings.delivery")} ${Salla.lang.get("common.elements.to")} ${trunc(intent.address_details?.city?.name, 10)}`;
|
|
1533
|
+
btn.style.display = "inline-flex";
|
|
1538
1534
|
btn.onclick = () => this.open();
|
|
1539
1535
|
const span = btn.querySelector('span:not([class*="sicon"]):not([class*="icon"])');
|
|
1540
1536
|
if (span) {
|
|
@@ -1550,6 +1546,31 @@ export class SallaBulletDelivery {
|
|
|
1550
1546
|
await Salla.onReady();
|
|
1551
1547
|
try {
|
|
1552
1548
|
this.overrideScopeSwitchUI();
|
|
1549
|
+
this.cartSubmittingHandler = async () => {
|
|
1550
|
+
if (this.pendingCartSubmitPromise) {
|
|
1551
|
+
await this.pendingCartSubmitPromise;
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
// Logged-in users with a complete intent can continue checkout without re-prompting.
|
|
1555
|
+
if (this.hasCompleteIntentForLoggedInUser()) {
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
this.cartSubmitConfirmationPending = true;
|
|
1559
|
+
this.pendingCartSubmitPromise = new Promise((resolve) => {
|
|
1560
|
+
this.pendingCartSubmitResolver = resolve;
|
|
1561
|
+
if (this.isGuestUser()) {
|
|
1562
|
+
Salla.auth.setCanRedirect(false);
|
|
1563
|
+
Salla.event.dispatch("login::open", {
|
|
1564
|
+
withoutReload: true,
|
|
1565
|
+
source: "cart-submit",
|
|
1566
|
+
});
|
|
1567
|
+
return;
|
|
1568
|
+
}
|
|
1569
|
+
this.open();
|
|
1570
|
+
});
|
|
1571
|
+
await this.pendingCartSubmitPromise;
|
|
1572
|
+
};
|
|
1573
|
+
Salla.cart.event.onSubmitting(this.cartSubmittingHandler);
|
|
1553
1574
|
}
|
|
1554
1575
|
catch (e) {
|
|
1555
1576
|
console.warn("SallaBulletDelivery: overrideScopeSwitchUI failed", e);
|
|
@@ -1557,11 +1578,40 @@ export class SallaBulletDelivery {
|
|
|
1557
1578
|
Salla.event.on("bullet-delivery::open", this.bulletDeliveryOpenHandler);
|
|
1558
1579
|
this.closeHandler = this.close.bind(this);
|
|
1559
1580
|
Salla.event.on("bullet-delivery::close", this.closeHandler);
|
|
1560
|
-
// Listen for successful login to sync guest session to user profile (AC7)
|
|
1561
|
-
this.guestLoginSyncHandler = this.handleGuestToRegisteredSync.bind(this);
|
|
1562
|
-
Salla.event.on("login::success", this.guestLoginSyncHandler);
|
|
1563
|
-
Salla.event.on("auth::logged-in", this.guestLoginSyncHandler);
|
|
1564
1581
|
this.isRTL = Salla.config.get("theme.is_rtl");
|
|
1582
|
+
this.authLoggedInHandler = () => {
|
|
1583
|
+
if (this.cartSubmitConfirmationPending) {
|
|
1584
|
+
Salla.event.dispatch("login::close");
|
|
1585
|
+
if (this.hasCompleteIntentForLoggedInUser()) {
|
|
1586
|
+
this.resolvePendingCartSubmit();
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1589
|
+
if (!this.modal?.hasAttribute?.("visible")) {
|
|
1590
|
+
this.open();
|
|
1591
|
+
}
|
|
1592
|
+
return;
|
|
1593
|
+
}
|
|
1594
|
+
// Always prompt after login when intent is incomplete, regardless of prior prompted flags.
|
|
1595
|
+
if (!this.hasIncompleteUserAddressIntent())
|
|
1596
|
+
return;
|
|
1597
|
+
if (this.modal?.hasAttribute?.("visible"))
|
|
1598
|
+
return;
|
|
1599
|
+
this.open();
|
|
1600
|
+
};
|
|
1601
|
+
Salla.event.on("auth::logged.in", this.authLoggedInHandler);
|
|
1602
|
+
this.authLoggedOutHandler = () => {
|
|
1603
|
+
this.clearBulletDeliveryStoredData();
|
|
1604
|
+
};
|
|
1605
|
+
Salla.event.on("auth::logged.out", this.authLoggedOutHandler);
|
|
1606
|
+
this.loginClosedHandler = () => {
|
|
1607
|
+
// Guest cart-submit flow opens login first; if login is dismissed, unblock submit gate.
|
|
1608
|
+
if (!this.cartSubmitConfirmationPending || !this.isGuestUser())
|
|
1609
|
+
return;
|
|
1610
|
+
if (this.hasCompleteIntentForLoggedInUser())
|
|
1611
|
+
return;
|
|
1612
|
+
this.resolvePendingCartSubmit();
|
|
1613
|
+
};
|
|
1614
|
+
Salla.event.on("salla-login::closed", this.loginClosedHandler);
|
|
1565
1615
|
// Listen for add-to-cart events for 'after_add_to_cart' opening strategy (after salla is ready)
|
|
1566
1616
|
this.cartItemAddedHandler = () => this.handleAfterAddToCart();
|
|
1567
1617
|
if (typeof Salla.cart?.event?.onItemAdded === "function") {
|
|
@@ -1573,7 +1623,7 @@ export class SallaBulletDelivery {
|
|
|
1573
1623
|
}
|
|
1574
1624
|
}
|
|
1575
1625
|
render() {
|
|
1576
|
-
return (h(Host, { key: '
|
|
1626
|
+
return (h(Host, { key: '751566707c28202b5ccf4ecde28bfb09550ae886', class: "s-bullet-delivery" }, h("salla-modal", { key: '25a18755aa4aa85b55f08bb73829e30833ca5328', ref: (modal) => {
|
|
1577
1627
|
this.modal = modal;
|
|
1578
1628
|
}, 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())))));
|
|
1579
1629
|
}
|
|
@@ -1593,12 +1643,22 @@ export class SallaBulletDelivery {
|
|
|
1593
1643
|
if (!this.hasBeenShownThisSession()) {
|
|
1594
1644
|
this.open();
|
|
1595
1645
|
}
|
|
1646
|
+
else if (this.shouldPromptIncompleteIntentThisSession()) {
|
|
1647
|
+
this.markIncompleteIntentPrompted();
|
|
1648
|
+
this.open();
|
|
1649
|
+
}
|
|
1596
1650
|
break;
|
|
1597
1651
|
case "on_cart_click":
|
|
1598
1652
|
// Open automatically when user is on the cart page
|
|
1599
1653
|
if (Salla.url.is_page("cart")) {
|
|
1600
|
-
|
|
1654
|
+
const shown = this.getShownStorage().get(this.sessionShownKey) === true;
|
|
1655
|
+
if (!shown) {
|
|
1656
|
+
this.open();
|
|
1657
|
+
}
|
|
1658
|
+
else if (this.shouldPromptIncompleteIntentThisSession()) {
|
|
1659
|
+
this.markIncompleteIntentPrompted();
|
|
1601
1660
|
this.open();
|
|
1661
|
+
}
|
|
1602
1662
|
}
|
|
1603
1663
|
break;
|
|
1604
1664
|
case "after_add_to_cart":
|
|
@@ -1622,11 +1682,6 @@ export class SallaBulletDelivery {
|
|
|
1622
1682
|
Salla.event.off("bullet-delivery::close", this.closeHandler);
|
|
1623
1683
|
this.closeHandler = null;
|
|
1624
1684
|
}
|
|
1625
|
-
if (this.guestLoginSyncHandler) {
|
|
1626
|
-
Salla.event.off("login::success", this.guestLoginSyncHandler);
|
|
1627
|
-
Salla.event.off("auth::logged-in", this.guestLoginSyncHandler);
|
|
1628
|
-
this.guestLoginSyncHandler = null;
|
|
1629
|
-
}
|
|
1630
1685
|
if (this.cartItemAddedHandler) {
|
|
1631
1686
|
if (this.useCartEventApi && typeof Salla.cart?.event?.offItemAdded === "function") {
|
|
1632
1687
|
Salla.cart.event.offItemAdded(this.cartItemAddedHandler);
|
|
@@ -1636,6 +1691,27 @@ export class SallaBulletDelivery {
|
|
|
1636
1691
|
}
|
|
1637
1692
|
this.cartItemAddedHandler = null;
|
|
1638
1693
|
}
|
|
1694
|
+
if (this.cartSubmittingHandler) {
|
|
1695
|
+
if (typeof Salla.cart?.event?.offSubmitting === "function") {
|
|
1696
|
+
Salla.cart.event.offSubmitting(this.cartSubmittingHandler);
|
|
1697
|
+
}
|
|
1698
|
+
else {
|
|
1699
|
+
Salla.event.off("cart::submitting", this.cartSubmittingHandler);
|
|
1700
|
+
}
|
|
1701
|
+
this.cartSubmittingHandler = null;
|
|
1702
|
+
}
|
|
1703
|
+
if (this.authLoggedInHandler) {
|
|
1704
|
+
Salla.event.off("auth::logged.in", this.authLoggedInHandler);
|
|
1705
|
+
this.authLoggedInHandler = null;
|
|
1706
|
+
}
|
|
1707
|
+
if (this.authLoggedOutHandler) {
|
|
1708
|
+
Salla.event.off("auth::logged.out", this.authLoggedOutHandler);
|
|
1709
|
+
this.authLoggedOutHandler = null;
|
|
1710
|
+
}
|
|
1711
|
+
if (this.loginClosedHandler) {
|
|
1712
|
+
Salla.event.off("salla-login::closed", this.loginClosedHandler);
|
|
1713
|
+
this.loginClosedHandler = null;
|
|
1714
|
+
}
|
|
1639
1715
|
}
|
|
1640
1716
|
static get is() { return "salla-bullet-delivery"; }
|
|
1641
1717
|
static get originalStyleUrls() {
|