291 lines
7.3 KiB
Vue
291 lines
7.3 KiB
Vue
<script setup>
|
|
const props = defineProps({
|
|
currentStep: {
|
|
type: Number,
|
|
required: false,
|
|
},
|
|
checkoutData: {
|
|
type: null,
|
|
required: true,
|
|
},
|
|
})
|
|
|
|
const emit = defineEmits([
|
|
'update:currentStep',
|
|
'update:checkout-data',
|
|
])
|
|
|
|
const checkoutAddressDataLocal = ref(JSON.parse(JSON.stringify(props.checkoutData)))
|
|
const isEditAddressDialogVisible = ref(false)
|
|
|
|
watch(() => props.checkoutData, value => {
|
|
checkoutAddressDataLocal.value = JSON.parse(JSON.stringify(value))
|
|
})
|
|
|
|
const deliveryOptions = [
|
|
{
|
|
icon: { icon: 'tabler-user' },
|
|
title: 'Standard',
|
|
desc: 'Get your product in 1 Week.',
|
|
value: 'free',
|
|
},
|
|
{
|
|
icon: { icon: 'tabler-star' },
|
|
title: 'Express',
|
|
desc: 'Get your product in 4 days.',
|
|
value: 'express',
|
|
},
|
|
{
|
|
icon: { icon: 'tabler-crown' },
|
|
title: 'Overnight',
|
|
desc: 'Get your product in 1 day.',
|
|
value: 'overnight',
|
|
},
|
|
]
|
|
|
|
const resolveAddressBadgeColor = {
|
|
home: 'primary',
|
|
office: 'success',
|
|
}
|
|
|
|
const resolveDeliveryBadgeData = {
|
|
free: {
|
|
color: 'success',
|
|
price: 0,
|
|
text: 'Free',
|
|
},
|
|
express: {
|
|
color: 'secondary',
|
|
price: 10,
|
|
text: '$10',
|
|
},
|
|
overnight: {
|
|
color: 'secondary',
|
|
price: 15,
|
|
text: '$15',
|
|
},
|
|
}
|
|
|
|
const totalPriceWithDeliveryCharges = computed(() => {
|
|
let deliveryCharges = 0
|
|
if (checkoutAddressDataLocal.value.deliverySpeed !== 'free')
|
|
deliveryCharges = resolveDeliveryBadgeData[checkoutAddressDataLocal.value.deliverySpeed].price
|
|
|
|
return checkoutAddressDataLocal.value.orderAmount + deliveryCharges
|
|
})
|
|
|
|
const updateAddressData = () => {
|
|
checkoutAddressDataLocal.value.deliveryCharges = resolveDeliveryBadgeData[checkoutAddressDataLocal.value.deliverySpeed].price
|
|
emit('update:checkout-data', checkoutAddressDataLocal.value)
|
|
}
|
|
|
|
const nextStep = () => {
|
|
updateAddressData()
|
|
emit('update:currentStep', props.currentStep ? props.currentStep + 1 : 1)
|
|
}
|
|
|
|
watch(() => props.currentStep, updateAddressData)
|
|
</script>
|
|
|
|
<template>
|
|
<VRow>
|
|
<VCol
|
|
cols="12"
|
|
md="8"
|
|
>
|
|
<!-- 👉 Address options -->
|
|
<h6 class="text-h6 mb-4">
|
|
Select your preferable address
|
|
</h6>
|
|
|
|
<!-- 👉 Address custom input -->
|
|
<CustomRadios
|
|
v-model:selected-radio="checkoutAddressDataLocal.deliveryAddress"
|
|
:radio-content="checkoutAddressDataLocal.addresses"
|
|
:grid-column="{ cols: '12', sm: '6' }"
|
|
>
|
|
<template #default="{ item }">
|
|
<div class="w-100">
|
|
<div class="d-flex justify-space-between mb-3">
|
|
<h6 class="text-base font-weight-medium">
|
|
{{ item.title }}
|
|
</h6>
|
|
|
|
<VChip
|
|
:color="resolveAddressBadgeColor[item.value]"
|
|
label
|
|
size="small"
|
|
class="text-capitalize"
|
|
>
|
|
{{ item.value }}
|
|
</VChip>
|
|
</div>
|
|
|
|
<p class="mb-0 text-sm">
|
|
{{ item.desc }}
|
|
</p>
|
|
<p class="text-sm mb-3">
|
|
Mobile: {{ item.subtitle }}
|
|
</p>
|
|
<VDivider />
|
|
<div class="pt-2">
|
|
<a
|
|
href="#"
|
|
class="me-4"
|
|
>Edit</a>
|
|
<a href="#">Remove</a>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</CustomRadios>
|
|
|
|
<!-- 👉 Add New Address -->
|
|
<VBtn
|
|
variant="tonal"
|
|
class="mt-4 mb-6"
|
|
@click="isEditAddressDialogVisible = !isEditAddressDialogVisible"
|
|
>
|
|
Add New Address
|
|
</VBtn>
|
|
|
|
<!-- 👉 Delivery options -->
|
|
<h6 class="text-h6 mb-4">
|
|
Choose Delivery Speed
|
|
</h6>
|
|
|
|
<!-- 👉 Delivery options custom input -->
|
|
<CustomRadiosWithIcon
|
|
v-model:selected-radio="checkoutAddressDataLocal.deliverySpeed"
|
|
:radio-content="deliveryOptions"
|
|
:grid-column="{ cols: '12', sm: '4' }"
|
|
>
|
|
<template #default="{ item }">
|
|
<div class="d-flex flex-column align-center gap-2 w-100">
|
|
<div class="d-flex justify-end w-100 mb-n3">
|
|
<VChip
|
|
:color="resolveDeliveryBadgeData[item.value].color"
|
|
size="small"
|
|
label
|
|
>
|
|
{{ resolveDeliveryBadgeData[item.value].text }}
|
|
</VChip>
|
|
</div>
|
|
|
|
<VIcon
|
|
v-bind="item.icon"
|
|
size="28"
|
|
/>
|
|
|
|
<h6 class="text-h6">
|
|
{{ item.title }}
|
|
</h6>
|
|
<p class="text-sm text-center mb-0">
|
|
{{ item.desc }}
|
|
</p>
|
|
</div>
|
|
</template>
|
|
</CustomRadiosWithIcon>
|
|
</VCol>
|
|
|
|
<VCol
|
|
cols="12"
|
|
md="4"
|
|
>
|
|
<VCard
|
|
flat
|
|
variant="outlined"
|
|
>
|
|
<!-- 👉 Delivery estimate date -->
|
|
<VCardText>
|
|
<h6 class="text-h6 mb-4">
|
|
Estimated Delivery Date
|
|
</h6>
|
|
|
|
<VList class="card-list">
|
|
<VListItem
|
|
v-for="product in checkoutAddressDataLocal.cartItems"
|
|
:key="product.name"
|
|
>
|
|
<template #prepend>
|
|
<img
|
|
height="70"
|
|
width="60"
|
|
:src="product.image"
|
|
class="me-4"
|
|
>
|
|
</template>
|
|
|
|
<div class="text-body-1">
|
|
{{ product.name }}
|
|
</div>
|
|
<h6 class="text-h6 text-medium-emphasis">
|
|
{{ product.estimatedDelivery }}
|
|
</h6>
|
|
</VListItem>
|
|
</VList>
|
|
</VCardText>
|
|
|
|
<VDivider />
|
|
|
|
<!-- 👉 Price details -->
|
|
<VCardText>
|
|
<h6 class="text-h6 mb-4">
|
|
Price Details
|
|
</h6>
|
|
|
|
<div class="d-flex align-center justify-space-between mb-2">
|
|
<span class="text-high-emphasis">Order Total</span>
|
|
<span>${{ checkoutAddressDataLocal.orderAmount }}</span>
|
|
</div>
|
|
|
|
<div class="d-flex align-center justify-space-between">
|
|
<span class="text-high-emphasis">Delivery Charges</span>
|
|
<div class="text-end">
|
|
<div
|
|
v-if="checkoutAddressDataLocal.deliverySpeed === 'free'"
|
|
class="d-flex align-center"
|
|
>
|
|
<div class="text-decoration-line-through text-disabled me-2">
|
|
$5.00
|
|
</div>
|
|
<VChip
|
|
size="small"
|
|
color="success"
|
|
>
|
|
FREE
|
|
</VChip>
|
|
</div>
|
|
<span v-else>${{ resolveDeliveryBadgeData[checkoutAddressDataLocal.deliverySpeed ].price }}.00</span>
|
|
</div>
|
|
</div>
|
|
</VCardText>
|
|
|
|
<VDivider />
|
|
|
|
<VCardText class="d-flex align-center justify-space-between text-high-emphasis">
|
|
<span class="text-base font-weight-medium">Total</span>
|
|
<span class="text-base font-weight-medium">
|
|
${{ totalPriceWithDeliveryCharges }}
|
|
|
|
</span>
|
|
</VCardText>
|
|
</VCard>
|
|
|
|
<VBtn
|
|
block
|
|
class="mt-4"
|
|
@click="nextStep"
|
|
>
|
|
Place Order
|
|
</VBtn>
|
|
</VCol>
|
|
</VRow>
|
|
<AddEditAddressDialog v-model:is-dialog-visible="isEditAddressDialogVisible" />
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.card-list {
|
|
--v-card-list-gap: 1rem;
|
|
}
|
|
</style>
|