parent
bd4edfdade
commit
f857c40ca2
@ -1,6 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<UPageCard>
|
<teleport
|
||||||
|
v-if="isMobile && isSummary" to="footer"
|
||||||
|
>
|
||||||
|
<UPageCard
|
||||||
|
class="pay-block--mobile"
|
||||||
|
variant="ghost"
|
||||||
|
:ui="{
|
||||||
|
body: 'w-full',
|
||||||
|
footer: 'hidden',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template #body>
|
||||||
|
<div class="d-flex flex-row">
|
||||||
|
<div>
|
||||||
|
<div v-if="cartSum">
|
||||||
|
<ProductPrice :is-headline="false" :price="cartSum" />
|
||||||
|
</div>
|
||||||
|
<div>{{ `${cart?.line_items?.length} шт` }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<UButton
|
||||||
|
class="justify-center text-center w-full ml10"
|
||||||
|
size="xl"
|
||||||
|
:label="pay ? 'оформить заказ' : 'перейти к оформлению'"
|
||||||
|
@click="pay ? createOrder() : router.push(`/checkout/delivery`)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</UPageCard>
|
||||||
|
</teleport>
|
||||||
|
|
||||||
|
<UPageCard v-else>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div>товары {{ `(${cart?.line_items?.length} шт)` }}</div>
|
<div>товары {{ `(${cart?.line_items?.length} шт)` }}</div>
|
||||||
<div v-if="cartSum">
|
<div v-if="cartSum">
|
||||||
@ -22,15 +53,23 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { IBspb } from '~/server/shared/types/bspb'
|
import type { IBspb } from '~/server/shared/types/bspb'
|
||||||
|
import { useMediaQuery } from '@vueuse/core'
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
pay: {
|
pay: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
isSummary: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const isMobile = useMediaQuery('(max-width: 1280px)', {
|
||||||
|
ssrWidth: 768,
|
||||||
|
})
|
||||||
const { cart, cartSum } = useCart()
|
const { cart, cartSum } = useCart()
|
||||||
|
|
||||||
const createOrder = async () => {
|
const createOrder = async () => {
|
||||||
@ -50,3 +89,15 @@ const createOrder = async () => {
|
|||||||
window.open(redirectUrl, '_blank')
|
window.open(redirectUrl, '_blank')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.pay-block {
|
||||||
|
&--mobile {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -23,6 +23,10 @@ export const useCart = () => {
|
|||||||
cartItem?.variation_id === item?.variation_id), 1)
|
cartItem?.variation_id === item?.variation_id), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cartRemoveAllItems = () => {
|
||||||
|
cart.value = { line_items: [] }
|
||||||
|
}
|
||||||
|
|
||||||
const cartProducts = computed(() => cart?.value?.line_items?.map((line_item) => {
|
const cartProducts = computed(() => cart?.value?.line_items?.map((line_item) => {
|
||||||
const { productsData } = useProduct(line_item?.variation_id.toString())
|
const { productsData } = useProduct(line_item?.variation_id.toString())
|
||||||
return productsData
|
return productsData
|
||||||
@ -37,6 +41,7 @@ export const useCart = () => {
|
|||||||
cart,
|
cart,
|
||||||
cartAddItem,
|
cartAddItem,
|
||||||
cartRemoveItem,
|
cartRemoveItem,
|
||||||
|
cartRemoveAllItems,
|
||||||
|
|
||||||
cartProducts,
|
cartProducts,
|
||||||
cartSum,
|
cartSum,
|
||||||
|
|||||||
@ -34,14 +34,17 @@ export const useCheckout = createSharedComposable(() => {
|
|||||||
{
|
{
|
||||||
step: 1,
|
step: 1,
|
||||||
title: isMobile.value ? 'mobileDelivery' : 'delivery',
|
title: isMobile.value ? 'mobileDelivery' : 'delivery',
|
||||||
|
route: 'delivery',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
step: 2,
|
step: 2,
|
||||||
title: isMobile.value ? 'mobileContacts' : 'contacts',
|
title: isMobile.value ? 'mobileContacts' : 'contacts',
|
||||||
|
route: 'contacts',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
step: 3,
|
step: 3,
|
||||||
title: isMobile.value ? 'mobileSummary' : 'summary',
|
title: isMobile.value ? 'mobileSummary' : 'summary',
|
||||||
|
route: 'summary',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -57,7 +60,7 @@ export const useCheckout = createSharedComposable(() => {
|
|||||||
const findIndex = checkoutSteps.findIndex(value => value.step === currentCheckoutStep.value.step)
|
const findIndex = checkoutSteps.findIndex(value => value.step === currentCheckoutStep.value.step)
|
||||||
if (findIndex !== 0) {
|
if (findIndex !== 0) {
|
||||||
currentCheckoutStep.value = checkoutSteps[findIndex - 1]
|
currentCheckoutStep.value = checkoutSteps[findIndex - 1]
|
||||||
router.push(`/checkout/${currentCheckoutStep?.value.title}`)
|
router.push(`/checkout/${currentCheckoutStep?.value.route}`)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
router.push(`/cart`)
|
router.push(`/cart`)
|
||||||
@ -68,12 +71,12 @@ export const useCheckout = createSharedComposable(() => {
|
|||||||
const findIndex = checkoutSteps.findIndex(value => value.step === currentCheckoutStep.value.step)
|
const findIndex = checkoutSteps.findIndex(value => value.step === currentCheckoutStep.value.step)
|
||||||
if (findIndex + 1 !== checkoutSteps.length) {
|
if (findIndex + 1 !== checkoutSteps.length) {
|
||||||
currentCheckoutStep.value = checkoutSteps[findIndex + 1]
|
currentCheckoutStep.value = checkoutSteps[findIndex + 1]
|
||||||
router.push(`/checkout/${currentCheckoutStep?.value.title}`)
|
router.push(`/checkout/${currentCheckoutStep?.value.route}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStep(pathName: string) {
|
function setStep(pathName: string) {
|
||||||
currentCheckoutStep.value = checkoutSteps.find(value => value.title === pathName) || checkoutSteps[0]
|
currentCheckoutStep.value = checkoutSteps.find(value => value.route === pathName) || checkoutSteps[0]
|
||||||
router.push(`/checkout/${pathName}`)
|
router.push(`/checkout/${pathName}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,19 +12,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="main">
|
<main class="main" :style="showFooter ? 'margin-bottom: 54px' : 'margin-bottom: 0'">
|
||||||
<UContainer class="container">
|
<UContainer class="container">
|
||||||
<slot />
|
<slot />
|
||||||
</UContainer>
|
</UContainer>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<footer class="footer" :class="{ 'footer--hidden': !showFooter }" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useCheckout } from '../composables/useCheckout'
|
import { useMediaQuery } from '@vueuse/core'
|
||||||
|
import { useCheckout } from '~/composables/useCheckout'
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const { t } = useI18n()
|
||||||
|
const isMobile = useMediaQuery('(max-width: 1280px)', {
|
||||||
|
ssrWidth: 768,
|
||||||
|
})
|
||||||
|
const showFooter = computed(() => route.path !== '/checkout/delivery' && isMobile.value)
|
||||||
|
|
||||||
const { previewStep, currentCheckoutStep, checkoutSteps } = useCheckout()
|
const { previewStep, currentCheckoutStep, checkoutSteps } = useCheckout()
|
||||||
const { t } = useI18n()
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -63,8 +72,27 @@ const { t } = useI18n()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 100;
|
||||||
|
height: 70px;
|
||||||
|
background-color: #0f172b;
|
||||||
|
|
||||||
|
&--hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.main {
|
.main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin-top: 54px;
|
margin-top: 54px;
|
||||||
|
margin-bottom: 64px;
|
||||||
|
|
||||||
|
&__hide-footer {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -32,15 +32,20 @@
|
|||||||
</UContainer>
|
</UContainer>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- <footer class="footer"> -->
|
<footer class="footer" :class="{ 'footer--hidden': !(route.path === '/cart' && isMobile) }" />
|
||||||
<!-- Footer -->
|
|
||||||
<!-- </footer> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useMediaQuery } from '@vueuse/core'
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { cart } = useCart()
|
const { cart } = useCart()
|
||||||
|
|
||||||
|
const isMobile = useMediaQuery('(max-width: 1280px)', {
|
||||||
|
ssrWidth: 768,
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -106,12 +111,22 @@ const { cart } = useCart()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.main {
|
.footer {
|
||||||
flex: 1;
|
position: fixed;
|
||||||
margin-top: 54px;
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 100;
|
||||||
|
height: 70px;
|
||||||
|
background-color: #0f172b;
|
||||||
|
|
||||||
|
&--hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.main {
|
||||||
margin-top: auto;
|
flex: 1;
|
||||||
|
margin-block: 54px 64px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PayBlock />
|
<PayBlock :is-summary="true" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ import { useCart } from '~/composables'
|
|||||||
import PayBlock from '../components/PayBlock.vue'
|
import PayBlock from '../components/PayBlock.vue'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const { cart } = useCart()
|
const { cart, cartRemoveAllItems } = useCart()
|
||||||
const { checkoutContacts, checkoutPickupPoint } = useCheckout()
|
const { checkoutContacts, checkoutPickupPoint } = useCheckout()
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@ -46,6 +46,8 @@ onMounted(async () => {
|
|||||||
status: 'processing',
|
status: 'processing',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
cartRemoveAllItems()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -63,6 +65,7 @@ onMounted(async () => {
|
|||||||
@include mobile {
|
@include mobile {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
padding-inline: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__items {
|
&__items {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<form class="contacts" @submit.prevent="onSubmit">
|
<form v-if="checkoutContacts" class="contacts" @submit.prevent="onSubmit">
|
||||||
<div>
|
<div>
|
||||||
<UInput
|
<UInput
|
||||||
id="name"
|
id="name"
|
||||||
@ -138,7 +138,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useCheckout } from '../../composables/useCheckout'
|
import { useCheckout } from '~/composables/useCheckout'
|
||||||
|
|
||||||
const { checkoutContacts, setCheckoutContacts, nextStep } = useCheckout()
|
const { checkoutContacts, setCheckoutContacts, nextStep } = useCheckout()
|
||||||
|
|
||||||
@ -199,11 +199,17 @@ definePageMeta({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@use '~/assets/scss/utils' as *;
|
||||||
|
|
||||||
.contacts {
|
.contacts {
|
||||||
margin-inline: auto;
|
margin-inline: auto;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|
||||||
|
@include mobile {
|
||||||
|
padding-inline: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -58,7 +58,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PayBlock pay />
|
<ClientOnly>
|
||||||
|
<PayBlock pay :is-summary="true" />
|
||||||
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -85,10 +87,18 @@ definePageMeta({
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
|
@include mobile {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
&__info {
|
&__info {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|
||||||
|
@include mobile {
|
||||||
|
margin-bottom: 26px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__items {
|
&__items {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user