UNPKG

@salla.sa/twilight-components

Version:
276 lines (275 loc) • 10.9 kB
import { type EventEmitter } from "../../stencil-public-runtime"; import type { AddressCreatedEvent, Branch, BulletDeliveryConfirmedEvent, City, Country, District, HeaderContextUpdateEvent, IntentType, NewAddressFormData, Region, SavedAddress } from "./interfaces"; type ViewMode = "main" | "add-address"; /** * @slot footer - The bottom section of the component for custom actions. */ export declare class SallaBulletDelivery { private modal; private confirmBtn; private confirming; private pendingCartSubmitResolver; private pendingCartSubmitPromise; private cartSubmitConfirmationPending; private branchSearchDebounceTimer; private countrySearchTimer; private regionSearchTimer; private citySearchTimer; private districtSearchTimer; private citySearchCounter; private preselectedAddressId?; private preselectedBranchId?; private componentReady; private pendingOpen; private tabChanging; private readonly intentStorageKey; private readonly sessionShownKey; private readonly incompleteIntentPromptKey; private readonly cartItemAddedEvent; private cartItemAddedHandler; private cartSubmittingHandler; private useCartEventApi; private authLoggedInHandler; private authLoggedOutHandler; private loginClosedHandler; private hasExplicitPreselectedIdsForOpen; private bulletDeliveryOpenHandler; private closeHandler; private bulletDeliveryMobileSelectHandler; /** True after saved addresses have been loaded (lazy: only when address tab is shown). */ private savedAddressesLoaded; private isRTL; activeTab: IntentType; isLoggedIn: boolean; viewMode: ViewMode; countries: Country[]; regions: Region[]; cities: City[]; districts: District[]; loadingRegions: boolean; selectedCountry: Country | null; selectedRegion: Region | null; selectedCity: City | null; selectedDistrict: District | null; districtName: string; savedAddresses: SavedAddress[]; selectedSavedAddress: SavedAddress | null; /** True when user selected the session address (guest address from before login, not yet saved) */ selectedSessionAddress: boolean; branches: Branch[]; filteredBranches: Branch[]; selectedBranch: Branch | null; branchSearchQuery: string; loadingCountries: boolean; loadingCities: boolean; loadingDistricts: boolean; loadingBranches: boolean; loadingNearestBranch: boolean; locationError: string; savingAddress: boolean; loadingSavedAddresses: boolean; showCartWillBeClearedBanner: boolean; countrySearchQuery: string; regionSearchQuery: string; citySearchQuery: string; districtSearchQuery: string; searchingCountries: boolean; searchingRegions: boolean; searchingCities: boolean; searchingDistricts: boolean; displayedCountries: Country[]; displayedRegions: Region[]; displayedCities: City[]; displayedDistricts: District[]; /** Shown when scopes/allocation returns 422 (address outside delivery coverage). Only on delivery tab. */ allocationOutOfCoverageMessage: string | null; /** * SA add-address view: 'confirmed' = selected address box + description + confirm, 'full' = all form fields (after Edit). */ private static readonly INITIAL_ADDRESS_FORM; newAddressForm: NewAddressFormData; /** Whether to show delivery + pickup tabs. From store.shipping.support_pickup */ private get supportsPickup(); /** The modal opening strategy: 'first_visit' | 'on_cart_click' | 'after_add_to_cart' */ private get openingType(); /** Whether the modal is required (cannot be closed/skipped). From store.settings.bullet_delivery.settings.is_required */ private get isRequired(); private get isMobileApp(); /** * Emitted when the user confirms their selection */ bulletDeliveryConfirmed: EventEmitter<BulletDeliveryConfirmedEvent>; /** * Emitted when the modal is closed */ bulletDeliveryClosed: EventEmitter<void>; /** * Emitted when a new address is created */ addressCreated: EventEmitter<AddressCreatedEvent>; /** * Emitted to sync with the global header (Delivering to: [location]) */ headerContextUpdate: EventEmitter<HeaderContextUpdateEvent>; /** * Opens the bullet delivery modal */ open(): Promise<void>; /** * Closes the bullet delivery modal */ close(): Promise<HTMLElement>; private resetState; private getIntentStorage; private getShownStorage; private getStoredIntent; private isGuestUser; private cleanStaleGuestAddressIdIfNeeded; private applyPreselectedIdsFromIntent; private hasIncompleteUserAddressIntent; private hasCompleteIntentForLoggedInUser; /** * Authenticated users on the cart page must select/confirm an address before * they can dismiss the modal. */ private shouldForceNonClosable; private shouldPromptIncompleteIntentThisSession; private markIncompleteIntentPrompted; private setStoredIntent; private clearBulletDeliveryStoredData; /** * Single prefill flow: load geography from stored intent and set selected location + form. * Assumes this.countries is already loaded. No-op if no intent or no city in intent. */ private prefillAddressFromStoredIntent; private updateNewAddressForm; /** Whether allocation completed successfully this session (modal won't auto-open again). */ private hasBeenShownThisSession; /** Mark allocation as completed this session (called only after allocateScope succeeds). */ private markShownThisSession; private getIPLocationConfig; private loadCountries; private prefillFromIPLocation; private loadCities; private loadDistricts; private findPrefillDistrict; private loadBranches; private filterBranches; /** * Prefill form fields from session storage */ private prefillFromSessionStorage; private loadSavedAddresses; private applyCountryChange; private loadRegions; private emitHeaderContextUpdate; private handleBranchSearch; private static readonly DROPDOWN_SEARCH_DEBOUNCE_MS; private static readonly DROPDOWN_SEARCH_MIN_CHARS; private handleCountrySearch; private handleRegionSearch; private handleCitySearch; private handleDistrictSearch; private clearSearchTimers; private resetSearchState; private handleCountryDropdownClosed; private handleRegionDropdownClosed; private handleCityDropdownClosed; private handleDistrictDropdownClosed; private loadBranchesWithLocation; /** Locate nearest branch using device geolocation (branches tab only). */ private handleFindNearestBranch; private handleBranchSelect; private handleSavedAddressSelect; private handleSessionAddressSelect; /** Show delete confirmation UI for this address (do not call API yet). */ /** * Switch to add-address form (unified form). Preselects country from session when present. */ private handleAddNewAddress; private handleBackToAddressList; /** * Build address/location payload from guest-form state (same fields as add-address). */ private buildAddressLocationPayload; /** * Submit add-address form: create address via API then switch back to list. */ private handleSubmitAddAddress; private handleTabChange; private isConfirmDisabled; private handleLogin; private resolvePendingCartSubmit; private buildIntentAddress; private buildIntentAddressFromSaved; private buildIntentBranch; private buildAllocationConfirmedAddressData; /** * Build a minimal `BulletDeliveryAllocationConfirmedAddressData` from a mobile * payload (no full SavedAddress object available). Only used for the * `salla::bullet-delivery.allocation.confirmed` event so existing listeners * keep working with the same shape they get on desktop. */ private buildAllocationConfirmedAddressFromIntent; /** Synthesise a minimal `Branch` from a mobile branch intent. */ private buildBranchFromIntent; /** Reconstruct the equivalent `ScopeAllocationPayload` from a mobile result. */ private buildAllocationRequestFromIntent; /** * Apply a selection performed inside the mobile app's native sheet. * * Mirrors the post-allocation side-effects of `handleConfirm()` so the * webview ends up in the exact same state as if the user had confirmed via * our component on desktop: * 1. Sets `s-scope-allocation-*` headers for subsequent API calls. * 2. Persists allocation in `Salla.storage.scope` (single source of truth). * 3. Marks the modal as shown for this session and stores the intent so * delivery-promise / scope-switch UIs reflect the selection. * 4. Clears the API cache so cached data from the previous scope is gone. * 5. Dispatches `salla::bullet-delivery.allocation.confirmed`, * `bulletDeliveryConfirmed`, and the header-context update event so * every listener (header pill, cart view, etc.) syncs. * 6. Reloads the page so prices, availability, and cart reflect the * newly-selected scope (matches desktop behaviour). */ private applyMobileBulletDeliverySelection; private extractMobileSelectPayload; private handleConfirm; private getCartViewConfig; /** Creates the cart view DOM for mounting into cart.items.start hook */ private createCartViewElement; private renderTabs; private renderAlert; private renderAllocationOutOfCoverageAlert; private handleCountrySelected; private renderCountrySelect; private handleRegionSelected; /** Region select (SA only): shown when SA is selected; city and district disabled until region selected. */ private renderRegionSelect; private handleCitySelected; private handleDistrictSelected; private renderCityDistrictSelects; private renderSavedAddressesEmptyState; /** * Save session address (guest intent) to user profile. Returns the newly saved address or null. */ private saveSessionAddressToProfile; private renderSavedAddresses; private renderAddressRow; private renderGuestDeliveryForm; private renderDeliveryTab; private renderBranchSearch; private renderBranchList; private renderPickupTab; /** Add-address form: same fields as guest form (country, region, city, district) only. */ private renderAddAddressForm; private renderFooter; private renderMainView; private handleAfterAddToCart; private overrideScopeSwitchUI; componentWillLoad(): Promise<void>; render(): any; componentDidLoad(): void; disconnectedCallback(): void; } export {};