@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.
Files changed (248) hide show
  1. package/dist/cjs/{filepond-CJUBlGWZ.js → filepond-Dz0w3b0-.js} +1 -1
  2. package/dist/cjs/{filepond-plugin-file-poster-DzfdX-da.js → filepond-plugin-file-poster-Bc2hFAJm.js} +1 -1
  3. package/dist/cjs/{filepond-plugin-file-validate-size-aKEs_A1i.js → filepond-plugin-file-validate-size-D-ntIPdx.js} +1 -1
  4. package/dist/cjs/{filepond-plugin-file-validate-type-BBQOuEjF.js → filepond-plugin-file-validate-type-1TnSvBgD.js} +1 -1
  5. package/dist/cjs/{filepond-plugin-image-edit-Ce6fwF2W.js → filepond-plugin-image-edit-DGi3QY5x.js} +1 -1
  6. package/dist/cjs/{filepond-plugin-image-exif-orientation-BcFGamVd.js → filepond-plugin-image-exif-orientation-CzMQBbqX.js} +1 -1
  7. package/dist/cjs/{filepond-plugin-image-preview-DktpahDI.js → filepond-plugin-image-preview-D555a4un.js} +1 -1
  8. package/dist/cjs/{index-CfgN9bup.js → index--a5myRaH.js} +1 -1
  9. package/dist/cjs/{index-Dc8V4JzY.js → index-Oy30xVAt.js} +2 -2
  10. package/dist/cjs/loader.cjs.js +1 -1
  11. package/dist/cjs/salla-accordion-body_3.cjs.entry.js +1 -1
  12. package/dist/cjs/salla-accordion_6.cjs.entry.js +1 -1
  13. package/dist/cjs/salla-add-product-button_4.cjs.entry.js +1 -1
  14. package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
  15. package/dist/cjs/salla-alert_2.cjs.entry.js +1 -1
  16. package/dist/cjs/salla-app-install-alert.cjs.entry.js +1 -1
  17. package/dist/cjs/salla-apps-icons.cjs.entry.js +1 -1
  18. package/dist/cjs/salla-booking-field_7.cjs.entry.js +10 -10
  19. package/dist/cjs/salla-bullet-delivery.cjs.entry.js +248 -188
  20. package/dist/cjs/salla-cart-item-offers_2.cjs.entry.js +1 -1
  21. package/dist/cjs/salla-comment-form_8.cjs.entry.js +1 -1
  22. package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
  23. package/dist/cjs/salla-contacts.cjs.entry.js +1 -1
  24. package/dist/cjs/salla-cookies-bar.cjs.entry.js +1 -1
  25. package/dist/cjs/salla-count-down_2.cjs.entry.js +1 -1
  26. package/dist/cjs/salla-custom-fields.cjs.entry.js +1 -1
  27. package/dist/cjs/salla-filters-widget.cjs.entry.js +1 -1
  28. package/dist/cjs/salla-filters.cjs.entry.js +1 -1
  29. package/dist/cjs/salla-gifting.cjs.entry.js +1 -1
  30. package/dist/cjs/salla-hook.cjs.entry.js +1 -1
  31. package/dist/cjs/salla-infinite-scroll.cjs.entry.js +1 -1
  32. package/dist/cjs/salla-installment.cjs.entry.js +1 -1
  33. package/dist/cjs/salla-list-tile.cjs.entry.js +1 -1
  34. package/dist/cjs/salla-localization-modal.cjs.entry.js +1 -1
  35. package/dist/cjs/salla-login-modal.cjs.entry.js +1 -1
  36. package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +1 -1
  37. package/dist/cjs/salla-loyalty-program.cjs.entry.js +1 -1
  38. package/dist/cjs/salla-loyalty.cjs.entry.js +1 -1
  39. package/dist/cjs/salla-maintenance-alert.cjs.entry.js +1 -1
  40. package/dist/cjs/salla-menu.cjs.entry.js +1 -1
  41. package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
  42. package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +1 -1
  43. package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +1 -1
  44. package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +1 -1
  45. package/dist/cjs/salla-notification-item.cjs.entry.js +1 -1
  46. package/dist/cjs/salla-notifications.cjs.entry.js +1 -1
  47. package/dist/cjs/salla-offer-modal.cjs.entry.js +1 -1
  48. package/dist/cjs/salla-offer.cjs.entry.js +1 -1
  49. package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
  50. package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
  51. package/dist/cjs/salla-order-details.cjs.entry.js +1 -1
  52. package/dist/cjs/salla-order-summary.cjs.entry.js +1 -1
  53. package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
  54. package/dist/cjs/salla-orders.cjs.entry.js +1 -1
  55. package/dist/cjs/salla-payments.cjs.entry.js +1 -1
  56. package/dist/cjs/salla-placeholder.cjs.entry.js +1 -1
  57. package/dist/cjs/salla-price-range.cjs.entry.js +1 -1
  58. package/dist/cjs/salla-product-size-guide.cjs.entry.js +1 -1
  59. package/dist/cjs/salla-products-list.cjs.entry.js +1 -1
  60. package/dist/cjs/salla-products-slider.cjs.entry.js +1 -1
  61. package/dist/cjs/salla-progress-bar.cjs.entry.js +1 -1
  62. package/dist/cjs/salla-quick-order.cjs.entry.js +1 -1
  63. package/dist/cjs/salla-rating-modal.cjs.entry.js +1 -1
  64. package/dist/cjs/salla-scopes.cjs.entry.js +1 -1
  65. package/dist/cjs/salla-search.cjs.entry.js +1 -1
  66. package/dist/cjs/salla-skeleton.cjs.entry.js +1 -1
  67. package/dist/cjs/salla-slider.cjs.entry.js +1 -1
  68. package/dist/cjs/salla-social-share.cjs.entry.js +1 -1
  69. package/dist/cjs/salla-social.cjs.entry.js +1 -1
  70. package/dist/cjs/salla-tab-content_3.cjs.entry.js +1 -1
  71. package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
  72. package/dist/cjs/salla-tooltip.cjs.entry.js +1 -1
  73. package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
  74. package/dist/cjs/salla-user-menu.cjs.entry.js +1 -1
  75. package/dist/cjs/salla-user-profile.cjs.entry.js +1 -1
  76. package/dist/cjs/salla-user-settings.cjs.entry.js +1 -1
  77. package/dist/cjs/salla-verify.cjs.entry.js +1 -1
  78. package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
  79. package/dist/cjs/twilight.cjs.js +1 -1
  80. package/dist/cjs/{vanilla-picker-DR583jAq.js → vanilla-picker-BjBHEsil.js} +1 -1
  81. package/dist/collection/components/salla-bullet-delivery/helpers.js +4 -20
  82. package/dist/collection/components/salla-bullet-delivery/salla-bullet-delivery.js +244 -168
  83. package/dist/components/index.js +2 -2
  84. package/dist/components/salla-bullet-delivery.js +247 -187
  85. package/dist/esm/{filepond-BWifXQjU.js → filepond-BXxeKj-9.js} +1 -1
  86. package/dist/esm/{filepond-plugin-file-poster-Cwfa6rZE.js → filepond-plugin-file-poster-B5BTs5Ly.js} +1 -1
  87. package/dist/esm/{filepond-plugin-file-validate-size-BrX587rP.js → filepond-plugin-file-validate-size-_PyCg3tk.js} +1 -1
  88. package/dist/esm/{filepond-plugin-file-validate-type-CR3s_l2K.js → filepond-plugin-file-validate-type-uSrSfAxF.js} +1 -1
  89. package/dist/esm/{filepond-plugin-image-edit-DcaaNA7K.js → filepond-plugin-image-edit-Cke6iTN3.js} +1 -1
  90. package/dist/esm/{filepond-plugin-image-exif-orientation-BhT9UmOS.js → filepond-plugin-image-exif-orientation-DKLDaeeL.js} +1 -1
  91. package/dist/esm/{filepond-plugin-image-preview-nWsxKqF2.js → filepond-plugin-image-preview-KfxXXS81.js} +1 -1
  92. package/dist/esm/{index-DHu5e7PE.js → index-B2mHcqWp.js} +1 -1
  93. package/dist/esm/{index-CSCx8X8V.js → index-D4I5TLtE.js} +2 -2
  94. package/dist/esm/loader.js +2 -2
  95. package/dist/esm/salla-accordion-body_3.entry.js +1 -1
  96. package/dist/esm/salla-accordion_6.entry.js +1 -1
  97. package/dist/esm/salla-add-product-button_4.entry.js +1 -1
  98. package/dist/esm/salla-advertisement.entry.js +1 -1
  99. package/dist/esm/salla-alert_2.entry.js +1 -1
  100. package/dist/esm/salla-app-install-alert.entry.js +1 -1
  101. package/dist/esm/salla-apps-icons.entry.js +1 -1
  102. package/dist/esm/salla-booking-field_7.entry.js +10 -10
  103. package/dist/esm/salla-bullet-delivery.entry.js +248 -188
  104. package/dist/esm/salla-cart-item-offers_2.entry.js +1 -1
  105. package/dist/esm/salla-comment-form_8.entry.js +1 -1
  106. package/dist/esm/salla-conditional-offer.entry.js +1 -1
  107. package/dist/esm/salla-contacts.entry.js +1 -1
  108. package/dist/esm/salla-cookies-bar.entry.js +1 -1
  109. package/dist/esm/salla-count-down_2.entry.js +1 -1
  110. package/dist/esm/salla-custom-fields.entry.js +1 -1
  111. package/dist/esm/salla-filters-widget.entry.js +1 -1
  112. package/dist/esm/salla-filters.entry.js +1 -1
  113. package/dist/esm/salla-gifting.entry.js +1 -1
  114. package/dist/esm/salla-hook.entry.js +1 -1
  115. package/dist/esm/salla-infinite-scroll.entry.js +1 -1
  116. package/dist/esm/salla-installment.entry.js +1 -1
  117. package/dist/esm/salla-list-tile.entry.js +1 -1
  118. package/dist/esm/salla-localization-modal.entry.js +1 -1
  119. package/dist/esm/salla-login-modal.entry.js +1 -1
  120. package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
  121. package/dist/esm/salla-loyalty-program.entry.js +1 -1
  122. package/dist/esm/salla-loyalty.entry.js +1 -1
  123. package/dist/esm/salla-maintenance-alert.entry.js +1 -1
  124. package/dist/esm/salla-menu.entry.js +1 -1
  125. package/dist/esm/salla-metadata.entry.js +1 -1
  126. package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +1 -1
  127. package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +1 -1
  128. package/dist/esm/salla-multiple-bundle-product.entry.js +1 -1
  129. package/dist/esm/salla-notification-item.entry.js +1 -1
  130. package/dist/esm/salla-notifications.entry.js +1 -1
  131. package/dist/esm/salla-offer-modal.entry.js +1 -1
  132. package/dist/esm/salla-offer.entry.js +1 -1
  133. package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
  134. package/dist/esm/salla-order-details-options.entry.js +1 -1
  135. package/dist/esm/salla-order-details.entry.js +1 -1
  136. package/dist/esm/salla-order-summary.entry.js +1 -1
  137. package/dist/esm/salla-order-totals-card.entry.js +1 -1
  138. package/dist/esm/salla-orders.entry.js +1 -1
  139. package/dist/esm/salla-payments.entry.js +1 -1
  140. package/dist/esm/salla-placeholder.entry.js +1 -1
  141. package/dist/esm/salla-price-range.entry.js +1 -1
  142. package/dist/esm/salla-product-size-guide.entry.js +1 -1
  143. package/dist/esm/salla-products-list.entry.js +1 -1
  144. package/dist/esm/salla-products-slider.entry.js +1 -1
  145. package/dist/esm/salla-progress-bar.entry.js +1 -1
  146. package/dist/esm/salla-quick-order.entry.js +1 -1
  147. package/dist/esm/salla-rating-modal.entry.js +1 -1
  148. package/dist/esm/salla-scopes.entry.js +1 -1
  149. package/dist/esm/salla-search.entry.js +1 -1
  150. package/dist/esm/salla-skeleton.entry.js +1 -1
  151. package/dist/esm/salla-slider.entry.js +1 -1
  152. package/dist/esm/salla-social-share.entry.js +1 -1
  153. package/dist/esm/salla-social.entry.js +1 -1
  154. package/dist/esm/salla-tab-content_3.entry.js +1 -1
  155. package/dist/esm/salla-tiered-offer.entry.js +1 -1
  156. package/dist/esm/salla-tooltip.entry.js +1 -1
  157. package/dist/esm/salla-trust-badges.entry.js +1 -1
  158. package/dist/esm/salla-user-menu.entry.js +1 -1
  159. package/dist/esm/salla-user-profile.entry.js +1 -1
  160. package/dist/esm/salla-user-settings.entry.js +1 -1
  161. package/dist/esm/salla-verify.entry.js +1 -1
  162. package/dist/esm/salla-wallet.entry.js +1 -1
  163. package/dist/esm/twilight.js +2 -2
  164. package/dist/esm/{vanilla-picker-CQ4dQJev.js → vanilla-picker-CM1O2U8w.js} +1 -1
  165. package/dist/twilight/{p-713d20a2.entry.js → p-0127cd6e.entry.js} +1 -1
  166. package/dist/twilight/{p-47740515.entry.js → p-0476b736.entry.js} +1 -1
  167. package/dist/twilight/{p-3c669bb0.entry.js → p-0537ad3e.entry.js} +1 -1
  168. package/dist/twilight/{p-fcf342fd.entry.js → p-06e10077.entry.js} +1 -1
  169. package/dist/twilight/{p-b9496c6c.entry.js → p-08c37adc.entry.js} +1 -1
  170. package/dist/twilight/{p-58a203ef.entry.js → p-0e82b9cd.entry.js} +1 -1
  171. package/dist/twilight/{p-cc499b03.entry.js → p-12e9e619.entry.js} +1 -1
  172. package/dist/twilight/{p-4ba25464.entry.js → p-15732417.entry.js} +1 -1
  173. package/dist/twilight/{p-f58f83a1.entry.js → p-15c7e73a.entry.js} +1 -1
  174. package/dist/twilight/{p-7eb215ae.entry.js → p-181da663.entry.js} +1 -1
  175. package/dist/twilight/{p-eff84a35.entry.js → p-283727c3.entry.js} +1 -1
  176. package/dist/twilight/{p-76293bed.entry.js → p-28665675.entry.js} +1 -1
  177. package/dist/twilight/{p-c7f7c0fc.entry.js → p-29da0820.entry.js} +1 -1
  178. package/dist/twilight/{p-7c46f469.entry.js → p-2c5880fe.entry.js} +1 -1
  179. package/dist/twilight/{p-b851cdcd.entry.js → p-30bdeebc.entry.js} +1 -1
  180. package/dist/twilight/{p-b56db8c8.entry.js → p-33727c81.entry.js} +1 -1
  181. package/dist/twilight/{p-b4013078.entry.js → p-35bab511.entry.js} +1 -1
  182. package/dist/twilight/{p-f2b2e290.entry.js → p-37996e21.entry.js} +1 -1
  183. package/dist/twilight/{p-c8e6b463.entry.js → p-3a67bf02.entry.js} +1 -1
  184. package/dist/twilight/{p-c819a24b.entry.js → p-3cf6308d.entry.js} +1 -1
  185. package/dist/twilight/{p-20695fed.entry.js → p-408f439d.entry.js} +1 -1
  186. package/dist/twilight/{p-0bd2951c.entry.js → p-48db8cc1.entry.js} +1 -1
  187. package/dist/twilight/{p-d880213f.entry.js → p-4b34c403.entry.js} +1 -1
  188. package/dist/twilight/{p-759ea776.entry.js → p-4d80d014.entry.js} +1 -1
  189. package/dist/twilight/{p-55f08b09.entry.js → p-4ede0af7.entry.js} +1 -1
  190. package/dist/twilight/{p-ec07da81.entry.js → p-4f5c85b6.entry.js} +1 -1
  191. package/dist/twilight/{p-ddf4eb18.entry.js → p-503a0362.entry.js} +1 -1
  192. package/dist/twilight/{p-74fb528f.entry.js → p-5338f5de.entry.js} +1 -1
  193. package/dist/twilight/{p-54bdfaa1.entry.js → p-5bc80a29.entry.js} +1 -1
  194. package/dist/twilight/{p-e1baac53.entry.js → p-5bc914c3.entry.js} +1 -1
  195. package/dist/twilight/{p-7effdd10.entry.js → p-653b2dac.entry.js} +1 -1
  196. package/dist/twilight/{p-612e7ad0.entry.js → p-6a8ae21b.entry.js} +1 -1
  197. package/dist/twilight/{p-1d296b1e.entry.js → p-6b66894c.entry.js} +1 -1
  198. package/dist/twilight/{p-9d9fd6ea.entry.js → p-6c1eb2aa.entry.js} +1 -1
  199. package/dist/twilight/{p-0e364b43.entry.js → p-70799a42.entry.js} +1 -1
  200. package/dist/twilight/{p-2abc4a24.entry.js → p-72ebeb8b.entry.js} +1 -1
  201. package/dist/twilight/{p-c8c92bd6.entry.js → p-7424ba6e.entry.js} +1 -1
  202. package/dist/twilight/{p-bfdce729.entry.js → p-7a874935.entry.js} +1 -1
  203. package/dist/twilight/{p-4fd0fc2a.entry.js → p-7ac9fe96.entry.js} +1 -1
  204. package/dist/twilight/{p-27f38623.entry.js → p-7b18c9e0.entry.js} +1 -1
  205. package/dist/twilight/{p-d969e5f8.entry.js → p-89635370.entry.js} +1 -1
  206. package/dist/twilight/{p-54a45b62.entry.js → p-90dc7be8.entry.js} +1 -1
  207. package/dist/twilight/{p-e1d3b456.entry.js → p-91f1e6df.entry.js} +1 -1
  208. package/dist/twilight/{p-eb7a8a3f.entry.js → p-95afe7b9.entry.js} +1 -1
  209. package/dist/twilight/{p-2598b0e2.entry.js → p-9ac3d8e7.entry.js} +1 -1
  210. package/dist/twilight/{p-211ecdf8.entry.js → p-9b68f4f7.entry.js} +1 -1
  211. package/dist/twilight/{p-67440334.entry.js → p-9cf8788e.entry.js} +1 -1
  212. package/dist/twilight/{p-CNaBlSvx.js → p-BbjmfFRJ.js} +1 -1
  213. package/dist/twilight/{p-PTrxhb6X.js → p-BjbWnZaV.js} +1 -1
  214. package/dist/twilight/{p-jh2tazFy.js → p-Bm_ows1a.js} +1 -1
  215. package/dist/twilight/{p-CGbcJTo7.js → p-D339DoJY.js} +2 -2
  216. package/dist/twilight/{p-CSCx8X8V.js → p-D4I5TLtE.js} +1 -1
  217. package/dist/twilight/p-D_Ov4zes.js +9 -0
  218. package/dist/twilight/{p-CQE3hxmT.js → p-Dr8Bgm1u.js} +1 -1
  219. package/dist/twilight/{p-DVkH3hdE.js → p-OQFknQfe.js} +1 -1
  220. package/dist/twilight/{p-CrmdYuCr.js → p-Q1_LG8_l.js} +1 -1
  221. package/dist/twilight/{p-C3V6igTx.js → p-Ym28Ytut.js} +1 -1
  222. package/dist/twilight/{p-cdba6449.entry.js → p-a2b440ae.entry.js} +1 -1
  223. package/dist/twilight/{p-621ddaae.entry.js → p-a32e417b.entry.js} +1 -1
  224. package/dist/twilight/{p-8d8f3c5a.entry.js → p-a348dd40.entry.js} +1 -1
  225. package/dist/twilight/{p-71393e6a.entry.js → p-a56efe37.entry.js} +1 -1
  226. package/dist/twilight/{p-3ae26c18.entry.js → p-a751f592.entry.js} +1 -1
  227. package/dist/twilight/{p-bd7a418e.entry.js → p-ba723c9d.entry.js} +1 -1
  228. package/dist/twilight/{p-7818157c.entry.js → p-bd3ed9f5.entry.js} +1 -1
  229. package/dist/twilight/{p-cef440b0.entry.js → p-c3c51233.entry.js} +1 -1
  230. package/dist/twilight/{p-d0c9709f.entry.js → p-c52ad0b1.entry.js} +1 -1
  231. package/dist/twilight/{p-db802523.entry.js → p-cfa77298.entry.js} +1 -1
  232. package/dist/twilight/{p-2f4597e6.entry.js → p-d0e38089.entry.js} +1 -1
  233. package/dist/twilight/{p-c4bea50f.entry.js → p-d4035f22.entry.js} +1 -1
  234. package/dist/twilight/{p-375f007b.entry.js → p-d6dccd1f.entry.js} +1 -1
  235. package/dist/twilight/{p-3584002e.entry.js → p-d8510bea.entry.js} +1 -1
  236. package/dist/twilight/p-dbb2069c.entry.js +4 -0
  237. package/dist/twilight/{p-a1cd434a.entry.js → p-e8601f3e.entry.js} +1 -1
  238. package/dist/twilight/{p-69e3c48a.entry.js → p-e8b67cc3.entry.js} +1 -1
  239. package/dist/twilight/{p-d2992ac9.entry.js → p-ebc8b253.entry.js} +1 -1
  240. package/dist/twilight/{p-a22e6e33.entry.js → p-f5004752.entry.js} +1 -1
  241. package/dist/twilight/{p-8f0f02dc.entry.js → p-f8693f42.entry.js} +1 -1
  242. package/dist/twilight/{p-d51c988f.entry.js → p-fe2adfd8.entry.js} +1 -1
  243. package/dist/twilight/twilight.esm.js +1 -1
  244. package/dist/types/components/salla-bullet-delivery/helpers.d.ts +1 -3
  245. package/dist/types/components/salla-bullet-delivery/salla-bullet-delivery.d.ts +19 -16
  246. package/package.json +5 -5
  247. package/dist/twilight/p-1OAIxNJF.js +0 -9
  248. 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
