init
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<el-card class="order-summary-panel" shadow="never">
|
||||
<template #header>
|
||||
<span>Summary</span>
|
||||
</template>
|
||||
|
||||
<el-descriptions :column="1" direction="vertical" class="order-summary-panel__details">
|
||||
<el-descriptions-item label="Order ID">
|
||||
<span class="mono text-break">{{ order.id }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="Access token">
|
||||
<el-input
|
||||
class="mono access-token-input"
|
||||
:model-value="order.accessToken"
|
||||
type="password"
|
||||
show-password
|
||||
readonly
|
||||
/>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="Created">{{ formatDate(order.createdAt) }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item v-if="order.failureReason" label="Failure reason">
|
||||
<span class="failure-reason">{{ formatOrderFailureReason(order.failureReason) }}</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<div class="order-summary-panel__totals order-totals pt-24">
|
||||
<div class="flex justify-between gap-12 mb-12">
|
||||
<span>Subtotal</span>
|
||||
<span>{{ subtotalFormatted }}</span>
|
||||
</div>
|
||||
|
||||
<p v-if="discounts.length > 0" class="order-totals__section m-0 mb-8">Discounts</p>
|
||||
|
||||
<div
|
||||
v-for="discount in discounts"
|
||||
:key="discount.id"
|
||||
class="flex justify-between gap-12 mb-4 order-totals__discount"
|
||||
>
|
||||
<span>{{ discount.code }}</span>
|
||||
<span>−{{ formatFiatPrice(discount.amountFiat, fiatCurrency) }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between gap-12 mt-12 mb-12">
|
||||
<span>Total discounts</span>
|
||||
<span>{{ discountTotalFormatted }}</span>
|
||||
</div>
|
||||
|
||||
<template v-if="hasManualLines">
|
||||
<div class="flex justify-between gap-12 mt-12 mb-12 order-totals__order-total">
|
||||
<span>Total</span>
|
||||
<span>{{ totalFormatted }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between gap-12 mb-12">
|
||||
<span>Shipping</span>
|
||||
<span>{{ shippingFormatted }}</span>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between gap-12 order-totals__total pt-8">
|
||||
<span>Grand total</span>
|
||||
<span>{{ grandTotalFormatted }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div v-else class="flex justify-between gap-12 order-totals__total pt-8 mt-12">
|
||||
<span>Total</span>
|
||||
<span>{{ totalFormatted }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, type PropType } from 'vue';
|
||||
import type { OrderExtended } from '@/types/order/OrderExtended';
|
||||
import { DeliveryMode } from '@/types/product/DeliveryMode';
|
||||
import { formatDate } from '@/utils/formatDate';
|
||||
import { formatFiatPrice } from '@/utils/formatFiatPrice';
|
||||
import { formatOrderFailureReason } from '@/utils/order/formatOrderFailureReason';
|
||||
|
||||
const props = defineProps({
|
||||
order: {
|
||||
type: Object as PropType<OrderExtended>,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const fiatCurrency = computed(() => props.order.fiatCurrency);
|
||||
|
||||
const discounts = computed(() => props.order.discounts ?? []);
|
||||
|
||||
const hasManualLines = computed(() =>
|
||||
(props.order.lines ?? []).some(line => line.deliveryMode === DeliveryMode.Manual)
|
||||
);
|
||||
|
||||
const subtotalFormatted = computed(() => formatFiatPrice(props.order.totals.subtotalFiat, fiatCurrency.value));
|
||||
|
||||
const discountTotalFormatted = computed(() =>
|
||||
formatOrderDiscountTotal(props.order.totals.discountTotalFiat, fiatCurrency.value)
|
||||
);
|
||||
|
||||
const totalFormatted = computed(() => formatFiatPrice(props.order.totals.totalFiat, fiatCurrency.value));
|
||||
|
||||
const shippingFormatted = computed(() => {
|
||||
const shippingAmount = props.order.totals.shippingCostFiat;
|
||||
|
||||
if (shippingAmount === null) {
|
||||
return '—';
|
||||
}
|
||||
|
||||
return formatFiatPrice(shippingAmount, fiatCurrency.value);
|
||||
});
|
||||
|
||||
const grandTotalFormatted = computed(() => {
|
||||
const grandTotal = props.order.totals.grandTotalFiat ?? props.order.totals.totalFiat;
|
||||
|
||||
return formatFiatPrice(grandTotal, fiatCurrency.value);
|
||||
});
|
||||
|
||||
const formatOrderDiscountTotal = (discountTotalFiat: number, currency: string): string => {
|
||||
if (discountTotalFiat <= 0) {
|
||||
return formatFiatPrice(0, currency);
|
||||
}
|
||||
|
||||
return `−${formatFiatPrice(discountTotalFiat, currency)}`;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.order-summary-panel {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
:deep(.el-card__body) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.order-summary-panel__details {
|
||||
flex-shrink: 0;
|
||||
|
||||
:deep(.el-descriptions__content) {
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.order-summary-panel__totals {
|
||||
flex-shrink: 0;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.access-token-input {
|
||||
width: 100%;
|
||||
max-width: min(350px, 100%);
|
||||
}
|
||||
|
||||
.failure-reason {
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
|
||||
.order-totals__section {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.order-totals__discount {
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: var(--el-font-size-small);
|
||||
}
|
||||
|
||||
.order-totals__order-total {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.order-totals__total {
|
||||
font-size: var(--el-font-size-large);
|
||||
font-weight: 600;
|
||||
border-top: 1px solid var(--el-border-color-lighter);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user