Files
web/app/components/customer/CustomerQuickAdd.vue
2026-06-04 13:57:27 +07:00

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ọ 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>