chore: install prettier

This commit is contained in:
Viet An
2026-05-04 15:22:27 +07:00
parent 93d29ca7d8
commit bd58e2b847
267 changed files with 22950 additions and 13581 deletions

View File

@@ -7,17 +7,8 @@ const props = defineProps({
row: Object,
});
const {
$buildFileUrl,
$id,
$formatFileSize,
$getdata,
$getpath,
$getapi,
$findapi,
$snackbar,
$exportpdf,
} = useNuxtApp();
const { $buildFileUrl, $id, $formatFileSize, $getdata, $getpath, $getapi, $findapi, $snackbar, $exportpdf } =
useNuxtApp();
const store = useStore();
const product = props.row || {};
const tab = ref("info");
@@ -37,19 +28,7 @@ const documents = ref([]);
const projectDocuments = ref([]);
const viewingImage = ref(null);
const imageExtensions = ["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"];
const documentExtensions = [
"pdf",
"doc",
"docx",
"xls",
"xlsx",
"ppt",
"pptx",
"txt",
"csv",
"zip",
"rar",
];
const documentExtensions = ["pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "csv", "zip", "rar"];
const policies = ref([]);
const selectedPolicy = ref(null);
@@ -79,9 +58,7 @@ async function loadAllPolicyData() {
const plansData = await $getdata("paymentplan", {}, undefined, false);
policies.value = policiesData || [];
allPaymentPlans.value = plansData
? plansData.sort((a, b) => a.cycle - b.cycle)
: [];
allPaymentPlans.value = plansData ? plansData.sort((a, b) => a.cycle - b.cycle) : [];
if (policies.value.length > 0) {
loadPlansForPolicy(policies.value[0].id);
@@ -102,27 +79,18 @@ function loadPlansForPolicy(id) {
if (!policy) return;
selectedPolicy.value = policy;
paymentPlans.value = allPaymentPlans.value.filter(
(plan) => plan.policy === id
);
paymentPlans.value = allPaymentPlans.value.filter((plan) => plan.policy === id);
activeTab.value = id;
}
function printContent() {
if (!record.value || !selectedPolicy.value) {
$snackbar(
isVietnamese.value
? "Vui lòng chọn chính sách"
: "Please select a policy",
{ type: "is-warning" }
);
$snackbar(isVietnamese.value ? "Vui lòng chọn chính sách" : "Please select a policy", { type: "is-warning" });
return;
}
const docId = 'print-area';
const fileName = `${selectedPolicy.value?.name || "Payment Schedule"} - ${
record.value?.code
}`;
const docId = "print-area";
const fileName = `${selectedPolicy.value?.name || "Payment Schedule"} - ${record.value?.code}`;
if (typeof $exportpdf === "function") {
$exportpdf(docId, fileName);
@@ -184,12 +152,7 @@ async function loadProductFiles() {
const files = await Promise.all(
links.map(async (link) => {
const fileData = await $getdata(
"file",
{ id: link.file },
undefined,
true
).catch((error) => {
const fileData = await $getdata("file", { id: link.file }, undefined, true).catch((error) => {
console.error(`Error loading file ${link.file}:`, error);
return null;
});
@@ -203,7 +166,7 @@ async function loadProductFiles() {
caption: fileData?.caption || "",
create_time: link.create_time,
};
})
}),
);
const imageList = [];
@@ -256,12 +219,7 @@ async function loadProjectFiles() {
const files = await Promise.all(
links.map(async (link) => {
const fileData = await $getdata(
"file",
{ id: link.file },
undefined,
true
).catch((error) => {
const fileData = await $getdata("file", { id: link.file }, undefined, true).catch((error) => {
console.error(`Error loading project file ${link.file}:`, error);
return null;
});
@@ -269,7 +227,7 @@ async function loadProjectFiles() {
link,
fileData,
};
})
}),
);
const validFiles = files.filter((entry) => entry.fileData);
@@ -286,9 +244,7 @@ async function loadProjectFiles() {
caption: entry.fileData.caption || "",
url: $buildFileUrl(entry.fileData.file),
file: entry.fileData.file,
size: entry.fileData.size
? $formatFileSize(Number(entry.fileData.size))
: "",
size: entry.fileData.size ? $formatFileSize(Number(entry.fileData.size)) : "",
uploaded_by: entry.fileData.creator__fullname || "Admin",
uploaded_at: entry.fileData.create_time || entry.link.create_time || "",
};
@@ -333,48 +289,44 @@ async function loadLookupNames() {
if (record.value.status && !record.value.status__name) {
promises.push(
$getdata("productstatus", { id: record.value.status }, undefined, true)
.then((data) => {
if (data && data.name) {
record.value.status__name = data.name;
}
})
$getdata("productstatus", { id: record.value.status }, undefined, true).then((data) => {
if (data && data.name) {
record.value.status__name = data.name;
}
}),
);
}
if (record.value.type && !record.value.type__name) {
promises.push(
$getdata("producttype", { id: record.value.type }, undefined, true)
.then((data) => {
if (data && data.name) {
record.value.type__name = data.name;
record.value.type__en = data.name_en || data.en || data.name;
}
})
$getdata("producttype", { id: record.value.type }, undefined, true).then((data) => {
if (data && data.name) {
record.value.type__name = data.name;
record.value.type__en = data.name_en || data.en || data.name;
}
}),
);
}
if (record.value.direction && !record.value.direction__name) {
promises.push(
$getdata("direction", { id: record.value.direction }, undefined, true)
.then((data) => {
if (data && data.name) {
record.value.direction__name = data.name;
record.value.direction__en = data.name_en || data.en || data.name;
}
})
$getdata("direction", { id: record.value.direction }, undefined, true).then((data) => {
if (data && data.name) {
record.value.direction__name = data.name;
record.value.direction__en = data.name_en || data.en || data.name;
}
}),
);
}
if (record.value.zone_type && !record.value.zone_type__name) {
promises.push(
$getdata("zonetype", { id: record.value.zone_type }, undefined, true)
.then((data) => {
if (data && data.name) {
record.value.zone_type__name = data.name;
record.value.zone_type__en = data.name_en || data.en || data.name;
}
})
$getdata("zonetype", { id: record.value.zone_type }, undefined, true).then((data) => {
if (data && data.name) {
record.value.zone_type__name = data.name;
record.value.zone_type__en = data.name_en || data.en || data.name;
}
}),
);
}
@@ -391,21 +343,16 @@ async function loadLookupNames() {
const rs = await $getapi([projectApi]);
const data = rs[0]?.data;
if (data) {
const projectName =
data.name || data.fullname || data.code || data.title;
const projectName = data.name || data.fullname || data.code || data.title;
if (projectName) {
record.value.project__name = projectName;
record.value.project__fullname =
data.fullname || data.name || projectName;
record.value.project__fullname = data.fullname || data.name || projectName;
}
}
} catch (err) {
console.error(
`Failed to load project for id ${record.value.project}:`,
err
);
console.error(`Failed to load project for id ${record.value.project}:`, err);
}
})()
})(),
);
}
@@ -418,20 +365,13 @@ async function loadLookupNames() {
async function loadFullData() {
if (!props.row?.id) return;
try {
const fullData = await $getdata(
"product",
{ id: props.row.id },
undefined,
true
);
const fullData = await $getdata("product", { id: props.row.id }, undefined, true);
record.value = fullData;
await loadLookupNames();
await loadProductFiles();
await loadProjectFiles();
await loadAllPolicyData();
} catch (error) {
console.error("Error loading full product data:", error);
record.value = props.row ? { ...props.row } : null;
@@ -450,7 +390,7 @@ watch(
await loadFullData();
}
},
{ immediate: false }
{ immediate: false },
);
watch(
@@ -463,7 +403,7 @@ watch(
projectDocuments.value = [];
}
},
{ immediate: false }
{ immediate: false },
);
onMounted(async () => {
@@ -472,7 +412,10 @@ onMounted(async () => {
</script>
<template>
<div v-if="record" class="px-5">
<div
v-if="record"
class="px-5"
>
<div class="tabs is-toggle is-fullwidth mb-4">
<ul>
<li :class="{ 'is-active': tab === 'info' }">
@@ -502,14 +445,17 @@ onMounted(async () => {
</div>
<div class="">
<div v-if="tab === 'info' && record" :id="docid">
<div
v-if="tab === 'info' && record"
:id="docid"
>
<TransactionView
pagename="ProductView"
:transactionId="product.txnprd"
:productId="product.id"
/>
</div>
<!-- Tab Hình ảnh -->
<div v-if="tab === 'image' && record">
<div class="columns is-gapless">
@@ -565,9 +511,7 @@ onMounted(async () => {
</div>
<div class="card-content p-2">
<div class="image-meta">
<p
class="has-text-weight-semibold is-size-7 is-clipped"
>
<p class="has-text-weight-semibold is-size-7 is-clipped">
{{ image.name }}
</p>
<p class="is-size-7 is-clipped">
@@ -578,7 +522,10 @@ onMounted(async () => {
</div>
</div>
</div>
<div v-else class="has-text-centered py-4">
<div
v-else
class="has-text-centered py-4"
>
<p class="">Chưa hình ảnh nào được tải lên.</p>
</div>
</div>
@@ -609,9 +556,7 @@ onMounted(async () => {
</div>
<div class="card-content p-2">
<div class="image-meta">
<p
class="has-text-weight-semibold is-size-7 is-clipped"
>
<p class="has-text-weight-semibold is-size-7 is-clipped">
{{ image.name }}
</p>
<p class="is-size-7 is-clipped">
@@ -622,7 +567,10 @@ onMounted(async () => {
</div>
</div>
</div>
<div v-else class="has-text-centered py-4">
<div
v-else
class="has-text-centered py-4"
>
<p class="">Chưa hình ảnh dự án nào được tải lên.</p>
</div>
</div>
@@ -636,16 +584,13 @@ onMounted(async () => {
@click.self="closeViewImage"
>
<div class="modal-background"></div>
<div class="modal-content" style="width: 90vw; height: 90vh">
<div
class="modal-content"
style="width: 90vw; height: 90vh"
>
<figure
class="image"
style="
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
"
style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center"
>
<img
:src="viewingImage.url"
@@ -704,7 +649,10 @@ onMounted(async () => {
</tr>
</thead>
<tbody>
<tr v-for="doc in documents" :key="doc.id">
<tr
v-for="doc in documents"
:key="doc.id"
>
<td>
<div class="is-flex is-align-items-center">
<span class="icon is-medium has-text-info mr-2">
@@ -735,13 +683,7 @@ onMounted(async () => {
{{ doc.uploaded_by }}
</p>
<p class="is-size-7 has-text-grey">
{{
doc.uploaded_at
? new Date(doc.uploaded_at).toLocaleString(
"vi-VN"
)
: "-"
}}
{{ doc.uploaded_at ? new Date(doc.uploaded_at).toLocaleString("vi-VN") : "-" }}
</p>
</div>
</td>
@@ -767,10 +709,11 @@ onMounted(async () => {
</td>
</tr>
<tr v-if="documents.length === 0">
<td colspan="4" class="has-text-centered py-4">
<p class="has-text-grey">
Chưa có tài liệu nào được đính kèm.
</p>
<td
colspan="4"
class="has-text-centered py-4"
>
<p class="has-text-grey">Chưa có tài liệu nào được đính kèm.</p>
</td>
</tr>
</tbody>
@@ -791,7 +734,10 @@ onMounted(async () => {
</tr>
</thead>
<tbody>
<tr v-for="doc in projectDocuments" :key="doc.id">
<tr
v-for="doc in projectDocuments"
:key="doc.id"
>
<td>
<div class="is-flex is-align-items-center">
<span class="icon is-medium has-text-info mr-2">
@@ -822,13 +768,7 @@ onMounted(async () => {
{{ doc.uploaded_by }}
</p>
<p class="is-size-7 has-text-grey">
{{
doc.uploaded_at
? new Date(doc.uploaded_at).toLocaleString(
"vi-VN"
)
: "-"
}}
{{ doc.uploaded_at ? new Date(doc.uploaded_at).toLocaleString("vi-VN") : "-" }}
</p>
</div>
</td>
@@ -854,10 +794,11 @@ onMounted(async () => {
</td>
</tr>
<tr v-if="projectDocuments.length === 0">
<td colspan="4" class="has-text-centered py-4">
<p class="has-text-grey">
Chưa có tài liệu dự án nào được đính kèm.
</p>
<td
colspan="4"
class="has-text-centered py-4"
>
<p class="has-text-grey">Chưa có tài liệu dự án nào được đính kèm.</p>
</td>
</tr>
</tbody>
@@ -869,11 +810,18 @@ onMounted(async () => {
</div>
<!-- Tab Chính sách tài chính -->
<div v-if="tab === 'financial-policy' && record" class="py-3">
<div v-if="isLoadingPolicies" class="has-text-centered">
<div
v-if="tab === 'financial-policy' && record"
class="py-3"
>
<div
v-if="isLoadingPolicies"
class="has-text-centered"
>
<p class="has-text-info is-italic">Đang tải chính sách...</p>
</div>
<PaymentSchedule v-else
<PaymentSchedule
v-else
:productData="record"
:policies="policies"
:activeTab="activeTab"
@@ -1052,4 +1000,4 @@ li a:hover .icon :deep(img) {
border-bottom: 1px solid #e0e0e0;
padding-bottom: 1rem;
}
</style>
</style>