\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","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{b as e}from\"./_rollupPluginBabelHelpers-fc5c8eb1.js\";import{styled as n}from\"./styled.js\";var t,r,o,i=n.span(t||(t=e([\"\\n position: absolute;\\n top: \",\";\\n left: 0;\\n height: 16px;\\n width: 16px;\\n border-radius: 100%;\\n background-color: \",\";\\n border: 1px solid\\n \",\";\\n box-sizing: border-box;\\n\\n &:after {\\n content: '';\\n position: absolute;\\n display: none;\\n top: 2px;\\n left: 2px;\\n width: 10px;\\n height: 10px;\\n border-radius: 100%;\\n background-color: \",\";\\n }\\n\"])),(function(e){var n=e.position;return n>0?n+\"px\":0}),(function(e){return e.disabled?e.theme.palette.neutralLighter:e.theme.palette.basicInverse}),(function(e){return e.disabled?e.theme.palette.neutralLight:e.isHovered?e.theme.palette.basic:e.theme.palette.neutralDark}),(function(e){return e.disabled?e.theme.palette.neutralLight:e.theme.palette.basic})),a=n.label(r||(r=e([\"\\n display: block;\\n position: relative;\\n padding-left: 32px;\\n cursor: \",\";\\n color: \",\";\\n user-select: none;\\n font-size: 14px;\\n font-weight: \",\";\\n\\n &:hover input:not(:disabled):not(:checked) ~ \",\" {\\n border: 1px solid \",\";\\n }\\n\"])),(function(e){return e.disabled?\"inherit\":\"pointer\"}),(function(e){var n=e.disabled,t=e.theme;return n?t.palette.neutral:t.palette.basic}),(function(e){var n=e.bold;return void 0!==n&&n?800:300}),i,(function(e){return e.theme.palette.basic})),l=n.input(o||(o=e([\"\\n position: absolute;\\n opacity: 0;\\n top: 0;\\n left: 0;\\n\\n &:checked {\\n ~ \",\" {\\n border-color: \",\";\\n\\n &:after {\\n display: block;\\n }\\n }\\n }\\n\"])),i,(function(e){return e.disabled?e.theme.palette.neutralLight:e.theme.palette.basic}));export{a as C,l as S,i as a};\n//# sourceMappingURL=styled-78109075.js.map\n","import*as e from\"react\";import{n as o}from\"./utils-ec9be121.js\";import{C as s,S as a,a as r}from\"./styled-78109075.js\";import\"./_rollupPluginBabelHelpers-fc5c8eb1.js\";import\"./styled.js\";import\"styled-components\";var t=function(t){var i=t.children,d=t.disabled,l=t.checked,n=t.isHovered,m=t.onChange,c=void 0===m?o:m,p=t.position,b=void 0===p?0:p,v=t.className,f=t.bold,h=t.name;return e.createElement(s,{disabled:d,className:v,bold:f},i,e.createElement(a,{disabled:d,type:\"radio\",checked:l,onChange:c,bold:f,name:h}),e.createElement(r,{disabled:d,position:b,isHovered:n}))};export{t as RadioButton};\n//# sourceMappingURL=RadioButton.js.map\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.palette.neutralDark};\n padding-bottom: 0.25rem;\n`;\n\nexport const StoreStockAvailabilityWrapper = styled.div`\n color: ${theme.palette.success};\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.palette.neutralAlt};\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","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 * as React from 'react';\nimport { FormattedMessage } from 'react-intl';\n\nimport { snakeCase } from 'lodash';\n\nimport {\n ButtonModel,\n Colors,\n RadioButton,\n Spinner,\n} from '@notino/react-styleguide';\nimport {\n GetProductViewQuery,\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: GetProductViewQuery['productDetailByMasterId'][number];\n selectedVariant: GetProductViewQuery['productDetailByMasterId'][number]['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.id));\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.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 { GetProductViewQuery } from '@notino/shared/definitions/types';\n\nimport { getModifaceVariants, getModifaceHairVariants } from '../utils';\n\nexport const useModifaceVariants = (\n variants: GetProductViewQuery['productDetailByMasterId'][number]['variants']\n) => {\n return React.useMemo(() => getModifaceVariants(variants), [variants]);\n};\n\nexport const useModiface = (\n variants: GetProductViewQuery['productDetailByMasterId'][number]['variants']\n) => {\n return React.useMemo(\n () => ({\n makeup: getModifaceVariants(variants),\n hair: getModifaceHairVariants(variants),\n }),\n [variants]\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';\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 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 { GetProductViewQuery } 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: GetProductViewQuery['productDetailByMasterId'][number]['variants'][number];\n product: GetProductViewQuery['productDetailByMasterId'][number];\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","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 { trackPageView } from '@notino/web-tracking';\n\nimport { 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\nexport const trackLoyaltyModalDeprecated = (\n status: LoyaltyStatus,\n path?: string\n) => {\n trackPageView({\n type: 'Service',\n path: path ?? `/overlay_vip-discount/${status}/`,\n description: `/overlay_vip-discount/${status}/`,\n title: 'VIP program',\n params: {\n loyaltyStatus: status,\n },\n });\n};\n","import{_ as e}from\"./_rollupPluginBabelHelpers-fc5c8eb1.js\";import*as l from\"react\";import{Icon as m}from\"./index.js\";import\"./ThemeContext.js\";import\"styled-components\";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.palette.neutralLight};\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.palette.basic};\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';\nimport { trackEvent } from '@notino/web-tracking';\n\nimport { useFeatureFlags } from '@context/launch-darkly/LDProvider';\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 trackLoyaltyModalDeprecated,\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 { loyaltyGa4 } = useFeatureFlags();\n const { hideModal } = ModalContext.useModalContext();\n\n const { data } = useQuery(getCustomerBenefitsQuery);\n\n React.useEffect(() => {\n if (loyaltyGa4) {\n trackLoyaltyModalOpen(LoyaltyStatus.activated, timing);\n }\n }, [timing, loyaltyGa4]);\n\n React.useEffect(() => {\n if (!loyaltyGa4) {\n trackLoyaltyModalDeprecated(\n LoyaltyStatus.activated,\n '/overlay_vip-discount/confirmation/'\n );\n }\n }, [loyaltyGa4]);\n\n const handleSettingsClick = () => {\n if (loyaltyGa4) {\n dispatchTrackingEvent({\n event: 'vip_overlay_cta',\n vip: {\n action: 'click_on_overlay',\n name: 'change_settings',\n },\n });\n } else {\n trackEvent({\n eventCategory: 'Service',\n eventAction: 'LoyaltyOverlaySettings',\n eventLabel: undefined,\n eventValue: undefined,\n eventNonInteraction: undefined,\n });\n }\n };\n\n const handleOkClick = () => {\n if (loyaltyGa4) {\n trackLoyaltyModalClose();\n }\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.palette.neutralDarker};\n`;\n\nexport const LoginLink = styled.a`\n cursor: pointer;\n text-decoration: underline;\n color: ${theme.palette.neutralDarker};\n margin-left: 0.5rem;\n\n &:hover {\n text-decoration: none;\n }\n\n color: ${theme.palette.basic};\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 ? theme.palette.basic : theme.palette.neutralLight};\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 { trackEvent } from '@notino/web-tracking';\n\nimport { 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\nexport const trackLoyaltyCTADeprecated = (eventLabel: string) => {\n trackEvent({\n eventCategory: 'Service',\n eventAction: 'LoyaltyCTA',\n eventLabel,\n eventValue: undefined,\n eventNonInteraction: undefined,\n });\n};\n","import * as React from 'react';\nimport { FormattedMessage, useIntl } from 'react-intl';\n\nimport { useQuery } from '@apollo/client';\n\nimport {\n ButtonModel,\n CheckIcon,\n CloseIcon,\n Colors,\n} from '@notino/react-styleguide';\nimport {\n Roles,\n GetCustomerBenefitsQuery,\n GetUserLoyaltyProgressQuery,\n} from '@notino/shared/definitions/types';\n\nimport { LOGIN_URL } from '@constants';\nimport { useFeatureFlags } from '@context/launch-darkly/LDProvider';\n\nimport { MY_NOTINO_BENEFIT_PAGE, REGISTER_URL } from '../../constants';\nimport getCustomerBenefitsQuery from '../../queries/getCustomerBenefits.graphql';\nimport {\n determineStatus,\n trackLoyaltyModalDeprecated,\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, trackLoyaltyCTADeprecated } 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 { loyaltyGa4 } = useFeatureFlags();\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 if (loyaltyGa4) {\n trackLoyaltyCTA('register');\n } else {\n trackLoyaltyCTADeprecated('Register');\n }\n location.href = REGISTER_URL;\n } else {\n if (loyaltyGa4) {\n trackLoyaltyCTA('change_settings');\n } else {\n trackLoyaltyCTADeprecated('ChangeSettings');\n }\n location.href = MY_NOTINO_BENEFIT_PAGE;\n }\n };\n\n const handleLoginClick = () => {\n if (loyaltyGa4) {\n trackLoyaltyCTA('log_in');\n } else {\n trackLoyaltyCTADeprecated('Log in');\n }\n };\n\n React.useEffect(() => {\n if (loyaltyGa4 && !getUserLoading) {\n trackLoyaltyModalOpen(determineStatus(fulfilledSteps), timing);\n }\n }, [fulfilledSteps, timing, loyaltyGa4, getUserLoading]);\n\n React.useEffect(() => {\n if (!loyaltyGa4 && !getUserLoading) {\n trackLoyaltyModalDeprecated(determineStatus(fulfilledSteps));\n }\n }, [fulfilledSteps, loyaltyGa4, 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.palette.neutralDarker} !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-fc5c8eb1.js\";import*as e from\"react\";import{Icon as r}from\"./index.js\";import\"./ThemeContext.js\";import\"styled-components\";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, Colors } from '@notino/react-styleguide';\nimport {\n VariantFragmentFragment,\n GetCustomerBenefitsQuery,\n} from '@notino/shared/definitions/types';\nimport { resetDataLayer } from '@notino/web-tracking';\n\nimport { useFeatureFlags } from '@context/launch-darkly/LDProvider';\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: VariantFragmentFragment['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 { loyaltyGa4 } = useFeatureFlags();\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: Colors.basicInverse, md: Colors.neutralDark }\n : undefined,\n onClose: () => {\n if (loyaltyGa4) {\n trackLoyaltyModalClose();\n }\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 \n \n ),\n more: (\n \n \n \n ),\n }}\n />\n \n )}\n >\n \n );\n};\n","import { defineMessages } from 'react-intl';\n\nexport const messages = defineMessages({\n engravingMaxOrderQtyHeader: {\n id: 'engraving.max.order.quantity.header',\n defaultMessage: 'Lze objednat pouze {quantity} {unit}',\n },\n engravingMaxOrderQtyDesc: {\n id: 'engraving.max.order.quantity.description',\n defaultMessage:\n 'Aby se dostalo na co nejvíce zákazníku, z výrobních důvodů zatím neumožňujeme gravírování více kusů na jednu objednávku.',\n },\n addToCartQuantity: {\n id: 'pd.addToCart.quantity',\n defaultMessage: 'Množství',\n },\n});\n","import{a as o,_ as t}from\"./_rollupPluginBabelHelpers-fc5c8eb1.js\";import*as n from\"react\";import{T as r}from\"./index-f865d2ff.js\";import\"./TextAlign.js\";import\"./index-865c84cb.js\";import\"./utils-ec9be121.js\";import\"./StyledDropdown.js\";import\"./breakpoints.js\";import\"./theme.js\";import\"./styled.js\";import\"styled-components\";import\"./Colors.js\";import\"./CheckIcon.js\";import\"./index.js\";import\"./ThemeContext.js\";import\"./HorizontalChevron.js\";import\"./ChevronDownIcon.js\";import\"./ChevronUpIcon.js\";var e=[\"options\",\"unit\",\"handleOptionSelect\",\"currentOption\"],i=function(i){var p=i.options,s=i.unit,m=i.handleOptionSelect,c=void 0===m?function(){return null}:m,u=i.currentOption,l=void 0===u?0:u,a=o(i,e),d=n.useMemo((function(){var o=s?\" \"+s:\"\";return p.map((function(t){return{id:t,label:\"\"+t+o}}))}),[p,s]),j=n.useCallback((function(o){var t=o.id;c(Number(t))}),[c]),f=n.useMemo((function(){return l&&d.find((function(o){return o.id===l}))||d[0]}),[l,d]);return n.createElement(r,t({},a,{options:d,currentOption:f,handleOptionSelect:j}))};export{i as QuantitySelector};\n//# sourceMappingURL=QuantitySelector.js.map\n","import styled, { css } from 'styled-components';\n\nimport { breakpoints, QuantitySelector } from '@notino/react-styleguide';\n\nconst getGridTemplateAreas = (\n isClickAndCollect: boolean,\n isLoyaltyDiscount: boolean\n) => {\n if (isClickAndCollect && isLoyaltyDiscount) {\n return css`\n grid-template-areas:\n 'loyalty'\n 'addToCart'\n 'clickAndCollect';\n @media (min-width: ${breakpoints.sm}) {\n grid-template-columns: 1fr 1fr 1fr;\n grid-template-areas:\n 'loyalty loyalty loyalty'\n 'addToCart clickAndCollect _';\n }\n `;\n }\n if (isLoyaltyDiscount) {\n return css`\n grid-template-areas:\n 'loyalty'\n 'addToCart';\n `;\n }\n if (isClickAndCollect) {\n return css`\n grid-template-areas:\n 'addToCart'\n 'clickAndCollect';\n @media (min-width: ${breakpoints.sm}) {\n grid-template-columns: auto auto 1fr;\n grid-template-areas: 'addToCart clickAndCollect';\n }\n `;\n }\n return css`\n grid-template-areas: 'addToCart';\n `;\n};\n\nconst getNewGridTemplateAreas = (\n isClickAndCollect: boolean,\n isLoyaltyDiscount: boolean\n) => {\n if (isClickAndCollect && isLoyaltyDiscount) {\n return css`\n grid-template-areas:\n 'loyalty'\n 'addToCart'\n 'clickAndCollect';\n `;\n }\n if (isLoyaltyDiscount) {\n return css`\n grid-template-areas:\n 'loyalty'\n 'addToCart';\n `;\n }\n if (isClickAndCollect) {\n return css`\n grid-template-areas:\n 'addToCart'\n 'clickAndCollect';\n `;\n }\n return css`\n grid-template-areas: 'addToCart';\n `;\n};\n\nexport const BuyButtons = styled.div`\n display: grid;\n align-items: center;\n\n ${({ newDesign, isClickAndCollect, isLoyaltyDiscount, canBuy }) =>\n newDesign\n ? css`\n width: 100%;\n grid-gap: 0.5rem;\n padding: 1rem 0 1.5rem;\n ${getNewGridTemplateAreas(isClickAndCollect, isLoyaltyDiscount)}\n `\n : css`\n ${getGridTemplateAreas(isClickAndCollect, isLoyaltyDiscount)}\n grid-gap: 1rem;\n padding: 1rem 0;\n\n @media (min-width: ${breakpoints.sm}) {\n grid-gap: ${canBuy ? '2rem 1rem' : '0rem'};\n }\n `}\n`;\n\nexport const ButtonWrapper = styled.div<{ newDesign: boolean }>`\n & > button,\n form button {\n padding: 0 0.5625rem !important;\n height: 2.75rem;\n min-width: 7.5rem;\n text-transform: none !important;\n font-weight: normal !important;\n }\n flex: 1;\n min-width: 7.5rem;\n\n ${({ newDesign }) =>\n newDesign\n ? css`\n & > button,\n form button {\n height: 3.25rem;\n }\n `\n : css`\n @media (min-width: ${breakpoints.sm}) {\n flex: 0 1;\n }\n `}\n`;\n\nexport const Label = styled.label`\n display: none;\n`;\n\nexport const DropdownButtonSeparator = styled.div<{ newDesign: boolean }>`\n ${({ newDesign }) =>\n newDesign ? 'padding-right: 0.5rem' : 'padding-right: 1rem'}\n`;\n\nexport const QuantityWrapper = styled.div`\n width: 5.25rem;\n font-size: 0.875rem;\n & > div > div {\n min-height: 2.75rem;\n }\n`;\n\ninterface IWrapperProps {\n isClickAndCollect?: boolean;\n isLoyaltyDiscount?: boolean;\n canBuy?: boolean;\n newDesign: boolean;\n}\n\nexport const AddToCartWrapper = styled.div`\n grid-area: addToCart;\n\n display: flex;\n align-items: center;\n`;\n\nexport const ClickAndCollectWrapper = styled.div`\n grid-area: clickAndCollect;\n\n ${({ isClickAndCollect, newDesign }) =>\n isClickAndCollect &&\n css`\n margin-top: ${newDesign ? '-0.5rem' : '-1rem'};\n `}\n\n @media (min-width: ${breakpoints.sm}) {\n margin-top: 0;\n }\n`;\n\nexport const LoyaltyDiscountWrapper = styled.div`\n grid-area: loyalty;\n\n ${({ newDesign }) =>\n newDesign &&\n css`\n margin-bottom: 0.75rem;\n width: 100%;\n `}\n`;\n\nexport const StyledQuantitySelector = styled(QuantitySelector)<{\n newDesign: boolean;\n}>`\n ${({ newDesign }) =>\n newDesign &&\n css`\n [role='combobox'] {\n height: 3.25rem;\n }\n `}\n`;\n","import { snakeCase } from 'lodash';\n\nimport { GetProductViewQuery } from '@notino/shared/definitions/types';\nimport { CartType } from '@notino/web-tracking';\n\nimport { dispatchTrackingEvent } from '@context/tracking/utils';\nimport { ProductEventWither } from '@helpers/googleTagManager';\n\nexport const ENGRAVING_CODE = 'ENGXXXU_SENG01';\n\nexport const engravingPrefix = (text: string) => {\n return `Engraving - ${text}`;\n};\n\nexport const trackEngravingAddToCart = (\n productInfo: GetProductViewQuery['productDetailByMasterId'][number],\n variant: GetProductViewQuery['productDetailByMasterId'][number]['variants'][number],\n quantity,\n additionalPromoLabels: string[]\n) => {\n dispatchTrackingEvent({\n event: 'add_to_cart',\n product: ProductEventWither()\n .withProduct(productInfo)\n .withVariant(variant)\n .withAdditionalData({\n // use engraving product code instead of product code\n // more info in comments: https://notino.tpondemand.com/entity/132907-nushopweb-pd-trackovani-pridavani-gravirovani-do\n product_code: ENGRAVING_CODE,\n price: variant.engraving.config.price,\n brand_name: engravingPrefix(productInfo.brand),\n ...(variant.name && {\n name: engravingPrefix(variant.name),\n }),\n cart_type: snakeCase(CartType.cart),\n quantity,\n })\n .withAdditionalPromoLabels(additionalPromoLabels)\n .build(),\n _clear: true,\n });\n};\n","export const prepareOptions = (maxQuantity: number): number[] => {\n const options = [];\n\n for (let option = 1; option <= maxQuantity; option++) {\n options.push(option);\n }\n\n return options;\n};\n","import * as React from 'react';\nimport { FormattedMessage, useIntl } from 'react-intl';\n\nimport { snakeCase } from 'lodash';\n\nimport { ModalModel, TextAlign, ModalContext } from '@notino/react-styleguide';\nimport {\n CartServiceType,\n GetProductViewQuery,\n} from '@notino/shared/definitions/types';\nimport { AdditionalServicesAvailability, CartType } from '@notino/web-tracking';\nimport { Ga4Events } from '@notino/web-tracking/dist/types/package/ga4/events';\n\nimport ErrorBoundary from '@components/ErrorBoundary';\nimport { useTrackingDisplayType } from '@containers/ProductDetailContainer/utils';\nimport { useTrackingContext } from '@context/tracking/TrackingContext';\nimport { dispatchTrackingEvent } from '@context/tracking/utils';\nimport { ProductEventWither } from '@helpers/googleTagManager';\nimport { AddToCartButton } from '@sharedComponents/AddToCartButton/AddToCartButton';\n\nimport { ICurrency } from '../../../../App/model';\nimport { useNewPdDesignEnabled } from '../../hooks/useNewPdDesignEnabled';\nimport { usePriceLogic } from '../../hooks/usePriceLogic';\nimport {\n MIN_PRICE_PROMO_LABEL,\n RRP_PRICE_PROMO_LABEL,\n} from '../../hooks/usePriceLogic/tracking';\nimport { IModifaceEffectVariants } from '../../ModiFaceModal/model';\nimport { trackPageReload } from '../../tracking';\nimport { getLoyaltyDiscountState } from '../../utils';\nimport { ClickAndCollect } from '../ClickAndCollect';\nimport { useEngravingTryItFirstContext } from '../context/EngravingTryItFirst';\nimport { LoyaltyDiscount } from '../LoyaltyDiscount';\n\nimport { messages } from './addToCartMessages';\nimport {\n ButtonWrapper,\n BuyButtons,\n Label,\n DropdownButtonSeparator,\n QuantityWrapper,\n AddToCartWrapper,\n ClickAndCollectWrapper,\n LoyaltyDiscountWrapper,\n StyledQuantitySelector,\n} from './styled';\nimport { trackEngravingAddToCart } from './tracking';\nimport { prepareOptions } from './utils/prepareOptions';\n\ninterface IAddToCartProps {\n product: GetProductViewQuery['productDetailByMasterId'][number];\n variant: GetProductViewQuery['productDetailByMasterId'][number]['variants'][number];\n orderUnit: string;\n productCode: string;\n currency: ICurrency;\n onProductAdded: () => void;\n modifaceVariants: IModifaceEffectVariants;\n engravingAvailable: AdditionalServicesAvailability;\n tryItFirstAvailable: AdditionalServicesAvailability;\n giftAvailable: boolean;\n}\n\nconst QUANTITY_SELECTOR_KEYBOARD_CONFIG = {\n keyNavigation: true,\n};\n\nexport const AddToCart: React.FC = React.memo(\n ({\n variant,\n product,\n orderUnit,\n onProductAdded,\n modifaceVariants,\n engravingAvailable,\n tryItFirstAvailable,\n giftAvailable,\n }) => {\n const {\n state: { engravingInitials, withEngraving, withTryItFirst },\n } = useEngravingTryItFirstContext();\n const { hideModal, toggleModal } = ModalContext.useModalContext();\n const { getTimeFromInit } = useTrackingContext();\n const { formatMessage } = useIntl();\n const newDesign = useNewPdDesignEnabled();\n const [quantity, setQuantity] = React.useState(1);\n const { rrpShown, minimalPriceShown } = usePriceLogic(variant);\n\n const trackingDisplayType = useTrackingDisplayType(product);\n\n const onModalClose = React.useCallback(() => {\n setQuantity(1);\n hideModal();\n }, [hideModal]);\n\n const changeAmount = React.useCallback(\n (newQuantity: number): void => {\n if (withEngraving && newQuantity > 1) {\n const modalOptions = {\n header: (\n \n {formatMessage(messages.engravingMaxOrderQtyHeader, {\n quantity: 1,\n unit: orderUnit,\n })}\n
\n ),\n type: ModalModel.Types.default,\n onClose: onModalClose,\n };\n\n const modalContent = (\n \n );\n\n toggleModal(modalContent, modalOptions);\n }\n setQuantity(newQuantity);\n },\n [formatMessage, onModalClose, orderUnit, toggleModal, withEngraving]\n );\n\n const loyaltyDiscount = getLoyaltyDiscountState(variant.customerBenefits);\n\n const handleGtmPushProductDetail = React.useCallback(() => {\n trackPageReload({\n rrpShown,\n minimalPriceShown,\n variant,\n product,\n modifaceVariants,\n engravingAvailable,\n tryItFirstAvailable,\n giftAvailable,\n loyaltyDiscount,\n trackingDisplayType,\n });\n }, [\n variant,\n product,\n modifaceVariants,\n engravingAvailable,\n tryItFirstAvailable,\n giftAvailable,\n loyaltyDiscount,\n rrpShown,\n minimalPriceShown,\n trackingDisplayType,\n ]);\n\n const handleQuantitySelectorClick = () => {\n dispatchTrackingEvent({\n event: 'element_click',\n element: {\n timing: getTimeFromInit(),\n interaction: 'click',\n mode: undefined,\n name: 'quantity_selector',\n type: 'product_detail',\n action: 'click_on_element',\n promo_labels: undefined,\n },\n _clear: true,\n });\n };\n\n const services = React.useMemo(\n () =>\n withEngraving && [\n {\n type: CartServiceType.Engraving,\n value: engravingInitials,\n count: quantity,\n productId: variant.id,\n },\n ],\n [withEngraving, engravingInitials, quantity, variant.id]\n );\n\n const trackingProduct: Extract<\n Ga4Events,\n { event: 'add_to_cart' }\n >['product'] = React.useMemo(\n () =>\n ProductEventWither()\n .withProduct(product)\n .withVariant(variant)\n .withServices({\n modifaceVariants,\n tryItFirstAvailable,\n engravingAvailable,\n shadefinderAvailable: product.isShadeFinderAvailable,\n })\n .withAdditionalData({ quantity, cart_type: snakeCase(CartType.cart) })\n .withAdditionalPromoLabels([\n rrpShown && RRP_PRICE_PROMO_LABEL,\n minimalPriceShown && MIN_PRICE_PROMO_LABEL,\n ])\n .build(),\n [\n engravingAvailable,\n tryItFirstAvailable,\n product,\n minimalPriceShown,\n rrpShown,\n modifaceVariants,\n quantity,\n variant,\n ]\n );\n\n const handleProductAdded = React.useCallback(() => {\n onProductAdded();\n\n const additionalPromoLabels = [\n rrpShown && RRP_PRICE_PROMO_LABEL,\n minimalPriceShown && MIN_PRICE_PROMO_LABEL,\n ];\n dispatchTrackingEvent({\n event: 'add_to_cart',\n product: trackingProduct,\n _clear: true,\n });\n\n if (withEngraving) {\n trackEngravingAddToCart(\n product,\n variant,\n quantity,\n additionalPromoLabels\n );\n }\n }, [\n trackingProduct,\n product,\n variant,\n quantity,\n withEngraving,\n minimalPriceShown,\n rrpShown,\n onProductAdded,\n ]);\n\n const trackAddFailed = React.useCallback(\n (message: string) => {\n dispatchTrackingEvent({\n event: 'add_to_cart_failed',\n add: {\n products: [trackingProduct],\n },\n error: {\n status: message || '',\n },\n _clear: true,\n });\n },\n [trackingProduct]\n );\n\n const isClickAndCollect = variant.availablePickUpStores > 0;\n const isLoyaltyDiscount =\n Boolean(variant.customerBenefits?.availableDiscount) ||\n Boolean(variant.customerBenefits?.customerDiscount);\n\n return (\n \n \n {variant.canBuy && (\n \n \n \n \n \n \n (\n \n )}\n showAddToCartModal={product.config.showAddToCartModal}\n buttonElementId=\"pd-buy-button\"\n onProductAdded={handleProductAdded}\n onProductAddFailed={trackAddFailed}\n onClosingModal={handleGtmPushProductDetail}\n withLegacyAddToCart={true}\n />\n \n )}\n {isClickAndCollect && (\n \n 1}\n />\n \n )}\n {isLoyaltyDiscount && variant.canBuy && (\n \n \n \n )}\n \n \n );\n }\n);\n\nAddToCart.displayName = 'AddToCart';\n","import { defineMessages } from 'react-intl';\n\nexport const messages = defineMessages({\n taxIncludedDE: {\n id: 'pd.price.tax.included',\n defaultMessage: ', inkl. MwSt',\n },\n});\n","import styled from 'styled-components';\n\nimport { CurrencyStyled } from '@components/PriceLabel/components/styled';\n\nexport const PriceWrapper = styled.span`\n font-size: inherit;\n`;\n\nexport const CurrencyWrapper = styled(CurrencyStyled)`\n font-size: inherit;\n`;\n","import * as React from 'react';\nimport { FormattedMessage } from 'react-intl';\n\nimport { useQuery } from '@apollo/client';\n\nimport { IStock } from '@notino/shared/definitions/custom-definitions';\nimport { GetShowUnitPricesQuery } from '@notino/shared/definitions/types';\n\nimport PriceLabel from '@components/PriceLabel';\nimport { ILocale } from '@containers/App/model';\nimport { IPrice } from '@containers/ProductListing/model';\nimport getShowUnitPricesQuery from '@queries/showUnitPrices.graphql';\nimport { UnitPriceDecimalPlaces } from '@utils/constants';\n\nimport { messages } from './messages';\nimport { CurrencyWrapper, PriceWrapper } from './styled';\n\nexport interface IPriceRatioProps {\n stockAvailability: string;\n unitAmount: number;\n locale: ILocale;\n unit: string;\n unitPrice?: IPrice;\n settingsQuery?: GetShowUnitPricesQuery;\n prepend?: JSX.Element;\n}\n\nexport const showPriceRatio = (\n queryResult: GetShowUnitPricesQuery,\n stockAvailability: string,\n unitPrice: IPrice,\n unitAmount: number\n): boolean =>\n queryResult.Settings &&\n queryResult.Settings.showUnitPrices &&\n stockAvailability !== IStock.outOfStock &&\n unitPrice &&\n !!unitAmount;\n\nexport const PriceRatio: React.FC = ({\n unitAmount,\n unit,\n stockAvailability,\n unitPrice,\n settingsQuery: settingsQueryResultProps,\n prepend,\n}) => {\n const { data: settingsQueryResult } = useQuery(\n getShowUnitPricesQuery,\n {\n ssr: true,\n skip: Boolean(settingsQueryResultProps),\n }\n );\n\n const queryResult = settingsQueryResultProps || settingsQueryResult;\n\n if (!showPriceRatio(queryResult, stockAvailability, unitPrice, unitAmount)) {\n return null;\n }\n\n return (\n <>\n {prepend}\n \n {' '}\n / {`${unitAmount}\\u00A0${unit}`}\n \n \n >\n );\n};\n","import * as React from 'react';\nimport { FormattedMessage } from 'react-intl';\n\nimport { useQuery } from '@apollo/client';\n\nimport { Colors, Tooltip, TooltipModel } from '@notino/react-styleguide';\nimport { IStock } from '@notino/shared/definitions/custom-definitions';\nimport {\n Roles,\n VariantFragmentFragment,\n GetUserWithCartQuery,\n} from '@notino/shared/definitions/types';\n\nimport { useFormatPrice } from '@components/PriceLabel/useFormattedPrice';\nimport { ILocale } from '@containers/App/model';\nimport {\n IDamage,\n MaximumVolumeInPercent,\n} from '@containers/ProductListing/model';\nimport getUserWithCartQuery from '@queries/userWithCart.graphql';\n\nimport messages from '../../../messages';\nimport { useNewPdDesignEnabled } from '../../hooks/useNewPdDesignEnabled';\nimport { usePriceLogic } from '../../hooks/usePriceLogic';\nimport { PriceRatio } from '../VariantsInSelectBox/PriceRatio';\n\nimport {\n Wrapper,\n CodeBlock,\n CodeName,\n Separator,\n Availability,\n AdditionalDescriptionStyled,\n AdditionalText,\n StyledInfoIcon,\n TooltipContent,\n} from './styled';\n\nconst Damage: React.FC<{ damage: IDamage }> = ({ damage }) => {\n const message =\n damage.volumeInPercent === MaximumVolumeInPercent\n ? messages.productDamaged\n : messages.productReturned;\n\n return (\n \n \n \n );\n};\n\ninterface IBelowTheLineProps {\n variant: VariantFragmentFragment;\n locale: ILocale;\n}\n\nexport const BellowTheLine: React.FC = React.memo(\n ({ variant, locale }) => {\n const {\n stockAvailability,\n attributes,\n orderCode,\n productCode,\n id,\n annotation,\n additionalText,\n availablePickUpStores,\n canBuy,\n } = variant;\n\n const { data: { user: { role } = { role: null } } = {} } =\n useQuery(getUserWithCartQuery);\n\n const { bottomRecentPrice } = usePriceLogic(variant);\n const formatPrice = useFormatPrice();\n const newDesign = useNewPdDesignEnabled();\n\n const isImmediateCollection = availablePickUpStores > 0 && !canBuy;\n\n const isMaster = attributes && attributes.Master;\n\n return (\n \n \n {isImmediateCollection ? (\n \n ) : (\n \n )}\n \n\n {variant.unitPrice && (\n | }\n stockAvailability={variant.stockAvailability.code}\n unitAmount={variant.unitPrice.perAmount}\n locale={locale}\n unit={variant.unitPrice.unit}\n unitPrice={variant.unitPrice}\n />\n )}\n\n {bottomRecentPrice && (\n <>\n | \n {' '}\n {formatPrice(bottomRecentPrice.value)?.formattedPriceWithCurrency}\n {bottomRecentPrice.tooltip}\n }\n position={TooltipModel.Position.topLeft}\n >\n \n \n >\n )}\n\n | \n\n \n \n {' '}\n \n\n {role === Roles.Admin ? (\n \n {orderCode} {productCode} {id}\n {isMaster && M}\n \n ) : (\n orderCode\n )}\n \n\n {role === Roles.Admin && attributes.EAN && (\n \n EAN: {attributes.EAN}\n \n )}\n\n {attributes.IsForProfessionals && (\n \n \n \n )}\n\n {attributes.Damage && }\n\n {attributes.WithoutCellophane && (\n \n \n \n )}\n\n {attributes.DifferentPackaging && (\n \n \n \n )}\n\n {annotation && annotation.length > 0 && (\n \n {annotation}\n \n )}\n\n {additionalText && (\n \n )}\n \n );\n }\n);\n","import{_ as e}from\"./_rollupPluginBabelHelpers-fc5c8eb1.js\";import{c as t}from\"./createSvgIcon-89a7bcb8.js\";import\"react\";import\"./index.js\";import\"./ThemeContext.js\";import\"styled-components\";var o=function(o){return t(\"M497.535,14.465c-19.569-19.568-51.395-19.241-70.557,0.726L322.092,124.488L66.131,39.781L12.4,93.513l213.352,131.365L117.796,337.372l-69.231-11.366L0,374.571l101.78,35.649L137.429,512l48.565-48.565l-11.366-69.231l112.494-107.955L418.487,499.6l53.732-53.732l-84.706-255.961L496.808,85.022C516.776,65.86,517.103,34.034,497.535,14.465z\",e({viewBox:\"0 0 512 512\",\"data-testid\":\"plane-icon\"},o))};export{o as PlaneIcon};\n//# sourceMappingURL=PlaneIcon.js.map\n","import{c as e}from\"./createSvgIcon-89a7bcb8.js\";import\"react\";import\"./index.js\";import\"./_rollupPluginBabelHelpers-fc5c8eb1.js\";import\"./ThemeContext.js\";import\"styled-components\";var r=function(r){return e(\"M0,21.95,8,4h8.42L10.5,22ZM0,30V25H56v5H52.5V60H23V36H9V60H3.47V30Zm12.25-8L18.37,4H27V22ZM28.07,49H47V36H28.07ZM29,22V4h8.64l6.12,18ZM39.59,4H48l7.66,18H45.5Z\",r)};export{r as ShopIcon};\n//# sourceMappingURL=ShopIcon.js.map\n","import styled, { css } from 'styled-components';\n\nimport { breakpoints, theme } from '@notino/react-styleguide';\n\nexport const Container = styled.div<{ newDesign: boolean }>`\n padding: 1rem 0;\n\n ${({ newDesign }) =>\n newDesign &&\n css`\n padding: 1rem 0 2rem;\n @media (min-width: ${breakpoints.lg}) {\n padding: 1rem 0;\n }\n `}\n`;\n\nexport const SelectWrapper = styled.div``;\n\nexport const Select = styled.div`\n display: flex;\n justify-content: space-between;\n cursor: pointer;\n`;\n\nexport const DeliveryList = styled.div`\n flex: 10;\n padding-right: 0.5rem;\n`;\n\nexport const ChevronIconWrapper = styled.button<{ newDesign: boolean }>`\n cursor: pointer;\n width: 1rem;\n border: none;\n background-color: ${(props) => props.theme.palette.basicInverse};\n display: flex;\n justify-content: center;\n align-items: center;\n\n ${({ newDesign }) =>\n newDesign\n ? css`\n max-height: 6.5rem;\n `\n : css`\n max-height: 5.5rem;\n @media (min-width: ${breakpoints.sm}) {\n max-height: 3.1rem;\n }\n @media (min-width: ${breakpoints.md}) {\n max-height: 5.5rem;\n }\n @media (min-width: ${breakpoints.lg}) {\n max-height: 3.1rem;\n }\n `}\n`;\n\nexport const FlexRow = styled.div`\n align-items: flex-start;\n justify-content: space-between;\n color: ${(props) => props.theme.palette.neutralDarker};\n display: flex;\n flex-wrap: wrap;\n`;\n\nexport const FlexRowWithMargin = styled(FlexRow)<{ newDesign: boolean }>`\n &:last-child {\n margin-bottom: 0;\n }\n\n ${({ newDesign }) =>\n newDesign\n ? css`\n margin-bottom: 0.75rem;\n `\n : css`\n margin-bottom: 0.625rem;\n `}\n`;\n\nexport const DeliveryInfo = styled.div`\n display: flex;\n justify-content: space-between;\n flex-basis: 100%;\n align-items: center;\n`;\n\nexport const TopDeliveryInfo = styled(DeliveryInfo)<{ newDesign: boolean }>`\n flex-basis: 100%;\n\n &:last-child {\n margin-bottom: 0;\n }\n\n ${({ newDesign }) =>\n newDesign\n ? css`\n margin-bottom: 1.25rem;\n `\n : css`\n margin-bottom: 0.625rem;\n `}\n`;\n\nexport const DeliveryInfoWrapper = styled.div<{ newDesign: boolean }>`\n display: flex;\n width: 100%;\n\n ${({ newDesign }) =>\n newDesign\n ? css`\n flex-direction: column;\n `\n : css`\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: 0.25rem;\n `}\n`;\n\nexport interface IDeliveryTextColorProps {\n isInactive: boolean;\n newPdDesignEnabled: boolean;\n}\n\nconst deliveryTextColor = css`\n color: ${(props: IDeliveryTextColorProps) =>\n props.isInactive ? theme.palette.neutral : theme.palette.basic};\n`;\n\nexport const Name = styled.div`\n padding-right: 0.3125rem;\n min-width: 12.5rem;\n flex-basis: 100%;\n line-height: 1.2rem;\n ${deliveryTextColor};\n\n ${({ newPdDesignEnabled }) =>\n newPdDesignEnabled\n ? theme.typography.labelRegular\n : css`\n font-weight: bold;\n font-size: 0.875rem;\n `}\n\n @media (min-width: ${breakpoints.sm}) {\n flex-basis: auto;\n line-height: 1.3rem;\n }\n\n @media (min-width: ${breakpoints.md}) {\n flex-basis: 100%;\n line-height: 1.2rem;\n }\n\n @media (min-width: ${breakpoints.lg}) {\n flex-basis: auto;\n line-height: 1.3rem;\n }\n`;\n\nexport const DeliveryDate = styled.div`\n line-height: 1.2rem;\n ${deliveryTextColor}\n\n ${({ newPdDesignEnabled }) =>\n newPdDesignEnabled\n ? theme.typography.labelRegular400\n : css`\n font-weight: 300;\n font-size: 1rem;\n `}\n\n @media (min-width: ${breakpoints.sm}) {\n line-height: 1.3rem;\n }\n`;\n\nexport const TimeText = styled.span`\n color: ${(props) => props.theme.palette.successDark};\n`;\n\nexport const StyledHr = styled.hr<{ newDesign: boolean }>`\n height: 0.0625rem;\n border: none;\n background-color: ${(props) => props.theme.palette.neutralLighter};\n\n ${({ newDesign }) =>\n newDesign\n ? css`\n margin: 1.25rem 0 0.75rem 0;\n `\n : css`\n margin-top: 1rem;\n `}\n`;\n\nexport const DeliveryDescription = styled.div<{ newPdDesignEnabled: boolean }>`\n margin: 0.625rem 0 0.75rem 0;\n\n color: ${(props) => props.theme.palette.neutralDarker};\n\n ${({ newPdDesignEnabled }) =>\n newPdDesignEnabled\n ? theme.typography.bodySmall\n : css`\n font-size: 0.875rem;\n `}\n`;\n","import * as React from 'react';\n\nimport { Colors } from '@notino/react-styleguide';\n\nimport { useNewPdDesignEnabled } from '../../hooks/useNewPdDesignEnabled';\nimport { LeftIconWrapper } from '../styled';\n\nimport { DeliveryDate, DeliveryInfoWrapper, Name } from './styled';\n\ninterface IDeliveryLineProps {\n showIcon: boolean;\n icon: JSX.Element;\n name: string;\n description: JSX.Element | string;\n isInactive: boolean;\n}\n\nexport const DeliveryLine: React.FC = ({\n showIcon,\n icon,\n name,\n description,\n isInactive,\n}) => {\n const newPdDesignEnabled = useNewPdDesignEnabled();\n\n return (\n <>\n \n {showIcon &&\n React.cloneElement(icon, {\n color: isInactive ? Colors.neutral : Colors.basic,\n width: '20px',\n height: '20px',\n })}\n \n\n \n \n {name}\n \n\n \n {description}\n \n \n >\n );\n};\n","import { defineMessages } from 'react-intl';\n\nexport const messages = defineMessages({\n deliveryInfo: {\n id: 'pd.delivery.info',\n defaultMessage: 'Způsoby dopravy',\n },\n});\n","import * as React from 'react';\nimport { useIntl } from 'react-intl';\n\nimport styled, { css } from 'styled-components';\n\nimport { theme } from '@notino/react-styleguide';\n\nimport { useNewPdDesignEnabled } from '../../hooks/useNewPdDesignEnabled';\n\ninterface IFormattedDateProps {\n date: string;\n}\n\ninterface IFormattedTimeProps {\n from: string;\n to: string;\n}\n\nconst Span = styled.span<{ newDesign: boolean }>`\n ${({ newDesign }) =>\n newDesign &&\n css`\n color: ${theme.palette.neutralDarker};\n ${theme.typography.labelRegular400}\n `}\n`;\n\nexport const FormattedDate: React.FC = ({ date }) => {\n const { formatDate } = useIntl();\n const newDesign = useNewPdDesignEnabled();\n\n const dateObj = new Date(date);\n const dayName = formatDate(dateObj, { weekday: 'long' });\n const dayNumber = formatDate(dateObj, {\n day: 'numeric',\n month: 'numeric',\n year: 'numeric',\n });\n\n return {`${dayName} ${dayNumber}`};\n};\n\nexport const FormattedTime: React.FC = ({ from, to }) => {\n const { formatTime } = useIntl();\n const newDesign = useNewPdDesignEnabled();\n\n const fromObj = new Date(from);\n const fromNumber = formatTime(fromObj, {\n hour: '2-digit',\n minute: '2-digit',\n });\n\n const toObj = new Date(to);\n const toNumber = formatTime(toObj, {\n hour: '2-digit',\n minute: '2-digit',\n });\n\n return {`${fromNumber} - ${toNumber}`};\n};\n","import * as React from 'react';\nimport { FormattedMessage } from 'react-intl';\n\nimport messages from '../../../messages';\nimport { isTomorrow } from '../utils/dateUtils';\n\nimport { FormattedDate, FormattedTime } from './FormattedDate';\nimport { TimeText as StyledTimeText } from './styled';\n\ninterface ITimeTextProps {\n date: string;\n from?: string;\n to?: string;\n}\n\nexport const TimeText: React.FC = ({ date, from, to }) => {\n const dateToCompare = new Date(date);\n const nowDate = new Date().getDate();\n\n const isTomorrowDate = isTomorrow(dateToCompare);\n const isTodayDate = dateToCompare.getDate() === nowDate;\n\n const getFormattedDate = () => {\n if (from && to && (isTodayDate || isTomorrowDate)) {\n return ;\n }\n return ;\n };\n\n if (isTomorrowDate) {\n return (\n <>\n \n \n {' '}\n {getFormattedDate()}\n >\n );\n } else if (isTodayDate) {\n return (\n <>\n \n {' '}\n \n {from && to && getFormattedDate()}\n >\n );\n }\n\n return getFormattedDate();\n};\n","import * as React from 'react';\nimport { FormattedMessage, useIntl } from 'react-intl';\n\nimport {\n Colors,\n PlaneIcon,\n ShopIcon,\n TruckIcon,\n} from '@notino/react-styleguide';\nimport { GetProductViewQuery } from '@notino/shared/definitions/types';\n\nimport ErrorBoundary from '@components/ErrorBoundary';\nimport { useNewPdDesignEnabled } from '@containers/ProductDetailContainer/ProductDetail/hooks/useNewPdDesignEnabled';\nimport {\n DeliveryDisallowedReasons,\n IDelivery,\n} from '@containers/ProductListing/model';\nimport { useTrackingContext } from '@context/tracking/TrackingContext';\nimport { dispatchTrackingEvent } from '@context/tracking/utils';\nimport { HorizontalChevron } from '@sharedComponents/Icons/HorizontalChevron';\n\nimport messages from '../../../messages';\n\nimport { DeliveryLine } from './DeliveryLine';\nimport { messages as deliveryMessages } from './messages';\nimport {\n ChevronIconWrapper,\n Container,\n DeliveryDescription,\n DeliveryInfo,\n DeliveryList,\n FlexRow,\n FlexRowWithMargin,\n Select,\n SelectWrapper,\n StyledHr,\n TopDeliveryInfo,\n} from './styled';\nimport { TimeText } from './TimeText';\nimport {\n groupPossibleDeliveries,\n hasOneDeliveryTypeWithTwoOptions,\n} from './utils';\n\nexport enum DeliveriesDisplayMode {\n Static = 'Static',\n Expandable = 'Expandable',\n}\n\nexport interface IDeliveryTimeProps {\n deliveries: GetProductViewQuery['productDetailByMasterId'][number]['deliveries'];\n displayMode?: DeliveriesDisplayMode;\n}\n\nconst disallowedReasonMessageKeyMapping = {\n [DeliveryDisallowedReasons.AirTransportDisallowed]:\n messages.deliveryDisallowed,\n};\n\nconst getIconByDelivery = (delivery: IDelivery): JSX.Element => {\n if (delivery.isPersonal) {\n return ;\n } else if (delivery.isAirTransport) {\n return ;\n }\n\n return ;\n};\n\nexport const DeliveryTime: React.FC = React.memo(\n ({ deliveries, displayMode }) => {\n const { formatMessage } = useIntl();\n const { getTimeFromInit } = useTrackingContext();\n const isStatic = displayMode === DeliveriesDisplayMode.Static;\n const newPdDesignEnabled = useNewPdDesignEnabled();\n\n const [showAllDeliveriesMode, setShowAllDeliveriesMode] =\n React.useState(isStatic);\n\n const handleDeliveryListClick = (e: React.SyntheticEvent) => {\n e.preventDefault();\n\n dispatchTrackingEvent({\n event: 'element_click',\n element: {\n name: 'delivery_options',\n type: 'product_detail',\n mode: !showAllDeliveriesMode ? 'on' : 'off',\n timing: getTimeFromInit(),\n interaction: 'click',\n action: 'click_on_delivery',\n promo_labels: undefined,\n },\n _clear: true,\n });\n\n setShowAllDeliveriesMode((old) => !old);\n };\n\n const getDeliveryDescription = (delivery: IDelivery) => {\n if (delivery.disallowedReason) {\n const messageDescriptor =\n disallowedReasonMessageKeyMapping[delivery.disallowedReason];\n\n if (messageDescriptor) {\n return ;\n }\n }\n\n return (\n \n );\n };\n\n const groupedDeliveries = React.useMemo(\n () => groupPossibleDeliveries(deliveries),\n [deliveries]\n );\n\n const showAllDeliveries =\n showAllDeliveriesMode ||\n hasOneDeliveryTypeWithTwoOptions(groupedDeliveries);\n\n return (\n \n \n