- return !!(c && city && (!isSaudiArabia(code) || d));
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, findMatchingAddress, getGeolocationErrorMessage, getIntentSubtitle, getIntentCountryId, getIntentCountryCode, getIntentRegionId, getIntentCityId, getIntentDistrictId, getIntentBranchId, getIntentLatitude, getIntentLongitude, hasSessionAddressIntent, requireRegionAndDistrictForSA, buildAddressLocationPayloadFromSelection, } from "./helpers";
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 = "bullet_delivery_shown_this_session";
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
- // 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
+ 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
- removeStoredIntent() {
261
- this.getIntentStorage().remove(this.intentStorageKey);
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
- return !!Salla.storage.session.get(this.sessionShownKey);
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
- Salla.storage.session.set(this.sessionShownKey, true);
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: 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
- }
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-loading", { size: "16", width: "3" })));
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", null, h("salla-loading", { size: "md" })));
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 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
- ]
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
- intent.address_details.country.id,
1377
- intent.address_details.city.id,
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: sessionAddressTitle,
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 = (builtLine2 || address.formatted?.address_two) ?? "";
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-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))));
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
- if (this.hasBeenShownThisSession())
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 = !intent
1533
- ? Salla.lang.get("common.titles.shipping")
1534
- : intent.type === "branch"
1535
- ? `${Salla.lang.get("mobile_app.strings.pickup")} ${Salla.lang.get("common.elements.from")} ${trunc(intent.branch_details?.name, 20)}`
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: '5d79f6404692b4a68504770a54f46c9e5161e533', class: "s-bullet-delivery" }, h("salla-modal", { key: 'f123012f8593e20eeb14ebf59fc8dc5af9bbe12b', ref: (modal) => {
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
- Salla.storage.session.get(this.sessionShownKey) !== true &&
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() {