191 lines
5.3 KiB
Vue
191 lines
5.3 KiB
Vue
<template>
|
|
<div>
|
|
<div class="fixed-grid">
|
|
<div class="grid">
|
|
<div class="cell is-col-span-2">
|
|
<div class="field">
|
|
<label class="label">Họ và tên<b class="ml-1 has-text-danger">*</b></label>
|
|
<div class="control">
|
|
<input
|
|
class="input"
|
|
type="text"
|
|
v-model="record.fullname"
|
|
placeholder="Nguyễn Văn A"
|
|
/>
|
|
</div>
|
|
<p
|
|
v-if="errors.fullname"
|
|
class="help is-danger"
|
|
>
|
|
{{ errors.fullname }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="cell">
|
|
<div class="field">
|
|
<label class="label">Số điện thoại<b class="ml-1 has-text-danger">*</b></label>
|
|
<InputPhone
|
|
v-bind="{
|
|
record,
|
|
attr: 'phone',
|
|
onPhone: (e) => selected('phone', e),
|
|
}"
|
|
/>
|
|
<p
|
|
v-if="errors.phone"
|
|
class="help is-danger"
|
|
>
|
|
{{ errors.phone }}
|
|
<a
|
|
v-if="existedCustomer"
|
|
class="has-text-primary"
|
|
@click="showCustomer()"
|
|
>
|
|
Chi tiết
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="cell">
|
|
<div class="field">
|
|
<label class="label">Email<b class="ml-1 has-text-danger">*</b></label>
|
|
<InputEmail
|
|
v-bind="{
|
|
record,
|
|
attr: 'email',
|
|
onEmail: (e) => selected('email', e),
|
|
}"
|
|
/>
|
|
<p
|
|
class="help is-danger"
|
|
v-if="errors.email"
|
|
>
|
|
{{ errors.email }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mt-5 buttons is-right">
|
|
<button
|
|
class="button is-white"
|
|
@click="emit('close')"
|
|
>
|
|
Hủy
|
|
</button>
|
|
<button
|
|
:class="['button is-primary', isLoading && 'is-loading']"
|
|
@click="createCustomer"
|
|
>
|
|
<span class="icon">
|
|
<Icon
|
|
name="material-symbols:add-rounded"
|
|
:size="20"
|
|
/>
|
|
</span>
|
|
<span>Tạo khách hàng</span>
|
|
</button>
|
|
</div>
|
|
<Modal
|
|
v-if="showModal"
|
|
v-bind="showModal"
|
|
@close="showModal = undefined"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed } from "vue";
|
|
import InputPhone from "@/components/common/InputPhone.vue";
|
|
import InputEmail from "@/components/common/InputEmail.vue";
|
|
import { useStore } from "~/stores/index";
|
|
import { isNotNil, pickBy } from "es-toolkit";
|
|
|
|
const emit = defineEmits(["close", "update", "modalevent"]);
|
|
const { $getdata, $insertapi, $empty, $errEmail, $errPhone, $resetNull, $snackbar } = useNuxtApp();
|
|
|
|
const store = useStore();
|
|
const isVietnamese = computed(() => store.lang === "vi");
|
|
|
|
const record = ref({});
|
|
const isLoading = ref(false);
|
|
const errors = ref({});
|
|
const showModal = ref();
|
|
const existedCustomer = ref();
|
|
|
|
function showCustomer() {
|
|
showModal.value = {
|
|
component: "customer/CustomerView",
|
|
width: "60%",
|
|
height: "600px",
|
|
title: "Khách hàng",
|
|
vbind: { row: existedCustomer.value },
|
|
};
|
|
}
|
|
|
|
const selected = (field, value) => {
|
|
record.value[field] = value && typeof value === "object" ? value.id : value;
|
|
if (errors.value[field]) delete errors.value[field];
|
|
};
|
|
|
|
function checkError() {
|
|
errors.value = {};
|
|
if ($empty(record.value.fullname)) {
|
|
errors.value.fullname = isVietnamese.value ? "Họ tên không được bỏ trống" : "Full name is required";
|
|
}
|
|
errors.value.phone = $errPhone(record.value.phone);
|
|
errors.value.email = $errEmail(record.value.email);
|
|
|
|
const realErrors = pickBy(errors.value, isNotNil);
|
|
return Object.keys(realErrors).length > 0;
|
|
}
|
|
|
|
async function createCustomer() {
|
|
try {
|
|
if (checkError()) return;
|
|
|
|
isLoading.value = true;
|
|
if (record.value.phone) {
|
|
const phoneCheck = await $getdata("customer", {
|
|
first: true,
|
|
filter: { phone: record.value.phone.trim() },
|
|
});
|
|
if (phoneCheck) {
|
|
existedCustomer.value = phoneCheck;
|
|
errors.value.phone = isVietnamese.value ? "Số điện thoại đã tồn tại." : "Phone already exists.";
|
|
return;
|
|
}
|
|
}
|
|
if (record.value.email) {
|
|
const emailCheck = await $getdata("customer", {
|
|
first: true,
|
|
filter: { email: record.value.email.trim() },
|
|
});
|
|
if (emailCheck) {
|
|
existedCustomer.value = emailCheck;
|
|
errors.value.email = isVietnamese.value ? "Email đã tồn tại." : "Email already exists.";
|
|
return;
|
|
}
|
|
}
|
|
|
|
const customerData = $resetNull({ ...record.value });
|
|
const res = await $insertapi("customer", { data: customerData, notify: false });
|
|
if (!res || res === "error") return;
|
|
|
|
const completedData = await $getdata("customer", {
|
|
first: true,
|
|
filter: { id: res.id },
|
|
});
|
|
|
|
isLoading.value = false;
|
|
$snackbar("Khách hàng đã được khởi tạo thành công", "Success");
|
|
emit("modalevent", { name: "dataevent", data: completedData });
|
|
emit("update", completedData);
|
|
setTimeout(() => emit("close"), 100);
|
|
} catch (e) {
|
|
isLoading.value = false;
|
|
console.error(e);
|
|
}
|
|
}
|
|
</script>
|