changes
This commit is contained in:
@@ -10,11 +10,6 @@
|
|||||||
border: 1px solid $grey-lighter;
|
border: 1px solid $grey-lighter;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
|
||||||
// somehow this value keeps picking dark mode values despite [data-theme]="light"
|
|
||||||
--bulma-hr-background-color: var(--bulma-white-ter);
|
|
||||||
}
|
|
||||||
|
|
||||||
.title,
|
.title,
|
||||||
.subtitle {
|
.subtitle {
|
||||||
--bulma-subtitle-weight: var(--bulma-weight-semibold);
|
--bulma-subtitle-weight: var(--bulma-weight-semibold);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</section>
|
</section>
|
||||||
<footer class="modal-card-foot px-4 pb-4 pt-0"></footer>
|
<footer class="modal-card-foot p-4"></footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
@@ -166,6 +166,7 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
.modal-card-foot {
|
.modal-card-foot {
|
||||||
background-color: var(--bulma-modal-card-body-background-color);
|
background-color: var(--bulma-modal-card-body-background-color);
|
||||||
|
box-shadow: 0 -0.125em 0 0 hsla(var(--bulma-shadow-h), var(--bulma-shadow-s), var(--bulma-shadow-l), 0.1);
|
||||||
|
|
||||||
&:empty {
|
&:empty {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
@@ -97,7 +97,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- <div class="navbar-end">
|
<!-- <div class="navbar-end">
|
||||||
<a class="navbar-item" @click="changeTab(tabConfig)" v-if="tabConfig">
|
<a class="navbar-item" @click="changeTab(tabConfig)" v-if="tabConfig">
|
||||||
<SvgIcon v-bind="{ name: 'configuration.svg', type: 'findata', size: 24 }"></SvgIcon>
|
<Icon name="material-symbols:settings-outline-rounded" :size="20" />
|
||||||
</a>
|
</a>
|
||||||
<a class="navbar-item" @click="openProfile()" v-if="avatar">
|
<a class="navbar-item" @click="openProfile()" v-if="avatar">
|
||||||
<Avatarbox v-bind="avatar"></Avatarbox>
|
<Avatarbox v-bind="avatar"></Avatarbox>
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
<template>
|
|
||||||
<span :style="{ color: color }">{{ text }}</span>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
const props = defineProps({
|
|
||||||
text: { type: String, required: true },
|
|
||||||
color: { type: String, default: "#000" },
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<template>
|
|
||||||
<span :style="color ? `color:${color}` : ''">{{ $dayjs(date).format("L") }}</span>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const { $dayjs } = useNuxtApp();
|
const { $dayjs } = useNuxtApp();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
date: String,
|
date: String,
|
||||||
color: String,
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span>{{ $dayjs(date).format("L") }}</span>
|
||||||
|
</template>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<template>
|
|
||||||
<span :style="color ? `color:${color}` : ''">{{ value === 0 || value === null ? "-" : $numtoString(value) }}</span>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const { $numtoString } = useNuxtApp();
|
const { $empty, $numtoString } = useNuxtApp();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
value: Number,
|
value: Number,
|
||||||
color: String,
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span>{{ $empty(value) ? "-" : $numtoString(value) }}</span>
|
||||||
|
</template>
|
||||||
|
|||||||
@@ -1,45 +1,3 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="control has-icons-left"
|
|
||||||
ref="datepickerRoot"
|
|
||||||
>
|
|
||||||
<div :class="['dropdown w-full', pos, focused && 'is-active']">
|
|
||||||
<div class="dropdown-trigger w-full">
|
|
||||||
<input
|
|
||||||
:disabled="disabled"
|
|
||||||
:class="['input', error && 'is-danger', disabled && 'has-text-dark']"
|
|
||||||
type="text"
|
|
||||||
placeholder="DD/MM/YYYY"
|
|
||||||
maxlength="10"
|
|
||||||
@focus="setFocus"
|
|
||||||
@blur="lostFocus"
|
|
||||||
@keyup.enter="pressEnter"
|
|
||||||
@keyup="checkDate"
|
|
||||||
v-model="show"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="dropdown-menu"
|
|
||||||
role="menu"
|
|
||||||
@click="doClick()"
|
|
||||||
>
|
|
||||||
<div class="dropdown-content px-2 w-xs">
|
|
||||||
<PickDay
|
|
||||||
v-bind="{ date, mindate, maxdate }"
|
|
||||||
@date="selectDate"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="icon is-left">
|
|
||||||
<Icon
|
|
||||||
name="material-symbols:calendar-today-outline-rounded"
|
|
||||||
:size="21"
|
|
||||||
:class="focused ? 'has-text-primary' : 'has-text-grey'"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import PickDay from "~/components/datepicker/PickDay.vue";
|
import PickDay from "~/components/datepicker/PickDay.vue";
|
||||||
|
|
||||||
@@ -61,25 +19,20 @@ const error = ref(false);
|
|||||||
const focused = ref(false);
|
const focused = ref(false);
|
||||||
const count1 = ref(0);
|
const count1 = ref(0);
|
||||||
const count2 = ref(0);
|
const count2 = ref(0);
|
||||||
const pos = ref();
|
|
||||||
const datepickerRoot = useTemplateRef("datepickerRoot");
|
const datepickerRoot = useTemplateRef("datepickerRoot");
|
||||||
|
|
||||||
function getPos() {
|
const pos = computed(() => {
|
||||||
switch (props.position) {
|
switch (props.position) {
|
||||||
case "is-top-left":
|
case "is-top-left":
|
||||||
pos.value = "is-up is-left";
|
return "is-up is-left";
|
||||||
break;
|
|
||||||
case "is-top-right":
|
case "is-top-right":
|
||||||
pos.value = "is-up is-right";
|
return "is-up is-right";
|
||||||
break;
|
|
||||||
case "is-bottom-left":
|
case "is-bottom-left":
|
||||||
pos.value = "is-left";
|
return "is-left";
|
||||||
break;
|
|
||||||
case "is-bottom-right":
|
case "is-bottom-right":
|
||||||
pos.value = "is-right";
|
return "is-right";
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
function initializeDate() {
|
function initializeDate() {
|
||||||
if (props.record) {
|
if (props.record) {
|
||||||
@@ -153,15 +106,56 @@ function checkDate() {
|
|||||||
} else error.value = true;
|
} else error.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
getPos();
|
|
||||||
initializeDate();
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.record,
|
() => props.record,
|
||||||
() => {
|
() => {
|
||||||
initializeDate();
|
initializeDate();
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="control has-icons-left"
|
||||||
|
ref="datepickerRoot"
|
||||||
|
>
|
||||||
|
<div :class="['dropdown w-full', pos, focused && 'is-active']">
|
||||||
|
<div class="dropdown-trigger w-full">
|
||||||
|
<input
|
||||||
|
:disabled="disabled"
|
||||||
|
:class="['input', error && 'is-danger', disabled && 'has-text-dark']"
|
||||||
|
type="text"
|
||||||
|
placeholder="DD/MM/YYYY"
|
||||||
|
maxlength="10"
|
||||||
|
@focus="setFocus"
|
||||||
|
@blur="lostFocus"
|
||||||
|
@keyup.enter="pressEnter"
|
||||||
|
@keyup="checkDate"
|
||||||
|
v-model="show"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="dropdown-menu"
|
||||||
|
role="menu"
|
||||||
|
@click="doClick()"
|
||||||
|
>
|
||||||
|
<div class="dropdown-content px-2 w-xs">
|
||||||
|
<PickDay
|
||||||
|
v-bind="{ date, mindate, maxdate }"
|
||||||
|
@date="selectDate"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="icon is-left">
|
||||||
|
<Icon
|
||||||
|
name="material-symbols:calendar-today-outline-rounded"
|
||||||
|
:size="21"
|
||||||
|
:class="focused ? 'has-text-primary' : 'has-text-grey'"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function openEditModal() {
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:class="['card is-clickable', selected && 'selected']"
|
:class="['card is-clickable', selected && 'selected']"
|
||||||
@click="$emit('selectAddress', address.id)"
|
@click="$emit('selectAddress', address)"
|
||||||
>
|
>
|
||||||
<div class="card-content is-flex is-justify-content-space-between">
|
<div class="card-content is-flex is-justify-content-space-between">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const props = defineProps({
|
|||||||
variant: Object,
|
variant: Object,
|
||||||
});
|
});
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const { $getdata, $snackbar } = useNuxtApp();
|
const { $getdata, $insertapi, $snackbar } = useNuxtApp();
|
||||||
const emit = defineEmits(["close"]);
|
const emit = defineEmits(["close"]);
|
||||||
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
@@ -26,7 +26,10 @@ function toggleSelected(imeiRec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addToCart() {
|
function addToCart() {
|
||||||
store.selectedImeis = [...store.selectedImeis, ...selectedImeis.value];
|
// store.selectedImeis = [...store.selectedImeis, ...selectedImeis.value];
|
||||||
|
/*
|
||||||
|
insert into cart with customer =
|
||||||
|
*/
|
||||||
$snackbar(`Thêm ${selectedImeis.value.length} sản phẩm vào giỏ hàng`, "Success");
|
$snackbar(`Thêm ${selectedImeis.value.length} sản phẩm vào giỏ hàng`, "Success");
|
||||||
emit("close");
|
emit("close");
|
||||||
}
|
}
|
||||||
|
|||||||
138
app/components/pos/ConfirmOrder.vue
Normal file
138
app/components/pos/ConfirmOrder.vue
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<script setup>
|
||||||
|
import ProductCard from "~/components/pos/ProductCard.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
customer: Object,
|
||||||
|
address: Object,
|
||||||
|
paymentMethod: Object,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { $insertapi } = useNuxtApp();
|
||||||
|
const id = "confirmOrder";
|
||||||
|
const store = useStore();
|
||||||
|
const subtotal = computed(() => {
|
||||||
|
return store.selectedImeis.reduce((prev, curr) => prev + curr.variant__price, 0);
|
||||||
|
});
|
||||||
|
const shipping_address = computed(() => {
|
||||||
|
return `${props.address.address_detail}, ${props.address.ward}, ${props.address.district}, ${props.address.city}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
async function createOrder() {
|
||||||
|
const order = await $insertapi("Invoice", {
|
||||||
|
data: {
|
||||||
|
customer: props.customer.id,
|
||||||
|
customer_name: props.customer.fullname,
|
||||||
|
customer_phone: props.customer.phone,
|
||||||
|
customer_email: props.customer.email,
|
||||||
|
shipping_address,
|
||||||
|
product_amount: store.selectedImeis.length,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :id="id">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content has-background-primary-100">
|
||||||
|
<p class="icon-text font-semibold mb-2">
|
||||||
|
<span class="icon">
|
||||||
|
<Icon
|
||||||
|
name="material-symbols:supervisor-account-outline-rounded"
|
||||||
|
:size="18"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>Khách hàng</span>
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<p>{{ props.customer.fullname }}</p>
|
||||||
|
<p class="is-size-7 has-text-grey">
|
||||||
|
{{ props.customer.phone }}
|
||||||
|
•
|
||||||
|
{{ props.customer.email }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content has-background-primary-100">
|
||||||
|
<p class="icon-text font-semibold mb-2">
|
||||||
|
<span class="icon">
|
||||||
|
<Icon
|
||||||
|
name="material-symbols:shopping-cart-outline-rounded"
|
||||||
|
:size="18"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>{{ store.selectedImeis.length }} sản phẩm</span>
|
||||||
|
</p>
|
||||||
|
<div class="is-flex is-flex-direction-column is-gap-1">
|
||||||
|
<ProductCard
|
||||||
|
v-for="imei in store.selectedImeis"
|
||||||
|
:key="imei.id"
|
||||||
|
:imei="imei"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content has-background-primary-100">
|
||||||
|
<p class="icon-text font-semibold mb-2">
|
||||||
|
<span class="icon">
|
||||||
|
<Icon
|
||||||
|
name="material-symbols:credit-card-outline"
|
||||||
|
:size="18"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>Thanh toán</span>
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<div class="block is-flex is-justify-content-space-between">
|
||||||
|
<span>Phương thức thanh toán</span>
|
||||||
|
<span>{{ props.paymentMethod.name }}</span>
|
||||||
|
</div>
|
||||||
|
<table class="table is-fullwidth fs-13">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span>Tạm tính</span>
|
||||||
|
<span> ({{ store.selectedImeis.length }} sản phẩm)</span>
|
||||||
|
</td>
|
||||||
|
<td class="has-text-right">{{ $numtoString(subtotal, { hasUnit: true }) }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="font-bold fs-14">Tổng cộng</td>
|
||||||
|
<td class="has-text-right has-text-success-35 font-bold fs-17">
|
||||||
|
{{ $numtoString(subtotal, { hasUnit: true }) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<pre>{{ props }}</pre>
|
||||||
|
<Teleport
|
||||||
|
defer
|
||||||
|
:to="`.modal-card:has(#${id}) .modal-card-foot`"
|
||||||
|
>
|
||||||
|
<div class="buttons w-full is-right">
|
||||||
|
<button
|
||||||
|
@click="$emit('close')"
|
||||||
|
class="button is-white"
|
||||||
|
>
|
||||||
|
Huỷ
|
||||||
|
</button>
|
||||||
|
<button class="button is-success">Đặt hàng</button>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style scoped>
|
||||||
|
.table {
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
td {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import { isNil } from "es-toolkit";
|
||||||
import Address from "~/components/pos/Address.vue";
|
import Address from "~/components/pos/Address.vue";
|
||||||
import ProductCard from "~/components/pos/ProductCard.vue";
|
import ProductCard from "~/components/pos/ProductCard.vue";
|
||||||
import SearchBox from "~/components/SearchBox.vue";
|
import SearchBox from "~/components/SearchBox.vue";
|
||||||
import { isNil } from "es-toolkit";
|
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const { $getdata, $numtoString } = useNuxtApp();
|
const { $getdata, $numtoString } = useNuxtApp();
|
||||||
@@ -19,6 +19,7 @@ function openModal() {
|
|||||||
const orderInfo = ref({
|
const orderInfo = ref({
|
||||||
customer: null,
|
customer: null,
|
||||||
address: null,
|
address: null,
|
||||||
|
deliveryMethod: null,
|
||||||
paymentMethod: null,
|
paymentMethod: null,
|
||||||
});
|
});
|
||||||
const addresses = ref([]);
|
const addresses = ref([]);
|
||||||
@@ -39,7 +40,7 @@ watch(
|
|||||||
await getAddresses();
|
await getAddresses();
|
||||||
if (oldVal === null || oldVal.id !== newVal.id) {
|
if (oldVal === null || oldVal.id !== newVal.id) {
|
||||||
const defaultAddress = addresses.value.find((add) => add.is_default);
|
const defaultAddress = addresses.value.find((add) => add.is_default);
|
||||||
orderInfo.value.address = defaultAddress?.id;
|
orderInfo.value.address = defaultAddress;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
addresses.value = null;
|
addresses.value = null;
|
||||||
@@ -47,38 +48,49 @@ watch(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const showConfirmModal = ref();
|
||||||
|
function openConfirmModal() {
|
||||||
|
showConfirmModal.value = {
|
||||||
|
component: "pos/ConfirmOrder",
|
||||||
|
title: "Xác nhận đơn hàng",
|
||||||
|
width: "60%",
|
||||||
|
height: "auto",
|
||||||
|
vbind: orderInfo.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="block">
|
|
||||||
<button
|
|
||||||
@click="openModal"
|
|
||||||
class="button is-primary"
|
|
||||||
>
|
|
||||||
<span class="icon">
|
|
||||||
<Icon
|
|
||||||
name="material-symbols:add-rounded"
|
|
||||||
:size="20"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<span>Chọn sản phẩm</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="fixed-grid has-1-cols-mobile has-12-cols">
|
<div class="fixed-grid has-1-cols-mobile has-12-cols">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div :class="['cell', store.viewport < 4 ? 'is-col-span-12' : 'is-col-span-8']">
|
<div :class="['cell', store.viewport < 4 ? 'is-col-span-12' : 'is-col-span-8']">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<p class="icon-text fs-16 font-semibold mb-4">
|
<div class="is-flex is-justify-content-space-between">
|
||||||
<span class="icon">
|
<p class="icon-text fs-16 font-semibold mb-4">
|
||||||
<Icon
|
<span class="icon">
|
||||||
name="material-symbols:shopping-cart-outline-rounded"
|
<Icon
|
||||||
:size="18"
|
name="material-symbols:shopping-cart-outline-rounded"
|
||||||
/>
|
:size="18"
|
||||||
</span>
|
/>
|
||||||
<span>Giỏ hàng</span>
|
</span>
|
||||||
</p>
|
<span>Giỏ hàng</span>
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
@click="openModal"
|
||||||
|
class="button is-primary"
|
||||||
|
>
|
||||||
|
<span class="icon">
|
||||||
|
<Icon
|
||||||
|
name="material-symbols:add-rounded"
|
||||||
|
:size="20"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>Thêm sản phẩm</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="store.selectedImeis.length > 0"
|
v-if="store.selectedImeis.length > 0"
|
||||||
class="is-flex is-flex-direction-column is-gap-1"
|
class="is-flex is-flex-direction-column is-gap-1"
|
||||||
@@ -87,11 +99,12 @@ watch(
|
|||||||
v-for="imei in store.selectedImeis"
|
v-for="imei in store.selectedImeis"
|
||||||
:key="imei.id"
|
:key="imei.id"
|
||||||
:imei="imei"
|
:imei="imei"
|
||||||
|
deleteable
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
v-else
|
v-else
|
||||||
class="py-4 fs-16 has-text-grey has-text-centered"
|
class="py-4 fs-16 has-text-centered has-text-grey"
|
||||||
>
|
>
|
||||||
Không có sản phẩm nào trong giỏ hàng
|
Không có sản phẩm nào trong giỏ hàng
|
||||||
</p>
|
</p>
|
||||||
@@ -99,7 +112,7 @@ watch(
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :class="['cell', store.viewport < 4 ? 'is-col-span-12' : 'is-col-span-4']">
|
<div :class="['cell', store.viewport < 4 ? 'is-col-span-12' : 'is-col-span-4']">
|
||||||
<div class="card mb-3">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<p class="icon-text fs-16 font-semibold mb-4">
|
<p class="icon-text fs-16 font-semibold mb-4">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
@@ -130,7 +143,7 @@ watch(
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card mb-3">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<p class="icon-text fs-16 font-semibold mb-4">
|
<p class="icon-text fs-16 font-semibold mb-4">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
@@ -142,6 +155,18 @@ watch(
|
|||||||
<span>Giao hàng</span>
|
<span>Giao hàng</span>
|
||||||
</p>
|
</p>
|
||||||
<div>
|
<div>
|
||||||
|
<SearchBox
|
||||||
|
v-bind="{
|
||||||
|
api: 'Delivery_Method',
|
||||||
|
field: 'name',
|
||||||
|
column: ['name'],
|
||||||
|
first: true,
|
||||||
|
placeholder: 'Phương thức giao hàng',
|
||||||
|
onOption: (e) => (orderInfo.deliveryMethod = e),
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-if="orderInfo.customer">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<p class="mb-2">Thông tin người nhận</p>
|
<p class="mb-2">Thông tin người nhận</p>
|
||||||
<div v-if="orderInfo.customer">
|
<div v-if="orderInfo.customer">
|
||||||
@@ -179,16 +204,22 @@ watch(
|
|||||||
v-for="address in addresses"
|
v-for="address in addresses"
|
||||||
:key="address"
|
:key="address"
|
||||||
:address="address"
|
:address="address"
|
||||||
:selected="orderInfo.address === address.id"
|
:selected="orderInfo.address?.id === address.id"
|
||||||
@selectAddress="orderInfo.address = $event"
|
@selectAddress="orderInfo.address = $event"
|
||||||
@update="getAddresses"
|
@update="getAddresses"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<p
|
||||||
|
v-else-if="orderInfo.deliveryMethod?.code === 'HOME_DELIVERY'"
|
||||||
|
class="has-text-grey-light py-4 has-text-centered"
|
||||||
|
>
|
||||||
|
Chưa chọn khách hàng
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card mb-3">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<p class="icon-text fs-16 font-semibold mb-4">
|
<p class="icon-text fs-16 font-semibold mb-4">
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
@@ -213,7 +244,7 @@ watch(
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card mb-3">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<p class="icon-text fs-16 font-semibold mb-4">Tổng cộng</p>
|
<p class="icon-text fs-16 font-semibold mb-4">Tổng cộng</p>
|
||||||
<div>
|
<div>
|
||||||
@@ -235,6 +266,7 @@ watch(
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<button
|
<button
|
||||||
|
@click="openConfirmModal"
|
||||||
class="button is-fullwidth is-success"
|
class="button is-fullwidth is-success"
|
||||||
:disabled="Object.values(orderInfo).some(isNil)"
|
:disabled="Object.values(orderInfo).some(isNil)"
|
||||||
>
|
>
|
||||||
@@ -246,5 +278,10 @@ watch(
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Modal
|
||||||
|
v-if="showConfirmModal"
|
||||||
|
v-bind="showConfirmModal"
|
||||||
|
@close="showConfirmModal = undefined"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { remove } from "es-toolkit";
|
|||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
imei: Object,
|
imei: Object,
|
||||||
|
deleteable: Boolean,
|
||||||
});
|
});
|
||||||
const { $numtoString, $snackbar } = useNuxtApp();
|
const { $numtoString, $snackbar } = useNuxtApp();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
@@ -35,7 +36,7 @@ function removeFromCart() {
|
|||||||
</div>
|
</div>
|
||||||
<p class="has-text-primary-50 font-medium">{{ $numtoString(imei.variant__price, { hasUnit: true }) }}</p>
|
<p class="has-text-primary-50 font-medium">{{ $numtoString(imei.variant__price, { hasUnit: true }) }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div v-if="deleteable">
|
||||||
<button
|
<button
|
||||||
@click="removeFromCart"
|
@click="removeFromCart"
|
||||||
class="button is-danger is-light"
|
class="button is-danger is-light"
|
||||||
|
|||||||
@@ -31,12 +31,6 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
{ name: "modelfields", url: "model-fields/", params: {} },
|
{ name: "modelfields", url: "model-fields/", params: {} },
|
||||||
{ name: "readexcel", url: "read-excel/", params: {} },
|
{ name: "readexcel", url: "read-excel/", params: {} },
|
||||||
{ name: "findkey", url: "find-key/", params: {} },
|
{ name: "findkey", url: "find-key/", params: {} },
|
||||||
{
|
|
||||||
name: "dealerrights",
|
|
||||||
url: "data/Biz_Rights/",
|
|
||||||
url_detail: "data-detail/Biz_Rights/",
|
|
||||||
params: { sort: "-id" },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "individual",
|
name: "individual",
|
||||||
url: "data/Individual/",
|
url: "data/Individual/",
|
||||||
@@ -824,33 +818,12 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
url_detail: "data-detail/Email_Template/",
|
url_detail: "data-detail/Email_Template/",
|
||||||
params: {},
|
params: {},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "projectfile",
|
|
||||||
url: "data/Project_File/",
|
|
||||||
url_detail: "data-detail/Project_File/",
|
|
||||||
params: { values: "id,project,file,create_time" },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "issuedplace",
|
name: "issuedplace",
|
||||||
url: "data/Issued_Place/",
|
url: "data/Issued_Place/",
|
||||||
url_detail: "data-detail/Issued_Place/",
|
url_detail: "data-detail/Issued_Place/",
|
||||||
params: { values: "id,code,name,create_time" },
|
params: { values: "id,code,name,create_time" },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "dealer",
|
|
||||||
url: "data/Dealer/",
|
|
||||||
url_detail: "data-detail/Dealer/",
|
|
||||||
params: {
|
|
||||||
values:
|
|
||||||
"id,count_sale,code,name,phone,address,email,create_time,sale_amount,pay_sale,commission_amount,pay_commission,commission_remain,batch_date",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "layersetting",
|
|
||||||
url: "data/Layer_Setting/",
|
|
||||||
url_detail: "data-detail/Layer_Setting/",
|
|
||||||
params: { values: "id,code,name,detail,user,create_time,update_time" },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "grouprights",
|
name: "grouprights",
|
||||||
commit: "grouprights",
|
commit: "grouprights",
|
||||||
@@ -889,8 +862,7 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
params: {},
|
params: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invoice",
|
name: "Invoice",
|
||||||
commit: "invoice",
|
|
||||||
url: "data/Invoice/",
|
url: "data/Invoice/",
|
||||||
url_detail: "data-detail/Invoice/",
|
url_detail: "data-detail/Invoice/",
|
||||||
params: {},
|
params: {},
|
||||||
@@ -1043,6 +1015,12 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|||||||
url_detail: "data-detail/Customer_Address/",
|
url_detail: "data-detail/Customer_Address/",
|
||||||
params: {},
|
params: {},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Delivery_Method",
|
||||||
|
url: "data/Delivery_Method/",
|
||||||
|
url_detail: "data-detail/Delivery_Method/",
|
||||||
|
params: {},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const { $copy, $clone, $updateSeriesFields, $snackbar, $store, $remove, $dialog } = nuxtApp;
|
const { $copy, $clone, $updateSeriesFields, $snackbar, $store, $remove, $dialog } = nuxtApp;
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ import FormatDate from "~/components/datatable/format/FormatDate.vue";
|
|||||||
import DataTable from "~/components/datatable/DataTable.vue";
|
import DataTable from "~/components/datatable/DataTable.vue";
|
||||||
import DataModel from "~/components/datatable/DataModel.vue";
|
import DataModel from "~/components/datatable/DataModel.vue";
|
||||||
import InputNumber from "~/components/common/InputNumber.vue";
|
import InputNumber from "~/components/common/InputNumber.vue";
|
||||||
import ColorText from "~/components/datatable/format/ColorText.vue";
|
|
||||||
|
|
||||||
// menu
|
// menu
|
||||||
import MenuAction from "~/components/menu/MenuAction.vue";
|
import MenuAction from "~/components/menu/MenuAction.vue";
|
||||||
@@ -95,7 +94,6 @@ const components = {
|
|||||||
CustomerForm,
|
CustomerForm,
|
||||||
CountdownTimer,
|
CountdownTimer,
|
||||||
ViewList,
|
ViewList,
|
||||||
ColorText,
|
|
||||||
CountWithAdd,
|
CountWithAdd,
|
||||||
MenuAction,
|
MenuAction,
|
||||||
Email,
|
Email,
|
||||||
|
|||||||
Reference in New Issue
Block a user