\n `,\n }}\n />\n );\n};\n","import { defineMessages } from 'react-intl';\n\nexport const messages = defineMessages({\n pickupNow: {\n id: 'pd.clickandcollect.pickup.now',\n defaultMessage: 'Vyzvednout ihned',\n },\n});\n","import { styled, theme } from '@notino/react-styleguide';\n\nexport const StoreTitle = styled.p`\n ${theme.typography.labelRegular400}\n margin-bottom: 0.25rem;\n`;\n\nexport const StoreDescription = styled.span`\n font-weight: 300;\n ${theme.typography.labelRegular400}\n color:${theme.color.text.tertiary};\n padding-bottom: 0.25rem;\n`;\n\nexport const StoreStockAvailabilityWrapper = styled.div`\n color: ${theme.color.text.positive};\n ${theme.typography.labelRegular400}\n`;\n","/**\n * @return [tomorrow, date after tomorrow]\n */\nconst getNextTwoDays = (): [Date, Date] => {\n const now = new Date();\n const tomorrowTime = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate() + 1,\n 0,\n 0,\n 0\n );\n const dayAfterTomorrowTime = new Date(\n now.getFullYear(),\n now.getMonth(),\n now.getDate() + 2,\n 0,\n 0,\n 0\n );\n return [tomorrowTime, dayAfterTomorrowTime];\n};\n\nexport const isTomorrow = (date: Date) => {\n const timeToCompare = new Date(date).getTime();\n const [tomorrow, dayAfterTomorrow] = getNextTwoDays();\n\n return (\n timeToCompare >= tomorrow.getTime() &&\n timeToCompare < dayAfterTomorrow.getTime()\n );\n};\n\nexport const isToday = (date: Date) => {\n const timeToCompare = new Date(date).getTime();\n const startOfToday = new Date();\n startOfToday.setHours(0, 0, 0, 0);\n const [tomorrow] = getNextTwoDays();\n\n return (\n timeToCompare >= startOfToday.getTime() &&\n timeToCompare < tomorrow.getTime()\n );\n};\n","import { defineMessages } from 'react-intl';\n\nexport const messages = defineMessages({\n chooseStore: {\n id: 'pd.clickandcollect.choose.store',\n defaultMessage: 'Vyberte pobočku',\n },\n pickHere: {\n id: 'pd.clickandcollect.pick.here',\n defaultMessage: 'Vyzvednout zde',\n },\n availableFrom: {\n id: 'pd.clickandcollect.available.from',\n defaultMessage: '{date} od {time}',\n },\n today: {\n id: 'pd.clickandcollect.today',\n defaultMessage: 'dnes',\n },\n tomorrow: {\n id: 'pd.clickandcollect.tomorrow',\n defaultMessage: 'zítra',\n },\n lessThan5: {\n id: 'pd.clickandcollect.lessThan5',\n defaultMessage: '{count} ks',\n },\n moreThan5: {\n id: 'pd.clickandcollect.moreThan5',\n defaultMessage: 'Více než 5 ks',\n },\n moreThan20: {\n id: 'pd.clickandcollect.moreThan20',\n defaultMessage: 'Více než 20 ks',\n },\n});\n","import * as React from 'react';\n\nimport { IStore } from '../../model';\n\nimport { StoreStockAvailabilityWrapper } from './styled';\nimport { usePickUpTime } from './usePickupTime';\nimport { useStockCount } from './useStockCount';\n\nexport const StoreStockAvailability = ({\n stockCount,\n earliestPickup,\n}: IStore): JSX.Element => {\n const stockCountMessage = useStockCount(stockCount);\n const pickupTime = usePickUpTime(earliestPickup);\n return (\n
\n {`${stockCountMessage} | ${pickupTime}`}\n \n );\n};\n","import { useIntl } from 'react-intl';\n\nimport { StockAvailability } from '@notino/shared/definitions/types';\n\nimport { messages } from '../../messages';\n\nexport const useStockCount = (stockCount: string): string => {\n const { formatMessage } = useIntl();\n switch (stockCount) {\n case StockAvailability.Last1:\n return formatMessage(messages.lessThan5, { count: 1 });\n case StockAvailability.Last2:\n return formatMessage(messages.lessThan5, { count: 2 });\n case StockAvailability.Last3:\n return formatMessage(messages.lessThan5, { count: 3 });\n case StockAvailability.Last4:\n return formatMessage(messages.lessThan5, { count: 4 });\n case StockAvailability.Last5:\n return formatMessage(messages.lessThan5, { count: 5 });\n case StockAvailability.MoreThan20:\n return formatMessage(messages.moreThan20, {});\n case StockAvailability.MoreThan5:\n return formatMessage(messages.moreThan5, {});\n }\n};\n","import { useIntl } from 'react-intl';\n\nimport { isToday, isTomorrow } from '../../../../utils/dateUtils';\nimport { messages } from '../../messages';\n\nimport { getEarliestPickupDate } from './utils';\n\nexport const usePickUpTime = (earliestPickup: string): string => {\n const { formatTime, formatDate, formatMessage } = useIntl();\n\n const earliestPickupDate = getEarliestPickupDate(new Date(earliestPickup));\n\n const time = formatTime(earliestPickupDate, {\n hour: 'numeric',\n minute: 'numeric',\n });\n\n let dateName: string;\n if (isToday(earliestPickupDate)) {\n dateName = formatMessage(messages.today);\n } else if (isTomorrow(earliestPickupDate)) {\n dateName = formatMessage(messages.tomorrow);\n } else {\n dateName = formatDate(earliestPickupDate, {\n weekday: 'long',\n });\n }\n\n return formatMessage(messages.availableFrom, {\n date: dateName,\n time,\n });\n};\n","/**\n * in case that API returns time in the past, change it to now\n * @param earliestPickup\n */\nexport const getEarliestPickupDate = (earliestPickup: Date) => {\n const now = new Date();\n return earliestPickup > now ? earliestPickup : now;\n};\n","import * as React from 'react';\n\nimport { IStore } from '../../model';\n\nimport { StoreStockAvailability } from './StoreStockAvailability';\nimport { StoreDescription, StoreTitle } from './styled';\n\ninterface IStoreProps {\n data: IStore;\n}\n\nexport const Store: React.FC
= ({ data }) => {\n return (\n <>\n {data.name}\n \n \n >\n );\n};\n","import styled from 'styled-components';\n\nimport {\n ActionButtonWithConfirmation,\n breakpoints,\n theme,\n} from '@notino/react-styleguide';\n\nexport const StoreWrapper = styled.div`\n padding: 1.25rem 0;\n &:not(:last-child) {\n border-bottom: solid 1px ${theme.color.border.disabled};\n }\n &:first-child {\n padding-top: 0;\n }\n`;\nexport const ModalContentWrapper = styled.div`\n max-height: 50vh;\n overflow-y: auto;\n margin-bottom: 1rem;\n`;\n\nexport const CenterWrapper = styled.div`\n padding-top: 2.8125rem;\n display: flex;\n justify-content: center;\n`;\n\nexport const StyledActionButtonWithConfirmation = styled(\n ActionButtonWithConfirmation\n)`\n @media (min-width: ${breakpoints.sm}) {\n width: auto;\n margin: auto;\n display: block;\n }\n`;\n","import * as React from 'react';\n\nimport { useMutation, useQuery } from '@apollo/client';\n\nimport {\n AddToClickAndCollectMutation,\n AddToClickAndCollectMutationVariables,\n GetStoresQuery,\n} from '@notino/shared/definitions/types';\n\nimport { useSettings } from '@containers/ProductDetailContainer/hooks/useSettings';\n\nimport addToClickAndCollectMutation from './mutations/addToClickAndCollect.graphql';\nimport getStoresQuery from './queries/stores.graphql';\nimport { redirectToClickAndCollectCart } from './utils';\n\nexport const useClickAndCollect = (variantId: number) => {\n const { Settings: { isNewShoppingCartEndpointEnabled: isNewEndpoint } = {} } =\n useSettings();\n\n const { data: stores, loading: storesLoading } = useQuery(\n getStoresQuery,\n {\n variables: { productId: variantId },\n }\n );\n\n const [addToClickAndCollectCart, addToClickAndCollectData] = useMutation<\n AddToClickAndCollectMutation,\n AddToClickAndCollectMutationVariables\n >(addToClickAndCollectMutation, {\n onCompleted: (response) => {\n redirectToClickAndCollectCart(\n response.addProductToClickAndCollect.cartId,\n isNewEndpoint\n );\n },\n });\n\n const handleAddToClickAndCollect = React.useCallback(\n async (warehouseCode: string) => {\n await addToClickAndCollectCart({\n variables: {\n productId: variantId,\n warehouseCode: warehouseCode,\n },\n });\n },\n [addToClickAndCollectCart, variantId]\n );\n\n return React.useMemo(\n () => ({\n stores,\n storesLoading,\n handleAddToClickAndCollect,\n addToClickAndCollectData,\n }),\n [\n stores,\n storesLoading,\n handleAddToClickAndCollect,\n addToClickAndCollectData,\n ]\n );\n};\n","import * as React from 'react';\nimport { FormattedMessage } from 'react-intl';\n\nimport { snakeCase } from 'lodash';\n\nimport { ButtonModel, RadioButton, Spinner } from '@notino/react-styleguide';\nimport {\n GetCatalogProductViewQuery,\n StockAvailability,\n} from '@notino/shared/definitions/types';\nimport { CartType } from '@notino/web-tracking';\n\nimport { useModifaceVariants } from '@containers/ProductDetailContainer/ProductDetail/hooks/useModifaceVariants';\nimport { usePriceLogic } from '@containers/ProductDetailContainer/ProductDetail/hooks/usePriceLogic';\nimport {\n MIN_PRICE_PROMO_LABEL,\n RRP_PRICE_PROMO_LABEL,\n} from '@containers/ProductDetailContainer/ProductDetail/hooks/usePriceLogic/tracking';\nimport { useProductDetailContext } from '@containers/ProductDetailContainer/ProductDetail/ProductDetailContext';\nimport { dispatchTrackingEvent } from '@context/tracking/utils';\nimport { ProductEventWither } from '@helpers/googleTagManager';\n\nimport { Store } from './components/Store';\nimport { useTrackModalShow } from './hooks/useTrackModalShow';\nimport { messages } from './messages';\nimport {\n ModalContentWrapper,\n StoreWrapper,\n CenterWrapper,\n StyledActionButtonWithConfirmation,\n} from './styled';\nimport { useClickAndCollect } from './useClickAndCollect';\n\ninterface IClickAndCollectModalProps {\n product: GetCatalogProductViewQuery['productDetailByCatalogMasterId'];\n selectedVariant: GetCatalogProductViewQuery['productDetailByCatalogMasterId']['variants'][number];\n}\n\nexport const ClickAndCollectModal = ({\n selectedVariant,\n product,\n}: IClickAndCollectModalProps) => {\n const [selectedStore, setSelectedStore] = React.useState('');\n const { rrpShown, minimalPriceShown } = usePriceLogic(selectedVariant);\n\n const {\n tryItFirstAvailable,\n engravingAvailable,\n product: { variants },\n } = useProductDetailContext();\n const modifaceVariants = useModifaceVariants(variants);\n\n const {\n stores,\n storesLoading,\n handleAddToClickAndCollect,\n addToClickAndCollectData: {\n loading: addToCnCLoading,\n error: addToCnCError,\n },\n } = useClickAndCollect(Number(selectedVariant.webId));\n\n useTrackModalShow();\n\n if (storesLoading) {\n return (\n \n \n \n );\n }\n\n const onRadioButtonClick = (storeId: string) => () => {\n setSelectedStore(storeId);\n };\n\n const handleSubmit = async () => {\n dispatchTrackingEvent({\n event: 'add_to_cart',\n product: ProductEventWither()\n .withProduct(product)\n .withVariant(selectedVariant)\n .withServices({\n modifaceVariants,\n tryItFirstAvailable,\n engravingAvailable,\n shadefinderAvailable: !!product.features.isShadeFinderAvailable,\n })\n .withAdditionalData({\n quantity: 1,\n cart_type: snakeCase(CartType.clickAndCollect),\n })\n .withAdditionalPromoLabels([\n rrpShown && RRP_PRICE_PROMO_LABEL,\n minimalPriceShown && MIN_PRICE_PROMO_LABEL,\n ])\n .build(),\n _clear: true,\n });\n\n await handleAddToClickAndCollect(selectedStore);\n };\n\n return (\n <>\n \n {stores?.collectStoresByProductId?.map((store) => {\n const outOfStock = store.stockCount === StockAvailability.OutOfStock;\n if (outOfStock) {\n return null;\n }\n\n return (\n \n \n \n \n \n );\n })}\n \n\n \n \n \n >\n );\n};\n","import * as React from 'react';\n\nimport { useTrackingContext } from '@context/tracking/TrackingContext';\nimport { dispatchTrackingEvent } from '@context/tracking/utils';\n\nexport const useTrackModalShow = () => {\n const { getTimeFromInit } = useTrackingContext();\n\n React.useEffect(() => {\n dispatchTrackingEvent({\n event: 'subpage_view',\n subpage: {\n name: 'click_and_collect_modal',\n interaction: 'automatic',\n timing: getTimeFromInit(),\n action: 'click_and_collect_opened',\n type: 'click_and_collect',\n },\n _clear: true,\n });\n }, [getTimeFromInit]);\n};\n","import * as React from 'react';\n\nimport { GetCatalogProductViewQuery } from '@notino/shared/definitions/types';\n\nimport { getModifaceVariants, getModifaceHairVariants } from '../utils';\n\nexport const useModifaceVariants = (\n variants: GetCatalogProductViewQuery['productDetailByCatalogMasterId']['variants']\n) => {\n return React.useMemo(() => getModifaceVariants(variants), [variants]);\n};\n\nexport const useModiface = (\n variants: GetCatalogProductViewQuery['productDetailByCatalogMasterId']['variants']\n) => {\n return React.useMemo(\n () => ({\n makeup: getModifaceVariants(variants),\n hair: getModifaceHairVariants(variants),\n }),\n [variants]\n );\n};\n","export const redirectToClickAndCollectCart = (\n cartId: string,\n isNewEndpoint: boolean\n) => {\n window.location.href = isNewEndpoint\n ? `/reservation/${cartId}`\n : `/reservation-1/${cartId}`;\n};\n","import styled, { css } from 'styled-components';\n\nimport { breakpoints, Button, theme } from '@notino/react-styleguide';\n\nexport const PickUpButtonWrapper = styled.div`\n margin-top: 0.5rem;\n flex: 0 1 100%;\n @media (min-width: ${breakpoints.sm}) {\n margin-top: 0;\n flex: auto;\n }\n`;\n\nexport const PickUpButton = styled(Button)<{ newDesign: boolean }>`\n width: 100%;\n ${({ newDesign }) =>\n newDesign\n ? css`\n height: 3.25rem;\n ${theme.typography.labelRegular}\n `\n : css`\n @media (min-width: ${breakpoints.sm}) {\n width: auto;\n }\n `}\n`;\n","import * as React from 'react';\nimport { FormattedMessage, useIntl } from 'react-intl';\n\nimport { ButtonModel, ModalContext, Text } from '@notino/react-styleguide';\nimport { GetCatalogProductViewQuery } from '@notino/shared/definitions/types';\n\nimport { useTrackingContext } from '@context/tracking/TrackingContext';\n\nimport { useNewPdDesignEnabled } from '../../hooks/useNewPdDesignEnabled';\n\nimport { trackModalClose, trackModalOpen } from './gtm/tracking';\nimport { messages } from './messages';\nimport { ClickAndCollectModal } from './Modal';\nimport { messages as modalMessages } from './Modal/messages';\nimport { PickUpButton, PickUpButtonWrapper } from './styled';\n\ntype IClickAndCollectProps = {\n selectedVariant: GetCatalogProductViewQuery['productDetailByCatalogMasterId']['variants'][number];\n product: GetCatalogProductViewQuery['productDetailByCatalogMasterId'];\n onModalClosing: () => void;\n disabled?: boolean;\n};\n\nexport const ClickAndCollect: React.FC = ({\n selectedVariant,\n product,\n onModalClosing,\n disabled = false,\n}) => {\n const newDesign = useNewPdDesignEnabled();\n const { formatMessage } = useIntl();\n const { getTimeFromInit } = useTrackingContext();\n const { toggleModal, hideModal } = ModalContext.useModalContext();\n\n const toggleClickAndCollectModal = React.useCallback(() => {\n trackModalOpen({ timing: getTimeFromInit() });\n\n const handleModalCloseTracking = () => {\n hideModal();\n trackModalClose({ timing: getTimeFromInit() });\n onModalClosing();\n };\n\n const header = formatMessage(modalMessages.chooseStore);\n\n toggleModal(\n ,\n {\n header: {header},\n center: true,\n positionBottomOnMobile: true,\n withFocusTrap: true,\n onClose: handleModalCloseTracking,\n }\n );\n }, [\n getTimeFromInit,\n toggleModal,\n selectedVariant,\n product,\n formatMessage,\n hideModal,\n onModalClosing,\n ]);\n\n return (\n \n \n \n \n \n );\n};\n","import { TrackingAttributes } from '@context/tracking/types';\nimport { dispatchTrackingEvent } from '@context/tracking/utils';\n\nexport const trackModalClose = ({\n timing,\n}: Omit) => {\n dispatchTrackingEvent({\n event: 'element_click',\n element: {\n name: 'click_and_collect',\n interaction: 'click',\n action: 'close_click_and_collect',\n timing,\n mode: 'off',\n type: 'product_detail',\n promo_labels: undefined,\n },\n _clear: true,\n });\n};\n\nexport const trackModalOpen = ({\n timing,\n}: Omit) => {\n dispatchTrackingEvent({\n event: 'element_click',\n element: {\n name: 'click_and_collect',\n interaction: 'click',\n action: 'open_click_and_collect',\n timing,\n mode: 'on',\n type: 'product_detail',\n promo_labels: undefined,\n },\n _clear: true,\n });\n};\n","export const REGISTER_URL = '/myaccount.asp#registration';\nexport const MY_NOTINO_BENEFIT_PAGE = '/mynotino/my-benefits/';\n\nexport const STANDARD_MODAL_IMAGE_PATH =\n 'https://cdn.notinoimg.com/images/gallery/loyalty/new-vip-modal.jpg';\nexport const RETINA_MODAL_IMAGE_PATH =\n 'https://cdn.notinoimg.com/images/gallery/loyalty/new-vip-modal-retina.jpg';\nexport const MOBILE_MODAL_IMAGE_PATH =\n 'https://cdn.notinoimg.com/images/gallery/loyalty/mobile-vip-modal.jpg';\n","import { dispatchTrackingEvent } from '@context/tracking/utils';\n\nimport { FullfilledSteps } from './components/HowToLoyaltyDiscountModal';\n\nexport enum LoyaltyStatus {\n nonRegistered = 'non-registered',\n registered = 'registered',\n subscribed = 'subscribed',\n activated = 'activated',\n unsubscribed = 'unsubscribed',\n}\n\nexport const determineStatus = (fullfilledSteps: FullfilledSteps) => {\n let status = LoyaltyStatus.nonRegistered;\n\n if (fullfilledSteps.registerStep) {\n status = LoyaltyStatus.registered;\n }\n\n if (fullfilledSteps.registerStep && fullfilledSteps.newsletterStep) {\n status = LoyaltyStatus.subscribed;\n }\n\n if (\n fullfilledSteps.registerStep &&\n fullfilledSteps.chooseBrandAndCategoryStep &&\n !fullfilledSteps.newsletterStep\n ) {\n status = LoyaltyStatus.unsubscribed;\n }\n\n return status;\n};\n\nexport const trackLoyaltyModalOpen = (\n status: LoyaltyStatus,\n timing: number\n) => {\n dispatchTrackingEvent({\n event: 'subpage_view',\n _clear: true,\n subpage: {\n name: `/overlay_vip-discount/${status}/`,\n action: 'open_vip_overlay',\n interaction: 'click',\n type: 'service',\n title: 'VIP program',\n timing,\n },\n });\n};\n\nexport const trackLoyaltyModalClose = () =>\n dispatchTrackingEvent({\n event: 'subpage_close',\n subpage: undefined,\n _clear: true,\n });\n","import{_ as e}from\"./_rollupPluginBabelHelpers-c70560be.js\";import*as l from\"react\";import{Icon as m}from\"./utils/index.js\";import\"./getSemanticColor.js\";import\"./theme.js\";var t=function(t){return l.createElement(m,e({},t,{viewBox:\"0 0 256.62 256\"}),l.createElement(\"path\",{fill:\"#6e6e6e\",d:\"M201.7,52.25H67.58L13.77,111,134.64,256,255.51,111ZM137.18,113.1H172l-20.43,72.12Zm-19.51,72.12L97.24,113.1H132.1ZM97,108.94,102.77,76l27.42,32.91Zm42.12,0L166.51,76l5.8,32.91Zm37.45,0L171,77.37l29.71,31.57Zm-41.9-1.18L104.58,71.69l30.06-15,30.06,15Zm-41.9,1.18H68.6L98.31,77.37Zm.17,4.16,19.15,67.61L67.64,113.1Zm41.73,8.54L149.12,194,134.64,245.1,120.17,194Zm41.73-8.54h25.27l-44.42,67.61Zm28-6.33L170.7,71l11.73-14.07L212.55,72Zm11.13-29.12,12.89,31.29H208.13ZM167.44,68.4l-24-12h34Zm-65.6,0-10-12h34ZM98.58,71,64.92,106.77,56.73,72,86.85,56.93ZM61.15,108.94H40.9L53.79,77.65Zm1,4.16L82.8,187.28l-5.48-6.57-36-67.61Zm7.16,10.19L115.84,194,130,243.88,89.29,195.07ZM153.44,194l46.49-70.75L180,195.07l-40.68,48.81Zm53.65-80.94H228l-36,67.61-5.48,6.57Zm25.65,0H248.3L205.07,165Zm.14-4.16L220.54,79l27.47,30ZM207.61,64.86l-16.9-8.45h9.15ZM69.42,56.41h9.15l-16.9,8.45ZM48.74,79l-12.34,30H21.27ZM36.54,113.1,64.21,165,21,113.1Z\"}),l.createElement(\"polygon\",{fill:\"#dc0069\",points:\"42.52 56.69 48.19 34.01 70.86 28.34 48.19 22.68 42.52 0 36.85 22.68 14.17 28.34 36.85 34.01 42.52 56.69\"}),l.createElement(\"polygon\",{fill:\"#6e6e6e\",points:\"18.9 87.4 22.68 72.28 37.79 68.5 22.68 64.72 18.9 49.6 15.12 64.72 0 68.5 15.12 72.28 18.9 87.4\"}),l.createElement(\"polygon\",{fill:\"#dc0069\",points:\"226.76 56.69 229.6 45.35 240.94 42.52 229.6 39.68 226.76 28.34 223.93 39.68 212.59 42.52 223.93 45.35 226.76 56.69\"}),l.createElement(\"polygon\",{fill:\"#6e6e6e\",points:\"108.66 44.88 111.49 33.54 122.83 30.71 111.49 27.87 108.66 16.54 105.82 27.87 94.48 30.71 105.82 33.54 108.66 44.88\"}))};export{t as DiamondBigIcon};\n//# sourceMappingURL=DiamondBigIcon.js.map\n","import { defineMessages } from 'react-intl';\n\nexport const messages = defineMessages({\n imgAlt: {\n id: 'pd.loyalty.modal.img.alt',\n defaultMessage: 'zákaznická sleva',\n },\n});\n","import styled, { css } from 'styled-components';\n\nimport {\n Heading,\n breakpoints,\n ImagePlaceholder,\n theme,\n} from '@notino/react-styleguide';\n\nexport const ModalHeader = styled(Heading.H3)`\n text-align: left;\n margin: 0 auto;\n ${theme.typography.titleLarge}\n`;\n\nexport const DiamondIconWrapper = styled.div`\n display: flex;\n flex-basis: 20%;\n height: 100%;\n`;\n\nexport const ModalContent = styled.div`\n display: flex;\n flex-direction: column;\n text-align: center;\n max-height: 90vh;\n\n @media (min-width: ${breakpoints.md}) {\n flex-direction: row-reverse;\n height: auto;\n }\n\n flex-direction: column-reverse;\n max-height: 80vh;\n overflow-y: auto;\n`;\n\nexport const ContentWrapper = styled.div`\n width: 100%;\n padding: 2rem 0;\n\n @media (min-width: ${breakpoints.md}) {\n width: 50%;\n }\n`;\n\nexport const TextContentWrapper = styled.div`\n display: flex;\n padding: 1rem;\n\n @media (min-width: ${breakpoints.md}) {\n padding: 2rem;\n }\n\n padding: 0 1.25rem 1.5rem;\n flex-direction: column;\n gap: 1rem;\n\n @media (min-width: ${breakpoints.md}) {\n padding: 0 2rem 1.5rem;\n }\n`;\n\nexport const InfoWrapper = styled.div`\n flex-basis: 75%;\n\n @media (min-width: ${breakpoints.md}) {\n flex-basis: 80%;\n }\n`;\n\nexport const ImageWrapper = styled.div<{ hideOnMobile: boolean }>`\n display: flex;\n justify-content: center;\n align-items: flex-start;\n overflow: hidden;\n\n ${({ hideOnMobile }) =>\n hideOnMobile &&\n css`\n display: none;\n `}\n\n @media (min-width: ${breakpoints.md}) {\n display: flex;\n align-items: center;\n }\n`;\n\nexport const StyledImagePlaceholder = styled(ImagePlaceholder)`\n min-width: 100%;\n min-height: 100%;\n`;\n","import * as React from 'react';\nimport { useIntl } from 'react-intl';\n\nimport { DiamondBigIcon } from '@notino/react-styleguide';\n\nimport { useIsDesktop } from '@utils/helpers';\n\nimport {\n STANDARD_MODAL_IMAGE_PATH,\n RETINA_MODAL_IMAGE_PATH,\n MOBILE_MODAL_IMAGE_PATH,\n} from '../../constants';\n\nimport { messages } from './messages';\nimport {\n ModalHeader,\n ModalContent,\n TextContentWrapper,\n DiamondIconWrapper,\n InfoWrapper,\n ContentWrapper,\n ImageWrapper,\n StyledImagePlaceholder,\n} from './styled';\n\ninterface IBaseLoyaltyModalProps {\n headerMessage: string;\n children: JSX.Element;\n footerContent: JSX.Element;\n hideImageOnMobile?: boolean;\n}\n\nexport const BaseLoyaltyModal: React.FC = ({\n headerMessage,\n children,\n footerContent,\n hideImageOnMobile,\n}) => {\n const { formatMessage } = useIntl();\n const isDesktop = useIsDesktop();\n\n return (\n \n \n \n \n \n \n \n {headerMessage}\n {children}\n \n \n {footerContent}\n \n \n \n \n \n );\n};\n","import styled from 'styled-components';\n\nimport { Button } from '@notino/react-styleguide';\n\nexport const StyledButton = styled(Button)`\n padding: 0 3rem;\n`;\n","import { defineMessages, MessageDescriptor } from 'react-intl';\n\nexport const benefitsModalTableMessages: {\n [key: string]: MessageDescriptor;\n} = defineMessages({\n notChosen: {\n id: 'pd.loyalty.benefits.modal.table.not.chosen',\n defaultMessage: 'nevybráno',\n },\n ok: {\n id: 'pd.loyalty.benefits.modal.ok',\n defaultMessage: 'Ok',\n },\n settings: {\n id: 'pd.loyalty.benefits.modal.settings',\n defaultMessage: 'Nastavení',\n },\n});\n","import styled from 'styled-components';\n\nimport { theme } from '@notino/react-styleguide';\n\nexport const BenefitsModalTableWrapper = styled.div``;\n\ninterface IBenefitsModalTableLineProps {\n isOpaque?: boolean;\n}\n\nexport const BenefitsModalTableLine = styled.div`\n display: flex;\n justify-content: space-between;\n padding: 0.5rem 0 0.5rem 0.5rem;\n border-bottom: 1px solid ${theme.color.border.divider};\n opacity: ${({ isOpaque }) => (isOpaque ? '0.5' : '1')};\n`;\n\nexport const BrandName = styled.span`\n text-align: left;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n width: 75%;\n`;\n","import * as React from 'react';\nimport { FormattedMessage } from 'react-intl';\n\nimport { GetCustomerBenefitsQuery } from '@notino/shared/definitions/types';\n\nimport { benefitsModalTableMessages } from './messages';\nimport {\n BenefitsModalTableLine,\n BenefitsModalTableWrapper,\n BrandName,\n} from './styled';\n\ninterface IBenefitsModalTableProps {\n customerBenefits: GetCustomerBenefitsQuery['customerBenefits'];\n}\n\nexport const BenefitsModalTable: React.FC = ({\n customerBenefits,\n}) => {\n const availableDiscounts = new Array(\n customerBenefits.brandDiscountLimit +\n customerBenefits.categoryDiscountLimit -\n (customerBenefits.brandDiscounts.length +\n customerBenefits.categoryDiscounts.length)\n ).fill(0);\n\n return (\n \n {customerBenefits.brandDiscounts.map((brandDiscount) => (\n \n \n {brandDiscount.subjectName}\n \n -{brandDiscount.value}%\n \n ))}\n {customerBenefits.categoryDiscounts.map((brandDiscount) => (\n \n \n {brandDiscount.subjectName}\n \n -{brandDiscount.value}%\n \n ))}\n {availableDiscounts.map((_, i) => (\n // eslint-disable-next-line react/no-array-index-key\n \n \n \n \n 0%\n \n ))}\n \n );\n};\n","import { defineMessages } from 'react-intl';\n\nexport const benefitsModalMessages = defineMessages({\n header: {\n id: 'pd.benefits.modal.header',\n defaultMessage: 'Vaše oblíbené značky a kategorie se slevou',\n },\n});\n","import styled from 'styled-components';\n\nimport { breakpoints, theme } from '@notino/react-styleguide';\n\nexport const BenefitsModalContentWrapper = styled.div`\n margin-top: 1rem;\n @media (min-width: ${breakpoints.sm}) {\n width: 75%;\n }\n`;\n\nexport const ButtonWrapper = styled.div`\n margin: 1rem 0 0.5rem 0;\n display: flex;\n justify-content: center;\n`;\n\nexport const SettingsWrapper = styled.a`\n margin-top: 0.5rem;\n text-decoration: underline;\n text-align: center;\n cursor: pointer;\n color: ${theme.color.text.primary};\n &:hover {\n text-decoration: none;\n }\n`;\n\nexport const FooterContent = styled.div`\n display: flex;\n flex-direction: column;\n padding: 0 1.25rem;\n button {\n width: 100%;\n }\n\n @media (min-width: ${breakpoints.md}) {\n padding: 0 2rem;\n align-items: flex-start;\n }\n`;\n","import * as React from 'react';\nimport { FormattedMessage, useIntl } from 'react-intl';\n\nimport { useQuery } from '@apollo/client';\n\nimport { ButtonModel, ModalContext } from '@notino/react-styleguide';\nimport { GetCustomerBenefitsQuery } from '@notino/shared/definitions/types';\n\nimport { dispatchTrackingEvent } from '@context/tracking/utils';\n\nimport { MY_NOTINO_BENEFIT_PAGE } from '../../constants';\nimport getCustomerBenefitsQuery from '../../queries/getCustomerBenefits.graphql';\nimport {\n LoyaltyStatus,\n trackLoyaltyModalClose,\n trackLoyaltyModalOpen,\n} from '../../trackLoyaltyModal';\nimport { BaseLoyaltyModal } from '../BaseLoyaltyModal';\nimport { StyledButton } from '../styled';\n\nimport { BenefitsModalTable } from './BenefitsModalTable';\nimport { benefitsModalTableMessages } from './BenefitsModalTable/messages';\nimport { benefitsModalMessages } from './messages';\nimport {\n BenefitsModalContentWrapper,\n ButtonWrapper,\n FooterContent,\n SettingsWrapper,\n} from './styled';\n\nexport const BenefitsModal: React.FC<{ timing: number }> = ({ timing }) => {\n const { formatMessage } = useIntl();\n const { hideModal } = ModalContext.useModalContext();\n\n const { data } = useQuery(getCustomerBenefitsQuery);\n\n React.useEffect(() => {\n trackLoyaltyModalOpen(LoyaltyStatus.activated, timing);\n }, [timing]);\n\n const handleSettingsClick = () => {\n dispatchTrackingEvent({\n event: 'vip_overlay_cta',\n vip: {\n action: 'click_on_overlay',\n name: 'change_settings',\n },\n });\n };\n\n const handleOkClick = () => {\n trackLoyaltyModalClose();\n hideModal();\n };\n\n return (\n \n \n \n \n \n \n \n \n \n \n }\n >\n \n {data?.customerBenefits && (\n \n \n \n )}\n
\n \n );\n};\n","import { defineMessages } from 'react-intl';\n\nexport const messages = defineMessages({\n howToGetLoyaltyDiscountHeader: {\n id: 'pd.loyalty.discount.how.to.header',\n defaultMessage: 'Kupujte oblíbené značky a kategorie se slevou',\n },\n registerStep: {\n id: 'pd.loyalty.discount.how.to.register',\n defaultMessage: 'Registrujte se',\n },\n newsletterStep: {\n id: 'pd.loyalty.discount.how.to.newsletter',\n defaultMessage: 'Odebírejte náš newsletter',\n },\n chooseBrandAndCategoryStep: {\n id: 'pd.loyalty.discount.how.to.choose.brand.category',\n defaultMessage: 'Vyberte si 3 značky a kategorii',\n },\n alreadyHaveAccount: {\n id: 'pd.loyalty.discount.how.to.already.have.account',\n defaultMessage: 'Již máte účet?',\n },\n logIn: {\n id: 'pd.loyalty.discount.how.to.log.in',\n defaultMessage: 'Přihlásit se',\n },\n registerNow: {\n id: 'pd.loyalty.discount.how.to.register.now',\n defaultMessage: 'Registrovat se',\n },\n setUpNow: {\n id: 'pd.loyalty.discount.how.to.set.up.now',\n defaultMessage: 'Nastavit',\n },\n});\n","import styled from 'styled-components';\n\nimport { breakpoints, theme } from '@notino/react-styleguide';\n\nexport const LoginWrapper = styled.div`\n text-align: center;\n margin-top: 1rem;\n color: ${theme.color.text.secondary};\n`;\n\nexport const LoginLink = styled.a`\n cursor: pointer;\n text-decoration: underline;\n color: ${theme.color.text.secondary};\n margin-left: 0.5rem;\n\n &:hover {\n text-decoration: none;\n }\n\n color: ${theme.color.text.primary};\n font-weight: 500;\n`;\n\nexport const StepProgressCircle = styled.div<{\n isFulfilled: boolean;\n}>`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.125rem;\n height: 1.125rem;\n background: ${(props) =>\n props.isFulfilled\n ? theme.color.background.inverse\n : theme.color.background.tertiary};\n border-radius: 50%;\n margin-right: 1.125rem;\n width: 1.25rem;\n height: 1.25rem;\n`;\n\nexport const StepWrapper = styled.span`\n display: flex;\n width: 100%;\n margin: 1rem auto;\n text-align: left;\n\n &:first-child {\n margin: 0.75rem 0 0.5rem;\n }\n &:last-child {\n margin: 0;\n }\n margin: 0 0 0.5rem;\n`;\n\nexport const FooterContent = styled.div`\n display: flex;\n flex-direction: column;\n padding: 0 1.25rem;\n @media (min-width: ${breakpoints.md}) {\n padding: 0 2rem;\n align-items: flex-start;\n }\n`;\n","import { dispatchTrackingEvent } from '@context/tracking/utils';\n\nexport const trackLoyaltyCTA = (\n eventName: 'register' | 'log_in' | 'change_settings'\n) => {\n dispatchTrackingEvent({\n event: 'vip_overlay_cta',\n vip: {\n action: 'click_on_overlay',\n name: eventName,\n },\n });\n};\n","import * as React from 'react';\nimport { FormattedMessage, useIntl } from 'react-intl';\n\nimport { useQuery } from '@apollo/client';\n\nimport { ButtonModel, CheckIcon, CloseIcon } from '@notino/react-styleguide';\nimport {\n Roles,\n GetCustomerBenefitsQuery,\n GetUserLoyaltyProgressQuery,\n} from '@notino/shared/definitions/types';\n\nimport { LOGIN_URL } from '@constants';\n\nimport { MY_NOTINO_BENEFIT_PAGE, REGISTER_URL } from '../../constants';\nimport getCustomerBenefitsQuery from '../../queries/getCustomerBenefits.graphql';\nimport {\n determineStatus,\n trackLoyaltyModalOpen,\n} from '../../trackLoyaltyModal';\nimport { BaseLoyaltyModal } from '../BaseLoyaltyModal';\nimport { StyledButton } from '../styled';\n\nimport { messages } from './messages';\nimport getUserLoyaltyProgressQuery from './queries/getUserLoyaltyProgress.graphql';\nimport {\n LoginWrapper,\n LoginLink,\n StepProgressCircle,\n StepWrapper,\n FooterContent,\n} from './styled';\nimport { trackLoyaltyCTA } from './trackLoyaltyCTA';\n\nenum HowToGetDiscountSteps {\n Register = 'registerStep',\n Newsletter = 'newsletterStep',\n ChooseBrandAndCategory = 'chooseBrandAndCategoryStep',\n}\n\nexport type FullfilledSteps = Record;\n\nexport const HowToLoyaltyModal: React.FC<{ timing: number }> = ({ timing }) => {\n const { formatMessage } = useIntl();\n const { data: getUser, loading: getUserLoading } =\n useQuery(getUserLoyaltyProgressQuery);\n\n const { data: checkCustomerBenefitsResult } =\n useQuery(getCustomerBenefitsQuery);\n\n const brandDiscountsSelected =\n checkCustomerBenefitsResult?.customerBenefits?.brandDiscounts?.length > 0;\n const categoryDiscountsSelected =\n checkCustomerBenefitsResult?.customerBenefits?.categoryDiscounts?.length >\n 0;\n\n const fulfilledSteps = React.useMemo(\n () => ({\n [HowToGetDiscountSteps.Register]:\n getUser && getUser.user ? getUser.user.role !== Roles.Anonymous : false,\n [HowToGetDiscountSteps.Newsletter]: getUser?.isUserSubscribed ?? false,\n [HowToGetDiscountSteps.ChooseBrandAndCategory]: Boolean(\n brandDiscountsSelected || categoryDiscountsSelected\n ),\n }),\n [brandDiscountsSelected, categoryDiscountsSelected, getUser]\n );\n\n const onButtonClick = () => {\n if (!fulfilledSteps.registerStep) {\n trackLoyaltyCTA('register');\n location.href = REGISTER_URL;\n } else {\n trackLoyaltyCTA('change_settings');\n location.href = MY_NOTINO_BENEFIT_PAGE;\n }\n };\n\n const handleLoginClick = () => {\n trackLoyaltyCTA('log_in');\n };\n\n React.useEffect(() => {\n if (!getUserLoading) {\n trackLoyaltyModalOpen(determineStatus(fulfilledSteps), timing);\n }\n }, [fulfilledSteps, timing, getUserLoading]);\n\n return (\n \n \n {fulfilledSteps.registerStep ? (\n \n ) : (\n \n )}\n \n {!fulfilledSteps.registerStep && (\n \n \n \n \n \n \n )}\n \n )\n }\n >\n \n {Object.values(HowToGetDiscountSteps).map((step) => (\n \n \n {fulfilledSteps[step] ? (\n \n ) : (\n \n )}\n \n \n \n ))}\n
\n \n );\n};\n","import { defineMessages } from 'react-intl';\n\nexport const messages = defineMessages({\n possibleDiscount: {\n id: 'pd.loyalty.discount.possible.discount',\n defaultMessage: 'Chci slevu {value}',\n },\n customerDiscountBold: {\n id: 'pd.loyalty.discount.customer.discount.bold',\n defaultMessage: 'Vaše sleva {value}',\n },\n customerDiscount: {\n id: 'pd.loyalty.discount.customer.discount',\n defaultMessage:\n '{customerDiscountBold} na {subjectType} {discountSubject} se uplatní v košíku. {more}',\n },\n moreDiscountInfo: {\n id: 'pd.loyalty.discount.more.discount.info',\n defaultMessage: 'Více',\n },\n categoryDiscount: {\n id: 'pd.loyalty.discount.category.discount',\n defaultMessage: 'kategorii',\n },\n brandDiscount: {\n id: 'pd.loyalty.discount.brand.discount',\n defaultMessage: 'značku',\n },\n});\n","import styled, { css } from 'styled-components';\n\nimport { DiamondIcon, theme } from '@notino/react-styleguide';\n\ninterface LoyaltyDiscountStyledWrapperProps {\n isCustomerDiscount: boolean;\n newDesign: boolean;\n}\n\nexport const LoyaltyDiscountStyledWrapper = styled.button`\n display: flex;\n align-items: center;\n font-size: 0.9rem;\n text-decoration: ${({ isCustomerDiscount }) =>\n isCustomerDiscount ? 'none' : 'underline'};\n cursor: pointer;\n background: none;\n border: none;\n color: #000 !important;\n &:hover {\n text-decoration: none;\n }\n\n ${({ newDesign }) =>\n newDesign &&\n css`\n color: ${theme.color.text.secondary} !important;\n `}\n`;\n\nexport const CustomerDiscountWrapper = styled.span`\n text-decoration: underline;\n &:hover {\n text-decoration: none;\n }\n`;\n\nexport const StyledDiamondIcon = styled(DiamondIcon)`\n margin-right: 1rem;\n`;\n\nexport const CustomerDiscountBoldWrapper = styled.span`\n font-weight: 600;\n`;\n","import{_ as t}from\"./_rollupPluginBabelHelpers-c70560be.js\";import*as e from\"react\";import{Icon as r}from\"./utils/index.js\";import\"./getSemanticColor.js\";import\"./theme.js\";var l=function(l){return e.createElement(r,t({},l,{viewBox:\"0 0 68 64\"}),e.createElement(\"path\",{fill:\"#505050\",d:\"M48.27,12.69H18.85L8.31,28.11,33.56,63.9,58.81,28.11ZM32.17,54.4l-17-24.14H35.51Zm7.72-24.14H52L36.93,51.6Zm12.17-4.34H39.4l-4-8.89H46ZM21.14,17h9.49l4,8.89H15.06Z\"}),e.createElement(\"rect\",{fill:\"#505050\",x:\"2.59\",y:\"13.57\",width:\"4.34\",height:\"8.78\",transform:\"translate(-11.31 8.63) rotate(-45)\"}),e.createElement(\"rect\",{fill:\"#dc0069\",x:\"14.34\",y:\"1.57\",width:\"4.34\",height:\"8.79\",transform:\"translate(-0.97 7.57) rotate(-25.1)\"}),e.createElement(\"rect\",{fill:\"#dc0069\",x:\"31.39\",y:\"0.07\",width:\"4.34\",height:\"8.78\"}),e.createElement(\"rect\",{fill:\"#dc0069\",x:\"57.97\",y:\"15.79\",width:\"8.78\",height:\"4.34\",transform:\"translate(5.56 49.36) rotate(-45)\"}),e.createElement(\"rect\",{fill:\"#505050\",x:\"46.22\",y:\"3.79\",width:\"8.78\",height:\"4.34\",transform:\"translate(23.75 49.27) rotate(-64.9)\"}))};export{l as DiamondIcon};\n//# sourceMappingURL=DiamondIcon.js.map\n","import { DiscountType, SubjectType } from '@notino/shared/definitions/types';\n\nimport { messages } from './messages';\n\nexport const getDiscountWithSymbol = (\n discountType: DiscountType,\n value: number\n) =>\n ({\n // In future there is open possibility for other DiscountTypes\n [DiscountType.Percentage]: `${value}%`,\n }[discountType]);\n\nexport const subjectTypeMessages: Record<\n SubjectType,\n { id: string; defaultMessage: string }\n> = {\n [SubjectType.BrandDiscount]: messages.brandDiscount,\n [SubjectType.CategoryDiscount]: messages.categoryDiscount,\n};\n","import * as React from 'react';\nimport { FormattedMessage } from 'react-intl';\n\nimport { useQuery } from '@apollo/client';\n\nimport { ModalModel, ModalContext } from '@notino/react-styleguide';\nimport {\n CatalogVariantFragmentFragment,\n GetCustomerBenefitsQuery,\n} from '@notino/shared/definitions/types';\nimport { resetDataLayer } from '@notino/web-tracking';\n\nimport {\n TrackingContextProvider,\n useTrackingContext,\n} from '@context/tracking/TrackingContext';\n\nimport { useNewPdDesignEnabled } from '../../hooks/useNewPdDesignEnabled';\nimport { trackPageReload } from '../../tracking';\n\nimport { BenefitsModal } from './components/BenefitsModal';\nimport { HowToLoyaltyModal } from './components/HowToLoyaltyDiscountModal';\nimport { messages } from './messages';\nimport getCustomerBenefitsQuery from './queries/getCustomerBenefits.graphql';\nimport {\n CustomerDiscountBoldWrapper,\n CustomerDiscountWrapper,\n LoyaltyDiscountStyledWrapper,\n StyledDiamondIcon,\n} from './styled';\nimport { trackLoyaltyModalClose } from './trackLoyaltyModal';\nimport { getDiscountWithSymbol, subjectTypeMessages } from './utils';\n\ninterface ILoyaltyDiscount {\n customerBenefits: CatalogVariantFragmentFragment['features']['customerBenefits'];\n // We need these props to track pageView of PD after modal close\n gtmPageReloadProps: Parameters[0];\n}\n\nexport const LoyaltyDiscount: React.FC = ({\n customerBenefits,\n gtmPageReloadProps,\n}) => {\n const newDesign = useNewPdDesignEnabled();\n const { data, loading } = useQuery(\n getCustomerBenefitsQuery,\n {\n ssr: false,\n }\n );\n\n const { getTimeFromInit } = useTrackingContext();\n const { toggleModal, hideModal } = ModalContext.useModalContext();\n const modalLastClosedMs = React.useRef(0);\n TrackingContextProvider.useSubscribeToInitTimeReset(() => {\n modalLastClosedMs.current = 0;\n });\n\n const handleClick = () => {\n const hasBenefits = data?.customerBenefits?.hasActiveBenefits;\n const timing = getTimeFromInit() - modalLastClosedMs.current;\n toggleModal(\n hasBenefits ? (\n \n ) : (\n \n ),\n {\n noBorders: true,\n size: ModalModel.Sizes.large,\n showOverflow: true,\n positionBottomOnMobile: true,\n closeIconColor: !hasBenefits\n ? { xs: 'icon.inverse', md: 'icon.tertiary' }\n : undefined,\n onClose: () => {\n trackLoyaltyModalClose();\n modalLastClosedMs.current = getTimeFromInit();\n resetDataLayer();\n trackPageReload(gtmPageReloadProps);\n hideModal();\n },\n }\n );\n };\n\n const formattedBenefits = React.useMemo(\n () => ({\n availableDiscount: customerBenefits.availableDiscount && {\n value: getDiscountWithSymbol(\n customerBenefits.availableDiscount.discountType,\n customerBenefits.availableDiscount.value\n ),\n },\n customerDiscount: customerBenefits.customerDiscount && {\n value: getDiscountWithSymbol(\n customerBenefits.customerDiscount.discountType,\n customerBenefits.customerDiscount.value\n ),\n },\n }),\n [customerBenefits.availableDiscount, customerBenefits.customerDiscount]\n );\n\n if (\n !formattedBenefits.availableDiscount &&\n !formattedBenefits.customerDiscount\n ) {\n return null;\n }\n\n const isCustomerDiscount = Boolean(formattedBenefits.customerDiscount);\n\n return (\n \n <>\n \n {customerBenefits.availableDiscount && (\n \n )}\n {customerBenefits.customerDiscount && (\n \n \n ),\n customerDiscountBold: (\n \n