{"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      {{ '&bull;&bull;&bull;' }} {{ 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"}