{"version":3,"file":"_nuxt/CsOnTPnZ.js","sources":["../../../../components/Basket/basket-additive/BasketAdditiveItem.vue","../../../../components/Basket/basket-additive/BasketAdditiveToggle.vue","../../../../components/Basket/basket-additive/BasketAdditiveList.vue","../../../../components/Basket/basket-addresses/BasketAddressesCourier.vue","../../../../components/Basket/basket-addresses/BasketAddresses.vue","../../../../components/Basket/basket-client-pack/BasketClientPackInfo.vue","../../../../components/Basket/basket-client-pack/BasketClientPackItem.vue","../../../../components/Basket/basket-discount/BasketDiscountChoices.vue","../../../../components/Basket/basket-discount/BasketDiscountInput.vue","../../../../components/Basket/basket-discount/BasketDiscount.vue","../../../../components/Basket/basket-gifts/BasketGiftsInfo.vue","../../../../components/Basket/basket-gifts/BasketGiftsCard.vue","../../../../components/Basket/basket-gifts/BasketGiftsList.vue","../../../../components/Basket/basket-gifts/BasketGiftsToggle.vue","../../../../components/Basket/basket-utils/BasketSectionLoading.vue","../../../../components/Basket/basket-gifts/BasketGifts.vue","../../../../components/Basket/basket-note/BasketNote.vue","../../../../components/Basket/basket-order/BasketOrderHeader.vue","../../../../components/Basket/basket-order/BasketOrderAdditiveItem.vue","../../../../components/Basket/basket-order/BasketOrderGiftItem.vue","../../../../utils/formatProductForModification.ts","../../../../components/Basket/basket-order/BasketOrderItem.vue","../../../../components/Basket/basket-order/BasketOrderList.vue","../../../../components/Basket/basket-order/BasketOrder.vue","../../../../store/basket/basket.types.ts","../../../../store/basket/basket-time.ts","../../../../components/Basket/basket-price-panel/BasketPricePanelButton.vue","../../../../components/Basket/basket-price-panel/BasketPriceShortPanel.vue","../../../../components/Basket/basket-price-panel/BasketPricePanel.vue","../../../../components/Basket/basket-state/BasketFirstStep.vue","../../../../components/Basket/basket-payment/BasketCallSelect.vue","../../../../components/Basket/basket-payment/BasketPaymentChange.vue","../../../../components/Basket/basket-payment/BasketPaymentInfo.vue","../../../../components/Basket/basket-payment/BasketPaymentMethod.vue","../../../../components/Basket/basket-payment/BasketPaymentSavedCard.vue","../../../../components/Basket/basket-payment/BasketPaymentListItem.vue","../../../../components/Basket/basket-payment/BasketPaymentList.vue","../../../../components/Basket/basket-payment/BasketPayment.vue","../../../../types/components/basket-time.types.ts","../../../../components/Basket/basket-time/BasketTimeInfo.vue","../../../../components/Basket/basket-time/BasketAvailableTime.vue","../../../../components/Basket/basket-time/BasketOnTimeSelects.vue","../../../../components/Basket/basket-time/BasketOnTime.vue","../../../../components/Basket/basket-time/BasketTimeTabActive.vue","../../../../components/Basket/basket-time/BasketTimeTabs.vue","../../../../components/Basket/basket-time/BasketTime.vue","../../../../components/Basket/basket-state/BasketSecondStep.vue","../../../../utils/scrollToBlock.ts","../../../../components/Basket/basket-state/TheBasket.vue","../../../../pages/basket/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useProductCounter } from '@/composables/useProductCounter'\n\nimport { useCityStore } from '@/store/city/city'\n\nimport { AdditiveItem } from '@/types/api/api-v3/basket'\n\ntype Props = {\n additives: AdditiveItem[]\n additive: AdditiveItem\n}\n\nconst props = defineProps<Props>()\n\nconst { isMobile } = useResponsive()\n\nconst cityStore = useCityStore()\n\nconst productId = computed(() => props.additive.product_id)\n\nconst {\n quantitySelectedProducts,\n setProductQuantity,\n decreaseQuantity,\n increaseQuantity,\n} = useProductCounter(productId)\n\nconst currencySymbol = computed(() => {\n return cityStore.currencySymbol\n})\n\nconst additivePrice = computed(() => {\n return props.additive.total_price === 0\n ? `0 ${currencySymbol.value}`\n : `+${props.additive.total_price} ${currencySymbol.value}`\n})\n\nconst additives = computed(() => props.additives)\n\nconst isErrorImage = ref(false)\n\nconst productImage = computed(() => {\n if (isErrorImage.value || !props.additive.image_url) {\n return '/default-image-desktop.png'\n }\n\n return props.additive.image_url\n})\n\nwatch(additives, () => {\n for (const additive of additives.value) {\n /* Изменяем значение только для текущей добавки */\n if (additive.product_id === productId.value) {\n setProductQuantity(additive.total_quantity)\n return\n }\n }\n})\n\nonMounted(() => {\n setProductQuantity(props.additive.total_quantity)\n})\n</script>\n\n<template>\n <div class=\"additive\">\n <nuxt-img\n :src=\"productImage\"\n :alt=\"additive.title\"\n class=\"additive__image\"\n @error=\"isErrorImage = true\"\n />\n\n <p class=\"additive__price\">\n {{ additivePrice }}\n </p>\n\n <p class=\"additive__title\" :title=\"additive.title\">{{ additive.title }}</p>\n\n <div class=\"additive__button\">\n <the-counter\n :min=\"0\"\n :value=\"quantitySelectedProducts\"\n :size=\"isMobile ? 'xs' : 'sm'\"\n variant=\"secondary\"\n @on-decrease=\"decreaseQuantity\"\n @on-increase=\"increaseQuantity\"\n />\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.additive {\n width: 100%;\n max-width: 128px;\n max-height: 206px;\n padding: 8px;\n font-size: 14px;\n font-weight: 600;\n background-color: var(--ui-grey);\n border-radius: 16px;\n\n &__image {\n width: 100%;\n height: 76px;\n object-fit: contain;\n }\n\n &__price {\n margin-bottom: 4px;\n font-weight: 800;\n color: var(--ui-text-primary);\n }\n\n &__title {\n margin-bottom: 16px;\n overflow: hidden;\n color: var(--ui-text-primary);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__button {\n display: flex;\n justify-content: center;\n\n :deep(.app-counter) {\n min-width: 100%;\n height: 40px;\n }\n }\n\n @include media('<tablet') {\n width: 100%;\n min-width: 100px;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nconst TEXT = {\n show: 'Показать все',\n hide: 'Скрыть',\n}\n\ntype Props = {\n showAllAdditives: boolean\n}\n\nconst props = defineProps<Props>()\n\nconst emit = defineEmits(['toggleAdditives'])\n\nconst { isMobile } = useResponsive()\n\nconst text = computed(() => {\n if (isMobile.value) return TEXT.show\n\n return props.showAllAdditives ? TEXT.hide : TEXT.show\n})\n\nconst toggleAdditives = () => emit('toggleAdditives')\n</script>\n\n<template>\n <div class=\"button-wrapper\">\n <the-button\n class=\"button-wrapper__button\"\n variant=\"transparent\"\n size=\"sm\"\n font=\"sm\"\n type=\"button\"\n @click=\"toggleAdditives\"\n >\n {{ text }}\n\n <template #append>\n <the-icon\n class=\"button-wrapper__icon\"\n :class=\"{\n 'button-wrapper__icon--rotate': showAllAdditives && !isMobile,\n }\"\n name=\"expand-down\"\n color=\"var(--ui-primary)\"\n />\n </template>\n </the-button>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.button-wrapper {\n display: flex;\n justify-content: flex-start;\n\n &__button {\n display: flex;\n align-items: center;\n }\n\n &__icon {\n &--rotate {\n transform: rotate(-180deg);\n }\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { AdditiveItem } from '@/types/api/api-v3/basket'\n\nimport BasketAdditiveItem from '@/components/Basket/basket-additive/BasketAdditiveItem.vue'\nimport BasketAdditiveToggle from '@/components/Basket/basket-additive/BasketAdditiveToggle.vue'\nimport BasketTitle from '@/components/Basket/basket-utils/BasketTitle.vue'\n\nconst DialogBasketAdditives = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/DialogBasketAdditives.vue'),\n)\n\nconst MAX_VISIBLE_ADDITIVES_FOR_DESKTOP = 4\nconst MAX_VISIBLE_ADDITIVES_FOR_MOBILE = 3\n\ntype Props = {\n additives: AdditiveItem[]\n}\n\nconst props = defineProps<Props>()\n\nconst { isMobile } = useResponsive()\n\nconst showAllAdditives = ref(false)\n\nconst maxVisibleAdditives = computed(() => {\n return isMobile.value\n ? MAX_VISIBLE_ADDITIVES_FOR_MOBILE\n : MAX_VISIBLE_ADDITIVES_FOR_DESKTOP\n})\n\nconst dialogs = ref({\n allAdditives: {\n visible: false,\n },\n})\n\nconst showAllButtonVisible = computed(() => {\n if (isMobile.value) {\n return (\n props.additives.length > maxVisibleAdditives.value &&\n props?.additives?.length > MAX_VISIBLE_ADDITIVES_FOR_MOBILE\n )\n }\n\n return (\n props.additives.length > maxVisibleAdditives.value &&\n props?.additives?.length > MAX_VISIBLE_ADDITIVES_FOR_DESKTOP\n )\n})\n\nconst countOfVisibleAdditives = computed(() => {\n if (isMobile.value) return maxVisibleAdditives.value\n\n return showAllAdditives.value\n ? props.additives.length\n : maxVisibleAdditives.value\n})\n\nconst toggleShowAllAdditives = () => {\n if (isMobile.value) {\n dialogs.value.allAdditives.visible = true\n\n return\n }\n\n showAllAdditives.value = !showAllAdditives.value\n}\n</script>\n\n<template>\n <div class=\"additives\">\n <div class=\"additives__list\">\n <basket-additive-item\n v-for=\"(additive, index) of additives\"\n v-show=\"index + 1 <= countOfVisibleAdditives\"\n :key=\"additive.product_id\"\n :additive=\"additive\"\n :additives=\"additives\"\n class=\"additives__list-item\"\n />\n </div>\n\n <basket-additive-toggle\n v-if=\"showAllButtonVisible\"\n :show-all-additives=\"showAllAdditives\"\n @toggle-additives=\"toggleShowAllAdditives\"\n />\n\n <the-bottom-sheet v-if=\"isMobile\" v-model=\"dialogs.allAdditives.visible\">\n <basket-title class=\"dialog-title\" title=\"Добавить к заказу\" />\n\n <dialog-basket-additives :additives=\"additives\" />\n </the-bottom-sheet>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.additives {\n &__list {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 0 10px;\n margin-bottom: 15px;\n\n @include media('>=tablet') {\n grid-template-columns: repeat(4, 1fr);\n gap: 0 16px;\n justify-content: space-between;\n margin-bottom: 16px;\n }\n\n @include media('>=desktop-mini') {\n gap: 25px 16px;\n }\n }\n}\n\n.dialog-title {\n position: static !important;\n padding: 0 !important;\n margin-bottom: 0;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { required as veeRequiredValidator } from '@vee-validate/rules'\nimport { defineRule, Field as VeeField } from 'vee-validate'\n\nimport { useAddressesStore } from '@/store/addresses/addresses'\nimport { useAppStore } from '@/store/app/app'\nimport { SnackbarType } from '@/store/app/app.types'\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useToggleStore } from '@/store/toggle/toggle'\n\nimport { AddressClient } from '@/api/modules/addresses/addresses.types'\nimport { DeliveryMethods } from '@/api/modules/basket/types'\nimport { Success } from '@/api/results'\n\nimport BasketAddressList from '@/components/Basket/basket-addresses/BasketAddressList.vue'\n\nconst BasketFailed = defineAsyncComponent(\n () => import('@/components/Basket/basket-utils/BasketFailed.vue'),\n)\nconst DialogBasketAddAddressForm = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/DialogBasketAddAddressForm.vue'),\n)\nconst NewDialogBasketAddAddressForm = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/NewDialogBasketAddAddressForm.vue'),\n)\nconst NewDialogBasketEditAddress = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/NewDialogBasketEditAddress.vue'),\n)\nconst NewDialogBasketDeleteAddress = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/NewDialogBasketDeleteAddress.vue'),\n)\nconst DialogBasketEditAddressForm = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/DialogBasketEditAddressForm.vue'),\n)\nconst DialogBasketDeleteAddress = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/DialogBasketDeleteAddress.vue'),\n)\nconst DialogRedirectOtherCity = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/DialogRedirectOtherCity.vue'),\n)\nconst BasketDeliveryAddressNotification = defineAsyncComponent(\n () =>\n import(\n '@/components/Basket/basket-addresses/BasketDeliveryAddressNotification.vue'\n ),\n)\n\ntype Props = {\n selectedAddress?: AddressClient\n maxCountOfVisibleAddresses: number\n deliveryMethod: DeliveryMethods\n}\ndefineProps<Props>()\n\nconst { $metrics } = useNuxtApp()\n\nconst { showSnackbar } = useAppStore()\nconst basketStore = useBasketStore()\nconst addressesStore = useAddressesStore()\nconst { newFetchingApiEnabled } = useToggleStore()\n\nconst emit = defineEmits(['delivery-method-changed', 'select-delivery-courier'])\n\nconst dialogs = ref({\n addAddress: {\n visible: false,\n },\n editAddress: {\n visible: false,\n editableAddress: null as AddressClient | null,\n },\n deleteAddress: {\n visible: false,\n address: null as AddressClient | null,\n },\n redirectCity: {\n visible: false,\n address: null as AddressClient | null,\n },\n isShowNotification: false,\n})\n\nconst basket = computed(() => basketStore.data)\n\nconst addresses = computed(() => addressesStore.addresses)\n\nconst deliveryCost = computed(() => basket.value.delivery.cost)\n\nconst setSelectedAddress = async (value: AddressClient) => {\n if (!value || ('is_in_delivery_area' in value && !value.is_in_delivery_area))\n return\n\n await basketStore.setDeliveryMethod({\n address_id: value.id,\n delivery_method: DeliveryMethods.COURIER,\n })\n\n onDeliveryMethodChanged()\n}\n\nconst openAddAddressDialog = () => {\n dialogs.value.addAddress.visible = true\n $metrics?.eventSendGoal({ ym: 'basket_address_window_open' })\n}\n\nconst openEditAddressDialog = (address: AddressClient) => {\n dialogs.value.editAddress.visible = true\n dialogs.value.editAddress.editableAddress = address\n}\n\nconst closeEditAddressDialog = () => {\n dialogs.value.editAddress.visible = false\n dialogs.value.editAddress.editableAddress = null\n}\n\nconst openDeleteAddressDialog = (address: AddressClient) => {\n dialogs.value.deleteAddress.visible = true\n dialogs.value.deleteAddress.address = address\n}\n\nconst openDialogRedirectCity = (address: AddressClient) => {\n dialogs.value.redirectCity.visible = true\n dialogs.value.redirectCity.address = address\n}\n\nconst openDialogNotification = () => {\n dialogs.value.isShowNotification = true\n}\n\nconst closeDialogRedirectCity = () => {\n dialogs.value.redirectCity.visible = false\n}\n\nconst onDeliveryMethodChanged = () => {\n emit('delivery-method-changed')\n}\n\nconst onSelectDeliveryCourier = () => {\n emit('select-delivery-courier')\n}\n\nconst addAddress = async (address: AddressClient) => {\n const { allow_redirect, is_in_delivery_area, id } = address\n\n // Если адрес в зоне доставки, то не устанавливаем его\n if (is_in_delivery_area && !newFetchingApiEnabled) {\n await basketStore.setDeliveryMethod({\n delivery_method: DeliveryMethods.COURIER,\n address_id: id,\n })\n }\n\n // В случае если адрес в зоне доставки и адрес текущего города\n const isAllowedAddress =\n is_in_delivery_area && newFetchingApiEnabled && !allow_redirect\n\n if (isAllowedAddress) {\n await basketStore.setDeliveryMethod({\n delivery_method: DeliveryMethods.COURIER,\n address_id: id,\n })\n }\n\n onDeliveryMethodChanged()\n\n dialogs.value.addAddress.visible = false\n\n await fetchAddress()\n\n showSnackbar({\n message: 'Адрес добавлен',\n type: SnackbarType.SUCCESS,\n })\n\n // Если адрес вне зоны доставки\n if (!is_in_delivery_area) {\n openDialogNotification()\n\n return\n }\n\n // Если адрес в зоне доставки и другой город\n if (newFetchingApiEnabled && allow_redirect) {\n openDialogRedirectCity(address)\n\n return\n }\n\n basketStore.setAddress({\n type: DeliveryMethods.COURIER,\n id,\n })\n}\n\nconst fetchAddress = async () => {\n const result = await addressesStore.getAddresses()\n\n if (result instanceof Success) return\n\n showSnackbar({ message: 'Не удалось загрузить список адресов' })\n}\n\nconst editAddress = async () => {\n dialogs.value.editAddress.visible = false\n\n await fetchAddress()\n}\n\nconst closeDialogDeleteAddress = async (\n isUpdate: boolean,\n addressId?: number,\n) => {\n dialogs.value.deleteAddress.visible = false\n\n // В случае, если адреса не нужно обновлять или нет id\n if (!isUpdate || !addressId) return\n\n await fetchAddress()\n\n if (basket.value.delivery.addresses.courier === addressId) {\n await basketStore.fetchBasket()\n }\n}\n\nconst deleteAddress = async (addressId: number) => {\n dialogs.value.editAddress.visible = false\n\n await fetchAddress()\n\n if (basket.value.delivery.addresses.courier === addressId) {\n await basketStore.fetchBasket()\n }\n}\n\nconst requiredAddress = (value: string) => {\n if (!veeRequiredValidator(value)) {\n return 'Выберите адрес'\n }\n\n return true\n}\n\ndefineRule('required-address', requiredAddress)\n</script>\n\n<template>\n <div id=\"address_id\" class=\"basket-courier\">\n <the-loader\n v-if=\"addresses.isLoading\"\n size=\"100\"\n variant=\"circular\"\n color=\"var(--ui-primary)\"\n />\n\n <basket-failed\n v-else-if=\"addresses.error\"\n :error-message=\"'Не удалось загрузить список адресов'\"\n @update=\"fetchAddress\"\n />\n\n <div v-else>\n <div\n v-if=\"addresses.data.length === 0\"\n class=\"basket-courier__address-message\"\n >\n Укажите адрес для доставки\n </div>\n\n <vee-field\n v-slot=\"{ errors, field }\"\n rules=\"required-address\"\n name=\"address_id\"\n :model-value=\"selectedAddress\"\n validate-on-mount\n >\n <basket-address-list\n v-if=\"addresses.data.length\"\n class=\"basket-courier__address-list\"\n v-bind=\"field\"\n :model-value=\"selectedAddress\"\n :max-count-of-visible-addresses=\"maxCountOfVisibleAddresses\"\n :addresses=\"addresses.data\"\n :delivery-cost=\"deliveryCost\"\n :delivery-method=\"deliveryMethod\"\n @delivery-method-changed=\"onDeliveryMethodChanged\"\n @select-delivery-courier=\"onSelectDeliveryCourier\"\n @open-edit-address-dialog=\"openEditAddressDialog\"\n @open-delete-address-dialog=\"openDeleteAddressDialog\"\n @open-dialog-notification=\"openDialogNotification\"\n @open-dialog-redirect-city=\"openDialogRedirectCity\"\n @update:model-value=\"setSelectedAddress\"\n />\n\n <the-button\n class=\"basket-courier__btn-add\"\n icon=\"add-circle\"\n indent-left\n variant=\"transparent\"\n size=\"sm\"\n font=\"sm\"\n :ripple=\"false\"\n @click.prevent=\"openAddAddressDialog\"\n >\n Добавить адрес\n </the-button>\n\n <basket-failed\n v-if=\"Object.keys(errors).length\"\n :error-message=\"errors[0]\"\n without-button\n />\n\n <basket-failed\n v-else-if=\"deliveryCost && deliveryCost.error_message\"\n :error-message=\"deliveryCost.error_message\"\n without-button\n />\n\n <div\n v-else-if=\"deliveryCost && deliveryCost.help_message\"\n class=\"basket-courier__help-message\"\n >\n <nuxt-img src=\"/winking-face.png\" alt=\"winking face\" />\n {{ deliveryCost.help_message }}\n </div>\n </vee-field>\n </div>\n\n <the-dialog v-model=\"dialogs.editAddress.visible\" :max-width=\"560\">\n <template v-if=\"dialogs.editAddress.editableAddress\">\n <transition v-if=\"!newFetchingApiEnabled\" :duration=\"150\">\n <dialog-basket-edit-address-form\n :address=\"dialogs.editAddress.editableAddress\"\n @delete=\"deleteAddress\"\n @edit=\"editAddress\"\n />\n </transition>\n\n <transition v-if=\"newFetchingApiEnabled\" :duration=\"150\">\n <new-dialog-basket-edit-address\n :address=\"dialogs.editAddress.editableAddress\"\n @delete=\"deleteAddress\"\n @edit=\"editAddress\"\n @close=\"closeEditAddressDialog\"\n />\n </transition>\n </template>\n </the-dialog>\n\n <the-dialog v-model=\"dialogs.addAddress.visible\" :max-width=\"560\">\n <new-dialog-basket-add-address-form\n v-if=\"newFetchingApiEnabled\"\n @add=\"addAddress\"\n />\n\n <dialog-basket-add-address-form v-else @add=\"addAddress\" />\n </the-dialog>\n\n <the-dialog v-model=\"dialogs.deleteAddress.visible\">\n <template v-if=\"dialogs.deleteAddress.address\">\n <new-dialog-basket-delete-address\n v-if=\"newFetchingApiEnabled\"\n :address=\"dialogs.deleteAddress.address\"\n @close-dialog-delete-address=\"closeDialogDeleteAddress\"\n />\n\n <dialog-basket-delete-address\n v-else\n :address=\"dialogs.deleteAddress.address\"\n @close-dialog-delete-address=\"closeDialogDeleteAddress\"\n />\n </template>\n </the-dialog>\n\n <the-dialog\n v-if=\"newFetchingApiEnabled\"\n v-model=\"dialogs.redirectCity.visible\"\n :max-width=\"620\"\n >\n <dialog-redirect-other-city\n v-if=\"dialogs.redirectCity.address\"\n :id=\"dialogs.redirectCity.address.id\"\n :city-domain-prefix=\"dialogs.redirectCity.address.city_domain_prefix\"\n @close-dialog-delete-address=\"closeDialogRedirectCity\"\n @close-dialog-redirect-city=\"closeDialogRedirectCity\"\n />\n </the-dialog>\n\n <the-dialog\n v-model=\"dialogs.isShowNotification\"\n :max-width=\"620\"\n padding=\"0\"\n >\n <basket-delivery-address-notification\n @select-delivery-courier=\"onSelectDeliveryCourier\"\n />\n </the-dialog>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.basket-courier {\n .app-loader {\n position: relative;\n }\n\n &__address-message {\n margin-bottom: 24px;\n font-size: 18px;\n font-weight: 800;\n }\n\n &__address-list {\n margin-bottom: 10px;\n }\n\n &__help-message {\n display: flex;\n margin-top: 33px;\n font-size: 14px;\n font-weight: 600;\n\n img {\n align-self: flex-start;\n width: 24px;\n margin-right: 12px;\n }\n }\n\n &__dialog-title {\n font-size: 20px;\n font-weight: 800;\n }\n\n &__btn-add {\n padding-left: 32px;\n\n :deep(.app-button__icon) {\n left: 0px;\n }\n\n &:hover {\n background-color: transparent !important;\n }\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useBasketMethods } from '@/composables/useBasketMethods'\n\nimport { useAddressesStore } from '@/store/addresses/addresses'\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useBasketPaymentMethodsStore } from '@/store/basket/basket-payment-methods'\nimport { useBasketPointStore } from '@/store/basket/basket-point'\n\nimport {\n DeliveryMethods,\n SetDeliveryMethodPayload,\n} from '@/api/modules/basket/types'\nimport { BasketPoint } from '@/types/api/api-v3/basket-points'\nimport { isAddressClient } from '@/types/store/basket/index'\n\nimport BasketAddressesCourier from '@/components/Basket/basket-addresses/BasketAddressesCourier.vue'\nimport BasketAddressesTabs from '@/components/Basket/basket-addresses/BasketAddressesTabs.vue'\nimport BasketAddressesWindows from '@/components/Basket/basket-addresses/BasketAddressesWindows.vue'\nimport BasketTitle from '@/components/Basket/basket-utils/BasketTitle.vue'\n\nimport type { AddressClient } from '@/api/modules/addresses/addresses.types'\n\nconst DialogRedirectOtherCity = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/DialogRedirectOtherCity.vue'),\n)\n\nconst { $sentryCaptureException } = useNuxtApp()\n\nconst addressesStore = useAddressesStore()\nconst basketStore = useBasketStore()\nconst basketPaymentMethodsStore = useBasketPaymentMethodsStore()\nconst pointStore = useBasketPointStore()\n\nconst { setBasketDeliveryMethod } = useBasketMethods()\n\nconst isUpdatePoint = computed(() => basketStore.isExtraBasket)\n\n// Следим за флагом и обновляем список точек\nwatch(isUpdatePoint, () => pointStore.getPoints())\n\nconst dialogs = ref({\n redirect: {\n visible: false,\n address: null as AddressClient | null,\n },\n})\n\nconst onChangeBasketDeliveryMethod = async () => {\n const address = await setBasketDeliveryMethod()\n\n if (!address) return\n\n // Нужна задержка потому что ДО авторизации не успевает закрыться и получается наложение двух ДО\n setTimeout(() => {\n dialogs.value.redirect.visible = true\n dialogs.value.redirect.address = address\n }, 1000)\n}\n\nonMounted(async () => {\n await onChangeBasketDeliveryMethod()\n\n await Promise.all([pointStore.getPoints(), addressesStore.getAddresses()])\n\n if (pointStore.error || addressesStore.addresses.error)\n $sentryCaptureException(pointStore.error || addressesStore.addresses.error)\n\n await checkRelevanceOfDelivery()\n\n // @ts-ignore\n window.carrotquest?.track('Выбрана доставка', {})\n})\n\nconst deliveryMethod = computed(() => basketStore.data.delivery.method)\n\nconst courierPoints = computed(() => addressesStore.addresses.data)\nconst pickupPoints = computed(() => pointStore.pickupPoints)\nconst hallPoints = computed(() => pointStore.hallPoints)\n// TODO [basket-refactoring]\n// архитектурная проблема, что \"самовывоз\" и \"в ресторане\" - это одна модель и список, а \"Доставка\" - другая/другой\n// Поэтому приходится везде писать проверки на тип DeliveryMethod\nconst allPoints = computed(() => {\n return {\n [DeliveryMethods.COURIER]: courierPoints.value,\n [DeliveryMethods.PICKUP]: pickupPoints.value,\n [DeliveryMethods.HALL]: hallPoints.value,\n }\n})\n\n/* Windows */\nconst selectedAddress = computed(() => {\n const selectedAddressId =\n basketStore.data.delivery.addresses[deliveryMethod.value] || null\n\n // Ищем адрес целиком\n return allPoints.value[deliveryMethod.value].find(\n ({ id }) => id === selectedAddressId,\n )\n})\n\n// Метод проверки актуальности установленной доставки\nconst checkRelevanceOfDelivery = async () => {\n if (deliveryMethod.value === DeliveryMethods.COURIER) return\n\n // В случае если точки нет в списке\n if (!selectedAddress.value) {\n await basketStore.fetchBasket()\n\n return\n }\n\n const isNeedUpdateBasket = pointStore.checkRelevanceOfPoint(\n selectedAddress.value as BasketPoint,\n deliveryMethod.value,\n )\n\n if (isNeedUpdateBasket) await basketStore.fetchBasket()\n}\n\nconst deliveryMethodChanged = () => {\n // Устанавливаем первый из списка оплат\n if (basketPaymentMethodsStore.data.length)\n basketStore.setSelectedPaymentMethod(basketPaymentMethodsStore.data[0])\n}\n\nconst setDeliveryMethod = async (newDeliveryMethod: DeliveryMethods) => {\n const points = allPoints.value[newDeliveryMethod]\n\n let deliveryMethodPayload: SetDeliveryMethodPayload = {\n delivery_method: newDeliveryMethod,\n point_id: points[0]?.id,\n }\n\n // Для доставки формируем данные для бэкэнда\n const firstAddress = points[0]\n if (\n newDeliveryMethod === DeliveryMethods.COURIER &&\n isAddressClient(firstAddress)\n ) {\n const isAllowedAddress =\n !firstAddress ||\n !firstAddress.is_in_delivery_area ||\n firstAddress?.allow_redirect\n\n // Для доставки курьером проверяем существует ли адрес в зоне доставки, и соответсвует ли городу\n if (isAllowedAddress) {\n // Если не возможно установить адрес, то сбрасываем адрес виджета\n basketStore.setDeliveryOrderAddress('')\n\n return\n }\n\n deliveryMethodPayload = {\n delivery_method: newDeliveryMethod,\n }\n if (firstAddress.is_in_delivery_area) {\n deliveryMethodPayload.address_id = firstAddress.id\n }\n }\n\n await basketStore.setDeliveryMethod({\n ...deliveryMethodPayload,\n })\n\n deliveryMethodChanged()\n\n const carrotquestTracks = {\n courier: 'Выбрана доставка',\n pickup: 'Выбран самовывоз',\n hall: 'Выбран заказ в зал',\n }\n\n // @ts-ignore\n window.carrotquest?.track(carrotquestTracks[newDeliveryMethod], {})\n}\n\n/* Tabs */\nconst isShowPickupTab = computed(() => Boolean(pickupPoints.value.length))\n\nconst isShowHallTab = computed(() => Boolean(hallPoints.value.length))\n\nconst setModelValueDeliveryMethod = (value: DeliveryMethods) => {\n basketStore.setDeliveryMethodInState(value)\n\n setDeliveryMethod(value)\n}\n\nconst setSelectedAddress = async (value: SetDeliveryMethodPayload) => {\n await basketStore.setDeliveryMethod(value)\n\n deliveryMethodChanged()\n}\n\nconst pointsList = computed(() => {\n // При доставке списка точек нет\n if (deliveryMethod.value === DeliveryMethods.COURIER) return []\n\n return allPoints.value[deliveryMethod.value]\n})\n</script>\n\n<template>\n <section id=\"addresses\" class=\"addresses\">\n <basket-title title=\"Адрес\" />\n\n <basket-addresses-tabs\n :model-value=\"deliveryMethod\"\n :is-show-pickup-tab=\"isShowPickupTab\"\n :is-show-hall-tab=\"isShowHallTab\"\n @update:model-value=\"setModelValueDeliveryMethod\"\n />\n\n <basket-addresses-windows\n class=\"addresses__windows\"\n :delivery-method=\"deliveryMethod\"\n :max-count-of-visible-addresses=\"5\"\n :selected-address=\"selectedAddress\"\n :points-list=\"pointsList\"\n @delivery-method-changed=\"deliveryMethodChanged\"\n @select-delivery-courier=\"setDeliveryMethod(DeliveryMethods.PICKUP)\"\n @on-set-selected-address=\"setSelectedAddress\"\n >\n <basket-addresses-courier\n v-if=\"deliveryMethod === DeliveryMethods.COURIER\"\n :selected-address=\"selectedAddress as (AddressClient | undefined)\"\n :max-count-of-visible-addresses=\"5\"\n :delivery-method=\"deliveryMethod\"\n @delivery-method-changed=\"deliveryMethodChanged\"\n @select-delivery-courier=\"setDeliveryMethod\"\n />\n </basket-addresses-windows>\n\n <the-dialog v-model=\"dialogs.redirect.visible\" :max-width=\"620\">\n <dialog-redirect-other-city\n v-if=\"dialogs.redirect.address\"\n :id=\"dialogs.redirect.address.id\"\n :city-domain-prefix=\"dialogs.redirect.address.city_domain_prefix\"\n @close-dialog-delete-address=\"dialogs.redirect.visible = false\"\n @close-dialog-redirect-city=\"dialogs.redirect.visible = false\"\n />\n </the-dialog>\n </section>\n</template>\n\n<style lang=\"scss\" scoped>\n.addresses__windows {\n margin-top: 24px;\n}\n</style>\n","<script lang=\"ts\" setup>\ntype Props = {\n clientPacksCount: number\n}\n\nconst props = defineProps<Props>()\n\nconst info = computed(() => {\n return props.clientPacksCount\n ? 'В состав приборов входит вилка, ложка и салфетка'\n : 'Спасибо, что заботитесь об экологии и не заказываете приборы!'\n})\n</script>\n\n<template>\n <span class=\"info\" :class=\"{ 'info--success': !clientPacksCount }\">\n {{ info }}\n </span>\n</template>\n\n<style lang=\"scss\" scoped>\n.info {\n font-size: 14px;\n font-weight: 600;\n line-height: 18px;\n color: var(--ui-text-secondary);\n\n &--success {\n color: var(--ui-green);\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { useProductCounter } from '@/composables/useProductCounter'\n\nimport { useCityStore } from '@/store/city/city'\n\nimport { ClientPack } from '@/types/api/api-v3/basket'\n\nconst { currencySymbol } = useCityStore()\n\ntype Props = {\n clientPack: ClientPack\n isCardView?: boolean\n}\n\nconst props = defineProps<Props>()\n\nconst { isMobile } = useResponsive()\n\nconst clientPackImage = computed(() =>\n props?.clientPack?.image_url\n ? props.clientPack.image_url\n : '/no-image-category.webp',\n)\n// Нужен для миксина \"ProductCounter\"\nconst productId = computed(() => props?.clientPack?.product_id as number)\n\nconst counterSize = computed(() => {\n if (!props.isCardView) return 'sm'\n\n return isMobile.value ? 'xs' : 'sm'\n})\n\nconst {\n decreaseQuantity,\n increaseQuantity,\n setProductQuantity,\n quantitySelectedProducts,\n} = useProductCounter(productId)\n\nonMounted(() => {\n const productQuantity = props?.clientPack?.total_quantity || 0\n\n setProductQuantity(productQuantity)\n})\n</script>\n\n<template>\n <div\n class=\"client-pack-item\"\n :class=\"{\n 'client-pack-item--card': isCardView,\n }\"\n >\n <nuxt-img :src=\"clientPackImage\" alt=\"Приборы\" />\n\n <div class=\"client-pack-item__text\" :title=\"clientPack?.title\">\n {{ clientPack?.title }}\n </div>\n\n <div class=\"client-pack-item__price\">\n {{ clientPack?.total_price }} {{ currencySymbol }}\n </div>\n\n <div class=\"client-pack-item__counter\">\n <the-counter\n :min=\"0\"\n :value=\"quantitySelectedProducts\"\n :variant=\"isCardView ? 'secondary' : 'primary'\"\n :size=\"counterSize\"\n @on-decrease=\"decreaseQuantity\"\n @on-increase=\"increaseQuantity\"\n />\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.client-pack-item {\n display: grid;\n grid-template-rows: 1fr auto;\n grid-template-columns: auto 1fr max-content;\n margin-bottom: 16px;\n\n @include media('>=tablet') {\n margin-bottom: 20px;\n }\n\n img {\n grid-area: 1 / 1 / 3 / 2;\n width: 59px;\n\n @include media('>=tablet') {\n width: 76px;\n }\n }\n\n &__text {\n display: flex;\n grid-area: 1 / 2 / 2 / 3;\n align-items: center;\n margin-left: 20px;\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n text-align: left;\n\n @include media('>=tablet') {\n width: 268px;\n font-size: 14px;\n }\n }\n\n &__price {\n display: flex;\n grid-area: 2 / 2 / 3 / 3;\n align-items: center;\n margin-left: 22px;\n font-size: 14px;\n font-weight: 800;\n line-height: 20px;\n @include media('>=tablet') {\n width: 108px;\n margin-left: 20px;\n }\n }\n\n &__counter {\n display: flex;\n grid-area: 1 / 3 / 3 / 4;\n align-items: center;\n justify-content: flex-end;\n margin-left: 20px;\n }\n\n &--card {\n display: grid;\n grid-template-rows: repeat(4, max-content);\n grid-template-columns: 1fr;\n width: 100%;\n max-width: 128px;\n max-height: 206px;\n padding: 8px;\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n background-color: #f1f4f9;\n border-radius: 16px;\n\n img {\n grid-area: unset;\n width: 100%;\n height: 76px;\n object-fit: contain;\n }\n\n .client-pack-item__text {\n display: block;\n grid-area: 3 / 1 / 3 / 1;\n width: 100%;\n margin-bottom: 16px;\n margin-left: 0;\n overflow: hidden;\n line-height: unset;\n color: var(--ui-text-primary);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .client-pack-item__price {\n display: block;\n grid-area: 2 / 1 / 2 / 1;\n margin: 8px 0 5px;\n font-weight: 800;\n line-height: unset;\n color: var(--ui-text-primary);\n }\n\n .client-pack-item__counter {\n display: block;\n grid-area: unset;\n margin-left: 0;\n\n :deep(.app-counter) {\n min-width: 100%;\n height: 40px;\n }\n }\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { SelectedDiscount } from '@/types/basket'\n\ntype Props = {\n selectedDiscount: SelectedDiscount\n confirmedDiscount: SelectedDiscount | null\n bonusesCount: number\n spendAmountBonuses: number\n bonusSpendMessage: string\n isAuthenticated: boolean\n basketDiscountInfoVisible: boolean\n}\n\nconst props = defineProps<Props>()\n\nconst emit = defineEmits(['updateDiscountChoices'])\n\nconst bonusLabel = computed(() => {\n if (!props.isAuthenticated) {\n return 'Авторизуйтесь, чтобы использовать бонусы'\n }\n\n return `У вас ${\n props.bonusesCount !== 0 ? props.bonusesCount : 'нет'\n } бонусов`\n})\n\nconst isPromocodeChoiceDisabled = computed(\n () => props.confirmedDiscount === SelectedDiscount.BONUSES,\n)\n\nconst isPromocodeApplied = computed(() => {\n return (\n props.confirmedDiscount === SelectedDiscount.PROMOCODE &&\n props.bonusesCount > 0\n )\n})\n\nconst isBonusChoiceDisabled = computed(\n () => props.bonusesCount === 0 || isPromocodeApplied.value,\n)\n\nconst updateDiscountChoices = (value: SelectedDiscount) => {\n // Если кликаем по уже выбранной скидке\n if (value === props.selectedDiscount) {\n return\n }\n\n emit('updateDiscountChoices', value)\n}\n</script>\n\n<template>\n <the-radio-group\n :model-value=\"selectedDiscount\"\n name=\"basket-discount-choices\"\n >\n <div class=\"discount-choices__radio\">\n <the-radio\n label=\"Промокод\"\n :disabled=\"isPromocodeChoiceDisabled\"\n :value=\"SelectedDiscount.PROMOCODE\"\n @click=\"updateDiscountChoices(SelectedDiscount.PROMOCODE)\"\n />\n\n <div\n v-if=\"isPromocodeChoiceDisabled\"\n class=\"discount-choices__text discount-choices__text--disabled\"\n >\n Чтобы использовать промокод — отмените списание бонусов\n </div>\n </div>\n\n <div class=\"discount-choices__radio\">\n <the-radio\n :label=\"bonusLabel\"\n :disabled=\"isBonusChoiceDisabled || !isAuthenticated\"\n :value=\"SelectedDiscount.BONUSES\"\n @click=\"updateDiscountChoices(SelectedDiscount.BONUSES)\"\n />\n\n <template v-if=\"isAuthenticated\">\n <div\n v-if=\"isPromocodeApplied\"\n class=\"discount-choices__text discount-choices__text--disabled\"\n >\n Чтобы использовать бонусы — отмените промокод\n </div>\n\n <div\n v-if=\"!isBonusChoiceDisabled && !basketDiscountInfoVisible\"\n class=\"discount-choices__text\"\n >\n {{ bonusSpendMessage }}\n </div>\n </template>\n </div>\n </the-radio-group>\n</template>\n\n<style lang=\"scss\" scoped>\n.discount-choices__text {\n margin-top: 10px;\n margin-left: 32px;\n font-size: 12px;\n font-weight: 600;\n color: var(--ui-text-secondary);\n\n &--disabled {\n color: var(--ui-text-primary);\n opacity: 0.5;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { required as veeRequiredValidator } from '@vee-validate/rules'\nimport { defineRule, Field as VeeField, Form as VeeForm } from 'vee-validate'\n\nimport { vMaska } from 'maska'\nimport { useBasketStore } from '@/store/basket/basket'\n\nimport { SelectedDiscount } from '@/types/basket'\n\nimport BasketErrorMessage from '@/components/Basket/basket-utils/BasketErrorMessage.vue'\n\ntype Props = {\n modelValue: string\n selectedDiscount: string\n confirmedDiscount: SelectedDiscount | null\n isButtonLoading: boolean\n error: string\n}\n\nconst props = defineProps<Props>()\n\nconst emit = defineEmits(['setDiscount', 'updateModelValue', 'cancelDiscount'])\n\nconst { isMobile } = useResponsive()\n\nconst basketStore = useBasketStore()\n\nconst buttonText = computed(() => {\n if (props?.selectedDiscount === SelectedDiscount.BONUSES) {\n return props.confirmedDiscount ? 'Отменить' : 'Списать'\n }\n\n return props?.confirmedDiscount ? 'Отменить' : 'Применить'\n})\n\nconst updateModelValue = (value: string) => emit('updateModelValue', value)\nconst setDiscount = (setErrors: Function) => emit('setDiscount', setErrors)\nconst cancelDiscount = () => emit('cancelDiscount')\n\nconst onClickHandler = (setErrors: Function) => {\n props.confirmedDiscount ? cancelDiscount() : setDiscount(setErrors)\n}\n\nconst options = computed(() => {\n const mask =\n props.selectedDiscount === SelectedDiscount.PROMOCODE ? '' : '####'\n\n return { mask }\n})\n\nconst requiredDiscount = (value: string) => {\n if (!veeRequiredValidator(value)) {\n return props.selectedDiscount === SelectedDiscount.PROMOCODE\n ? 'Введите промокод'\n : 'Введите количество бонусов для списания'\n }\n\n return true\n}\n\nconst discountField = ref<any>(null)\n\n// Сбрасываем поле каждый раз при переключении радио кнопки\nwatch(\n () => props.selectedDiscount,\n () => discountField.value.reset(),\n)\n\ndefineRule('required-discount', requiredDiscount)\n\nconst bonusesValue = computed(() => {\n return basketStore.data.bonuses.toSpendAmount || props.modelValue\n})\n\nconst placeholder = computed(() => {\n const postfix =\n props.selectedDiscount === SelectedDiscount.PROMOCODE\n ? 'промокод'\n : 'бонусы'\n\n return `Введите ${postfix}`\n})\n</script>\n\n<template>\n <vee-form v-slot=\"{ handleSubmit }\" class=\"basket-discount-input\">\n <vee-field\n v-slot=\"{ field, errors, setErrors }\"\n ref=\"discountField\"\n name=\"discount\"\n vid=\"discount\"\n rules=\"required-discount\"\n :model-value=\"bonusesValue\"\n @update:model-value=\"updateModelValue\"\n >\n <div class=\"basket-discount-input__field\">\n <the-input\n v-maska:[options]\n v-bind=\"field\"\n hide-details\n :readonly=\"Boolean(confirmedDiscount)\"\n :clearable=\"false\"\n :placeholder=\"placeholder\"\n >\n <template v-if=\"confirmedDiscount\" #append-inner>\n <the-icon\n name=\"close\"\n clickable\n @click=\"onClickHandler(setErrors)\"\n />\n </template>\n </the-input>\n\n <the-button\n class=\"basket-discount-input__button\"\n size=\"sm\"\n font=\"sm\"\n type=\"button\"\n :radius=\"isMobile ? 'lg' : 'sm'\"\n block\n :loading=\"isButtonLoading\"\n :disabled=\"errors.length > 0\"\n @click=\"handleSubmit(onClickHandler(setErrors))\"\n >\n {{ buttonText }}\n </the-button>\n </div>\n\n <transition name=\"height\">\n <basket-error-message\n v-if=\"errors.length !== 0 || error\"\n class=\"basket-discount-input__error\"\n :error-message=\"errors[0] || error\"\n />\n </transition>\n </vee-field>\n </vee-form>\n</template>\n\n<style lang=\"scss\" scoped>\n@use '@/assets/styles/animations.scss' as *;\n\n.basket-discount-input {\n &__field {\n display: flex;\n gap: 0 16px;\n\n @include media('>=tablet') {\n gap: 0 24px;\n }\n }\n\n &__button {\n max-width: 120px;\n\n @include media('>=tablet') {\n max-width: 140px;\n }\n }\n\n &__error {\n padding-top: 25px;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useUserStore } from '@/store/user/user'\n\nimport { Success, UnprocessableEntityError } from '@/api/results'\nimport { SelectedDiscount } from '@/types/basket'\n\nimport BasketDiscountChoices from '@/components/Basket/basket-discount/BasketDiscountChoices.vue'\nimport BasketDiscountInfo from '@/components/Basket/basket-discount/BasketDiscountInfo.vue'\nimport BasketDiscountInput from '@/components/Basket/basket-discount/BasketDiscountInput.vue'\nimport BasketTitle from '@/components/Basket/basket-utils/BasketTitle.vue'\n\nconst { $metrics } = useNuxtApp()\n\nconst basketStore = useBasketStore()\nconst userStore = useUserStore()\n\nconst selectedDiscount = ref<SelectedDiscount>(SelectedDiscount.PROMOCODE)\nconst confirmedDiscount = ref<SelectedDiscount | null>(null)\nconst inputValue = ref('')\nconst isButtonLoading = ref(false)\n\nconst bonusesCount = computed(() => basketStore.data.bonuses.totalAmount)\n\nconst basketDiscountErrors = computed(\n () =>\n basketStore.data.promocode.error || basketStore.data.bonuses.errorMessage,\n)\n\nconst basketDiscountInfoVisible = computed(\n () =>\n (basketStore.data.promocode.value &&\n basketStore.data.promocode.valid &&\n !basketDiscountErrors.value) ||\n (basketStore.data.bonuses.toSpendAmount > 0 && !basketDiscountErrors.value),\n)\n\nconst bonuses = computed(() => basketStore.data.bonuses)\n\nconst discountTitle = computed(\n () => basketStore.data.promocode.title || bonuses?.value.message,\n)\n\nconst isAuthenticated = computed(() => userStore.isAuthenticated)\n\nconst setPromocode = async (setErrors: Function) => {\n isButtonLoading.value = true\n\n const result = await basketStore.promocodeApply({\n value: inputValue.value,\n })\n\n if (!(result instanceof Success)) {\n setErrors(result.data)\n }\n\n if (result instanceof Success) {\n confirmedDiscount.value = selectedDiscount.value\n\n $metrics?.eventSendGoal({ ym: 'use_ref' })\n }\n\n isButtonLoading.value = false\n}\n\nconst setBonuses = async (value: number, setErrors: Function) => {\n isButtonLoading.value = true\n\n const result = await basketStore.applyBonuses({ amount: value })\n\n if (result instanceof UnprocessableEntityError) {\n setErrors({ bonuses: result.data.amount })\n }\n\n if (result instanceof Success) {\n // Определяем, это reset bonus или apply\n value === 0\n ? (confirmedDiscount.value = null)\n : (confirmedDiscount.value = selectedDiscount.value)\n }\n\n isButtonLoading.value = false\n}\n\nconst resetPromocode = async () => {\n isButtonLoading.value = true\n\n await basketStore.promocodeReset()\n\n inputValue.value = ''\n\n isButtonLoading.value = false\n confirmedDiscount.value = null\n}\n\nconst updateSelectedDiscount = (value: SelectedDiscount) => {\n inputValue.value = ''\n selectedDiscount.value = value\n}\n\nconst updateModelValue = (value: string) => (inputValue.value = value)\n\nconst setDiscount = (setErrors: Function) =>\n selectedDiscount.value === SelectedDiscount.PROMOCODE\n ? setPromocode(setErrors)\n : setBonuses(+inputValue.value, setErrors)\n\nconst cancelDiscount = () =>\n selectedDiscount.value === SelectedDiscount.PROMOCODE\n ? resetPromocode()\n : setBonuses(0, () => {})\n\n// Инициализируем начальный выбранный тип скидки\nonMounted(() => {\n if (basketStore.data?.promocode?.value) {\n selectedDiscount.value = SelectedDiscount.PROMOCODE\n inputValue.value = basketStore.data?.promocode?.value\n confirmedDiscount.value = SelectedDiscount.PROMOCODE\n } else if (basketStore.data.bonuses.toSpendAmount) {\n selectedDiscount.value = SelectedDiscount.BONUSES\n inputValue.value = String(basketStore.data.bonuses.toSpendAmount)\n confirmedDiscount.value = SelectedDiscount.BONUSES\n }\n})\n</script>\n\n<template>\n <section id=\"discount\" class=\"discount\">\n <basket-title class=\"discount__headline\" title=\"Применение скидок\" />\n\n <basket-discount-choices\n :selected-discount=\"selectedDiscount\"\n :bonuses-count=\"bonusesCount\"\n :confirmed-discount=\"confirmedDiscount\"\n :spend-amount-bonuses=\"bonuses.toSpendAmount\"\n :bonus-spend-message=\"bonuses.message\"\n :is-authenticated=\"isAuthenticated\"\n :basket-discount-info-visible=\"basketDiscountInfoVisible\"\n @update-discount-choices=\"updateSelectedDiscount\"\n />\n\n <div class=\"discount__controls\">\n <basket-discount-input\n :model-value=\"inputValue\"\n :selected-discount=\"selectedDiscount\"\n :confirmed-discount=\"confirmedDiscount\"\n :is-button-loading=\"isButtonLoading\"\n :error=\"basketDiscountErrors\"\n @set-discount=\"setDiscount\"\n @cancel-discount=\"cancelDiscount\"\n @update-model-value=\"updateModelValue\"\n />\n </div>\n\n <transition class=\"discount__info\" name=\"height\">\n <basket-discount-info\n v-if=\"basketDiscountInfoVisible\"\n :discount-title=\"discountTitle\"\n />\n </transition>\n </section>\n</template>\n\n<style lang=\"scss\" scoped>\n@use '@/assets/styles/animations.scss' as *;\n\n.discount {\n &__headline {\n margin-bottom: 20px;\n }\n\n &--error {\n border: 1px solid var(--ui-error);\n }\n\n &__controls {\n margin-top: 15px;\n }\n\n &__info {\n margin-top: 25px;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nconst BasketErrorMessage = defineAsyncComponent(\n () => import('@/components/Basket/basket-utils/BasketErrorMessage.vue'),\n)\n\ntype Props = {\n errors: string[]\n}\n\ndefineProps<Props>()\n</script>\n\n<template>\n <div class=\"gifts-info\">\n <basket-error-message v-if=\"errors.length\" :error-message=\"errors[0]\" />\n\n <span v-else>В подарок не входят соусы, добавьте их отдельно</span>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.gifts-info {\n min-height: 25px;\n font-size: 14px;\n font-weight: 600;\n color: var(--ui-text-secondary);\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { GiftProduct } from '@/types/api/api-v3/basket'\n\nimport AppMeasureUnits from '@/components/App/AppMeasureUnits.vue'\n\ntype Props = {\n gift: GiftProduct\n isGiftSelected: boolean\n isGiftNeed: boolean | undefined\n}\n\nconst props = defineProps<Props>()\n\nconst emit = defineEmits(['on-select'])\n\nconst isErrorImage = ref(false)\n\nconst image = computed(() => {\n if (!props.gift.image || isErrorImage.value) {\n return './no-image-product-card.webp'\n }\n\n return props.gift.image\n})\n\nconst onSelect = () => emit('on-select')\n</script>\n\n<template>\n <div class=\"gift-card\" :class=\"{ 'gift-card--inactive': !isGiftNeed }\">\n <div\n class=\"gift-card__image\"\n :class=\"{ 'gift-card__image--selected': isGiftSelected }\"\n >\n <nuxt-img\n :src=\"image\"\n :alt=\"gift.title\"\n loading=\"lazy\"\n format=\"webp\"\n @error=\"isErrorImage = true\"\n />\n </div>\n\n <div class=\"gift-card__body\">\n <div class=\"gift-card__header\">\n <span v-if=\"gift.title\" class=\"gift-card__title\">\n {{ gift.title }}\n </span>\n\n <app-measure-units\n class=\"gift-card__weight\"\n :weight=\"gift.weight\"\n :measure=\"gift.measure\"\n :volume-in-liters=\"gift.volume_in_liters\"\n />\n </div>\n </div>\n\n <div class=\"gift-card__footer\">\n <the-card-button\n type=\"gift\"\n :is-active=\"isGiftSelected\"\n @on-add=\"onSelect\"\n />\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.gift-card {\n display: flex;\n flex-direction: column;\n height: 236px;\n background-color: var(--ui-grey);\n border-radius: 16px;\n\n @include media('>=desktop-mini') {\n height: 252px;\n }\n\n &__image {\n position: relative;\n height: 117px;\n overflow: hidden;\n border-radius: 16px;\n\n @include media('>=desktop-mini') {\n height: 129px;\n }\n\n img {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n object-fit: contain;\n object-position: bottom;\n }\n\n &::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 3;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 20px;\n font-weight: 800;\n line-height: 26px;\n color: var(--ui-white);\n pointer-events: none;\n visibility: hidden;\n content: '1';\n background-color: rgba(var(--ui-secondary-rgb), 0.6);\n opacity: 0;\n transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;\n\n @include media('>=desktop-mini') {\n font-size: 28px;\n font-weight: 900;\n line-height: 36px;\n }\n }\n\n &--selected {\n &::after {\n pointer-events: auto;\n visibility: visible;\n opacity: 1;\n }\n }\n }\n\n &__body {\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n justify-content: center;\n padding: 8px;\n }\n\n &__header {\n display: -webkit-box;\n overflow: hidden;\n line-height: 16px;\n text-overflow: ellipsis;\n white-space: normal;\n -webkit-line-clamp: 3;\n -webkit-box-orient: vertical;\n\n @include media('>=desktop-mini') {\n line-height: 18px;\n }\n }\n\n &__title {\n margin-right: 4px;\n font-size: 12px;\n font-weight: 600;\n color: var(--ui-text-primary);\n word-break: break-word;\n\n @include media('>=desktop-mini') {\n font-size: 14px;\n }\n }\n\n &__weight {\n font-size: 12px;\n font-weight: 600;\n color: var(--ui-text-secondary);\n\n @include media('>=desktop-mini') {\n font-size: 12px;\n }\n }\n\n &__footer {\n padding: 0 8px 8px;\n }\n\n &--inactive {\n pointer-events: none;\n opacity: 0.5;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { GiftPayload } from '@/api/modules/basket/types'\nimport { GiftProduct } from '@/types/api/api-v3/basket'\n\nimport BasketGiftsCard from '@/components/Basket/basket-gifts/BasketGiftsCard.vue'\n\ntype Props = {\n products: GiftProduct[]\n ruleId: number\n isGiftNeed: boolean | undefined\n selectedGift: GiftPayload | null\n}\n\nconst emit = defineEmits(['selectGift'])\nconst props = defineProps<Props>()\n\nconst selectGift = (productId: number) =>\n emit('selectGift', {\n rule_id: props?.ruleId,\n product_id: productId,\n })\n</script>\n\n<template>\n <div class=\"gifts-list\">\n <basket-gifts-card\n v-for=\"gift in products\"\n :key=\"gift.title\"\n class=\"gifts-list__card\"\n :gift=\"gift\"\n :is-gift-selected=\"selectedGift?.product_id === gift.product_id\"\n :is-gift-need=\"isGiftNeed\"\n @on-select=\"selectGift(gift.product_id)\"\n />\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.gifts-list {\n position: relative;\n display: flex;\n gap: 0 16px;\n justify-content: flex-start;\n padding: 0 20px;\n margin: 0 -20px 16px;\n overflow-x: auto;\n overflow-y: hidden;\n white-space: nowrap;\n scroll-snap-type: x mandatory;\n scroll-padding-inline: 20px;\n\n @include invisible-scroll-bar();\n\n &__card {\n flex-basis: 144px;\n flex-shrink: 0;\n max-width: 144px;\n scroll-snap-align: start;\n scroll-snap-stop: always;\n\n @include media('>=desktop-mini') {\n flex-basis: 176px;\n max-width: 176px;\n }\n }\n}\n</style>\n","<script lang=\"ts\" setup>\ntype Props = {\n isGiftNeed: boolean | undefined\n}\n\ndefineProps<Props>()\n\nconst emit = defineEmits(['update:model-value'])\n\nconst updateValue = (value: boolean | null) => {\n emit('update:model-value', !!value)\n}\n</script>\n\n<template>\n <div class=\"gifts-toggle\">\n <div class=\"gifts-toggle__headline\">Нужен подарок</div>\n\n <div class=\"gifts-toggle__control\">\n <the-switch :model-value=\"isGiftNeed\" @update:model-value=\"updateValue\" />\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.gifts-toggle {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n &__headline {\n font-size: 18px;\n font-weight: 800;\n color: var(--ui-text-primary);\n\n @include media('<tablet') {\n font-size: 14px;\n }\n }\n}\n</style>\n","<template>\n <div class=\"section-loading\">\n <the-loader size=\"28\" />\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.section-loading {\n position: absolute;\n z-index: 4;\n width: 100%;\n height: 100%;\n margin: -20px;\n background-color: rgba(var(--ui-white-rgb), 0.8);\n border-radius: 20px;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { defineRule, Field as VeeField } from 'vee-validate'\n\nimport { notActiveGift } from '@/utils/rulesOfValidate'\n\nimport { useAppStore } from '@/store/app/app'\nimport { SnackbarType } from '@/store/app/app.types'\nimport { useBasketStore } from '@/store/basket/basket'\n\nimport { GiftPayload } from '@/api/modules/basket/types'\nimport { Success } from '@/api/results'\nimport { Gift } from '@/types/api/api-v3/basket'\n\nimport BasketGiftsInfo from '@/components/Basket/basket-gifts/BasketGiftsInfo.vue'\nimport BasketGiftsList from '@/components/Basket/basket-gifts/BasketGiftsList.vue'\nimport BasketGiftsToggle from '@/components/Basket/basket-gifts/BasketGiftsToggle.vue'\nimport BasketSection from '@/components/Basket/basket-utils/BasketSection.vue'\nimport BasketTitle from '@/components/Basket/basket-utils/BasketTitle.vue'\n\nconst NOT_ACTIVE_GIFT = 'notActiveGift'\nconst FAILURE_MESSAGE = 'Что-то пошло не так'\nconst ADDED_GIFT_MESSAGE = 'Подарок добавлен в корзину'\nconst DELETED_GIFT_MESSAGE = 'Подарок удален из корзины'\n\ntype Props = {\n gifts: Gift[]\n}\n\ndefineProps<Props>()\n\nconst basketStore = useBasketStore()\nconst { showSnackbar } = useAppStore()\n\nconst isGiftNeed = defineModel<boolean>()\n\nconst selectedGift = ref<GiftPayload | null>(null)\nconst isLoading = ref<boolean>(false)\n\nconst rule = computed(() => (isGiftNeed.value ? NOT_ACTIVE_GIFT : ''))\n\n// Метод для удобной установки лоадинга блока подарков\nconst setLoading = (state: boolean) => (isLoading.value = state)\n\n// Метод обработки удаления/добавления подарка в корзину\nconst handleGiftResult = (result: unknown, successMessage: string) => {\n if (!(result instanceof Success)) {\n showSnackbar({ message: FAILURE_MESSAGE })\n setLoading(false)\n\n return false\n }\n\n showSnackbar({ message: successMessage, type: SnackbarType.SUCCESS })\n setLoading(false)\n\n return true\n}\n\n// Функция для обработки выбранного подарка\nconst onSelectGift = async (gift: GiftPayload) => {\n setLoading(true)\n\n // Сначала удаляем уже выбранный подарок\n if (selectedGift.value) {\n await basketStore.deleteGift({\n gift_id_list: [selectedGift.value.product_id],\n })\n }\n\n const result = await basketStore.setGift(gift)\n\n const isGiftHandled = handleGiftResult(result, ADDED_GIFT_MESSAGE)\n\n if (isGiftHandled) {\n isGiftNeed.value = true\n selectedGift.value = gift\n }\n}\n\n// Функция для переключения нужен/не нужен подарок\nconst updateModelValue = async (value: boolean) => {\n // Если включили тагл и уже есть выбранный подарок\n if (value && basketStore.getSelectedGift) {\n selectedGift.value = basketStore.getSelectedGift\n }\n\n // Если пользователь не добавлял подарок при включенном тагле - просто выключаем его и выходим\n if (value || !selectedGift.value) {\n isGiftNeed.value = value\n\n return\n }\n\n setLoading(true)\n\n const selectedGiftProductId = selectedGift.value?.product_id\n\n if (!selectedGiftProductId) {\n setLoading(false)\n isGiftNeed.value = value\n\n return\n }\n\n const result = await basketStore.deleteGift({\n gift_id_list: [selectedGiftProductId],\n })\n\n const isGiftHandled = handleGiftResult(result, DELETED_GIFT_MESSAGE)\n\n if (isGiftHandled) {\n isGiftNeed.value = value\n selectedGift.value = null\n }\n}\n\nonMounted(() => {\n // Получаем текущий выбранный подарок пользователем\n const selectedBasketGift = basketStore.getSelectedGift\n\n if (!selectedBasketGift) return\n\n // Устанавливаем подарок как текущий выбранный в компоненте и переключаем тагл на \"Нужен подарок\"\n selectedGift.value = selectedBasketGift\n isGiftNeed.value = true\n})\n\ndefineRule(NOT_ACTIVE_GIFT, notActiveGift)\n</script>\n\n<template>\n <basket-section id=\"gifts\" class=\"gifts\" :loading=\"isLoading\">\n <basket-title title=\"Подарки\" />\n\n <vee-field\n v-slot=\"{ errors }\"\n name=\"gifts\"\n vid=\"gifts\"\n :rules=\"rule\"\n :model-value=\"selectedGift\"\n >\n <basket-gifts-list\n v-for=\"gift in gifts\"\n :key=\"gift.rule_id\"\n :products=\"gift.products\"\n :rule-id=\"gift.rule_id\"\n :is-gift-need=\"isGiftNeed\"\n :selected-gift=\"selectedGift\"\n @select-gift=\"onSelectGift\"\n />\n\n <basket-gifts-info :errors=\"errors\" />\n </vee-field>\n\n <hr class=\"gifts__line\" />\n\n <basket-gifts-toggle\n :is-gift-need=\"isGiftNeed\"\n @update:model-value=\"updateModelValue\"\n />\n </basket-section>\n</template>\n\n<style lang=\"scss\" scoped>\n.gifts {\n overflow: hidden;\n}\n\n.gifts__line {\n margin: 20px;\n border: 1px solid var(--ui-grey);\n\n @include media('<tablet') {\n margin: 16px 0 20px;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { defineRule, Field as VeeField } from 'vee-validate'\n\nimport { maxNoteLength } from '@/utils/rulesOfValidate'\n\nimport { useBasketStore } from '@/store/basket/basket'\n\nimport BasketErrorMessage from '@/components/Basket/basket-utils/BasketErrorMessage.vue'\nimport BasketTitle from '@/components/Basket/basket-utils/BasketTitle.vue'\n\nconst MAX_NOTE_LENGTH_RULE = 'maxNoteLength'\n\nconst { isMobile } = useResponsive()\n\nconst basketStore = useBasketStore()\n\nconst note = computed({\n get() {\n return basketStore.data.note\n },\n set(value: string) {\n basketStore.setNote(value)\n },\n})\n\ndefineRule(MAX_NOTE_LENGTH_RULE, maxNoteLength)\n</script>\n\n<template>\n <section id=\"note\">\n <vee-field\n v-slot=\"{ errors, field }\"\n v-model=\"note\"\n name=\"note\"\n vid=\"note\"\n :rules=\"MAX_NOTE_LENGTH_RULE\"\n immediate\n >\n <basket-title title=\"Комментарий кухне\" />\n\n <the-textarea\n v-bind=\"field\"\n :model-value=\"note\"\n class=\"note__item\"\n counter=\"300\"\n placeholder=\"Здесь можно написать пояснения или пожелания к заказу\"\n :rows=\"isMobile ? 3 : 6\"\n />\n\n <basket-error-message\n v-if=\"errors.length !== 0\"\n :error-message=\"errors[0]\"\n />\n </vee-field>\n </section>\n</template>\n\n<style lang=\"scss\" scoped>\n.note {\n &__item {\n margin-bottom: 20px;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport BasketTitle from '@/components/Basket/basket-utils/BasketTitle.vue'\n\nconst emit = defineEmits(['showClearBasketDialog'])\n\nconst showClearBasketDialog = () => emit('showClearBasketDialog')\n</script>\n\n<template>\n <div class=\"header\">\n <basket-title class=\"header__headline\" title=\"Корзина\" />\n\n <the-button\n variant=\"transparent\"\n size=\"sm\"\n radius=\"lg\"\n icon=\"remove\"\n type=\"button\"\n @click=\"showClearBasketDialog\"\n />\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 20px;\n\n &__headline {\n margin-bottom: 0;\n }\n\n &__image {\n width: 24px;\n cursor: pointer;\n }\n\n @include media('<tablet') {\n margin-bottom: 15px;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { useProductCounter } from '@/composables/useProductCounter'\n\nimport { useCityStore } from '@/store/city/city'\n\nimport { AdditiveItem } from '@/types/api/api-v3/basket'\n\nconst { currencySymbol } = useCityStore()\n\ntype Props = {\n additive: AdditiveItem\n}\n\nconst props = defineProps<Props>()\n\nconst productId = computed(() => props.additive?.product_id || 0)\n\nconst {\n quantitySelectedProducts,\n setProductQuantity,\n decreaseQuantity,\n increaseQuantity,\n} = useProductCounter(productId)\n\nconst additiveImage = computed(() => {\n return props?.additive?.image_url || './no-image-category.webp'\n})\n\nconst priceWithSymbol = computed(() => {\n return `${props?.additive?.total_price} ${currencySymbol}`\n})\n\nonMounted(() => setProductQuantity(props.additive?.total_quantity || 0))\n</script>\n\n<template>\n <div class=\"additive\">\n <div class=\"additive__image\">\n <nuxt-img :src=\"additiveImage\" format=\"webp\" alt=\"изображение продукта\" />\n </div>\n\n <div class=\"additive__info\">\n <nuxt-link class=\"additive__info-link\" target=\"_blank\">\n {{ additive.title }}\n </nuxt-link>\n\n <div class=\"additive__info-attributes\">\n <div class=\"price\">{{ priceWithSymbol }}</div>\n </div>\n </div>\n\n <div class=\"additive__info-counter\">\n <the-counter\n :value=\"quantitySelectedProducts\"\n :min=\"0\"\n @on-increase=\"increaseQuantity\"\n @on-decrease=\"decreaseQuantity\"\n />\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.additive {\n display: grid;\n grid-template-columns: 60px 1fr max-content;\n gap: 16px;\n align-items: center;\n\n &__image {\n width: 60px;\n min-width: 60px;\n height: 40px;\n\n img {\n width: 100%;\n }\n }\n\n &__info {\n font-size: 14px;\n font-weight: 600;\n word-break: break-all;\n\n &-link {\n color: var(--ui-text-primary);\n word-break: break-word;\n }\n\n &-attributes {\n display: flex;\n gap: 8px;\n align-items: center;\n\n .price {\n font-weight: 800;\n color: var(--ui-text-primary);\n }\n }\n }\n\n @include media('>tablet') {\n grid-template-columns: 75px 1fr max-content;\n\n &__image {\n width: 75px;\n min-width: 75px;\n height: auto;\n }\n\n &__info {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n &-attributes {\n display: grid;\n gap: 4px;\n width: 97px;\n }\n }\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { useCityStore } from '@/store/city/city'\n\nimport { GiftProduct } from '@/types/api/api-v3/basket'\n\nimport AppMeasureUnits from '@/components/App/AppMeasureUnits.vue'\n\nconst { currencySymbol } = useCityStore()\n\ntype Props = {\n gift: GiftProduct\n giftTitle: string\n}\n\ndefineProps<Props>()\n</script>\n\n<template>\n <div class=\"gift\">\n <div v-if=\"gift?.image\" class=\"gift__image\">\n <nuxt-img :src=\"gift.image\" />\n </div>\n\n <div class=\"gift__titles\">\n <div>\n {{ gift?.title }}\n </div>\n\n <div class=\"gift__title-gift\">\n {{ giftTitle }}\n <nuxt-img\n class=\"gift__title-icon\"\n src=\"/gift-active.webp\"\n alt=\"Подарок\"\n width=\"16\"\n height=\"16\"\n />\n </div>\n </div>\n\n <div class=\"gift__wrapper\">\n <div class=\"gift__price\">0 {{ currencySymbol }}</div>\n\n <app-measure-units\n class=\"gift__weight\"\n :weight=\"gift.weight\"\n :volume-in-liters=\"gift.volume_in_liters\"\n :measure=\"gift.measure\"\n />\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.gift {\n display: grid;\n grid-template-areas: 'image titles price';\n grid-template-rows: 1fr;\n grid-template-columns: max-content 1fr;\n gap: 10px;\n\n @include media('>=tablet') {\n grid-template-columns: 120px 1fr 100px;\n gap: 0 20px;\n align-items: center;\n width: 100%;\n }\n\n @include media('>=desktop-mini') {\n grid-template-columns: 75px 1fr 1fr;\n gap: 0 16px;\n align-items: center;\n width: 100%;\n }\n\n @include media('<tablet') {\n grid-template-areas:\n 'image titles'\n '. price';\n }\n\n &__image {\n display: flex;\n grid-area: image;\n align-items: center;\n\n img {\n width: 60px;\n height: 40px;\n border-radius: 10px;\n\n @include media('>=tablet') {\n width: 75px;\n height: auto;\n }\n }\n }\n\n &__titles {\n display: flex;\n flex-direction: column;\n grid-area: titles;\n font-size: 14px;\n font-weight: 600;\n color: var(--ui-text-primary);\n\n @include media('>=tablet') {\n width: 80%;\n }\n }\n\n &__title-gift {\n img {\n margin-left: 4px;\n transform: translateY(3px);\n }\n }\n\n &__wrapper {\n display: flex;\n grid-area: price;\n gap: 8px;\n align-items: center;\n\n @include media('>=desktop-mini') {\n display: grid;\n }\n }\n\n &__price {\n font-size: 14px;\n font-weight: 800;\n color: var(--ui-text-primary);\n }\n\n &__weight {\n font-size: 12px;\n font-weight: 600;\n line-height: 14px;\n color: var(--ui-text-secondary);\n }\n}\n</style>\n","/* Types */\nimport { Item } from '~/types/api/api-v3/basket'\nimport { Modification } from '~/types/api/api-v3/product'\n\n/**\n * Формирование объекта под сигнатуру модификации\n * @param item - продукт корзины\n */\nexport const formatProductForModification = (\n item?: Item,\n): Partial<Modification> | null => {\n if (!item) return null\n\n return {\n id: item.product_id,\n name: item.title,\n full_name: item.title,\n price: item.price,\n }\n}\n","<script lang=\"ts\" setup>\nimport { formatProductForModification } from '@/utils/formatProductForModification'\n\nimport { useProductCounter } from '@/composables/useProductCounter'\n\nimport { useCityStore } from '@/store/city/city'\n\nimport { Item } from '@/types/api/api-v3/basket'\n\nimport AppMeasureUnits from '@/components/App/AppMeasureUnits.vue'\n\ntype Props = {\n item: Item\n}\n\nconst props = defineProps<Props>()\n\nconst { currencySymbol } = useCityStore()\n\nconst productId = computed(() => props.item?.product_id || 0)\n\nconst productModification = formatProductForModification(props.item)\n\nconst {\n quantitySelectedProducts,\n setProductQuantity,\n decreaseQuantity,\n increaseQuantity,\n} = useProductCounter(productId, productModification)\n\nconst productImage = props.item?.image_url\n ? props.item?.image_url\n : './no-image-category.webp'\n\nconst priceWithSymbol = computed(() => {\n return `${props?.item?.price * props?.item?.quantity} ${currencySymbol}`\n})\n\nwatch(\n () => props.item?.quantity,\n (updatedQuantity) => setProductQuantity(updatedQuantity || 0),\n)\n\nonMounted(() => setProductQuantity(props.item?.quantity || 0))\n</script>\n\n<template>\n <div class=\"product\">\n <div class=\"product__image\">\n <nuxt-img :src=\"productImage\" format=\"webp\" alt=\"изображение продукта\" />\n </div>\n\n <div class=\"product__info\">\n <nuxt-link class=\"product__info-link\" :to=\"item?.url\" target=\"_blank\">\n {{ item.title }}\n </nuxt-link>\n\n <div class=\"product__info-attributes\">\n <div class=\"price\">{{ priceWithSymbol }}</div>\n\n <app-measure-units\n v-if=\"item?.total_weight\"\n class=\"weight\"\n :weight=\"item.total_weight\"\n :volume-in-liters=\"item?.volume_in_liters\"\n :measure=\"item.measure\"\n />\n </div>\n </div>\n\n <div class=\"product__info-counter\">\n <the-counter\n :value=\"quantitySelectedProducts\"\n :min=\"0\"\n @on-increase=\"increaseQuantity\"\n @on-decrease=\"decreaseQuantity\"\n />\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.product {\n display: grid;\n grid-template-columns: 60px 1fr max-content;\n gap: 16px;\n align-items: center;\n\n &__image {\n width: 60px;\n min-width: 60px;\n height: 40px;\n\n img {\n width: 100%;\n border-radius: 10px;\n }\n }\n\n &__info {\n font-size: 14px;\n font-weight: 600;\n word-break: break-all;\n\n &-link {\n color: var(--ui-text-primary);\n word-break: break-word;\n\n &:hover {\n color: var(--ui-primary);\n }\n }\n\n &-attributes {\n display: flex;\n gap: 8px;\n align-items: center;\n\n .price {\n font-weight: 800;\n color: var(--ui-text-primary);\n }\n\n .weight {\n font-size: 12px;\n color: var(--ui-text-secondary);\n }\n }\n }\n\n @include media('>tablet') {\n grid-template-columns: 75px 1fr max-content;\n\n &__image {\n width: 75px;\n min-width: 75px;\n height: auto;\n }\n\n &__info {\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n &-link {\n padding-right: 16px;\n }\n\n &-attributes {\n display: grid;\n gap: 4px;\n width: 97px;\n min-width: 97px;\n }\n }\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { useBasketStore } from '@/store/basket/basket'\n\nimport {\n type AdditiveItem,\n type Gift,\n type Item,\n} from '@/types/api/api-v3/basket'\n\nimport BasketOrderAdditiveItem from '@/components/Basket/basket-order/BasketOrderAdditiveItem.vue'\nimport BasketOrderGiftItem from '@/components/Basket/basket-order/BasketOrderGiftItem.vue'\nimport BasketOrderItem from '@/components/Basket/basket-order/BasketOrderItem.vue'\n\ntype Props = {\n items: Item[]\n giftsWithoutChoice: Gift[]\n additives: AdditiveItem[]\n}\n\nconst props = defineProps<Props>()\n\nconst basketStore = useBasketStore()\n\nconst selectedGiftPayload = computed(() => basketStore.getSelectedGift)\n\nconst selectedGift = computed(() => {\n if (!selectedGiftPayload.value && !Array.isArray(selectedGiftPayload.value)) {\n return null\n }\n\n const giftWithChoice = basketStore.giftsOfChoice\n\n const { product_id, rule_id } = selectedGiftPayload.value\n\n if (!product_id || !rule_id) return null\n\n for (const { products, title } of giftWithChoice) {\n for (const product of products) {\n if (product.product_id === product_id) {\n return {\n ...product,\n giftTitle: title,\n }\n }\n }\n }\n})\n\nconst cartView = () => {\n // Событие просмотра корзины в CarrotQuest\n // Необходимо выводить в отдельных массивах\n const titles_list: string[] = []\n const url_list: string[] = []\n const price_list: number[] = []\n const image_list: string[] = []\n\n props?.items?.map((item) => ({\n titles_list: titles_list.push(item.title),\n url_list: url_list.push(item.url),\n price_list: price_list.push(item.price),\n image_list: image_list.push(item.image_url),\n }))\n\n window.carrotquest?.track('$cart_viewed', {\n $name: titles_list,\n $url: url_list,\n $amount: price_list,\n $img: image_list,\n })\n}\n\nonMounted(() => cartView)\n</script>\n\n<template>\n <div class=\"order-list\">\n <basket-order-item\n v-for=\"item in items\"\n :key=\"item.product_id\"\n class=\"order-list__item\"\n :item=\"item\"\n />\n\n <template v-for=\"additive in additives\" :key=\"additive.product_id\">\n <basket-order-additive-item\n :additive=\"additive\"\n class=\"order-list__item\"\n />\n </template>\n\n <template v-for=\"gift in giftsWithoutChoice\" :key=\"gift.rule_id\">\n <basket-order-gift-item\n v-for=\"product in gift.products\"\n :key=\"product.product_id\"\n :gift=\"product\"\n :gift-title=\"gift.title\"\n class=\"order-list__item\"\n />\n </template>\n\n <template v-if=\"selectedGift\">\n <basket-order-gift-item\n :gift=\"selectedGift\"\n :gift-title=\"selectedGift.giftTitle\"\n class=\"order-list__item\"\n />\n </template>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.order-list {\n &__item {\n padding: 20px 0 15px;\n border-bottom: 1px solid var(--ui-grey);\n\n &:first-child {\n padding-top: 0;\n }\n\n &:last-child {\n padding-bottom: 0;\n border-bottom: none;\n }\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useBasketStore } from '@/store/basket/basket'\n\nimport type { AdditiveItem, Gift, Item } from '@/types/api/api-v3/basket'\n\nimport BasketOrderHeader from '@/components/Basket/basket-order/BasketOrderHeader.vue'\nimport BasketOrderList from '@/components/Basket/basket-order/BasketOrderList.vue'\n\nconst DialogBasketClear = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/DialogBasketClear.vue'),\n)\n\ntype Props = {\n items: Item[]\n giftsWithoutChoice: Gift[]\n additives: AdditiveItem[]\n}\n\ndefineProps<Props>()\n\nconst basketStore = useBasketStore()\n\nconst isClearBasketDialogVisible = ref(false)\n\nconst clearBasket = async () => {\n window.carrotquest?.track('Корзина очищена', {})\n\n localStorage.setItem('showedWarningAdditivesOrClientPack', 'false')\n localStorage.removeItem('selectedGift')\n\n await basketStore.clearBasket()\n}\n</script>\n\n<template>\n <section class=\"order\">\n <basket-order-header\n @show-clear-basket-dialog=\"isClearBasketDialogVisible = true\"\n />\n\n <basket-order-list\n :items=\"items\"\n :gifts-without-choice=\"giftsWithoutChoice\"\n :additives=\"additives\"\n class=\"item-list\"\n />\n\n <the-dialog v-model=\"isClearBasketDialogVisible\" :max-width=\"620\">\n <dialog-basket-clear\n @allow=\"clearBasket\"\n @disallow=\"isClearBasketDialogVisible = false\"\n />\n </the-dialog>\n </section>\n</template>\n","import { AxiosError } from 'axios'\n\nimport { LoadState } from '@/store'\n\nimport {\n AdditiveItem,\n ClientPack,\n Cost,\n DeliveryMethods,\n ErrorData,\n Gift,\n Item,\n PromocodeType,\n PropositionItem,\n} from '@/api/modules/basket/types'\nimport { ChangeChoices } from '@/types/api/api-v3/basket'\nimport { BasketPayment } from '@/types/api/api-v3/paymentMethods'\n\nexport type BasketState = LoadState<Basket, AxiosError<ErrorData>>\n\nexport interface Basket {\n totalPrice: number\n totalAmount: number\n amountToPay: number\n itemsCount: number\n items: Item[]\n additives: AdditiveItem[]\n maxNumberOfPersons: number\n persons: Persons\n promocode: Promocode\n delivery: BasketDelivery\n gifts: Gift[]\n bonuses: Bonuses\n selectedPaymentMethod: BasketPayment | null\n note: string\n change: number\n proposition: Proposition\n clientPacks: ClientPack[]\n doNotCallMeBack: boolean\n isExtra: boolean\n}\n\nexport interface BasketDelivery {\n cost: Cost | null\n method: DeliveryMethods\n order_address: string | null\n addresses: BasketDeliveryAddresses\n}\n\nexport type BasketDeliveryAddresses = {\n [K in DeliveryMethods]: number | string | null\n}\n\nexport interface Persons {\n errorMessage: string\n helpMessage: string\n maxNumber: number | null\n message: string\n number: number | null\n}\n\nexport interface Promocode {\n discountAmount: number\n title: string\n value: string\n valid: boolean\n error: string\n type: PromocodeType | null\n}\n\nexport interface Bonuses {\n toSpendAmount: number\n maxSpendAmount: number\n toAccrueAmount: number\n totalAmount: number\n errorMessage: string\n message: string\n}\n\nexport interface Proposition {\n timeToLive: number\n popupText: string\n items: PropositionItem[]\n}\n\nexport interface ChangeState {\n choices: ChangeChoices[]\n quantitySelectedProducts: Record<number, number>\n}\n\nexport interface TimeState {\n delivery_at: string\n delivery_at_text: string\n error: string\n choices: DateTimeChoices[]\n message: string\n variants: TimeVariants[]\n warning: string\n warning_icon: string\n selectedTimeMethod: TimeMethod\n}\n\nexport interface TimeVariants {\n delivery_at_choice: string\n delivery_at_text: string\n delivery_at: string\n}\n\nexport interface DateTimeChoices {\n text: string\n value: string\n}\n\nexport enum TimeMethod {\n AVAILABLE_TIME = 'AVAILABLE_TIME',\n ON_TIME = 'ON_TIME',\n}\nexport interface SetTimePayload {\n delivery_at_client: boolean\n delivery_at?: string\n}\n","import { defineStore } from 'pinia'\nimport { useNuxtApp } from '#app'\n\nimport { StoreId } from '@/store'\nimport { TimeMethod, TimeState } from '@/store/basket/basket.types'\nimport { Success } from '@/api/results'\n\n/* Utils */\nimport { getListOfMonth } from '@/store/basket/basket.utils'\n\nconst defaultState: TimeState = {\n delivery_at: '',\n delivery_at_text: '',\n error: '',\n choices: [],\n message: '',\n variants: [],\n warning: '',\n warning_icon: '',\n selectedTimeMethod: TimeMethod.AVAILABLE_TIME,\n}\n\nexport const useBasketTimeStore = defineStore({\n id: StoreId.BASKET_TIME,\n state: (): TimeState => defaultState,\n actions: {\n setTime(newTimeState: Partial<TimeState>) {\n Object.assign(this.$state, newTimeState)\n },\n\n async getAvailableTime(props: {\n delivery_at_client: boolean\n delivery_at?: string\n }) {\n const { $apiService } = useNuxtApp()\n\n this.setTime({\n delivery_at: defaultState.delivery_at,\n })\n\n const result = await $apiService.basket.getAvailableTime(props)\n\n if (result instanceof Success) {\n this.setTime(result?.data || defaultState)\n\n return\n }\n\n this.setTime({ error: result.message })\n },\n\n async getDateChoices() {\n const { $apiService } = useNuxtApp()\n\n const result = await $apiService.basket.getDateChoices()\n\n if (result instanceof Success) {\n return result.data\n }\n\n return getListOfMonth()\n },\n\n async getTimeChoices({ date }: { date: string }) {\n const { $apiService } = useNuxtApp()\n\n this.setTime({\n delivery_at: defaultState.delivery_at,\n warning: defaultState.warning,\n variants: defaultState.variants,\n })\n\n const result = await $apiService.basket.getTimeChoices({ date })\n\n if (result instanceof Success) {\n this.setTime(result?.data || defaultState)\n\n return\n }\n\n this.setTime({ error: result.message })\n },\n },\n})\n","<script setup lang=\"ts\">\nimport { checkSavedCard } from '@/utils/checkSavedCard'\n\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useBasketTimeStore } from '@/store/basket/basket-time'\n\nimport { CostStatuses } from '@/api/modules/basket/types'\nimport { Cost } from '@/types/api/api-v3/basket'\nimport { PayMethods } from '@/types/api/api-v3/orders/order'\nimport {\n BasketPurchaseButtonEmit,\n BasketStep,\n CheckoutButtonState,\n CheckoutButtonStateInjectType,\n} from '@/types/basket'\n\ntype Props = {\n basketStep: BasketStep\n cost: Cost | null\n isAuthenticated: boolean\n isGiftNeed: boolean\n isLoading: boolean\n isPriceSectionSticky: boolean\n}\n\nconst checkoutButtonState = inject<CheckoutButtonStateInjectType>(\n 'checkoutButtonState',\n)\n\nconst basketStore = useBasketStore()\nconst basketTimeStore = useBasketTimeStore()\n\nconst emit = defineEmits([...Object.keys(BasketPurchaseButtonEmit)])\nconst props = defineProps<Props>()\n\nconst basketSelectedPaymentMethod = computed(\n () => basketStore.basketSelectedPaymentMethod,\n)\n\nconst basketGiftsWithChoice = computed(() => basketStore.giftsOfChoice)\n\nconst selectedAddress = computed(() => basketStore.selectedAddress)\n\nconst selectedGift = computed(() => basketStore.getSelectedGift)\n\nconst selectedPaymentMethod = computed(\n () => basketStore.data.selectedPaymentMethod,\n)\n\nconst purchaseButtonText = computed(() => {\n if (!selectedPaymentMethod.value) {\n return 'Оформить'\n }\n\n const isOnlineMethod = checkSavedCard(selectedPaymentMethod.value)\n ? true\n : ![PayMethods.CARD, PayMethods.CASH, PayMethods.SAVED_CARD].includes(\n selectedPaymentMethod.value?.type,\n )\n\n return isOnlineMethod ? 'Оплатить' : 'Оформить'\n})\n\nconst button = computed(() => {\n // Если пользователь неавторизован, то открываем ДО авторизации\n if (!props?.isAuthenticated) {\n return {\n text: 'Авторизоваться',\n emitName: BasketPurchaseButtonEmit.goToAuthorize,\n }\n }\n\n if (\n props?.cost?.error_message &&\n props?.cost?.status === CostStatuses.UNDER_MIN_AMOUNT\n )\n return {\n text: 'В каталог',\n emitName: BasketPurchaseButtonEmit.goToCatalog,\n }\n\n if (!basketStore.promocodeIsValid)\n return {\n text: 'Проверьте промокод',\n emitName: BasketPurchaseButtonEmit.goToDiscount,\n }\n\n if (\n basketGiftsWithChoice.value.length !== 0 &&\n props.isGiftNeed &&\n !selectedGift.value\n )\n return {\n text: 'К выбору подарка',\n emitName: BasketPurchaseButtonEmit.goToGifts,\n }\n\n // Если не выбрали адрес или есть ошибка в deliveryCost\n if (!selectedAddress.value || props.cost?.error_message)\n return {\n text: 'К выбору адреса',\n emitName: BasketPurchaseButtonEmit.goToAddress,\n }\n\n if (props?.basketStep === BasketStep.FIRST) {\n return {\n text: 'Ко времени и оплате',\n emitName: BasketPurchaseButtonEmit.goToSecondStep,\n }\n }\n\n if (basketTimeStore.error) {\n return {\n text: 'Ко времени',\n emitName: BasketPurchaseButtonEmit.goToDeliveryAt,\n }\n }\n\n if (basketSelectedPaymentMethod.value === 'Не выбрано' && props?.basketStep) {\n return {\n text: 'К способу оплаты',\n emitName: BasketPurchaseButtonEmit.goToPayment,\n }\n }\n\n if (checkoutButtonState?.get.value === CheckoutButtonState.changeExchange)\n return {\n text: checkoutButtonState.get.value,\n emitName: BasketPurchaseButtonEmit.goToPayment,\n }\n\n return {\n text: purchaseButtonText.value,\n emitName: BasketPurchaseButtonEmit.goToPurchase,\n }\n})\n\nconst onClickHandler = () => emit(button.value.emitName)\n</script>\n\n<template>\n <the-button\n class=\"button\"\n :class=\"{ 'button--sticky': isPriceSectionSticky }\"\n :loading=\"isLoading\"\n type=\"button\"\n @click=\"onClickHandler\"\n >\n {{ button.text }}\n </the-button>\n</template>\n\n<style lang=\"scss\" scoped>\n.button {\n width: 100%;\n overflow: hidden;\n transition: width 0.2s ease-in-out;\n\n &--sticky {\n width: 60%;\n overflow: hidden;\n transition: width 0.2s ease-in-out;\n }\n\n @include media('<tablet') {\n width: 100%;\n\n &--sticky {\n overflow: hidden;\n transition: width 0.2s ease-in-out;\n }\n }\n}\n</style>\n","<script setup lang=\"ts\">\n// components\n// types\nimport { Cost } from '@/types/api/api-v3/basket'\nimport { BasketPurchaseButtonEmit, BasketStep } from '@/types/basket'\n\nimport BasketPricePanelButton from '@/components/Basket/basket-price-panel/BasketPricePanelButton.vue'\n\ntype Props = {\n amountToPay: string\n basketStep: BasketStep\n cost: Cost | null\n isAuthenticated: boolean\n isGiftNeed?: boolean\n isLoading: boolean\n isPriceSectionSticky: boolean\n}\n\nconst emit = defineEmits([\n 'orderCheckout',\n ...Object.keys(BasketPurchaseButtonEmit),\n])\ndefineProps<Props>()\n\nconst { push } = useRouter()\n\nconst orderCheckout = () => emit('orderCheckout')\n\nconst goToCatalog = () => push('/')\n\nconst goToPayment = () => emit('goToPayment', 'payment_method')\n\nconst goToAuthorize = () => emit('goToAuthorize')\n\nconst goToAddress = () => emit('goToAddress', 'addresses')\n\nconst goToDeliveryAt = () => emit('goToDeliveryAt', 'delivery_at')\n\nconst goToDiscount = () => emit('goToDiscount', 'discount')\n\nconst goToGifts = () => emit('goToGifts', 'gifts')\n\nconst goToSecondStep = () => emit('goToSecondStep')\n</script>\n\n<template>\n <div id=\"short-panel\" class=\"panel\">\n <transition name=\"height\">\n <div v-if=\"cost?.error_message\" class=\"panel__top\">\n {{ cost.message }}\n </div>\n </transition>\n\n <div class=\"panel__bottom\">\n <div v-if=\"isPriceSectionSticky\" class=\"panel__bottom-info\">\n <div class=\"value\">\n {{ amountToPay }}\n </div>\n\n <div class=\"text\">Итого</div>\n </div>\n\n <div class=\"panel__bottom-button\">\n <basket-price-panel-button\n :cost=\"cost\"\n :is-authenticated=\"isAuthenticated\"\n :is-gift-need=\"isGiftNeed\"\n :is-loading=\"isLoading\"\n :basket-step=\"basketStep\"\n :is-price-section-sticky=\"isPriceSectionSticky\"\n @go-to-payment=\"goToPayment\"\n @go-to-catalog=\"goToCatalog\"\n @go-to-purchase=\"orderCheckout\"\n @go-to-authorize=\"goToAuthorize\"\n @go-to-address=\"goToAddress\"\n @go-to-delivery-at=\"goToDeliveryAt\"\n @go-to-discount=\"goToDiscount\"\n @go-to-gifts=\"goToGifts\"\n @go-to-second-step=\"goToSecondStep\"\n />\n </div>\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n@use '@/assets/styles/animations.scss' as *;\n\n.panel {\n display: grid;\n gap: 20px;\n\n &__top {\n font-size: 12px;\n font-weight: 700;\n color: var(--ui-text-secondary);\n text-align: center;\n }\n\n &__bottom {\n display: flex;\n gap: 0 40px;\n justify-content: space-between;\n\n &-info {\n width: max-content;\n white-space: nowrap;\n\n .value {\n font-size: 18px;\n font-weight: 800;\n }\n\n .text {\n font-size: 14px;\n font-weight: 600;\n color: var(--ui-text-secondary);\n }\n }\n\n &-button {\n display: flex;\n justify-content: flex-end;\n width: 100%;\n }\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { Field as VeeField } from 'vee-validate'\n\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useCityStore } from '@/store/city/city'\nimport { useUserStore } from '@/store/user/user'\n\nimport { DeliveryMethods } from '@/api/modules/basket/types'\nimport { BasketPurchaseButtonEmit, BasketStep } from '@/types/basket'\n\nimport BasketPricePanelRow from '@/components/Basket/basket-price-panel/BasketPricePanelRow.vue'\nimport BasketPriceShortPanel from '@/components/Basket/basket-price-panel/BasketPriceShortPanel.vue'\nimport BasketTitle from '@/components/Basket/basket-utils/BasketTitle.vue'\n\ntype Props = {\n basketStep: BasketStep\n isGiftNeed?: boolean\n isLoading: boolean\n isPriceSectionSticky: boolean\n amountToPayWithSymbol: string\n}\n\nconst cityStore = useCityStore()\nconst basketStore = useBasketStore()\nconst userStore = useUserStore()\n\nconst emit = defineEmits([\n 'orderCheckout',\n ...Object.keys(BasketPurchaseButtonEmit),\n])\nconst props = defineProps<Props>()\n\nconst isAuthenticated = computed(() => userStore.isAuthenticated)\n\nconst basket = computed(() => basketStore.data)\n\nconst currencySymbol = computed(() => cityStore.currencySymbol)\n\nconst selectedAddress = computed(() => basketStore.selectedAddress)\n\nconst isBasketOnFirstStep = computed(\n () => props?.basketStep === BasketStep.FIRST,\n)\n\nconst isDeliveryMethod = computed(\n () => basket.value?.delivery.method === DeliveryMethods.COURIER,\n)\n\nconst isDeliveryMethodTitle = computed(\n () => basketStore.basketSelectedDeliveryMethod,\n)\n\nconst isDeliveryMethodValue = computed(() => {\n if (!selectedAddress.value) return ''\n\n if (!basket.value.delivery.cost?.value) {\n return 'Бесплатно'\n }\n\n return `${basket.value.delivery.cost?.value} ${currencySymbol.value}`\n})\n\nconst basketSelectedPaymentMethod = computed(\n () => basketStore.basketSelectedPaymentMethod,\n)\n\nconst showChangeInfo = computed(\n () =>\n basket.value.change !== 0 &&\n basket.value.change > basket.value.amountToPay &&\n !!basketSelectedPaymentMethod.value &&\n basketSelectedPaymentMethod.value === 'Наличные',\n)\n\nconst toAccrueAmountBonuses = computed(\n () => basket?.value?.bonuses?.toAccrueAmount || 0,\n)\n\nconst scrollToErrorBlock = (errorBlock: string, error: boolean) => {\n if (error) return\n\n document\n .querySelector<HTMLElement>(`#${errorBlock}`)\n ?.scrollIntoView({ behavior: 'smooth', block: 'center' })\n}\n\nconst orderCheckout = () => emit('orderCheckout')\n\nconst goToAuthorize = () => emit('goToAuthorize')\n\nconst goToSecondStep = () => emit('goToSecondStep')\n</script>\n\n<template>\n <vee-field id=\"price-panel\" vid=\"detail\" name=\"detail\" as=\"section\">\n <basket-title\n v-if=\"!isPriceSectionSticky\"\n class=\"price-panel-title\"\n title=\"Стоимость заказа\"\n />\n\n <section v-if=\"!isPriceSectionSticky\" class=\"container\">\n <basket-price-panel-row\n v-if=\"isAuthenticated\"\n :title=\"isDeliveryMethodTitle\"\n :value=\"selectedAddress || 'Не указан'\"\n />\n\n <basket-price-panel-row\n v-if=\"isDeliveryMethod && isAuthenticated\"\n title=\"Доставка\"\n >\n <div>{{ isDeliveryMethodValue }}</div>\n </basket-price-panel-row>\n\n <basket-price-panel-row\n v-if=\"isAuthenticated && !isBasketOnFirstStep\"\n title=\"Оплата\"\n :value=\"basketSelectedPaymentMethod\"\n @click=\"\n scrollToErrorBlock('basket-payment', !basketSelectedPaymentMethod)\n \"\n />\n\n <basket-price-panel-row\n v-if=\"showChangeInfo && isAuthenticated && !isBasketOnFirstStep\"\n title=\"Сдача с\"\n :value=\"`${basket.change} ${currencySymbol}`\"\n @click=\"scrollToErrorBlock('change', showChangeInfo)\"\n />\n\n <basket-price-panel-row\n title=\"Сумма заказа\"\n :value=\"`${basket.totalAmount} ${currencySymbol}`\"\n />\n\n <basket-price-panel-row\n v-if=\"isAuthenticated\"\n title=\"Начислено бонусов\"\n @click=\"scrollToErrorBlock('bonuses', false)\"\n >\n <p v-if=\"isAuthenticated\">\n {{ toAccrueAmountBonuses }}\n </p>\n <p v-else>Нужно авторизоваться</p>\n </basket-price-panel-row>\n\n <basket-price-panel-row\n v-if=\"basket.bonuses.toSpendAmount && isAuthenticated\"\n title=\"Скидка бонусами\"\n :value=\"`${basket.bonuses.toSpendAmount} ${currencySymbol}`\"\n />\n\n <basket-price-panel-row\n v-if=\"basket.promocode.discountAmount && isAuthenticated\"\n title=\"Скидка по промокоду\"\n :value=\"`${basket.promocode.discountAmount} ${currencySymbol}`\"\n />\n\n <hr class=\"container__line\" />\n\n <basket-price-panel-row\n title=\"Итого\"\n :value=\"amountToPayWithSymbol\"\n is-title\n />\n </section>\n\n <basket-price-short-panel\n :cost=\"basket.delivery.cost\"\n :amount-to-pay=\"amountToPayWithSymbol\"\n :is-authenticated=\"isAuthenticated\"\n :is-gift-need=\"isGiftNeed\"\n :is-loading=\"isLoading\"\n :basket-step=\"basketStep\"\n :is-price-section-sticky=\"isPriceSectionSticky\"\n @order-checkout=\"orderCheckout\"\n @go-to-payment=\"scrollToErrorBlock\"\n @go-to-authorize=\"goToAuthorize\"\n @go-to-address=\"scrollToErrorBlock\"\n @go-to-delivery-at=\"scrollToErrorBlock\"\n @go-to-discount=\"scrollToErrorBlock\"\n @go-to-gifts=\"scrollToErrorBlock\"\n @go-to-second-step=\"goToSecondStep\"\n />\n </vee-field>\n</template>\n\n<style lang=\"scss\" scoped>\n.container {\n position: relative;\n display: grid;\n grid-template-rows: 1fr;\n gap: 8px 0;\n margin-bottom: 20px;\n overflow: hidden;\n\n &__line {\n margin: 8px 0;\n border: 0.5px solid var(--ui-grey);\n }\n\n &__total {\n font-size: 18px;\n font-weight: 800;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { Form as VeeForm, FormContext } from 'vee-validate'\n\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useCityStore } from '@/store/city/city'\nimport { useUserStore } from '@/store/user/user'\n\nimport { BasketStep } from '@/types/basket'\n\nimport BasketAdditive from '@/components/Basket/basket-additive/BasketAdditive.vue'\nimport BasketAddresses from '@/components/Basket/basket-addresses/BasketAddresses.vue'\nimport BasketClientPack from '@/components/Basket/basket-client-pack/BasketClientPack.vue'\nimport BasketDiscount from '@/components/Basket/basket-discount/BasketDiscount.vue'\nimport BasketGifts from '@/components/Basket/basket-gifts/BasketGifts.vue'\nimport BasketNote from '@/components/Basket/basket-note/BasketNote.vue'\nimport BasketOrder from '@/components/Basket/basket-order/BasketOrder.vue'\nimport BasketPricePanel from '@/components/Basket/basket-price-panel/BasketPricePanel.vue'\nimport BasketPriceShortPanel from '@/components/Basket/basket-price-panel/BasketPriceShortPanel.vue'\n\nconst DialogBasketAdditivesAndPacks = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/DialogBasketAdditivesAndPacks.vue'),\n)\nconst LoginForm = defineAsyncComponent(\n () => import('@/components/login/LoginForm.vue'),\n)\n\ntype Props = {\n clientPacksCount: number\n clientAdditivesCount: number\n}\n\nconst MT_EVENT_NAME = 'startofordering'\n\nconst emit = defineEmits(['goToStep', 'scrollToErrorBlock'])\nconst props = defineProps<Props>()\n\nconst { $metrics } = useNuxtApp()\n\nconst basketStore = useBasketStore()\nconst userStore = useUserStore()\nconst { currencySymbol } = useCityStore()\n\nconst basketObserver = ref<FormContext | null>(null)\nconst isGiftNeed = ref(false)\nconst isPriceSectionSticky = ref(true)\nconst dialogs = ref({\n additivesAndPacks: {\n visible: false,\n },\n userAuthorization: {\n visible: false,\n },\n})\n\nconst isClientPackAvailable = computed(() =>\n !basketStore.data.persons ? true : basketStore.data.persons.maxNumber === 0,\n)\nconst basket = computed(() => basketStore.data)\nconst isAuthenticated = computed(() => userStore.isAuthenticated)\nconst basketGiftsWithoutChoice = computed(() => basketStore.giftsNoChoice)\nconst basketGiftsWithChoice = computed(() => basketStore.giftsOfChoice)\nconst addedAdditives = computed(() => basketStore.addedAdditives)\nconst amountToPayWithSymbol = computed(() => {\n return `${basket.value.amountToPay} ${currencySymbol}`\n})\nconst basketOrderAddress = computed(() => {\n return basketStore.data.delivery?.order_address\n})\n\nconst setPricePanelStickyObserver = () => {\n useIntersectionObserver(\n '#price-panel',\n {\n threshold: 0.5,\n },\n ([{ isIntersecting, boundingClientRect }]) => {\n isPriceSectionSticky.value =\n !isIntersecting && boundingClientRect.top > 500\n },\n )\n}\n\n// Функция для получения значения из localStorage\nconst getShowedAdditivesAndPacksValue = (): boolean => {\n const localStorageValue = localStorage.getItem(\n 'showedWarningAdditivesOrClientPack',\n )\n\n if (!localStorageValue) return false\n\n return JSON.parse(localStorageValue)\n}\n\n// Функция для обработки показа диалогового окна добавок и приборов\nconst showAdditivesAndPacksDialog = (callback: () => void) => {\n // Получаем флаг из localStorage\n const isAdditivesAndClientPackModalShowed = getShowedAdditivesAndPacksValue()\n // Проверяем, добавил ли клиент добавки или приборы\n const isAdditivesOrPacksNotAdded =\n !props.clientAdditivesCount || !props.clientPacksCount\n\n /*\n Проверяем, показывали ли мы пользователю диалоговое окно с приборами и добавками\n Так же проверяем,\n */\n if (!isAdditivesAndClientPackModalShowed && isAdditivesOrPacksNotAdded) {\n dialogs.value.additivesAndPacks.visible = true\n\n return\n }\n\n // Выполняем переданный коллбек при достижении всех условий\n callback()\n}\n\nconst goToSecondStep = () => {\n // Если клиент не авторизован, то сначала показываем диалоговое окно авторизации\n if (!isAuthenticated.value) {\n dialogs.value.userAuthorization.visible = true\n\n return\n }\n\n showAdditivesAndPacksDialog(() => {\n emit('goToStep', BasketStep.SECOND)\n })\n}\n\nconst goToAuthorize = () => {\n showAdditivesAndPacksDialog(() => {\n dialogs.value.userAuthorization.visible = true\n })\n}\n\nconst goToCatalog = () => navigateTo('/')\n\nconst userAuthorizationDialogClose = () => {\n dialogs.value.userAuthorization.visible = false\n\n if (basketOrderAddress.value) return\n\n setTimeout(() => scrollToErrorBlock('addresses'), 1000)\n}\n\n// Скролл до блока с ошибкой\nconst showError = () =>\n setTimeout(() => {\n const fieldError = getFieldError()\n\n scrollToErrorBlock(fieldError)\n }, 0)\n\n// Функция для получения id блока, в котором есть ошибка валидации\nconst getFieldError = () => {\n const fieldsErrors = basketObserver.value?.errors\n\n if (!fieldsErrors) return null\n\n return Object.keys(fieldsErrors).at(0) || null\n}\n\nconst scrollToErrorBlock = (errorBlock?: string | null) => {\n emit('scrollToErrorBlock', errorBlock)\n}\n\nonMounted(() => {\n setPricePanelStickyObserver()\n\n $metrics?.eventSendGoal({ mt: MT_EVENT_NAME })\n})\n</script>\n\n<template>\n <vee-form\n v-slot=\"{ handleSubmit }\"\n ref=\"basketObserver\"\n class=\"basket__section\"\n validate-on-mount\n >\n <basket-order\n class=\"section order\"\n :items=\"basket.items\"\n :gifts-without-choice=\"basketGiftsWithoutChoice\"\n :additives=\"addedAdditives\"\n />\n\n <basket-client-pack\n v-if=\"isClientPackAvailable\"\n :client-packs=\"basket.clientPacks\"\n :client-packs-count=\"clientPacksCount\"\n class=\"section\"\n />\n\n <basket-additive\n v-if=\"basket.additives.length > 0\"\n id=\"additives\"\n :additives=\"basket.additives\"\n class=\"section additives\"\n @go-to-second-step=\"goToSecondStep\"\n />\n\n <basket-gifts\n v-if=\"basketGiftsWithChoice.length !== 0\"\n v-model=\"isGiftNeed\"\n class=\"section\"\n :gifts=\"basketGiftsWithChoice\"\n />\n\n <basket-note class=\"section\" />\n\n <basket-addresses v-if=\"isAuthenticated\" class=\"section\" />\n\n <basket-discount class=\"section\" />\n\n <transition name=\"ui-slide-up\">\n <div\n v-if=\"isPriceSectionSticky\"\n class=\"section section--sticky price-button\"\n >\n <basket-price-short-panel\n :amount-to-pay=\"amountToPayWithSymbol\"\n :is-loading=\"basketStore.isLoading\"\n :is-gift-need=\"isGiftNeed\"\n :basket-step=\"BasketStep.FIRST\"\n :cost=\"basket.delivery.cost\"\n :is-price-section-sticky=\"true\"\n :is-authenticated=\"isAuthenticated\"\n @go-to-catalog=\"goToCatalog\"\n @go-to-authorize=\"goToAuthorize\"\n @go-to-address=\"scrollToErrorBlock('addresses')\"\n @go-to-discount=\"scrollToErrorBlock('discount')\"\n @go-to-gifts=\"scrollToErrorBlock('gifts')\"\n @go-to-second-step=\"handleSubmit(goToSecondStep), showError()\"\n />\n </div>\n </transition>\n\n <basket-price-panel\n :basket-step=\"BasketStep.FIRST\"\n :amount-to-pay-with-symbol=\"amountToPayWithSymbol\"\n :cost=\"basket.delivery.cost\"\n :is-authenticated=\"isAuthenticated\"\n :is-gift-need=\"isGiftNeed\"\n :is-loading=\"basketStore.isLoading\"\n :is-price-section-sticky=\"false\"\n class=\"section price\"\n @go-to-catalog=\"goToCatalog\"\n @go-to-authorize=\"goToAuthorize\"\n @go-to-address=\"scrollToErrorBlock('addresses')\"\n @go-to-discount=\"scrollToErrorBlock('discount')\"\n @go-to-gifts=\"scrollToErrorBlock('gifts')\"\n @go-to-second-step=\"handleSubmit(goToSecondStep), showError()\"\n />\n </vee-form>\n\n <!-- Диалоговое окно добавок и клиент пакетов -->\n <dialog-basket-additives-and-packs\n v-model=\"dialogs.additivesAndPacks.visible\"\n :client-packs=\"basket.clientPacks\"\n :client-packs-count=\"clientPacksCount\"\n :additives=\"basket.additives\"\n :additives-count=\"clientAdditivesCount\"\n @go-to-second-step=\"goToSecondStep\"\n />\n\n <the-dialog v-model=\"dialogs.userAuthorization.visible\" :max-width=\"560\">\n <login-form\n @code-confirmed-by-named-user=\"userAuthorizationDialogClose\"\n @set-name=\"userAuthorizationDialogClose\"\n @sign-in-by-named-user=\"userAuthorizationDialogClose\"\n />\n </the-dialog>\n</template>\n\n<style lang=\"scss\" scoped>\n@use '@/assets/styles/basket' as *;\n</style>\n","<script lang=\"ts\" setup>\nimport { useBasketStore } from '@/store/basket/basket'\n\nconst basketStore = useBasketStore()\n\nconst doNotCallMeBack = computed(() => {\n return basketStore.data.doNotCallMeBack\n})\n\nconst changeDoNotCallMeBack = (value: boolean) => {\n // Отрицание значений, т.к. на бэке true - это не звонить\n basketStore.setDoNotCallMeBack(!value)\n}\n</script>\n\n<template>\n <div class=\"call\">\n <div class=\"call__top-container\">\n <div class=\"call__title\">Подтверждать заказ звонком</div>\n\n <the-switch\n :model-value=\"!doNotCallMeBack\"\n @update:model-value=\"changeDoNotCallMeBack\"\n />\n </div>\n\n <div class=\"call__description\">\n Больше не нужно ждать звонка. Отключите подтверждение заказа звонком и мы\n сразу примем ваш заказ\n </div>\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.call {\n &__top-container {\n display: flex;\n gap: 16px;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n }\n\n &__title {\n font-size: 18px;\n font-weight: 800;\n color: var(--ui-text-primary);\n\n @include media('<=tablet') {\n font-size: 14px;\n }\n }\n\n &__description {\n width: 100%;\n max-width: 414px;\n font-size: 14px;\n font-weight: 600;\n color: var(--ui-text-secondary);\n\n @include media('<tablet') {\n max-width: unset;\n }\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useBasketChangeStore } from '@/store/basket/basket-change'\n\ntype Props = {\n change: number\n}\ndefineProps<Props>()\n\nconst basketStore = useBasketStore()\nconst basketChangeStore = useBasketChangeStore()\n\nconst setSelectedChange = (currentChange: number) => {\n basketStore.setChange(currentChange)\n}\n\n// Устанавливаем сдачу 0, чтобы не сохранялся стейт между оформлением заказа и корзиной\nonBeforeUnmount(() => {\n basketStore.setChange(0)\n})\n\nconst changeList = computed(() => {\n return basketChangeStore.choices\n})\n</script>\n\n<template>\n <div class=\"change\">\n <the-dropdown\n :model-value=\"change\"\n :options=\"changeList\"\n item-title=\"text\"\n item-value=\"value\"\n variant=\"secondary\"\n width=\"auto\"\n @update:model-value=\"setSelectedChange\"\n />\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.change {\n width: 140px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { defineRule, Field as VeeField } from 'vee-validate'\n\nimport { requiredValidator } from '@/utils/rulesOfValidate'\n\nimport { DeliveryMethods } from '@/types/api/api-v3/basket'\nimport type { BasketPayment } from '@/types/api/api-v3/paymentMethods'\nimport {\n PaymentMethodDescriptions,\n PaymentMethodType,\n} from '@/types/api/api-v3/paymentMethods'\n\nimport BasketPaymentChange from '@/components/Basket/basket-payment/BasketPaymentChange.vue'\nimport BasketErrorMessage from '@/components/Basket/basket-utils/BasketErrorMessage.vue'\nconst BasketFailed = defineAsyncComponent(\n () => import('@/components/Basket/basket-utils/BasketFailed.vue'),\n)\n\ntype Props = {\n methodDelivery: DeliveryMethods\n selectedPaymentMethod: BasketPayment | null\n change: number\n amountToPay: number\n isChangeExist: boolean\n changeErrorShow: boolean\n validateErrors: string[]\n}\nconst props = defineProps<Props>()\n\nconst emit = defineEmits(['update:change'])\n\ndefineRule('required-payment-default', requiredValidator)\n\n// Формируем описание для способа оплат\nconst descriptionBasketPaymentMethod = computed(() => {\n if (!props.selectedPaymentMethod) return ''\n\n // Для оплаты картой курьеру и наличными формируем префикса в зависимости от способа доставки\n if (\n [PaymentMethodType.CARD, PaymentMethodType.CASH].includes(\n props.selectedPaymentMethod?.type,\n )\n ) {\n const prefix =\n props.methodDelivery === DeliveryMethods.COURIER ? '_courier' : ''\n\n return PaymentMethodDescriptions[\n `${props.selectedPaymentMethod?.type}${prefix}`\n ]\n }\n // Для сохраненной карты\n if (checkSavedCard(props.selectedPaymentMethod))\n return PaymentMethodDescriptions.saved_card\n\n return PaymentMethodDescriptions[props.selectedPaymentMethod?.type]\n})\n\n// Проверка на отображение блока сдачи:\n// - Способ оплаты выбран\n// - Способ оплаты - наличные\n// - ошибка с api отсутствует\nconst isVisibleChangeBlock = computed(() => {\n return (\n props.selectedPaymentMethod?.type === PaymentMethodType.CASH &&\n !props.changeErrorShow\n )\n})\n\nconst onGetChange = () => {\n emit('update:change')\n}\n\n// Ошибка если не существует списка сдач, способ оплаты, и выбран способ оплаты наличные\nconst checkErrorMessage = computed(() => {\n return (\n props.change !== 0 &&\n !props.isChangeExist &&\n props.selectedPaymentMethod?.type === PaymentMethodType.CASH\n )\n})\n\nconst changeErrorMessage = computed(() => {\n if (!props.isChangeExist && props.change <= props.amountToPay) {\n return 'Купюра для выдачи должна быть больше суммы заказа'\n } else if (!props.isChangeExist) {\n return 'Сумма корзины изменилась, укажите, пожалуйста, сдачу'\n }\n\n return ''\n})\n\nconst isValidateError = computed(() => props.validateErrors.length)\n</script>\n\n<template>\n <transition-group name=\"height\" class=\"payment-methods-info\" tag=\"div\">\n <basket-failed\n v-if=\"changeErrorShow\"\n error-message=\"Не удалось загрузить выбор сдачи\"\n @update=\"onGetChange\"\n />\n\n <div v-if=\"!isValidateError\" class=\"payment-methods-info__description\">\n <p\n v-if=\"descriptionBasketPaymentMethod\"\n class=\"payment-methods-info__description-text\"\n >\n {{ descriptionBasketPaymentMethod }}\n </p>\n\n <basket-payment-change\n v-if=\"isVisibleChangeBlock\"\n id=\"change\"\n :change=\"change\"\n class=\"payment-methods-info__change\"\n />\n </div>\n </transition-group>\n\n <transition v-if=\"checkErrorMessage || isValidateError\" name=\"height\">\n <!-- провайдер для скролла до блока сдачи в случае если купюра для сдачи меньше суммы заказа-->\n <vee-field vid=\"change\" name=\"change\" rules=\"required-payment-default\">\n <basket-error-message\n class=\"payment-methods-info__payment-error validation__error\"\n :error-message=\"changeErrorMessage || validateErrors[0]\"\n />\n </vee-field>\n </transition>\n</template>\n\n<style scoped lang=\"scss\">\n.payment-methods-info {\n &__description {\n display: flex;\n gap: 0 20px;\n align-items: center;\n justify-content: space-between;\n\n @include media('<tablet') {\n flex-direction: column-reverse;\n gap: 16px;\n }\n }\n\n &__description-text {\n margin-block-start: 0 !important;\n margin-block-end: 0 !important;\n font-size: 14px;\n font-weight: 600;\n line-height: 20px;\n color: var(--ui-text-secondary);\n white-space: break-spaces;\n }\n\n &__change {\n min-width: 140px;\n\n @include media('<=portrait-phone') {\n width: 100% !important;\n }\n }\n\n &__payment-error {\n margin-top: 20px;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\n/* Types */\nimport { DeliveryMethods } from '@/types/api/api-v3/basket'\nimport {\n PaymentMethod,\n PaymentMethodIcons,\n PaymentMethodName,\n PaymentMethodType,\n} from '@/types/api/api-v3/paymentMethods'\n\ntype Props = {\n payment: PaymentMethod\n methodDelivery: DeliveryMethods\n}\nconst props = defineProps<Props>()\n\n// Формируем наименование способа оплат, с исключением для картой курьеру/в ресторане\nconst namePaymentMethod = computed(() => {\n if (props.payment.type !== PaymentMethodType.CARD)\n return PaymentMethodName[props.payment.type]\n\n const prefix =\n props.methodDelivery === DeliveryMethods.COURIER ? '_courier' : ''\n\n return PaymentMethodName[`${PaymentMethodType.CARD}${prefix}`]\n})\n\n// Через тип оплаты определяем размеры иконок\nconst iconClasses = computed(() => {\n const classes = ['payment-method__icon']\n\n if (props.payment.type === PaymentMethodType.SBP) {\n classes.push('payment-method__icon--sbp')\n }\n\n return classes\n})\n\nconst paymentIcon = computed(() => PaymentMethodIcons[props.payment.type])\n</script>\n\n<template>\n <div class=\"payment-method\">\n <nuxt-img v-if=\"paymentIcon\" :class=\"iconClasses\" :src=\"paymentIcon\" />\n\n <p class=\"payment-method__text\">\n {{ namePaymentMethod }}\n </p>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.payment-method {\n &__icon {\n width: 24px;\n height: 24px;\n }\n\n &__text {\n overflow: hidden;\n font-size: 12px;\n font-weight: 600;\n line-height: 16px;\n\n @include media('>=tablet') {\n font-size: 14px;\n line-height: 19px;\n }\n }\n}\n</style>\n","<script lang=\"ts\" setup>\n/* Types */\n/* Utils */\nimport { cropNumberOfCard } from '@/utils/cropNumberOfCard'\n\nimport { SavedCard, TypeCards } from '@/types/api/api-v3/paymentMethods'\n\ntype Props = {\n savedCard: SavedCard\n}\nconst props = defineProps<Props>()\n\nconst numberCard = computed(() =>\n cropNumberOfCard(props.savedCard.card_number, 4),\n)\n\n// Определяем имя бренда (один бренд может быть разными данными)\nconst brandName = computed(() => {\n /* Виза */\n if (props.savedCard?.brand.includes(TypeCards.VISA)) {\n return TypeCards.VISA\n }\n\n /* Мастер кард */\n if (props.savedCard?.brand.includes(TypeCards.MASTER_CARD)) {\n return TypeCards.MASTER_CARD\n }\n\n /* МИР */\n if (props.savedCard?.brand.includes(TypeCards.MIR)) {\n return TypeCards.MIR\n }\n\n /* Дефолтное */\n return TypeCards.DEFAULT\n})\n\nconst detectedClassSavedCard = computed(() => {\n // Через тип карты определяем цвет карты\n return [\n 'payment-card',\n {\n 'payment-card--master': brandName.value === TypeCards.MASTER_CARD,\n 'payment-card--mir': brandName.value === TypeCards.MIR,\n 'payment-card--visa': brandName.value === TypeCards.VISA,\n 'payment-card--default': brandName.value === TypeCards.DEFAULT,\n },\n ]\n})\n\nconst iconCard = {\n MASTERCARD: 'payments/master-card.png',\n MIR: 'payments/mir.png',\n VISA: 'payments/visa.png',\n DEFAULT: 'payments/default-card.png',\n}\n\n// Определяем иконку для карты\nconst detectedIconOfBrand = computed(() => {\n const nameIcon = brandName.value\n\n if (iconCard[nameIcon]) {\n return iconCard[nameIcon]\n }\n\n return iconCard.DEFAULT\n})\n</script>\n\n<template>\n <div :class=\"detectedClassSavedCard\">\n <nuxt-img\n class=\"payment-card__icon\"\n :src=\"detectedIconOfBrand\"\n :alt=\"savedCard.brand\"\n />\n\n <div class=\"payment-card__number-card\">\n {{ '•••' }} {{ numberCard }}\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.payment-card {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n padding: 5px;\n color: var(--ui-text-primary);\n cursor: pointer;\n background: #f8fafc;\n border-radius: 6px;\n\n @include media('>tablet') {\n min-height: unset;\n }\n\n &__number-card {\n font-size: 12px;\n font-weight: 600;\n line-height: 14px;\n }\n\n &--default {\n color: var(--ui-white);\n background: linear-gradient(90deg, #3c2e97 0%, #6b5bd0 100%) !important;\n\n .payment-card__icon {\n width: 24px;\n height: 24px;\n }\n }\n\n &--master {\n color: var(--ui-white);\n background: linear-gradient(\n 269.42deg,\n #635e5e 0.38%,\n #343434 99.38%\n ) !important;\n\n .payment-card__icon {\n width: 31px;\n height: 19px;\n margin: 2px 0 0 4px;\n }\n }\n\n &--mir {\n color: var(--ui-white);\n background: linear-gradient(\n 269.42deg,\n #1bbf22 0.38%,\n #00960f 99.38%\n ) !important;\n\n .payment-card__icon {\n width: 38px;\n height: 10px;\n margin-top: 6px;\n }\n }\n &--visa {\n color: var(--ui-white);\n background: linear-gradient(\n 269.42deg,\n #347ed5 0.38%,\n #225fa6 99.38%\n ) !important;\n\n .payment-card__icon {\n width: 38px;\n height: 12px;\n margin-top: 5px;\n }\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { checkSavedCard } from '@/utils/checkSavedCard'\n\nimport type { DeliveryMethods } from '@/types/api/api-v3/basket'\nimport type { BasketPayment } from '@/types/api/api-v3/paymentMethods'\n\nimport BasketPaymentMethod from '@/components/Basket/basket-payment/BasketPaymentMethod.vue'\nimport BasketPaymentSavedCard from '@/components/Basket/basket-payment/BasketPaymentSavedCard.vue'\n\ntype Props = {\n paymentItem: BasketPayment\n isActive: boolean\n methodDelivery: DeliveryMethods\n}\n\nconst props = defineProps<Props>()\n\nconst emit = defineEmits(['update:selected-payment'])\n\nconst onUpdateSelectedPayment = () => {\n emit('update:selected-payment', props.paymentItem)\n}\n\nconst paymentItemClasses = computed(() => {\n const classes = ['payment-item payment-item--saved-card']\n\n if (!checkSavedCard(props.paymentItem)) {\n return classes\n }\n\n if (props.isActive) {\n classes.push('payment-item--active')\n }\n\n return classes\n})\n</script>\n\n<template>\n <div v-if=\"checkSavedCard(paymentItem)\" :class=\"paymentItemClasses\">\n <basket-payment-saved-card\n :saved-card=\"paymentItem\"\n @click=\"onUpdateSelectedPayment\"\n />\n </div>\n\n <basket-payment-method\n v-else\n class=\"payment-item\"\n :class=\"{ 'payment-item--active': isActive }\"\n :payment=\"paymentItem\"\n :method-delivery=\"methodDelivery\"\n @click=\"onUpdateSelectedPayment\"\n />\n</template>\n\n<style scoped lang=\"scss\">\n.payment-item {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 8px;\n justify-content: space-between;\n width: 100px;\n min-width: 100px;\n min-height: 64px;\n padding: 8px;\n overflow: hidden;\n cursor: pointer;\n background: var(--ui-grey);\n border-radius: 10px;\n outline: 2px solid transparent;\n outline-offset: -2px;\n transition: outline-color 0.15s ease-in-out;\n\n @include media('>=tablet') {\n gap: 7px;\n width: 132px;\n min-width: 132px;\n min-height: 74px;\n padding: 12px;\n }\n\n &--saved-card {\n padding: 6px;\n background: var(--ui-white);\n box-shadow: var(--ui-card-shadow);\n }\n\n &--active {\n outline: 2px solid var(--ui-green);\n }\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { checkSavedCard } from '@/utils/checkSavedCard'\n\nimport { DeliveryMethods } from '@/types/api/api-v3/basket'\nimport { BasketPayment } from '@/types/api/api-v3/paymentMethods'\n\nimport BasketPaymentListItem from '@/components/Basket/basket-payment/BasketPaymentListItem.vue'\n\ntype Props = {\n basketPaymentMethods: BasketPayment[]\n methodDelivery: DeliveryMethods\n selectedPaymentMethod: BasketPayment | null\n}\n\nconst props = defineProps<Props>()\n\nconst { isMobile, breakpoint } = useResponsive()\n\nconst emit = defineEmits(['update:selected-payment'])\n\nconst selectPaymentMethod = (paymentMethod: BasketPayment) =>\n emit('update:selected-payment', paymentMethod)\n\nconst selectedPaymentMethodType = computed(\n () => props.selectedPaymentMethod?.type,\n)\n\nconst selectedSavedCardId = computed(() => {\n if (checkSavedCard(props.selectedPaymentMethod)) {\n return props.selectedPaymentMethod.id\n }\n\n return null\n})\n\nconst checkActivePaymentItem = (paymentItem: BasketPayment) => {\n if (checkSavedCard(paymentItem)) {\n return paymentItem.id === selectedSavedCardId.value\n }\n\n return paymentItem.type === selectedPaymentMethodType.value\n}\n\nconst paymentsList = computed(() => {\n if (!props.basketPaymentMethods) {\n return []\n }\n\n const list = []\n\n for (const payment of props.basketPaymentMethods) {\n list.push({\n payment,\n isActive: checkActivePaymentItem(payment),\n })\n }\n\n return list\n})\n\nconst sliderOptions = computed(() => {\n if (isMobile.value) {\n return { spaceBetween: 8, slideWidth: 100 }\n }\n\n return { spaceBetween: 10, slideWidth: 132 }\n})\n\nconst sliderKey = computed(() => {\n return `${paymentsList.value.length}-${breakpoint.value}`\n})\n</script>\n\n<template>\n <div class=\"payment-list\">\n <the-slider\n v-if=\"paymentsList.length\"\n :key=\"sliderKey\"\n :slide-width=\"sliderOptions.slideWidth\"\n :space-between=\"sliderOptions.spaceBetween\"\n :slides-to-scroll=\"3\"\n :arrows=\"!isMobile\"\n :snap=\"!isMobile\"\n slide-class=\"payment-item\"\n >\n <basket-payment-list-item\n v-for=\"paymentItem in paymentsList\"\n :key=\"paymentItem.payment.type\"\n :payment-item=\"paymentItem.payment\"\n :is-active=\"paymentItem.isActive\"\n :method-delivery=\"methodDelivery\"\n @update:selected-payment=\"selectPaymentMethod\"\n />\n </the-slider>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.payment-list {\n margin: 0 -20px;\n\n @include media('>=desktop-mini') {\n margin: 0;\n }\n\n :deep(.app-slider) {\n z-index: 3;\n }\n\n :deep(.app-slider__track) {\n padding: 24px 20px;\n scroll-padding-inline: 20px;\n\n @include media('>=desktop-mini') {\n padding: 24px 0;\n scroll-padding-inline: 0;\n }\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { defineRule, Field as VeeField } from 'vee-validate'\n\nimport { requiredPaymentMethod } from '@/utils/rulesOfValidate'\n\nimport { useAppStore } from '@/store/app/app'\nimport { SnackbarType } from '@/store/app/app.types'\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useBasketChangeStore } from '@/store/basket/basket-change'\nimport { useBasketPaymentMethodsStore } from '@/store/basket/basket-payment-methods'\nimport { useToggleStore } from '@/store/toggle/toggle'\n\nimport { Success } from '@/api/results'\nimport { OfflinePayMethods } from '@/types/api/api-v3/orders/order'\nimport {\n BasketPayment,\n PaymentMethodType,\n} from '@/types/api/api-v3/paymentMethods'\nimport {\n CheckoutButtonState,\n CheckoutButtonStateInjectType,\n} from '@/types/basket'\n\nimport BasketCallSelect from '@/components/Basket/basket-payment/BasketCallSelect.vue'\nimport BasketPaymentInfo from '@/components/Basket/basket-payment/BasketPaymentInfo.vue'\nimport BasketPaymentList from '@/components/Basket/basket-payment/BasketPaymentList.vue'\nimport BasketSection from '@/components/Basket/basket-utils/BasketSection.vue'\nimport BasketTitle from '@/components/Basket/basket-utils/BasketTitle.vue'\n\nconst BasketFailed = defineAsyncComponent(\n () => import('@/components/Basket/basket-utils/BasketFailed.vue'),\n)\n\nconst checkoutButtonState = inject<CheckoutButtonStateInjectType>(\n 'checkoutButtonState',\n)\n\nconst isBasketPaymentLoading = computed(\n () => basketPaymentMethodsStore.isLoading,\n)\n\nconst { showSnackbar } = useAppStore()\nconst { $metrics } = useNuxtApp()\n\nconst basketStore = useBasketStore()\nconst basketPaymentMethodsStore = useBasketPaymentMethodsStore()\nconst basketChangeStore = useBasketChangeStore()\nconst toggleStore = useToggleStore()\n\nconst basket = computed(() => basketStore.data)\nconst selectedPaymentMethod = computed(() => basket.value.selectedPaymentMethod)\nconst amountToPay = computed(() => basket.value.amountToPay)\nconst change = computed(() => basket.value.change)\nconst methodDelivery = computed(() => basket.value.delivery.method)\n\nconst basketPaymentMethods = computed(() => basketPaymentMethodsStore.data)\n\nconst updateSelectedPayment = (paymentMethod: BasketPayment | null) => {\n basketStore.setSelectedPaymentMethod(paymentMethod)\n\n if (paymentMethod?.type === PaymentMethodType.PAY_SELECTION) {\n $metrics?.eventSendGoal({ ym: 'payment_payselection' })\n }\n}\n\n// Получаем список оплат\nconst getBasketPaymentMethods = async () =>\n await basketPaymentMethodsStore.getPaymentMethods()\n\nconst changeErrorShow = ref(true)\n\n// Получаем обновленные данные по корзине при выборе наличных со сдачей\nconst getChange = async () => {\n const result = await basketChangeStore.fetchChange(amountToPay.value)\n\n if (result instanceof Success) {\n checkChange()\n changeErrorShow.value = false\n\n return\n }\n\n changeErrorShow.value = true\n}\n\nonMounted(async () => {\n await Promise.all([getBasketPaymentMethods(), getChange()])\n\n // Устанавливаем первый из списка оплат\n if (basketPaymentMethods.value.length)\n updateSelectedPayment(basketPaymentMethods.value[0])\n})\n\nconst isOfflinePayment = computed(() => {\n const offlinePayMethods: string[] = Object.values(OfflinePayMethods)\n return offlinePayMethods.includes(selectedPaymentMethod.value?.type || '')\n})\n\nconst isShowCallBlock = computed(\n () =>\n isOfflinePayment.value &&\n toggleStore.featureToggle.basket_order_checkout_do_not_call_me_back_enabled,\n)\n\nconst isChangeExist = ref(true)\n\nconst checkChange = () => {\n // проверка на наличие текущей купюры для сдачи в новом списке купюр\n const changeList: number[] = []\n\n basketChangeStore.choices.map((item) => ({\n changeList: changeList.push(item.value),\n }))\n\n isChangeExist.value = changeList.includes(change.value)\n}\n\n// Уведомляем, если сумма для оплаты > выбранной купюры для сдачи\nwatch(isChangeExist, (value) => {\n if (value) {\n checkoutButtonState?.set(null)\n return\n }\n\n checkoutButtonState?.set(CheckoutButtonState.changeExchange)\n\n showSnackbar({\n message: 'Измените сдачу',\n type: SnackbarType.MESSAGE,\n })\n})\n\nwatch(change, checkChange)\n\nwatch(amountToPay, getChange)\n\n/*\n Наблюдатель за отслеживанием текущих доступных способов оплаты в зависимости от:\n * Адреса доставки/метода доставки\n * Времени и \"Умного распределения\"\n*/\nwatch(\n () => basketPaymentMethodsStore.isLoading,\n (currentValue, prevValue) => {\n // Если нет текущего выбранного способа опаты - выходим\n if (!basket.value.selectedPaymentMethod) return\n\n // Если флаг isLoading из false становится true - выходим\n if (currentValue || !prevValue) return\n\n // Текущие способы оплаты\n const paymentMethods = basketPaymentMethodsStore.data\n // Текущий выбранный тип способа оплаты\n const selectedPaymentMethodType = basket.value.selectedPaymentMethod?.type\n\n // Мапимся и убеждаемся, что после перезагрузки у нас остался выбранный способ оплаты\n const isSelectedPaymentMethodAvailable = paymentMethods.some(\n ({ type }) => type === selectedPaymentMethodType,\n )\n\n // Если выбранный способ олаты недоступен, чистим поле выбранной оплаты в корзине\n if (!isSelectedPaymentMethodAvailable)\n basketStore.setSelectedPaymentMethod(null)\n },\n)\n\ndefineRule('required-payment-method', requiredPaymentMethod)\n</script>\n\n<template>\n <basket-section\n id=\"payment_method\"\n :loading=\"isBasketPaymentLoading\"\n class=\"basket-payment\"\n >\n <basket-title class=\"basket-payment__title\" title=\"Способ оплаты\" />\n\n <basket-failed\n v-if=\"basketPaymentMethodsStore.error\"\n error-message=\"Не удалось загрузить способы оплаты\"\n @update=\"getBasketPaymentMethods\"\n />\n\n <vee-field\n v-else\n v-slot=\"{ errors, field }\"\n name=\"basket-payment\"\n vid=\"basket-payment\"\n rules=\"required-payment-method\"\n :model-value=\"selectedPaymentMethod\"\n >\n <div class=\"payment-methods\">\n <basket-payment-list\n v-bind=\"field\"\n :basket-payment-methods=\"basketPaymentMethods\"\n :method-delivery=\"methodDelivery\"\n :selected-payment-method=\"selectedPaymentMethod\"\n @update:selected-payment=\"updateSelectedPayment\"\n />\n\n <basket-payment-info\n :selected-payment-method=\"selectedPaymentMethod\"\n :method-delivery=\"methodDelivery\"\n :change-error-show=\"changeErrorShow\"\n :validate-errors=\"errors\"\n :is-change-exist=\"isChangeExist\"\n :change=\"change\"\n :amount-to-pay=\"amountToPay\"\n @update:change=\"getChange\"\n />\n </div>\n\n <template v-if=\"isShowCallBlock\">\n <transition-group name=\"height\">\n <hr class=\"hr\" />\n\n <basket-call-select id=\"call\" />\n </transition-group>\n </template>\n </vee-field>\n </basket-section>\n</template>\n\n<style lang=\"scss\" scoped>\n@use '@/assets/styles/animations.scss' as *;\n\n.basket-payment {\n overflow: hidden;\n\n &__title {\n margin-bottom: 0;\n }\n\n .hr {\n margin: 25px 0 20px;\n border: 1px solid var(--ui-grey);\n\n @include media('<=portrait-phone') {\n margin-top: 20px;\n }\n }\n\n .payment-methods {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n }\n}\n</style>\n","export enum TabTypes {\n FAST = 'fast',\n DELIVERY_ON_TIME = 'deliveryOnTime',\n}\n","<script lang=\"ts\" setup>\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useBasketTimeStore } from '@/store/basket/basket-time'\n\nimport { DeliveryMethods } from '@/types/api/api-v3/basket'\n\nconst basketStore = useBasketStore()\nconst basketTime = useBasketTimeStore()\n\nconst timeHeadline = computed(() =>\n basketStore.data.delivery.method === DeliveryMethods.COURIER\n ? 'Доставим'\n : 'Будет готово',\n)\n</script>\n\n<template>\n <div class=\"time-info\">\n <div class=\"time-info__item\">\n <div class=\"time-info__headline\">\n <h3>{{ timeHeadline }}</h3>\n\n <h3>{{ basketTime.delivery_at_text }}</h3>\n </div>\n </div>\n\n <div class=\"time-info__item\">\n <p>{{ basketTime.message }}</p>\n\n <nuxt-img\n src=\"/time-basket-icon.svg\"\n alt=\"картинка\"\n width=\"40\"\n height=\"40\"\n />\n </div>\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.time-info {\n display: grid;\n gap: 10px;\n\n &__item {\n display: grid;\n grid-template-columns: 200px max-content;\n justify-content: space-between;\n\n h3 {\n font-size: 18px;\n font-weight: 800;\n color: var(--ui-text-primary);\n }\n\n p {\n margin: 0;\n font-size: 12px;\n font-weight: 600;\n color: var(--ui-text-primary);\n }\n }\n\n &__headline {\n line-height: 22px;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\n/* Components */\nconst BasketErrorMessage = defineAsyncComponent(\n () => import('@/components/Basket/basket-utils/BasketErrorMessage.vue'),\n)\nconst BasketWarningMessage = defineAsyncComponent(\n () => import('@/components/Basket/basket-utils/BasketWarningMessage.vue'),\n)\n\ntype Props = {\n errorMessage?: string\n warningMessage?: string\n warningIcon?: string\n}\n\ndefineProps<Props>()\n</script>\n\n<template>\n <basket-error-message v-if=\"errorMessage\" :error-message=\"errorMessage\" />\n\n <basket-warning-message\n v-else-if=\"warningMessage\"\n :message=\"warningMessage\"\n :icon=\"warningIcon\"\n class=\"warning-message\"\n />\n</template>\n\n<style lang=\"scss\">\n.warning-message {\n padding-bottom: 30px;\n}\n</style>\n","<script setup lang=\"ts\">\n/* Types */\nimport { DateTimeChoices } from '@/store/basket/basket.types'\ntype Props = {\n dateChoices: DateTimeChoices[]\n timeChoices: DateTimeChoices[]\n errorMessage?: string\n}\ndefineProps<Props>()\n\nconst emit = defineEmits(['get-time-choices', 'update-time'])\n\nconst selectedDate = defineModel<string>('selectedDate')\nconst selectedTime = defineModel<string>('selectedTime')\n</script>\n\n<template>\n <div class=\"on-time-selects\">\n <the-dropdown\n v-model=\"selectedDate\"\n item-title=\"text\"\n item-value=\"value\"\n variant=\"secondary\"\n width=\"auto\"\n :options=\"dateChoices\"\n @update:model-value=\"emit('get-time-choices')\"\n />\n\n <the-dropdown\n v-model=\"selectedTime\"\n :disabled=\"!!errorMessage\"\n item-title=\"text\"\n item-value=\"value\"\n variant=\"secondary\"\n width=\"auto\"\n :options=\"timeChoices\"\n @update:model-value=\"emit('update-time')\"\n />\n </div>\n</template>\n\n<style scoped lang=\"scss\">\n.on-time-selects {\n display: grid;\n grid-template-columns: 180px 90px;\n gap: 0 10px;\n margin-bottom: 30px;\n\n @include media('>phone') {\n grid-template-columns: 185px 110px;\n gap: 0 15px;\n }\n}\n</style>\n","<script lang=\"ts\" setup>\n/* Types */\nimport { DateTimeChoices } from '@/store/basket/basket.types'\n/* Stores */\nimport { useBasketTimeStore } from '@/store/basket/basket-time'\n\n/* Components */\nimport BasketOnTimeSelects from '@/components/Basket/basket-time/BasketOnTimeSelects.vue'\nconst BasketWarningMessage = defineAsyncComponent(\n () => import('@/components/Basket/basket-utils/BasketWarningMessage.vue'),\n)\nconst BasketErrorMessage = defineAsyncComponent(\n () => import('@/components/Basket/basket-utils/BasketErrorMessage.vue'),\n)\nconst BasketTimeVariants = defineAsyncComponent(\n () => import('@/components/Basket/basket-time/BasketTimeVariants.vue'),\n)\n\ntype Props = {\n errorMessage?: string\n warningMessage?: string\n warningIcon?: string\n}\ndefineProps<Props>()\n\nconst emit = defineEmits(['update-time'])\n\nconst basketTime = useBasketTimeStore()\n\nconst dateChoices = ref<DateTimeChoices[]>([])\nconst selectedDate = ref('')\nconst selectedTime = ref('')\n\nconst updateCurrentTime = (deliveryAt: string) => {\n selectedTime.value = deliveryAt\n updateTime()\n}\n\nconst getDateChoices = async () => {\n const dateChoicesResult = await basketTime.getDateChoices()\n\n selectedDate.value = dateChoicesResult[0].value\n dateChoices.value = dateChoicesResult || []\n}\n\nconst getTimeChoices = async () => {\n selectedTime.value = ''\n\n await basketTime.getTimeChoices({\n date: selectedDate.value,\n })\n\n if (basketTime.choices && basketTime.choices[0]) {\n selectedTime.value = basketTime.choices[0].value\n }\n\n updateTime()\n}\n\nconst updateTime = () => {\n if (!selectedTime.value) return\n\n emit('update-time', {\n delivery_at_client: true,\n delivery_at: selectedTime.value,\n })\n}\n\nonMounted(async () => {\n await getDateChoices()\n\n getTimeChoices()\n})\n</script>\n\n<template>\n <div class=\"on-time\">\n <basket-error-message\n v-if=\"errorMessage\"\n :error-message=\"errorMessage\"\n class=\"on-time__error\"\n />\n\n <basket-on-time-selects\n v-model:selected-date=\"selectedDate\"\n v-model:selected-time=\"selectedTime\"\n :date-choices=\"dateChoices\"\n :time-choices=\"basketTime.choices\"\n :error-message=\"errorMessage\"\n @get-time-choices=\"getTimeChoices\"\n @update-time=\"updateTime\"\n />\n\n <basket-warning-message\n v-if=\"warningMessage\"\n :message=\"warningMessage\"\n :icon=\"warningIcon\"\n />\n\n <basket-time-variants\n v-if=\"basketTime?.variants.length\"\n :variants=\"basketTime.variants\"\n @set-time=\"updateCurrentTime\"\n />\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.on-time__error {\n margin-bottom: 30px;\n}\n</style>\n","<script setup lang=\"ts\">\n/* Types */\nimport { TabTypes } from '@/types/components/basket-time.types'\nimport { SetTimePayload } from '@/store/basket/basket.types'\n\n/* Components */\nimport BasketAvailableTime from '@/components/Basket/basket-time/BasketAvailableTime.vue'\nimport BasketOnTime from '@/components/Basket/basket-time/BasketOnTime.vue'\n\ntype Props = {\n selectedTab: TabTypes\n errorMessage?: string\n warningMessage?: string\n warningIcon?: string\n}\n\ndefineProps<Props>()\n\nconst emit = defineEmits(['update-time'])\n\nconst onUpdateTime = (data: SetTimePayload) => {\n emit('update-time', data)\n}\n</script>\n\n<template>\n <transition v-if=\"selectedTab === TabTypes.FAST\" name=\"height\">\n <basket-available-time\n :error-message=\"errorMessage\"\n :warning-message=\"warningMessage\"\n :warning-icon=\"warningIcon\"\n @update-time=\"onUpdateTime\"\n />\n </transition>\n\n <transition v-if=\"selectedTab === TabTypes.DELIVERY_ON_TIME\" name=\"height\">\n <basket-on-time\n :error-message=\"errorMessage\"\n :warning-message=\"warningMessage\"\n :warning-icon=\"warningIcon\"\n @update-time=\"onUpdateTime\"\n />\n </transition>\n</template>\n","<script setup lang=\"ts\">\n/* Types */\nimport { TabTypes } from '@/types/components/basket-time.types'\n\nconst model = defineModel<TabTypes>()\n</script>\n\n<template>\n <div class=\"basket-time-tabs\">\n <the-tabs v-model=\"model\">\n <the-tabs-item :value=\"TabTypes.FAST\" :ripple=\"false\">\n Как можно скорее\n </the-tabs-item>\n\n <the-tabs-item :value=\"TabTypes.DELIVERY_ON_TIME\" :ripple=\"false\">\n Ко времени\n </the-tabs-item>\n </the-tabs>\n </div>\n</template>\n","<script lang=\"ts\" setup>\nimport { useBasketStore } from '@/store/basket/basket'\nimport { SetTimePayload } from '@/store/basket/basket.types'\nimport { useBasketPaymentMethodsStore } from '@/store/basket/basket-payment-methods'\nimport { useBasketTimeStore } from '@/store/basket/basket-time'\n\nimport { TabTypes } from '@/types/components/basket-time.types'\n\nimport BasketTimeInfo from '@/components/Basket/basket-time/BasketTimeInfo.vue'\nimport BasketTimeTabActive from '@/components/Basket/basket-time/BasketTimeTabActive.vue'\nimport BasketTimeTabs from '@/components/Basket/basket-time/BasketTimeTabs.vue'\nimport BasketSection from '@/components/Basket/basket-utils/BasketSection.vue'\nimport BasketTitle from '@/components/Basket/basket-utils/BasketTitle.vue'\n\nconst emit = defineEmits(['goToPrevStep'])\n\nconst basketStore = useBasketStore()\nconst basketTimeStore = useBasketTimeStore()\nconst { getPaymentMethods } = useBasketPaymentMethodsStore()\n\nonMounted(() => {\n // Фетчим данные для \"Как можно скорее\"\n updateTime({ delivery_at_client: false })\n})\n\nconst selectedTab = ref<TabTypes>(TabTypes.FAST)\n\nwatch(\n () => selectedTab.value,\n (tabValue) => {\n if (tabValue === TabTypes.FAST) {\n updateTime({ delivery_at_client: false })\n }\n },\n)\n\nconst updateTime = async (data: SetTimePayload) => {\n await basketTimeStore.getAvailableTime(data)\n\n await basketStore.setTime({\n delivery_at: basketTimeStore.delivery_at,\n delivery_at_client: data.delivery_at_client,\n })\n\n await getPaymentMethods()\n}\n\nconst isLoading = computed(\n () =>\n !basketTimeStore.delivery_at &&\n !basketTimeStore.error &&\n basketTimeStore.variants.length === 0,\n)\n\nconst goToPrevStep = () => emit('goToPrevStep')\n</script>\n\n<template>\n <basket-section id=\"delivery_at\" :loading=\"isLoading\" class=\"basket-time\">\n <div class=\"basket-time__title\" @click=\"goToPrevStep\">\n <the-icon name=\"arrow-left\" />\n\n <span>Оформление заказа</span>\n </div>\n\n <basket-title title=\"Время\" />\n\n <basket-time-tabs v-model=\"selectedTab\" class=\"basket-time__tabs\" />\n\n <basket-time-tab-active\n :selected-tab=\"selectedTab\"\n :error-message=\"basketTimeStore.error\"\n :warning-message=\"basketTimeStore.warning\"\n :warning-icon=\"basketTimeStore.warning_icon\"\n @update-time=\"updateTime\"\n />\n\n <div v-if=\"isLoading\" class=\"basket-time__loader\">\n <the-loader />\n </div>\n\n <transition v-else-if=\"basketTimeStore.delivery_at\" name=\"height\">\n <basket-time-info />\n </transition>\n </basket-section>\n</template>\n\n<style lang=\"scss\" scoped>\n@use '@/assets/styles/animations.scss' as *;\n\n.basket-time {\n min-height: 250px;\n\n &__title {\n display: flex;\n gap: 16px;\n align-items: center;\n margin-bottom: 20px;\n font-size: 20px;\n font-weight: 800;\n }\n\n &__tabs {\n margin-bottom: 30px;\n }\n\n &__loader {\n position: relative;\n height: 24px;\n }\n\n &__items {\n margin-top: 24px;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { Form as VeeForm, FormContext } from 'vee-validate'\n\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useBasketTimeStore } from '@/store/basket/basket-time'\nimport { useCityStore } from '@/store/city/city'\n\nimport { PaymentMethodType, SavedCard } from '@/types/api/api-v3/paymentMethods'\nimport { BasketStep } from '@/types/basket'\n\nimport BasketPayment from '@/components/Basket/basket-payment/BasketPayment.vue'\nimport BasketPricePanel from '@/components/Basket/basket-price-panel/BasketPricePanel.vue'\nimport BasketTime from '@/components/Basket/basket-time/BasketTime.vue'\n\nconst DialogBasketTransactionTime = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/DialogBasketTransactionTime.vue'),\n)\n\nconst DialogBasketProposition = defineAsyncComponent(\n () => import('@/components/Basket/dialogs/DialogBasketProposition.vue'),\n)\n\nconst EVENT_TYPE_PS = 'payment_started_payselection'\nconst EVENT_YANDEX_NAME = 'payment_started_SBP'\n\ntype Props = {\n clientPacksCount: number\n clientAdditivesCount: number\n}\n\ntype AdditionalPaymentAction = (orderId: number) => Promise<void>\n\nconst emit = defineEmits(['scrollToErrorBlock', 'goToStep'])\ndefineProps<Props>()\n\nconst { $apiService, $metrics, $sentryCaptureException } = useNuxtApp()\n\nconst { currencySymbol } = useCityStore()\nconst basketStore = useBasketStore()\nconst basketTimeStore = useBasketTimeStore()\n\nconst basketObserver = ref<FormContext | null>(null)\nconst dialogs = ref({\n showProposition: {\n visible: false,\n },\n transactionTime: {\n visible: false,\n },\n})\n\nconst isPayProcessLoading = ref(false)\nconst propositionShowedAlready = ref(false)\n\nconst basket = computed(() => basketStore.data)\nconst checkSelectedSavedCard = computed(\n () => basketStore.checkSelectedSavedCard,\n)\nconst selectedPaymentMethod = computed(\n () => basketStore.data.selectedPaymentMethod,\n)\nconst amountToPayWithSymbol = computed(\n () => `${basket.value.amountToPay} ${currencySymbol}`,\n)\n\n// Скролл до блока с ошибкой\nconst showError = () =>\n setTimeout(() => {\n const fieldError = getFieldError()\n\n emit('scrollToErrorBlock', fieldError)\n }, 0)\n\n// Функция для получения id блока, в котором есть ошибка валидации\nconst getFieldError = () => {\n const fieldsErrors = basketObserver.value?.errors\n\n if (!fieldsErrors) return null\n\n return Object.keys(fieldsErrors).at(0) || null\n}\n\nconst showPropositionDialog = (): boolean => {\n // Если точка, на которую упадет заказ extra - не показываем доборы\n if (basket.value.isExtra) return false\n\n // Если показывали доборы до этого - не показываем доборы\n if (propositionShowedAlready.value) return false\n\n if (basket.value.proposition.items.length === 0) return false\n\n dialogs.value.showProposition.visible = true\n propositionShowedAlready.value = true\n\n return true\n}\n\nconst preClearanceCheckSave = async () => {\n // Переходим к оформлению заказа картой, в зависимости от того, добавлена она клиентом или нет\n checkSelectedSavedCard.value\n ? await orderCheckoutByCard()\n : await orderCheckout()\n}\n\n// Общий метод обработки оформления заказа\nconst handleOrderCheckout = async (\n showTransactionDialog: boolean,\n additionalPaymentAction: AdditionalPaymentAction | null,\n) => {\n // Показываем доборы\n const isPropositionDialogShowed = showPropositionDialog()\n\n if (isPropositionDialogShowed) return\n\n // Если оплата картой - показываем экран загрузки\n if (showTransactionDialog) dialogs.value.transactionTime.visible = true\n\n isPayProcessLoading.value = true\n\n const orderId = await basketStore.orderCheckout()\n\n if (basketStore.error) {\n dialogs.value.transactionTime.visible = false\n isPayProcessLoading.value = false\n\n return\n }\n\n if (additionalPaymentAction) {\n await additionalPaymentAction(orderId)\n } else {\n if (selectedPaymentMethod.value?.type === PaymentMethodType.SBP)\n $metrics?.eventSendGoal({ ym: EVENT_YANDEX_NAME })\n\n if (selectedPaymentMethod.value?.type === PaymentMethodType.PAY_SELECTION)\n $metrics?.eventSendGoal({ ym: EVENT_TYPE_PS, mt: EVENT_TYPE_PS })\n }\n\n redirectToOrderPage(orderId)\n}\n\nconst orderCheckout = async () => await handleOrderCheckout(false, null)\n\n// Метод оплаты по сохраненной карте\nconst orderCheckoutByCard = async () => {\n await handleOrderCheckout(true, async (orderId: number) => {\n const paymentMethodId = (selectedPaymentMethod.value as SavedCard)?.id\n\n // Если нет id метода оплаты - выходим без оплаты\n if (!paymentMethodId) {\n $sentryCaptureException(`Не удалось найти id оплаты: ${paymentMethodId}`)\n\n return\n }\n\n await $apiService.order.paySavedCardPaySelection(\n String(orderId),\n String(paymentMethodId),\n )\n })\n}\n\nconst closePropositionDialog = async (isError: boolean) => {\n dialogs.value.showProposition.visible = false\n\n // Если при добавлении добора ошибка - обновляем корзину\n if (isError) {\n propositionShowedAlready.value = false\n\n await basketStore.fetchBasket()\n\n return\n }\n\n checkSelectedSavedCard.value\n ? await orderCheckoutByCard()\n : await orderCheckout()\n}\n\nconst redirectToOrderPage = (orderId: string) => {\n localStorage.setItem('showedWarningAdditivesOrClientPack', 'false')\n\n navigateTo(`/profile/orders/${orderId}/`)\n}\n\nconst goToPrevStep = () => emit('goToStep', BasketStep.FIRST)\n</script>\n\n<template>\n <vee-form\n v-slot=\"{ handleSubmit }\"\n ref=\"basketObserver\"\n class=\"basket__section\"\n validate-on-mount\n >\n <basket-time\n v-if=\"basketStore.basketAddressSelected\"\n class=\"section delivery\"\n @go-to-prev-step=\"goToPrevStep\"\n />\n\n <basket-payment v-if=\"!basketTimeStore.error\" class=\"section\" />\n\n <basket-price-panel\n class=\"section\"\n :amount-to-pay-with-symbol=\"amountToPayWithSymbol\"\n :basket-step=\"BasketStep.SECOND\"\n :is-price-section-sticky=\"false\"\n :is-loading=\"isPayProcessLoading\"\n @order-checkout=\"handleSubmit(preClearanceCheckSave), showError()\"\n />\n </vee-form>\n\n <!-- Диалоговое окно обработки платежа -->\n <the-dialog\n :max-width=\"360\"\n :model-value=\"dialogs.transactionTime.visible\"\n padding=\"0\"\n persistent\n >\n <dialog-basket-transaction-time\n v-click-outside=\"false\"\n class=\"transaction-dialog\"\n />\n </the-dialog>\n\n <!-- Диалоговое окно доборов -->\n <dialog-basket-proposition\n v-if=\"dialogs.showProposition.visible\"\n :propositions=\"basket.proposition.items\"\n :time-to-live=\"basket.proposition.timeToLive\"\n @close=\"closePropositionDialog\"\n />\n</template>\n\n<style lang=\"scss\" scoped>\n@use '@/assets/styles/basket' as *;\n</style>\n","type SelectorType = `${'.' | '#'}${string}`\n\n/**\n * Скролл-переход к блоку по селектору\n * @param selector - селектор документа\n * @param options - опции скролла\n */\nexport const scrollToBlock = (\n selector: SelectorType,\n options: ScrollIntoViewOptions = {\n behavior: 'smooth',\n block: 'center',\n },\n) => {\n const element = document.querySelector(selector)\n\n if (!element) {\n console.warn(`Элемент с селектором ${selector} не найден.`)\n\n return\n }\n\n element.scrollIntoView(options)\n}\n","<script lang=\"ts\" setup>\nimport { FormContext } from 'vee-validate'\n\nimport { useAppStore } from '@/store/app/app'\nimport { SnackbarType } from '@/store/app/app.types'\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useBasketStateStore } from '@/store/basket/basket-state'\n\nimport { ServerError, UnprocessableEntityError } from '@/api/results'\nimport { BasketStep } from '@/types/basket'\n\nimport BasketFirstStep from '@/components/Basket/basket-state/BasketFirstStep.vue'\nimport BasketSecondStep from '@/components/Basket/basket-state/BasketSecondStep.vue'\n\n/* Объект для динамического рендера шагов корзины */\nconst BASKET_STEP = {\n FIRST: BasketFirstStep,\n SECOND: BasketSecondStep,\n}\nconst AUTO_DELETED_GIFT = 'Убрали подарок, проверьте условия для применения'\n\nconst { $sentryCaptureException } = useNuxtApp()\n\nconst basketStore = useBasketStore()\nconst basketStateStore = useBasketStateStore()\nconst { showSnackbar } = useAppStore()\n\nconst basketStep = ref<BasketStep>(BasketStep.FIRST)\nconst basketObserver = ref<FormContext | null>(null)\n\nconst basketError = computed(() => basketStore.error)\nconst clientPacksCount = computed(() => basketStore.clientPacksCount)\nconst clientAdditivesCount = computed(() => basketStore.clientAdditivesCount)\nconst getCurrentStepComponent = computed(() => BASKET_STEP[basketStep.value])\n\nwatch(basketError, async (basketError) => {\n if (!basketError) return\n\n if (\n basketError instanceof UnprocessableEntityError &&\n // @ts-ignore\n basketError.data?.product_id\n ) {\n showSnackbar({\n // @ts-ignore\n message: basketError.data?.product_id[0],\n type: SnackbarType.MESSAGE,\n })\n\n await basketStore.fetchBasket()\n } else if (\n basketError instanceof UnprocessableEntityError &&\n // @ts-ignore\n basketError.data\n ) {\n if (!basketObserver.value) {\n return\n }\n\n setTimeout(() => {\n // @ts-ignore\n const id = Object.keys(basketError.data)?.[0]\n\n scrollToErrorBlock(id)\n }, 50)\n } else if (basketError instanceof UnprocessableEntityError) {\n showSnackbar({\n message: 'Что-то пошло не так :( Попробуйте позже',\n type: SnackbarType.MESSAGE,\n })\n\n $sentryCaptureException(basketError)\n } else if (basketError instanceof ServerError) {\n $sentryCaptureException(basketError)\n }\n})\n\n// Следим за подарками - если подарков после обновления стало меньше -> показываем снекбар\nwatch(\n () => basketStore.data.gifts,\n (newState, prevState) => {\n const newNoChoiceGifts = newState.filter(\n ({ should_choose }) => !should_choose,\n )\n const prevNoChoiceGifts = prevState.filter(\n ({ should_choose }) => !should_choose,\n )\n\n // Если убрали подарки без выбора\n if (newNoChoiceGifts.length < prevNoChoiceGifts.length) {\n showSnackbar({\n message: AUTO_DELETED_GIFT,\n })\n }\n\n const newChoiceGifts = newState.filter(({ should_choose }) => should_choose)\n const prevChoiceGifts = prevState.filter(\n ({ should_choose }) => should_choose,\n )\n // Если убрали подарки с выбором\n // Кейс, когда в массиве gifts > 1 массивов с выбором, но мы отображаем всегда только первый\n if (!newChoiceGifts.length && prevChoiceGifts.length) {\n showSnackbar({\n message: AUTO_DELETED_GIFT,\n })\n }\n },\n)\n\nconst scrollToErrorBlock = (id?: string) => {\n // Если id передан - сразу скроллим до блока ошибки\n if (id) {\n scrollToBlock(`#${id}`)\n\n return\n }\n\n // Получаем ошибки формы\n const fieldErrors = basketObserver.value?.errors\n\n if (!fieldErrors?.length) return\n\n // Получаем ключи ошибок формы\n const errors = Object.keys(fieldErrors)\n\n // Берем первую ошибку\n id = errors[0].split('-')[0]\n\n // Скроллим до блока ошибки\n scrollToBlock(`#${id}`)\n}\n\nconst goToStep = async (newStep: BasketStep) => {\n basketStep.value = newStep\n basketStateStore.setStep(newStep)\n\n await nextTick(() => window.scrollTo({ top: 0, behavior: 'smooth' }))\n}\n\nonBeforeUnmount(() => basketStateStore.setStep(BasketStep.FIRST))\n</script>\n\n<template>\n <component\n :is=\"getCurrentStepComponent\"\n :client-packs-count=\"clientPacksCount\"\n :client-additives-count=\"clientAdditivesCount\"\n @scroll-to-error-block=\"scrollToErrorBlock\"\n @go-to-step=\"goToStep\"\n />\n</template>\n\n<style lang=\"scss\" scoped>\n.basket__section {\n position: relative;\n display: grid;\n gap: 60px 0;\n max-width: 620px;\n margin: auto;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { useBasketStore } from '@/store/basket/basket'\nimport { useMapSettingsStore } from '@/store/map-settings/map-settings'\nimport { useToggleStore } from '@/store/toggle/toggle'\n\nimport TheBasket from '@/components/Basket/basket-state/TheBasket.vue'\n\nconst BasketErrorPage = defineAsyncComponent(\n () => import('@/components/Basket/basket-state/BasketErrorPage.vue'),\n)\nconst BasketEmptyPage = defineAsyncComponent(\n () => import('@/components/Basket/basket-state/BasketEmptyPage.vue'),\n)\n\nconst basketStore = useBasketStore()\nconst toggleStore = useToggleStore()\nconst mapSettingsStore = useMapSettingsStore()\n\nconst isBasketLoaded = computed(() => basketStore.isLoaded)\n\nconst isBasketDisabled = computed(\n () =>\n basketStore.basketIsDisabled || !toggleStore.featureToggle.basket_enabled,\n)\n\nconst isBasketEmpty = computed(() => basketStore.basketIsEmpty)\n\nonMounted(() => mapSettingsStore.fetchMapSettings())\n\nusePopupFetch()\n</script>\n\n<template>\n <div\n class=\"basket-page\"\n :class=\"{ 'basket-page--exist': !isBasketEmpty && !isBasketDisabled }\"\n >\n <app-head title=\"Ваш заказ\" />\n\n <the-loader v-if=\"!isBasketLoaded\" size=\"100\" />\n\n <basket-error-page v-else-if=\"isBasketDisabled\" />\n\n <basket-empty-page v-else-if=\"isBasketEmpty\" />\n\n <the-basket v-else />\n </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.page--container {\n padding: 20px 0;\n}\n\n.basket-page {\n padding: 40px 0 60px;\n\n &--exist {\n background-color: var(--ui-grey);\n }\n\n @include media('<tablet') {\n padding: 0;\n }\n}\n</style>\n"],"names":["props","__props","isMobile","useResponsive","cityStore","useCityStore","productId","computed","quantitySelectedProducts","setProductQuantity","decreaseQuantity","increaseQuantity","useProductCounter","currencySymbol","additivePrice","additives","isErrorImage","ref","productImage","watch","additive","onMounted","TEXT","emit","__emit","text","toggleAdditives","MAX_VISIBLE_ADDITIVES_FOR_DESKTOP","MAX_VISIBLE_ADDITIVES_FOR_MOBILE","DialogBasketAdditives","defineAsyncComponent","__vitePreload","showAllAdditives","maxVisibleAdditives","dialogs","showAllButtonVisible","_a","_b","countOfVisibleAdditives","toggleShowAllAdditives","BasketFailed","DialogBasketAddAddressForm","NewDialogBasketAddAddressForm","NewDialogBasketEditAddress","NewDialogBasketDeleteAddress","DialogBasketEditAddressForm","DialogBasketDeleteAddress","DialogRedirectOtherCity","BasketDeliveryAddressNotification","$metrics","useNuxtApp","showSnackbar","useAppStore","basketStore","useBasketStore","addressesStore","useAddressesStore","newFetchingApiEnabled","useToggleStore","basket","addresses","deliveryCost","setSelectedAddress","value","DeliveryMethods","onDeliveryMethodChanged","openAddAddressDialog","openEditAddressDialog","address","closeEditAddressDialog","openDeleteAddressDialog","openDialogRedirectCity","openDialogNotification","closeDialogRedirectCity","onSelectDeliveryCourier","addAddress","allow_redirect","is_in_delivery_area","id","fetchAddress","SnackbarType","Success","editAddress","closeDialogDeleteAddress","isUpdate","addressId","deleteAddress","defineRule","veeRequiredValidator","$sentryCaptureException","basketPaymentMethodsStore","useBasketPaymentMethodsStore","pointStore","useBasketPointStore","setBasketDeliveryMethod","useBasketMethods","isUpdatePoint","onChangeBasketDeliveryMethod","checkRelevanceOfDelivery","deliveryMethod","courierPoints","pickupPoints","hallPoints","allPoints","selectedAddress","selectedAddressId","deliveryMethodChanged","setDeliveryMethod","newDeliveryMethod","points","deliveryMethodPayload","firstAddress","isAddressClient","carrotquestTracks","isShowPickupTab","isShowHallTab","setModelValueDeliveryMethod","pointsList","info","clientPackImage","counterSize","productQuantity","bonusLabel","isPromocodeChoiceDisabled","SelectedDiscount","isPromocodeApplied","isBonusChoiceDisabled","updateDiscountChoices","buttonText","updateModelValue","setDiscount","setErrors","cancelDiscount","onClickHandler","options","requiredDiscount","discountField","bonusesValue","placeholder","userStore","useUserStore","selectedDiscount","confirmedDiscount","inputValue","isButtonLoading","bonusesCount","basketDiscountErrors","basketDiscountInfoVisible","bonuses","discountTitle","isAuthenticated","setPromocode","result","setBonuses","UnprocessableEntityError","resetPromocode","updateSelectedDiscount","_d","_c","BasketErrorMessage","BasketErrorMessage$1","image","onSelect","selectGift","updateValue","_openBlock","_createElementBlock","_hoisted_1","NOT_ACTIVE_GIFT","FAILURE_MESSAGE","ADDED_GIFT_MESSAGE","DELETED_GIFT_MESSAGE","isGiftNeed","_useModel","selectedGift","isLoading","rule","setLoading","state","handleGiftResult","successMessage","onSelectGift","gift","selectedGiftProductId","selectedBasketGift","notActiveGift","MAX_NOTE_LENGTH_RULE","note","maxNoteLength","showClearBasketDialog","additiveImage","priceWithSymbol","formatProductForModification","item","productModification","updatedQuantity","selectedGiftPayload","giftWithChoice","product_id","rule_id","products","title","product","cartView","titles_list","url_list","price_list","image_list","DialogBasketClear","isClearBasketDialogVisible","clearBasket","TimeMethod","defaultState","useBasketTimeStore","defineStore","StoreId","newTimeState","$apiService","getListOfMonth","date","checkoutButtonState","inject","basketTimeStore","basketSelectedPaymentMethod","basketGiftsWithChoice","selectedPaymentMethod","purchaseButtonText","checkSavedCard","PayMethods","button","CostStatuses","BasketPurchaseButtonEmit","BasketStep","CheckoutButtonState","push","useRouter","orderCheckout","goToCatalog","goToPayment","goToAuthorize","goToAddress","goToDeliveryAt","goToDiscount","goToGifts","goToSecondStep","isBasketOnFirstStep","isDeliveryMethod","isDeliveryMethodTitle","isDeliveryMethodValue","showChangeInfo","toAccrueAmountBonuses","scrollToErrorBlock","errorBlock","error","MT_EVENT_NAME","DialogBasketAdditivesAndPacks","LoginForm","basketObserver","isPriceSectionSticky","isClientPackAvailable","basketGiftsWithoutChoice","addedAdditives","amountToPayWithSymbol","basketOrderAddress","setPricePanelStickyObserver","useIntersectionObserver","isIntersecting","boundingClientRect","getShowedAdditivesAndPacksValue","localStorageValue","showAdditivesAndPacksDialog","callback","isAdditivesAndClientPackModalShowed","isAdditivesOrPacksNotAdded","navigateTo","userAuthorizationDialogClose","showError","fieldError","getFieldError","fieldsErrors","doNotCallMeBack","changeDoNotCallMeBack","basketChangeStore","useBasketChangeStore","setSelectedChange","currentChange","onBeforeUnmount","changeList","requiredValidator","descriptionBasketPaymentMethod","PaymentMethodType","prefix","PaymentMethodDescriptions","isVisibleChangeBlock","onGetChange","checkErrorMessage","changeErrorMessage","isValidateError","namePaymentMethod","PaymentMethodName","iconClasses","classes","paymentIcon","PaymentMethodIcons","numberCard","cropNumberOfCard","brandName","TypeCards","detectedClassSavedCard","iconCard","detectedIconOfBrand","nameIcon","onUpdateSelectedPayment","paymentItemClasses","breakpoint","selectPaymentMethod","paymentMethod","selectedPaymentMethodType","selectedSavedCardId","checkActivePaymentItem","paymentItem","paymentsList","list","payment","sliderOptions","sliderKey","isBasketPaymentLoading","toggleStore","amountToPay","change","methodDelivery","basketPaymentMethods","updateSelectedPayment","getBasketPaymentMethods","changeErrorShow","getChange","checkChange","isOfflinePayment","OfflinePayMethods","isShowCallBlock","isChangeExist","currentValue","prevValue","paymentMethods","type","requiredPaymentMethod","TabTypes","basketTime","timeHeadline","BasketWarningMessage","selectedDate","selectedTime","BasketTimeVariants","dateChoices","updateCurrentTime","deliveryAt","updateTime","getDateChoices","dateChoicesResult","getTimeChoices","onUpdateTime","data","model","getPaymentMethods","selectedTab","tabValue","goToPrevStep","EVENT_TYPE_PS","EVENT_YANDEX_NAME","DialogBasketTransactionTime","DialogBasketProposition","isPayProcessLoading","propositionShowedAlready","checkSelectedSavedCard","showPropositionDialog","preClearanceCheckSave","orderCheckoutByCard","handleOrderCheckout","showTransactionDialog","additionalPaymentAction","orderId","redirectToOrderPage","paymentMethodId","closePropositionDialog","isError","scrollToBlock","selector","element","AUTO_DELETED_GIFT","BASKET_STEP","BasketFirstStep","BasketSecondStep","basketStateStore","useBasketStateStore","basketStep","basketError","clientPacksCount","clientAdditivesCount","getCurrentStepComponent","ServerError","newState","prevState","newNoChoiceGifts","should_choose","prevNoChoiceGifts","newChoiceGifts","prevChoiceGifts","fieldErrors","goToStep","newStep","nextTick","BasketErrorPage","BasketEmptyPage","mapSettingsStore","useMapSettingsStore","isBasketLoaded","isBasketDisabled","isBasketEmpty","usePopupFetch"],"mappings":"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","debug_id":"35848724-7673-553c-939a-0d97614c9604"}