};\n oabSelectedCounterId?: number;\n isOABStoreSelected: boolean;\n}\n\nconst SidebarBoxStyled = styled(SideBarBox)`\n margin: 0;\n & .elc-sidebar-row-primary {\n border-top: 0;\n border-bottom: 1px solid;\n margin: 0;\n ${storeBoxTheme}\n }\n`;\n\nconst SelectedStoreIconWrapper = styled.div`\n position: relative;\n`;\nSelectedStoreIconWrapper.displayName = 'SelectedStoreIconWrapper';\n\nconst SelectedStoreIcon = styled(CheckCircleIcon)`\n position: absolute;\n right: ${ContentSpacing.space10};\n margin-top: ${ContentSpacing.space10};\n height: 24px;\n width: 24px;\n`;\n\nconst storeItemClassName = classnames('elc-store-item', 'js-store-item');\nconst selectedStoreItemClassName = classnames('elc-store-item-selected', 'js-store-item-selected');\n\n// eslint-disable-next-line @estee/elc-best-practice/uses-observer\nexport const StoreCard = ({\n store,\n selectedStoreId,\n onCardClicked,\n storeRefs,\n selectOABStore,\n deselectOABStore,\n isOABStoreSelected,\n oabSelectedCounterId,\n ...storeItemProps\n}: IStoreCard) => {\n const isStoreSelected = store.id === selectedStoreId;\n const oabStoreSelected = isOABStoreSelected && store.id === oabSelectedCounterId?.toString();\n const isOAB = store.config?.config?.isOAB;\n\n return (\n \n {isOAB && oabStoreSelected && (\n \n \n \n )}\n \n \n \n
\n );\n};\n\n// eslint-disable-next-line @estee/elc-best-practice/uses-observer\nexport const SkeletonStoreCard = () => (\n \n \n \n \n
\n);\n","import * as React from 'react';\nimport * as classNames from 'classnames';\nimport { Icon } from './Icon';\n\nexport interface ICheckCircleIconProps {\n className?: string;\n}\n\nconst CheckCircleIcon = (props: ICheckCircleIconProps) => {\n const className = classNames('elc-check-circle-icon', props.className);\n const image = `url(\"data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' preserveAspectRatio='none' fill='%23000000' stroke-width='1px' %3E%3Cpath d='M0 0h24v24H0z' fill='none' /%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z' /%3E%3C/svg%3E\")`;\n\n return ;\n};\n\nexport { CheckCircleIcon };\n","import { observer } from 'mobx-react';\nimport * as React from 'react';\nimport styled from 'styled-components';\nimport { observable } from 'mobx';\nimport { breakpoint } from '@estee/elc-base-theme';\nimport { defaultCardTheme, selectedCardTheme } from '~theme/default-theme';\nimport { Store } from '~domain/entities/Store';\nimport { SkeletonStoreCard, StoreCard } from './StoreCard';\nimport { IStoreInventoryMap } from '~repositories/StoresRepository';\nimport { FindInStore } from '~domain/entities/FindInStore';\nimport { withConfigContext } from '~context/ContextContainer';\nimport { UIMode } from '~interfaces/IStoresInterfaces';\nimport { diContainer } from '~setup/diContainer';\nimport serviceNames from '~setup/StoresService';\nimport { Config } from '~domain/entities/Config';\n\nconst StoreListWrapper = styled.div`\n ${(props: { storesCount: number; isLanding: boolean; isOAB: boolean }) => `\n height: ${props.storesCount ? (props.isOAB ? 'auto' : 320) : 0}px;\n ${breakpoint('desktop')`\n height: ${props.isLanding ? 500 : 320}px;\n `}\n `};\n ${breakpoint('desktop')`\n position: relative;\n overflow: auto;\n `};\n\n .elc-store-item {\n ${defaultCardTheme};\n a {\n box-shadow: none !important;\n }\n }\n\n .elc-store-item-selected {\n ${selectedCardTheme};\n a {\n box-shadow: none !important;\n }\n }\n`;\n\nconst storeListWrapperClassName = 'elc-store-list-wrapper js-store-list-wrapper';\nconst skeletonItemsAmount = 3;\n\nexport interface IStoreBaseList {\n storeInventoryMap: IStoreInventoryMap;\n findInStore: FindInStore;\n onPhoneClick(): void;\n onStoreInfoLinkClick(): void;\n oabSelectedStoreId?: number;\n oabSelectedCounterId?: number;\n}\n\nexport interface IStoresListWrapper extends IStoreBaseList {\n scrollToStore(selectedStoreId: string): void;\n storeRefs: { [index: string]: React.RefObject };\n showStoreListItemIcons?: boolean;\n selectedStoreId: string;\n stores: Store[];\n areNearbyStoresLoading: boolean;\n config?: { mode: UIMode };\n onStoreSelected(storeId: string, counterId?: string, isSelecting?: boolean): void;\n onStoreDeselected(counterId?: string, isSelecting?: boolean): void;\n isOABStoreSelected: boolean;\n}\n\n@withConfigContext(['mode'])\n@observer\nexport class StoresListWrapper extends React.Component {\n @observable public configService: Config;\n\n constructor(props: IStoresListWrapper) {\n super(props);\n\n this.configService = diContainer.get(serviceNames.config);\n }\n public componentDidUpdate(prevProps: IStoresListWrapper) {\n if (this.props.selectedStoreId !== prevProps.selectedStoreId) {\n this.props.scrollToStore(this.props.selectedStoreId);\n }\n }\n\n private toStoreCards = ({\n stores,\n storeRefs,\n selectedStoreId,\n oabSelectedStoreId,\n onStoreSelected,\n onStoreDeselected,\n ...storeItemProps\n }: IStoresListWrapper) =>\n stores.map((store: Store) => (\n \n ));\n\n private get isLanding() {\n return (\n !this.props.config || !this.props.config.mode || this.props.config.mode === 'LANDING'\n );\n }\n\n private get isOAB() {\n const { config } = this.configService;\n\n return config && config.isOAB;\n }\n\n private skeletonStoreCards = () => Array(skeletonItemsAmount).fill();\n\n public render() {\n const { stores } = this.props;\n\n const { oabSelectedCounterId } = this.configService.config;\n\n return (\n \n {this.props.areNearbyStoresLoading\n ? this.skeletonStoreCards()\n : this.toStoreCards({ ...this.props, oabSelectedCounterId })}\n \n );\n }\n}\n","import classnames from 'classnames';\nimport * as React from 'react';\nimport styled from 'styled-components';\nimport { Body1 } from '@estee/elc-typography';\nimport { ContentSpacing } from '@estee/elc-base-theme';\nimport { IProduct } from '~domain/entities/Product';\n\nconst descriptionClass = classnames('elc-fis-item-description', 'js-fis-item-description');\n\nconst nameClass = classnames('elc-fis-product-name', 'js-fis-product-name');\nconst productDetailsClass = classnames('elc-fis-product-details', 'js-fis-product-details');\nconst sizeClass = classnames('elc-fis-product-size', 'js-fis-product-size');\nconst priceClass = classnames('elc-fis-product-price', 'js-fis-product-price');\n\nconst Description = styled.div`\n flex: 1;\n padding: ${ContentSpacing.space12} 0;\n`;\nconst Name = styled(Body1)`\n margin-bottom: ${ContentSpacing.space4};\n`;\n\nconst ProductDetails = styled.div`\n display: flex;\n`;\n\nconst ItemDetail = styled(Body1)`\n padding-right: ${ContentSpacing.space12};\n\n [dir='rtl'] & {\n padding-left: ${ContentSpacing.space12};\n }\n`;\n\nexport interface IProductDescriptionProps {\n product: IProduct;\n}\n\nexport const ProductDescription = (props: IProductDescriptionProps) => (\n \n \n {props.product.name}\n \n \n {props.product.formattedPrice && (\n \n {props.product.formattedPrice}\n \n )}\n \n {props.product.size}\n \n \n \n);\n","import * as React from 'react';\nimport classnames from 'classnames';\nimport styled from 'styled-components';\nimport { ContentSpacing } from '@estee/elc-base-theme';\n\nconst Container = styled.div`\n width: 30%;\n margin-right: ${ContentSpacing.space12};\n cursor: pointer;\n position: relative;\n max-width: 200px;\n min-height: 80px;\n\n [dir='rtl'] & {\n margin-left: ${ContentSpacing.space12};\n }\n`;\n\nconst Image = styled.img`\n display: block;\n max-height: 100%;\n max-width: 100%;\n margin: auto;\n position: absolute;\n top: 0;\n bottom: 0;\n right: 0;\n left: 0;\n user-select: none;\n`;\n\nexport interface IImageProps {\n className?: string;\n thumb: string;\n alt?: string;\n}\n\nexport class ImageWrapper extends React.PureComponent {\n public render() {\n const { className, thumb, alt } = this.props;\n const imageClass = classnames(className, 'elc-cart-item-image', 'js-cart-item-image');\n\n return (\n \n \n \n );\n }\n}\n","import classnames from 'classnames';\nimport * as React from 'react';\nimport styled from 'styled-components';\nimport { observer } from 'mobx-react';\nimport { ContentSpacing } from '@estee/elc-base-theme';\nimport { ITranslationsCollection } from '@estee/elc-service';\nimport { lazyInject } from '~setup/diContainer';\nimport serviceNames from '~setup/StoresService';\nimport { ProductDescription } from './ProductDescription';\nimport { ImageWrapper } from './ImageWrapper';\nimport { ProductViewController } from '~controllers/ProductViewController';\n\nconst descriptionWrapperClass = classnames(\n 'elc-fis-product-description-wrapper',\n 'js-fis-product-description-wrapper'\n);\n\nconst ProductWrapper = styled.div`\n display: flex;\n flex: 1;\n flex-direction: row;\n padding: ${ContentSpacing.space12} 0;\n`;\n\nconst DescriptionWrapper = styled.div`\n display: flex;\n flex-direction: column;\n`;\n\nexport interface IFindInStoreProduct {\n className?: string;\n translations?: ITranslationsCollection;\n}\n\n@observer\nexport class FindInStoreProduct extends React.Component {\n @lazyInject(serviceNames.productViewController)\n private productViewController: ProductViewController;\n\n public async componentDidMount() {\n await this.productViewController.loaded();\n }\n\n render() {\n const productClass = classnames('elc-fis-product', 'js-fis-product', this.props.className);\n const { product } = this.productViewController.data;\n\n return product ? (\n \n \n \n \n \n \n ) : null;\n }\n}\n","import { IAddressSearch } from '~interfaces/IStoresInterfaces';\nimport { MapSearchInputViewContainer } from './maps/MapSearchInputViewContainer';\nimport { SearchIcon } from '@estee/elc-icons';\nimport { GoToDirectory } from './GoToDirectory';\nimport * as React from 'react';\nimport { SearchBox } from './StoresSidebar';\nimport classnames from 'classnames';\n\nconst storeSearchBoxClassName = classnames('elc-store-search-box', 'js-store-store-search-box');\n\ninterface IStoresSidebarSearchBox {\n placeholder: string;\n onAddressSelect(address: IAddressSearch): void;\n apiKey: string;\n onClick(): void;\n onLocationReset(): void;\n goToDirectoryLabel: string;\n mapRegion?: string;\n mapLanguage?: string;\n}\n\nexport const StoresSidebarSearchBox = ({\n apiKey,\n mapRegion,\n mapLanguage,\n goToDirectoryLabel,\n onAddressSelect,\n onClick,\n onLocationReset,\n placeholder\n}: IStoresSidebarSearchBox) => (\n \n }\n autoCompleteTypes={[]}\n region={mapRegion}\n language={mapLanguage}\n hasGeoLocation\n />\n\n \n \n);\n","import { IAddressSearch, UIMode } from '../interfaces/IStoresInterfaces';\nimport { Heading2 } from '@estee/elc-typography';\nimport { FindInStoreProduct } from './findInStore/FindInStoreProduct';\nimport { StoresSidebarSearchBox } from './StoresSidebarSearchBox';\nimport * as React from 'react';\nimport styled from 'styled-components';\nimport { ContentSpacing } from '@estee/elc-base-theme';\nimport classnames from 'classnames';\nimport { SideBarBox } from '@estee/elc-layouts';\nimport { storeBoxTheme } from '~theme/default-theme';\nimport { defaultUIMode } from '~constants/constants';\nimport { withConfigContext } from '~context/ContextContainer';\n\nexport const SidebarBoxStyled = styled(SideBarBox)`\n margin: 0;\n & .elc-sidebar-row-primary {\n border-top: 0;\n border-bottom: 1px solid;\n margin: 0;\n ${storeBoxTheme}\n }\n`;\n\nconst ResultFiltersSideBarBox = styled(SidebarBoxStyled)`\n .elc-toggle {\n display: flex;\n }\n\n .elc-toggle-item {\n margin-right: ${ContentSpacing.space16};\n\n [dir='rtl'] & {\n margin-right: 0;\n margin-left: ${ContentSpacing.space16};\n }\n }\n`;\n\nconst storeLocatorFilters = classnames('elc-store-locator-filters', 'js-store-locator-filters');\nconst storeSearchTitleClassName = classnames('elc-store-search-title', 'js-store-search-title');\n\ninterface ISidebarSearchResultsFilters {\n searchTitle: string;\n placeholder: string;\n onAddressSelect(address: IAddressSearch): void;\n onLocationReset(): void;\n apiKey: string;\n onClick(): void;\n goToDirectoryLabel: string;\n config?: { mode: UIMode };\n mapRegion?: string;\n mapLanguage?: string;\n}\n\nconst storesSearchTitleId = 'stores-search-title';\n\nexport const SidebarSearchResultsFilters = withConfigContext(['mode'])(\n ({\n apiKey,\n mapRegion,\n mapLanguage,\n goToDirectoryLabel,\n onAddressSelect,\n onLocationReset,\n onClick,\n placeholder,\n searchTitle,\n config\n }: ISidebarSearchResultsFilters) => {\n const mode = (config && config.mode) || defaultUIMode;\n\n return (\n \n \n {searchTitle}\n \n {mode === 'FIND_IN_STORE' && }\n \n \n );\n }\n);\n","import { Colors } from '@estee/elc-base-theme';\n\nexport const selectedSwitchTheme = Colors.black;\nexport const unselectedSwitchTheme = Colors.primary300;\nexport const circleColorTheme = Colors.white;\nexport const circleColorActiveTheme = Colors.primary100;\n","import * as classnames from 'classnames';\nimport * as React from 'react';\nimport { observer } from 'mobx-react';\nimport styled from 'styled-components';\nimport {\n selectedSwitchTheme,\n unselectedSwitchTheme,\n circleColorActiveTheme,\n circleColorTheme\n} from '../theme/default-theme';\n\nexport interface ISwitch {\n onToggle(toggled: boolean): void;\n isSelected: boolean;\n className?: string;\n unselectedColor?: string;\n selectedColor?: string;\n circleColor?: string;\n circleColorActive?: string;\n borderColor?: string;\n width?: number;\n padding?: number;\n title?: string;\n}\n\nexport interface IToggle {\n toggled: boolean;\n}\n\ninterface IPassedProps extends ISwitch, IToggle {}\n\nconst RoundSwitch = styled.div`\n display: flex;\n cursor: pointer;\n align-items: center;\n overflow: hidden;\n position: relative;\n transform: translate3d(0, 0, 0);\n background-color: ${props => props.unselectedColor};\n height: ${props => props.width && props.padding && props.width / 2}px;\n width: ${props => props.width}px;\n border-radius: ${props => props.width && props.padding && props.width / 4}px;\n padding: ${props => props.padding}px;\n border: 1px solid ${props => (props.toggled ? props.selectedColor : props.borderColor)};\n`;\n\nconst SwitchCircle = styled.div`\n z-index: 2;\n border-radius: 50%;\n box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.2);\n transition: transform 0.3s cubic-bezier(1, 0.19, 0.15, 0.7);\n transition-delay: 0.1s;\n background-color: ${props => props.circleColor};\n border: 1px solid ${props => props.borderColor};\n height: ${props => props.width && props.padding && props.width / 2 - props.padding * 2}px;\n width: ${props => props.width && props.padding && props.width / 2 - props.padding * 2}px;\n transform: ${props =>\n props.toggled\n ? `translateX(${props.width && props.padding && props.width - props.width / 2}px)`\n : 'translateX(0px)'};\n &:active {\n background-color: ${props => props.circleColorActive};\n }\n`;\n\nconst SwitchBackground = styled.div`\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background-image: radial-gradient(\n circle,\n ${props => props.selectedColor} 10%,\n transparent 10.01%\n );\n background-repeat: no-repeat;\n background-position: 50%;\n pointer-events: none;\n transition: transform 0.5s, opacity 0.3s ease;\n transform: ${props => (props.toggled ? 'scale(10, 10)' : 'scale(0, 0)')};\n opacity: ${props => (props.toggled ? 1 : 0)};\n position: absolute;\n z-index: 1;\n`;\n\n@observer\nexport class Switch extends React.Component {\n constructor(props: ISwitch) {\n super(props);\n\n this.state = {\n toggled: false\n };\n }\n\n public componentDidUpdate(previousProps: ISwitch, previousState: { toggled: boolean }) {\n if (previousProps.isSelected !== this.props.isSelected) {\n this.setState({\n toggled: this.props.isSelected\n });\n }\n }\n\n public toggle = () => {\n this.setState(\n state => ({ toggled: !state.toggled }),\n () => {\n this.props.onToggle(this.state.toggled);\n }\n );\n };\n\n public static defaultProps: Partial = {\n width: 40,\n padding: 1,\n circleColor: circleColorTheme,\n circleColorActive: circleColorActiveTheme,\n selectedColor: selectedSwitchTheme,\n unselectedColor: unselectedSwitchTheme\n };\n\n public render() {\n const switchClassName = classnames('elc-switch', 'js-switch', this.props.className);\n\n return (\n \n \n \n \n );\n }\n}\n","import { Body2 } from '@estee/elc-typography';\nimport { Switch } from '@estee/elc-switch';\nimport * as React from 'react';\nimport styled from 'styled-components';\nimport { Colors, ContentSpacing, breakpoint } from '@estee/elc-base-theme';\n\nconst OpenStoresSwitchContainer = styled.div`\n display: flex;\n flex-direction: row;\n align-items: center;\n padding: 0 ${ContentSpacing.space16} ${ContentSpacing.space8};\n ${breakpoint('desktop')`\n padding: 0 0 ${ContentSpacing.space8};\n `};\n\n .elc-body--2 {\n margin-right: ${ContentSpacing.space8};\n\n [dir='rtl'] & {\n margin-right: 0;\n margin-left: ${ContentSpacing.space8};\n }\n }\n\n .elc-switch {\n &[role='button'] {\n background-color: ${Colors.primary300};\n }\n .elc-switch-background {\n background-image: radial-gradient(circle, ${Colors.black} 10%, transparent 10.01%);\n }\n }\n\n [dir='rtl'] & {\n .elc-switch {\n padding-right: ${ContentSpacing.space4};\n &[aria-pressed='true'] {\n .elc-switch-circle {\n transform: translateX(-${ContentSpacing.space24});\n }\n }\n }\n }\n`;\n\ninterface IOpenStoresSwitch {\n openNowToggleLabel: string;\n onToggle(): void;\n isEnabled: boolean;\n}\n\nexport class OpenStoresSwitch extends React.Component {\n render() {\n const { openNowToggleLabel, onToggle, isEnabled } = this.props;\n\n return isEnabled ? (\n \n {openNowToggleLabel}\n \n \n ) : null;\n }\n}\n","import * as React from 'react';\nimport styled from 'styled-components';\nimport { translate, ITranslationsCollection } from '@estee/elc-service';\nimport { Body2 } from '@estee/elc-typography';\nimport { ArrowIcon } from '@estee/elc-icons';\nimport classnames from 'classnames';\nimport { ContentSpacing, breakpoint } from '@estee/elc-base-theme';\nimport { IStoresFilter } from '~domain/entities/StoresFilter';\nimport { CheckBox } from '@estee/elc-checkbox';\nimport { StoresFiltersViewController } from '~controllers/StoresFiltersViewController';\nimport { observer } from 'mobx-react';\nimport { withConfigContext } from '~context/ContextContainer';\nimport { UIMode } from '~interfaces/IStoresInterfaces';\n\nconst StoresFilterWrapper = styled.div`\n padding: 0 ${ContentSpacing.space16} ${ContentSpacing.space8};\n ${breakpoint('desktop')`\n padding: 0 0 ${ContentSpacing.space8};\n `};\n`;\n\nconst FilterToggleBoxHeader = styled.div`\n display: flex;\n flex-direction: row;\n align-items: center;\n cursor: pointer;\n outline: none;\n\n .elc-icon {\n margin: 0 ${ContentSpacing.space8} 0 2px;\n }\n`;\n\nconst FilterArrowIcon = styled(ArrowIcon)`\n width: 20px;\n height: 20px;\n transform: ${(props) => (props.isOpen ? 'rotate(270deg)' : 'rotate(90deg)')};\n`;\n\nconst FilterTitle = styled(Body2)`\n padding-right: ${ContentSpacing.space4};\n`;\n\nconst FiltersList = styled.ul`\n padding-left: ${ContentSpacing.space4};\n max-height: ${(props) => (props.isExpanded ? '200px' : '0')};\n overflow: hidden;\n`;\n\nexport interface IStoreFiltersProps {\n translations?: ITranslationsCollection;\n isEnabled: boolean;\n viewController: StoresFiltersViewController;\n config?: { mode: UIMode };\n}\n\nexport interface IFiltersList {\n isExpanded: boolean;\n}\n\ninterface IFilterArrowIcon {\n isOpen: boolean;\n}\n\n@withConfigContext(['mode'])\n@translate([\n 'filters',\n 'doorTypeAirportDutyFreeStore',\n 'doorTypeDepartmentStore',\n 'doorTypeDutyFreeStore',\n 'doorTypeFreeStandingStore',\n 'doorTypePopupStore'\n])\n@observer\nexport class StoresFilters extends React.Component {\n private get isLanding() {\n return (\n !this.props.config || !this.props.config.mode || this.props.config.mode === 'LANDING'\n );\n }\n\n public render() {\n const {\n filters,\n doorTypeAirportDutyFreeStore,\n doorTypeDepartmentStore,\n doorTypeDutyFreeStore,\n doorTypeFreeStandingStore,\n doorTypePopupStore\n } = this.props.translations as ITranslationsCollection;\n const { isEnabled } = this.props;\n\n const { onFiltersListClick, onFilterClick } = this.props.viewController;\n const {\n isFiltersListExpanded,\n numberOfActiveFilters,\n availableFilters,\n multiOptionFilters\n } = this.props.viewController.data;\n\n const doorTypeLabelMappings: { [key: string]: string } = {\n AP: doorTypeAirportDutyFreeStore,\n DS: doorTypeDepartmentStore,\n DF: doorTypeDutyFreeStore,\n FSS: doorTypeFreeStandingStore,\n POP: doorTypePopupStore\n };\n\n const arrowClassnames = classnames({\n 'elc-filter-arrow': !isFiltersListExpanded,\n 'elc-filter-arrow-expanded': isFiltersListExpanded\n });\n\n // For now, the only query that accepts filters is storesNearPoint\n return isEnabled && this.isLanding ? (\n \n \n \n {`${filters} (${numberOfActiveFilters})`}\n \n \n \n \n {availableFilters.map((filter: IStoresFilter) => {\n return filter.options.map((filterOption: string, index: number) => {\n return (\n \n );\n });\n })}\n \n \n ) : null;\n }\n}\n","import * as React from 'react';\nimport classnames from 'classnames';\nimport { OpenStoresSwitch } from './OpenStoresSwitch';\nimport styled from 'styled-components';\nimport {\n SkeletonStoresSearchResultMessage,\n StoresSearchResultMessage\n} from './StoresSearchResultMessage';\nimport { ContentSpacing, breakpoint } from '@estee/elc-base-theme';\nimport { StoresFilters } from './StoresFilters';\nimport { StoresFiltersViewController } from '~controllers/StoresFiltersViewController';\n\nconst ResultMessagesContainer = styled.div`\n display: flex;\n flex-direction: row;\n padding: ${ContentSpacing.space8} ${ContentSpacing.space16};\n ${breakpoint('desktop')`\n padding: 0;\n `};\n`;\n\nconst resultMessagesContainerClassName = classnames(\n 'elc-store-search-result-message-container',\n 'js-store-search-result-message-container'\n);\n\nexport interface IStoresCountInfoLine {\n openNowToggleLabel: string;\n storesCount: number;\n isLoading: boolean;\n geolocationPermissions(): Promise;\n filtersViewController: StoresFiltersViewController;\n}\n\nexport const StoresCountAndFilters = ({\n openNowToggleLabel,\n storesCount,\n isLoading,\n geolocationPermissions,\n filtersViewController\n}: IStoresCountInfoLine) => {\n const {\n data: { openNowEnabled, filtersEnabled, isOAB, numberOfActiveFilters },\n onOpenNowClick\n } = filtersViewController;\n\n return (\n <>\n \n \n \n {isLoading ? (\n \n ) : (\n 0}\n storesCount={storesCount}\n geolocationPermissions={geolocationPermissions}\n />\n )}\n \n >\n );\n};\n","import { observer } from 'mobx-react';\nimport { computed } from 'mobx';\nimport * as React from 'react';\nimport classnames from 'classnames';\nimport styled from 'styled-components';\nimport { IAddressSearch } from '~interfaces/IStoresInterfaces';\nimport { searchBoxTheme, bopisProductBasicInfoTheme } from '~theme/default-theme';\nimport { ContentSpacing, breakpoint } from '@estee/elc-base-theme';\nimport { StoresSidebarViewController } from '~controllers/StoresSidebarViewController';\nimport { Desktop, Mobile } from './common/MediaQueryWrappers';\nimport { StoresListWrapper } from './StoresListWrapper';\nimport { SidebarBoxStyled, SidebarSearchResultsFilters } from './SidebarSearchResultsFilters';\nimport { StoresCountAndFilters } from './StoresCountAndFilters';\nimport { INavigatorPosition } from '~repositories/UserLocationRepository';\nimport { ServiceView } from '@estee/elc-service';\nimport { PRODUCT_BASIC_INFO } from '@estee/elc-service-view-names';\nimport { serviceName } from '~constants/constants';\nimport { diContainer } from '~setup/diContainer';\nimport serviceNames from '~setup/StoresService';\n\nexport const SearchBox = styled.div`\n padding: ${ContentSpacing.space12} 0;\n ${searchBoxTheme};\n\n & .elc-remove-icon {\n width: ${ContentSpacing.space16};\n height: ${ContentSpacing.space16};\n }\n\n & .elc-google-address-input {\n padding-top: ${ContentSpacing.space6};\n padding-bottom: ${ContentSpacing.space6};\n line-height: ${ContentSpacing.space28};\n }\n\n & .elc-clear-input {\n margin-top: ${-ContentSpacing.space8};\n }\n`;\n\nconst ProductSizeAndPriceFonts = `\n font-size: 14px;\n ${breakpoint('desktop')`\n font-size: 10px;\n `};\n ${breakpoint('largeScreen')`\n font-size: 12px;\n `};\n`;\n\nconst ProductBasicInfoWrapper = styled.div`\n padding: ${ContentSpacing.space8} ${ContentSpacing.space20};\n ${bopisProductBasicInfoTheme};\n\n .elc-product-images-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 25%;\n img {\n /* Image's resolution */\n max-width: 100px;\n }\n }\n\n .elc-product-name-wrapper {\n display: flex;\n align-items: center;\n width: 50%;\n margin: 0;\n .elc-product-display-name {\n font-size: 16px;\n ${breakpoint('desktop')`\n font-size: 14px;\n `};\n ${breakpoint('largeScreen')`\n font-size: 16px;\n `};\n }\n }\n\n .elc-product-size-wrapper {\n width: 10%;\n align-items: center;\n justify-content: center;\n ${ProductSizeAndPriceFonts};\n .elc-product-size-label {\n display: none;\n }\n }\n\n .elc-product-price-row-wrapper {\n display: flex;\n align-items: center;\n margin: 0;\n width: 15%;\n justify-content: flex-end;\n ${ProductSizeAndPriceFonts};\n }\n`;\n\nconst searchResultClassName = classnames(\n 'elc-store-search-result-message',\n 'js-store-search-result-message'\n);\n\nexport interface IStoresSidebar {\n className?: string;\n showStoreListItemIcons?: boolean;\n showOpenNowToggle?: boolean;\n onAddressSelected(address: IAddressSearch): void;\n onLocationReset(position: INavigatorPosition): void;\n searchTitle: string;\n searchPlaceholderLabel: string;\n openNowToggleLabel: string;\n goToDirectoryLabel: string;\n viewController: StoresSidebarViewController;\n isLocationLoading: boolean;\n showBopisProduct: boolean;\n skuId?: string;\n showOabWidget?: boolean;\n virtualServicesEnabled?: boolean;\n oabSelectedStoreId?: number;\n oabSelectedCounterId?: number;\n onStoreSelectButtonClick?(counterId: string, isSelecting: boolean): void;\n onStoresCardClick?(counterId: string, isSelecting: boolean): void;\n isOABStoreSelected: boolean;\n nextButtonRef?: React.RefObject;\n}\n\n@observer\nexport class StoresSidebar extends React.Component {\n public async componentDidMount() {\n await this.props.viewController.loaded();\n }\n\n @computed\n private get storeRefs(): { [index: string]: React.RefObject } {\n const {\n data: { stores }\n } = this.props.viewController;\n\n return stores.reduce((acc: { [key: string]: React.RefObject }, store) => {\n acc[store.id] = React.createRef();\n\n return acc;\n }, {});\n }\n\n @computed\n get areNearbyStoresLoading() {\n const { isLocationLoading } = this.props;\n const {\n data: { areStoresLoading },\n isLoading\n } = this.props.viewController;\n\n return isLocationLoading || isLoading || areStoresLoading;\n }\n\n public scrollToStore(storeId: string) {\n const currentRef = this.storeRefs[storeId] ? this.storeRefs[storeId].current : null;\n currentRef &&\n currentRef.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n inline: 'start'\n });\n }\n\n private getBopisProduct() {\n const { skuId } = this.props;\n const bopisProductBasicInfoClassName = 'elc-bopis-modal-product-basic-info';\n\n return (\n \n \n \n );\n }\n\n private getStoresCountAndFilters() {\n const { openNowToggleLabel } = this.props;\n const {\n data: { stores, geolocationPermissions }\n } = this.props.viewController;\n\n return (\n \n );\n }\n\n public render() {\n const {\n searchPlaceholderLabel,\n searchTitle,\n goToDirectoryLabel,\n showBopisProduct,\n showOabWidget,\n virtualServicesEnabled,\n oabSelectedStoreId,\n oabSelectedCounterId,\n onStoreSelectButtonClick,\n isOABStoreSelected,\n nextButtonRef\n } = this.props;\n const {\n data: {\n stores,\n selectedStoreId,\n apiKey,\n findInStore,\n storeInventoryMap,\n mapRegion,\n mapLanguage\n },\n onStoreSelected,\n onStoreDeselected,\n onPhoneClick,\n onStoreInfoLinkClick,\n onGoToDirectoryClick\n } = this.props.viewController;\n\n const storesListItemProps = {\n onStoreSelected: onStoreSelected(nextButtonRef),\n stores,\n selectedStoreId,\n onPhoneClick,\n onStoreInfoLinkClick,\n findInStore,\n storeInventoryMap,\n showOabWidget,\n virtualServicesEnabled,\n oabSelectedStoreId,\n oabSelectedCounterId,\n onStoreSelectButtonClick,\n onStoreDeselected,\n isOABStoreSelected\n };\n\n return (\n <>\n {showBopisProduct && this.getBopisProduct()}\n \n \n \n {this.getStoresCountAndFilters()}\n \n \n {this.getStoresCountAndFilters()}\n \n >\n );\n }\n}\n","import * as React from 'react';\nimport { observer } from 'mobx-react';\nimport { ITranslationsCollection, translate } from '@estee/elc-service';\nimport { IMarker, StoresMapViewController } from '~controllers/StoresMapViewController';\nimport { Desktop, Mobile } from './common/MediaQueryWrappers';\nimport { SearchBox } from './StoresSidebar';\nimport { SearchIcon } from '@estee/elc-icons';\nimport styled from 'styled-components';\nimport { ContentSpacing, breakpoint } from '@estee/elc-base-theme';\nimport { mobileSearchBoxTheme } from '~theme/default-theme';\nimport { defaultMapsZoom } from '~constants/constants';\nimport { Heading6 } from '@estee/elc-typography';\nimport classnames from 'classnames';\nimport { MapViewContainer } from './maps/MapViewContainer';\nimport { MapSearchInputViewContainer } from './maps/MapSearchInputViewContainer';\nimport { IAddressSearch } from '~interfaces/IStoresInterfaces';\nimport { FindInStoreProduct } from './findInStore/FindInStoreProduct';\nimport { IMapPanPosition } from '../strategies/StoresLandingAddressSelectedStrategies';\nimport { INavigatorPosition } from '~repositories/UserLocationRepository';\n\nconst MobileSearchBoxTitle = styled(Heading6)`\n padding-bottom: ${ContentSpacing.space10};\n`;\n\nconst MobileSearchBox = styled(SearchBox)`\n z-index: 4;\n padding: ${ContentSpacing.space10} ${ContentSpacing.space24} ${ContentSpacing.space16}\n ${ContentSpacing.space24};\n ${mobileSearchBoxTheme};\n`;\n\nconst MapBox = styled.div`\n flex-grow: 1;\n flex-basis: 0;\n margin: 0 0 ${ContentSpacing.space8};\n ${breakpoint('desktop')`\n margin: 0;\n `}\n`;\n\nexport interface IStoresMap {\n translations?: ITranslationsCollection;\n onAddressSelected(address: IAddressSearch): void;\n onLocationReset(position: INavigatorPosition): void;\n onMarkerClick(markerId: string): void;\n showFindInStoreProduct?: boolean;\n viewController: StoresMapViewController;\n onMapPan(center: IMapPanPosition): Promise;\n}\n\n@translate(['enterAddressPlaceholder', 'findStore', 'findInStore'])\n@observer\nexport class StoresMapView extends React.Component {\n private onMarkerClick = async (marker: IMarker) => {\n await this.props.viewController.onMarkerClicked(marker);\n this.props.onMarkerClick(marker.id);\n };\n\n private onMapPan = async () => {\n const { viewController } = this.props;\n\n if (viewController.centerLocation) {\n await this.props.onMapPan(viewController.centerLocation);\n }\n };\n\n private getMap() {\n const {\n storesMap: { mapCenter },\n markers,\n config: { googleApiKey, coloredMap, mapRegion, mapLanguage }\n } = this.props.viewController.data;\n\n return (\n \n );\n }\n\n public render() {\n const { googleApiKey, mapRegion, mapLanguage } = this.props.viewController.data.config;\n const { onAddressSelected, onLocationReset, showFindInStoreProduct } = this.props;\n const { enterAddressPlaceholder, findStore, findInStore } = this.props\n .translations as ITranslationsCollection;\n const mobileStoreSearchBoxClassName = classnames(\n 'elc-mobile-store-search-box',\n 'js-mobile-store-search-box'\n );\n const mobileStoreSearchTitleClassName = classnames(\n 'elc-mobile-store-search-title',\n 'js-mobile-store-search-title'\n );\n\n return googleApiKey ? (\n <>\n \n \n \n {showFindInStoreProduct ? findInStore : findStore}\n \n {showFindInStoreProduct && }\n }\n placeholder={enterAddressPlaceholder}\n onAddressSelected={onAddressSelected}\n onLocationReset={onLocationReset}\n name=\"address\"\n apiKey={googleApiKey}\n defaultValue={''}\n language={mapLanguage}\n region={mapRegion}\n autoCompleteTypes={[]}\n hasGeoLocation\n />\n \n {this.getMap()}\n \n {this.getMap()}\n >\n ) : null;\n }\n}\n","import { Breadcrumbs } from '@estee/elc-breadcrumbs';\nimport { StoresTitle } from './StoresTitle';\nimport * as React from 'react';\nimport styled from 'styled-components';\nimport { layoutPageContentWidth } from '@estee/elc-base-theme';\nimport classnames from 'classnames';\nimport { ITranslationsCollection, translate } from '@estee/elc-service';\n\nconst BreadCrumbsContainer = styled.div`\n margin: 0 auto;\n position: relative;\n max-width: ${layoutPageContentWidth}px;\n`;\n\nconst breadcrumbsClassnames = classnames('elc-stores-breadcrumbs', 'js-stores-breadcrumbs');\nconst titleClassnames = classnames('sd-stores-landing-title');\n\ninterface IStoresLandingHeader {\n homeUrlRef: string;\n translations?: ITranslationsCollection;\n}\n\n@translate(['storeLocator', 'homeLabel', 'storesLandingTitle', 'storesLandingSubtitle'])\nexport class StoresLandingHeader extends React.Component {\n render() {\n const { homeLabel, storeLocator, storesLandingTitle, storesLandingSubtitle } =\n this.props.translations || {};\n\n return (\n <>\n \n \n \n \n >\n );\n }\n}\n","import * as React from 'react';\nimport styled from 'styled-components';\nimport { ServiceView } from '@estee/elc-service';\nimport { PRODUCT_CTA } from '@estee/elc-service-view-names';\nimport { Desktop, Mobile } from './common/MediaQueryWrappers';\nimport { ContentSpacing } from '@estee/elc-base-theme';\nimport { serviceName } from '../../constants/constants';\n\ninterface IBopisFooter {\n skuId: string | undefined;\n}\n\nconst bopisDefaultAddToBagQuantity = 1;\nconst addToBagClassName = 'elc-bopis-modal-add-to-bag';\nconst desktopFooterClassName = 'elc-desktop-bopis-modal-footer';\nconst mobileFooterClassName = 'elc-mobile-bopis-modal-footer';\n\nconst AddToBagServiceView = ({ skuId }: IBopisFooter) => (\n \n);\n\nconst Footer = styled.div`\n display: flex;\n height: ${ContentSpacing.space80};\n align-items: center;\n`;\n\nconst AddToBagWrapper = styled.div`\n width: 25%;\n margin-left: 5%;\n`;\n\nconst MobileWrapper = styled.div`\n margin: ${ContentSpacing.space8};\n`;\n\nexport const BopisFooter = ({ skuId }: IBopisFooter) => (\n <>\n \n \n \n \n \n \n \n \n >\n);\n","import * as React from 'react';\nimport styled from 'styled-components';\nimport { Button } from '@estee/elc-buttons';\nimport { ContentSpacing, layoutPageContentWidth } from '@estee/elc-base-theme';\nimport classnames from 'classnames';\n\nexport interface IOABNextButton {\n storesNextLabel: string;\n isSelected: boolean;\n onClick(): void;\n reference?: React.RefObject;\n}\n\nconst NextButtonWrapper = styled.div`\n max-width: ${layoutPageContentWidth}px;\n padding-bottom: ${ContentSpacing.space12};\n padding-top: ${ContentSpacing.space28};\n margin: 0 auto;\n text-align: right;\n`;\nNextButtonWrapper.displayName = 'NextButtonWrapper';\n\nconst NextButton = styled(Button)`\n margin-bottom: ${ContentSpacing.space16};\n max-width: 380px;\n width: 100%;\n`;\n\nexport class OABNextButton extends React.Component {\n public render() {\n const { isSelected, onClick, storesNextLabel, reference } = this.props;\n const buttonClassname = classnames({\n 'elc-store-next-button': isSelected,\n 'elc-store-next-button-disabled': !isSelected\n });\n\n return (\n \n \n {storesNextLabel}\n \n \n );\n }\n}\n","import * as React from 'react';\nimport styled from 'styled-components';\nimport { ContentSpacing } from '@estee/elc-base-theme';\nimport { Body2 } from '@estee/elc-typography';\n\nconst VirtualOnlineAppointmentBookingInfoContainer = styled.div`\n display: flex;\n justify-content: flex-start;\n`;\n\nconst VirtualOnlineAppointmentBookingInfoLine = styled(Body2)`\n margin-bottom: ${ContentSpacing.space4};\n`;\nexport interface IVirtualOnlineAppointmentBookingInfoLine {\n description: string;\n}\n\nexport const VirtualOnlineAppointBookingInfoLine = ({\n description\n}: IVirtualOnlineAppointmentBookingInfoLine) => (\n \n \n {description}\n \n \n);\n","import * as React from 'react';\nimport { ITranslationsCollection, translate } from '@estee/elc-service';\nimport styled from 'styled-components';\nimport { VirtualOnlineAppointBookingInfoLine } from './VirtualOnlineAppointmentBookingInfoLine';\nimport { ContentSpacing, breakpoint } from '@estee/elc-base-theme';\nimport { OutlinedButton } from '@estee/elc-buttons';\nimport { SideBarBox } from '@estee/elc-layouts';\nimport { storeBoxTheme } from '~theme/default-theme';\n\nconst VirtualOnlineAppointmentBookingContainer = styled(SideBarBox)`\n padding: ${ContentSpacing.space16} 0;\n flex-direction: column;\n align-items: stretch;\n ${breakpoint('desktop')`\n flex-direction: row;\n justify-content: space-between;\n `};\n .elc-sidebar-row-primary {\n border-top: 0;\n border-bottom: 1px solid;\n margin: 0;\n ${storeBoxTheme}\n }\n .elc-grid-column {\n display: flex;\n }\n`;\n\nconst OutlinedButtonStyled = styled(OutlinedButton)`\n height: ${ContentSpacing.space36};\n line-height: ${ContentSpacing.space36};\n min-width: ${ContentSpacing.space60};\n margin-right: ${ContentSpacing.space4};\n padding: 0;\n`;\n\ninterface IVirtualOnlineAppointmentBooking {\n translations?: ITranslationsCollection;\n onVirtualAppointmentClick(): void;\n}\n\nexport const VirtualOnlineAppointmentBooking = translate([\n 'bookAVirtualAppointment',\n 'goToVirtualAppointmentBooking'\n])(({ translations, onVirtualAppointmentClick }: IVirtualOnlineAppointmentBooking) => {\n const {\n bookAVirtualAppointment,\n goToVirtualAppointmentBooking\n } = translations as ITranslationsCollection;\n\n return (\n \n \n \n {goToVirtualAppointmentBooking}\n \n \n );\n});\n","import { observer } from 'mobx-react';\nimport * as React from 'react';\nimport classnames from 'classnames';\nimport { StoresMapView } from '~views/StoresMapView';\nimport { IStoresMapConfig, UIMode } from '~interfaces/IStoresInterfaces';\nimport { StoresSidebar } from '~views/StoresSidebar';\nimport { LandscapeSidebarLayout } from '@estee/elc-layouts';\nimport { StoresViewController } from '~controllers/StoresViewController';\nimport { storeRowTheme } from '~theme/default-theme';\nimport styled from 'styled-components';\nimport { ContentSpacing } from '@estee/elc-base-theme';\nimport { ITranslationsCollection, translate } from '@estee/elc-service';\nimport { Desktop, Mobile } from '~views/common/MediaQueryWrappers';\nimport { diContainer } from '~setup/diContainer';\nimport serviceNames from '~setup/StoresService';\nimport { StoresTitle } from '~views/StoresTitle';\nimport { StoresLandingHeader } from '~views/StoresLandingHeader';\nimport { BopisFooter } from '~views/BopisFooter';\nimport { withConfigContext } from '~context/ContextContainer';\nimport { OABNextButton } from '~views/OABNextButton';\nimport { VirtualOnlineAppointmentBooking } from '~views/VirtualOnlineAppointmentBooking';\n\nexport interface IStoresLocatorConfig extends IStoresMapConfig {\n mode?: UIMode;\n skuId?: string;\n showOabWidget?: boolean;\n virtualServicesEnabled?: boolean;\n virtualCounterHasTimeSlots?: boolean;\n isOAB?: boolean;\n oabSelectedStoreId?: number;\n oabSelectedCounterId?: number;\n onStoreSelectButtonClick?(counterId: string, isSelecting: boolean): void;\n onStoresCardClick?(counterId: string, isSelecting: boolean): void;\n}\nexport interface IStoresLanding {\n config: IStoresLocatorConfig;\n className?: string;\n translations?: ITranslationsCollection;\n viewController: StoresViewController;\n}\n\nconst StyledLandscapeSidebarLayout = styled(LandscapeSidebarLayout)`\n &.elc-sidebar-row-primary {\n ${storeRowTheme};\n }\n`;\n\ninterface IMobileWrapper {\n isOAB: boolean;\n}\n\nconst MobileWrapper = styled.div`\n display: flex;\n flex-direction: column;\n margin: ${({ isOAB }: IMobileWrapper) => (isOAB ? '0 20px' : 'unset')};\n`;\n\ninterface IDesktopWrapper {\n isLanding: boolean;\n}\n\nconst ContentSpacing112 = `${ContentSpacing.space100} + ${ContentSpacing.space12}`;\n\nconst DesktopWrapper = styled.div`\n padding-bottom: calc(\n ${({ isLanding }: IDesktopWrapper) => (isLanding ? ContentSpacing112 : 0)}\n );\n`;\n\nconst MapBox = styled.div`\n height: 60vh;\n display: flex;\n flex-direction: column;\n`;\n\nconst ListBox = styled.div`\n flex: 1;\n overflow-y: ${({ isOAB }: IMobileWrapper) => (isOAB ? 'unset' : 'auto')};\n`;\n\n@withConfigContext(['mode', 'showGeolocationResetButton'])\n@translate([\n 'locations',\n 'searchPlaceholder',\n 'findStore',\n 'openNow',\n 'findInStore',\n 'goToDirectoryLabel',\n 'storesLandingTitle',\n 'storesLandingSubtitle',\n 'chooseAStore',\n 'storesNext'\n])\n@observer\nexport class StoresView extends React.Component {\n private storesSidebarRef: React.RefObject;\n private nextStepMobileRef: React.RefObject;\n public static displayName: string;\n\n constructor(props: IStoresLanding) {\n super(props);\n this.storesSidebarRef = React.createRef();\n this.nextStepMobileRef = React.createRef();\n }\n\n public async componentDidMount() {\n const { isOAB, oabSelectedStoreId, onStoreSelectButtonClick } = this.props.config;\n const { counterId, updateSelectedStore } = this.props.viewController;\n const serviceConfig = diContainer.get(serviceNames.config);\n serviceConfig.updateConfig({ isOAB, oabSelectedStoreId, onStoreSelectButtonClick });\n if (counterId !== String(oabSelectedStoreId)) {\n updateSelectedStore();\n }\n await this.props.viewController.loaded(this.props.config);\n }\n\n private get isFindInStore() {\n return this.props.config.mode === 'FIND_IN_STORE';\n }\n\n private get isLanding() {\n return !this.props.config.mode || this.props.config.mode === 'LANDING';\n }\n\n private get isBopis() {\n return this.props.config.mode === 'BOPIS';\n }\n\n private get isOAB() {\n return this.props.config.isOAB;\n }\n\n private onMapMarkerClick = (storeId: string) => {\n if (this.storesSidebarRef.current) {\n this.storesSidebarRef.current.scrollToStore(storeId);\n }\n };\n\n private get searchTitle() {\n const { findInStore, chooseAStore, findStore } = this.props\n .translations as ITranslationsCollection;\n if (this.isFindInStore) {\n return findInStore;\n }\n if (this.isOAB) {\n return chooseAStore;\n }\n\n return findStore;\n }\n\n private getSidebar(nextButtonRef?: React.RefObject) {\n const {\n showStoreListItemIcons,\n virtualServicesEnabled = false,\n showOabWidget,\n oabSelectedStoreId,\n oabSelectedCounterId,\n onStoreSelectButtonClick\n } = this.props.config;\n const { config: configService } = this.props.viewController.data;\n const { searchPlaceholder, openNow, goToDirectoryLabel } = this.props\n .translations as ITranslationsCollection;\n const { isSelecting } = this.props.viewController;\n const showBopisProduct = this.isBopis;\n\n return (\n \n );\n }\n\n private getMapView() {\n return (\n \n );\n }\n\n private getBopisFooter() {\n const { skuId } = this.props.config;\n\n return ;\n }\n\n private get displayVirtualOabWidget() {\n const {\n virtualServicesEnabled,\n showOabWidget,\n virtualCounterHasTimeSlots\n } = this.props.config;\n\n const displayability = {\n inStoreLocator: !this.isOAB && this.isLanding && showOabWidget,\n inOab: this.isOAB && virtualServicesEnabled\n };\n\n return (\n (displayability.inOab || displayability.inStoreLocator) && virtualCounterHasTimeSlots\n );\n }\n\n public render() {\n const { storesLandingTitle, storesLandingSubtitle, storesNext } = this.props\n .translations as ITranslationsCollection;\n\n const storeLocatorClassNames = classnames('elc-stores', 'js-stores', this.props.className);\n\n const titleClassnames = classnames('sd-stores-landing-title');\n const { isSelecting, counterId } = this.props.viewController;\n\n const { homeUrl } = this.props.viewController.data.breadcrumbsUrls;\n const onVirtualOnlineAppoinmentClick = this.props.viewController\n .onVirtualOnlineAppoinmentClick;\n\n return (\n <>\n \n \n {!this.isOAB && this.isLanding && (\n \n )}\n \n {this.displayVirtualOabWidget && (\n \n )}\n {this.getMapView()}\n \n {this.isOAB && (\n \n this.props.config?.onStoreSelectButtonClick?.(\n counterId,\n isSelecting\n )\n }\n />\n )}\n {this.isBopis && this.getBopisFooter()}\n \n \n \n \n {!this.isOAB && (\n \n )}\n {this.displayVirtualOabWidget && (\n \n )}\n {this.getMapView()}\n \n {this.getSidebar(this.nextStepMobileRef)}\n \n {this.isOAB && (\n \n this.props.config?.onStoreSelectButtonClick?.(\n counterId,\n isSelecting\n )\n }\n />\n )}\n {this.isBopis && this.getBopisFooter()}\n \n \n >\n );\n }\n}\n\nStoresView.displayName = 'StoresView';\n\nexport default StoresView;\n","import * as React from 'react';\nimport styled from 'styled-components';\nimport { ContentSpacing } from '@estee/elc-base-theme';\nimport { Heading1, Body2 } from '@estee/elc-typography';\nimport classnames from 'classnames';\n\nconst TitleContainer = styled.div`\n display: flex;\n height: 160px;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n`;\n\nconst Title = styled(Heading1)`\n margin-bottom: ${ContentSpacing.space20};\n`;\n\nexport interface IStoresTitle {\n title: string;\n subtitle?: string;\n titleDataTestId?: string;\n className: string;\n}\n\nconst StoresSubtitle = styled(Body2)`\n text-align: center;\n width: 80%;\n max-width: 450px;\n`;\nexport const StoresTitle = ({ title, subtitle, titleDataTestId, className }: IStoresTitle) => {\n const titleClassNames = classnames(className);\n\n return (\n \n \n {title}\n \n {subtitle}\n \n );\n};\n"],"names":["LastItemTheme","Colors","StyledAnchorTheme","BreadcrumbsList","ContentSpacing","Breadcrumb","Item","StyledAnchor","AnchorText","Delimiter","BoldText","Breadcrumbs","observer","props","classNames","classnames","className","item","links","BreadcrumbItem","breadcrumb","isLastItem","label","key","href","title","tabIndex","map","link","index","delimiter","SidebarBoxStyled","SelectedStoreIconWrapper","displayName","SelectedStoreIcon","Icon","size","image","storeItemClassName","selectedStoreItemClassName","StoreCard","store","selectedStoreId","onCardClicked","storeRefs","selectOABStore","deselectOABStore","isOABStoreSelected","oabSelectedCounterId","storeItemProps","isStoreSelected","id","oabStoreSelected","toString","isOAB","config","ref","isPrimary","role","StoreListItem","onStoreClicked","selected","SkeletonStoreCard","StoreListWrapper","storesCount","isLanding","constructor","super","toStoreCards","stores","oabSelectedStoreId","onStoreSelected","onStoreDeselected","skeletonStoreCards","Array","fill","this","configService","diContainer","componentDidUpdate","prevProps","scrollToStore","mode","render","length","areNearbyStoresLoading","observable","descriptionClass","nameClass","productDetailsClass","sizeClass","priceClass","Description","Name","ProductDetails","ItemDetail","ProductDescription","product","name","formattedPrice","Container","Image","ImageWrapper","thumb","alt","imageClass","src","descriptionWrapperClass","ProductWrapper","DescriptionWrapper","componentDidMount","productViewController","loaded","productClass","data","imageUrl","lazyInject","storeSearchBoxClassName","StoresSidebarSearchBox","apiKey","mapRegion","mapLanguage","goToDirectoryLabel","onAddressSelect","onClick","onLocationReset","placeholder","SearchBox","MapSearchInputViewContainer","onAddressSelected","defaultValue","icon","SearchIcon","autoCompleteTypes","region","language","hasGeoLocation","GoToDirectory","ResultFiltersSideBarBox","storeLocatorFilters","storeSearchTitleClassName","SidebarSearchResultsFilters","searchTitle","FindInStoreProduct","selectedSwitchTheme","unselectedSwitchTheme","circleColorTheme","circleColorActiveTheme","RoundSwitch","unselectedColor","width","padding","toggled","selectedColor","borderColor","SwitchCircle","circleColor","circleColorActive","SwitchBackground","toggle","setState","state","onToggle","previousProps","previousState","isSelected","switchClassName","defaultProps","OpenStoresSwitchContainer","OpenStoresSwitch","openNowToggleLabel","isEnabled","Switch","StoresFilterWrapper","FilterToggleBoxHeader","FilterArrowIcon","ArrowIcon","isOpen","FilterTitle","FiltersList","isExpanded","filters","doorTypeAirportDutyFreeStore","doorTypeDepartmentStore","doorTypeDutyFreeStore","doorTypeFreeStandingStore","doorTypePopupStore","translations","onFiltersListClick","onFilterClick","viewController","isFiltersListExpanded","numberOfActiveFilters","availableFilters","multiOptionFilters","doorTypeLabelMappings","AP","DS","DF","FSS","POP","arrowClassnames","filter","options","filterOption","CheckBox","onChange","value","isChecked","includes","ResultMessagesContainer","resultMessagesContainerClassName","StoresCountAndFilters","isLoading","geolocationPermissions","filtersViewController","openNowEnabled","filtersEnabled","onOpenNowClick","StoresFilters","StoresSearchResultMessage","isFiltered","ProductSizeAndPriceFonts","ProductBasicInfoWrapper","searchResultClassName","reduce","acc","isLocationLoading","areStoresLoading","storeId","currentRef","current","scrollIntoView","behavior","block","inline","getBopisProduct","skuId","ServiceView","serviceName","getStoresCountAndFilters","searchPlaceholderLabel","showBopisProduct","showOabWidget","virtualServicesEnabled","onStoreSelectButtonClick","nextButtonRef","findInStore","storeInventoryMap","onPhoneClick","onStoreInfoLinkClick","onGoToDirectoryClick","storesListItemProps","StoresListWrapper","showStoreListItemIcons","computed","MobileSearchBoxTitle","MobileSearchBox","MapBox","onMarkerClick","marker","onMarkerClicked","onMapPan","centerLocation","getMap","storesMap","mapCenter","markers","googleApiKey","coloredMap","MapViewContainer","mapRef","setMap","googleMapsAPIKey","defaultCenter","lat","lng","zoom","onDragEnd","colored","showFindInStoreProduct","enterAddressPlaceholder","findStore","mobileStoreSearchBoxClassName","mobileStoreSearchTitleClassName","BreadCrumbsContainer","breadcrumbsClassnames","titleClassnames","homeLabel","storeLocator","storesLandingTitle","storesLandingSubtitle","homeUrlRef","StoresTitle","subtitle","AddToBagServiceView","quantity","autoReplenishOptions","Footer","AddToBagWrapper","MobileWrapper","BopisFooter","NextButtonWrapper","NextButton","Button","OABNextButton","storesNextLabel","reference","buttonClassname","disabled","VirtualOnlineAppointmentBookingInfoContainer","VirtualOnlineAppointmentBookingInfoLine","VirtualOnlineAppointBookingInfoLine","description","VirtualOnlineAppointmentBookingContainer","OutlinedButtonStyled","VirtualOnlineAppointmentBooking","onVirtualAppointmentClick","bookAVirtualAppointment","goToVirtualAppointmentBooking","StyledLandscapeSidebarLayout","ContentSpacing112","DesktopWrapper","ListBox","onMapMarkerClick","storesSidebarRef","nextStepMobileRef","counterId","updateSelectedStore","updateConfig","String","isFindInStore","isBopis","chooseAStore","getSidebar","searchPlaceholder","openNow","isSelecting","StoresSidebar","showOpenNowToggle","featureFlags","getMapView","StoresMapView","getBopisFooter","displayVirtualOabWidget","virtualCounterHasTimeSlots","displayability","inStoreLocator","inOab","storesNext","storeLocatorClassNames","homeUrl","breadcrumbsUrls","onVirtualOnlineAppoinmentClick","StoresLandingHeader","sidebar","displayOnLeftSide","StoresView","TitleContainer","Title","StoresSubtitle","titleDataTestId","titleClassNames"],"sourceRoot":""}