feat: customer employee form (basic info & checkup)

This commit is contained in:
puriphatt 2024-06-07 12:24:09 +00:00
parent 768686d41c
commit a6a0c5d1e1
7 changed files with 728 additions and 136 deletions

View file

@ -14,6 +14,7 @@ defineProps<{
outlined?: boolean;
readonly?: boolean;
separator?: boolean;
employee?: boolean;
}>();
const adrressStore = useAddressStore();
@ -23,6 +24,7 @@ const provinceId = defineModel<string | null | undefined>('provinceId');
const districtId = defineModel<string | null | undefined>('districtId');
const subDistrictId = defineModel<string | null | undefined>('subDistrictId');
const zipCode = defineModel<string | null | undefined>('zipCode');
const sameWithEmployer = defineModel<boolean>('sameWithEmployer');
const addrOptions = reactive<{
provinceOps: Province[];
@ -73,9 +75,30 @@ watch(provinceId, fetchDistrict);
watch(districtId, fetchSubDistrict);
</script>
<template>
<div class="col-12 app-text-muted">
<div class="col-12 app-text-muted row items-center">
{{ title || $t('formDialogTitlePersonnelAddress') }}
<div
v-if="employee"
class="q-ml-lg surface-3 q-px-sm q-py-xs row"
style="border-radius: var(--radius-3)"
>
<span
class="q-px-sm q-mr-lg rounded cursor-pointer"
:class="{ dark: $q.dark.isActive, 'active-addr': sameWithEmployer }"
@click="sameWithEmployer = true"
>
เลอกทอยตามนายจาง
</span>
<span
class="q-px-sm rounded cursor-pointer"
:class="{ dark: $q.dark.isActive, 'active-addr': !sameWithEmployer }"
@click="sameWithEmployer = false"
>
กำหนดเอง
</span>
</div>
</div>
<div class="col-12 row q-col-gutter-y-md">
<div class="col-3 q-pl-xl app-text-muted">
{{ addressTitle || $t('formDialogTitleAddressPure') }}
@ -85,7 +108,7 @@ watch(districtId, fetchSubDistrict);
for="input-address"
:dense="dense"
:outlined="readonly ? false : outlined"
:readonly="readonly"
:readonly="readonly || sameWithEmployer"
:borderless="readonly"
hide-bottom-space
:label="$t('address')"
@ -100,9 +123,9 @@ watch(districtId, fetchSubDistrict);
<q-select
id="select-province"
:dense="dense"
:readonly="readonly"
:readonly="readonly || sameWithEmployer"
:outlined="readonly ? false : outlined"
:hide-dropdown-icon="readonly"
:hide-dropdown-icon="readonly || sameWithEmployer"
:borderless="readonly"
hide-bottom-space
emit-value
@ -123,9 +146,9 @@ watch(districtId, fetchSubDistrict);
<q-select
id="select-district"
:dense="dense"
:readonly="readonly"
:readonly="readonly || sameWithEmployer"
:outlined="readonly ? false : outlined"
:hide-dropdown-icon="readonly"
:hide-dropdown-icon="readonly || sameWithEmployer"
:borderless="readonly"
hide-bottom-space
emit-value
@ -146,9 +169,9 @@ watch(districtId, fetchSubDistrict);
<q-select
id="select-sub-district"
:dense="dense"
:readonly="readonly"
:readonly="readonly || sameWithEmployer"
:outlined="readonly ? false : outlined"
:hide-dropdown-icon="readonly"
:hide-dropdown-icon="readonly || sameWithEmployer"
:borderless="readonly"
hide-bottom-space
emit-value
@ -184,7 +207,7 @@ watch(districtId, fetchSubDistrict);
<q-input
for="input-address-en"
:dense="dense"
:readonly="readonly"
:readonly="readonly || sameWithEmployer"
:outlined="readonly ? false : outlined"
:borderless="readonly"
hide-bottom-space
@ -200,10 +223,10 @@ watch(districtId, fetchSubDistrict);
<q-select
id="select-province-en"
:dense="dense"
:readonly="readonly"
:readonly="readonly || sameWithEmployer"
:outlined="readonly ? false : outlined"
:borderless="readonly"
:hide-dropdown-icon="readonly"
:hide-dropdown-icon="readonly || sameWithEmployer"
emit-value
map-options
v-model="provinceId"
@ -222,10 +245,10 @@ watch(districtId, fetchSubDistrict);
<q-select
id="select-district-en"
:dense="dense"
:readonly="readonly"
:readonly="readonly || sameWithEmployer"
:outlined="readonly ? false : outlined"
:borderless="readonly"
:hide-dropdown-icon="readonly"
:hide-dropdown-icon="readonly || sameWithEmployer"
emit-value
map-options
v-model="districtId"
@ -244,10 +267,10 @@ watch(districtId, fetchSubDistrict);
<q-select
id="select-sub-district-en"
:dense="dense"
:readonly="readonly"
:readonly="readonly || sameWithEmployer"
:outlined="readonly ? false : outlined"
:borderless="readonly"
:hide-dropdown-icon="readonly"
:hide-dropdown-icon="readonly || sameWithEmployer"
emit-value
map-options
v-model="subDistrictId"
@ -282,3 +305,14 @@ watch(districtId, fetchSubDistrict);
style="padding-block: 0.5px; margin-top: 32px"
/>
</template>
<style lang="scss" scoped>
.active-addr {
color: hsl(var(--info-bg));
background-color: hsla(var(--info-bg) / 0.1);
&.dark {
background-color: var(--surface-1);
}
}
</style>

View file

@ -12,12 +12,14 @@ const telephoneNo = defineModel<string>('telephoneNo');
const email = defineModel<string>('email');
const gender = defineModel<string>('gender');
const birthDate = defineModel<Date | null>('birthDate');
const nationality = defineModel<string>('nationality');
defineProps<{
dense?: boolean;
outlined?: boolean;
readonly?: boolean;
separator?: boolean;
employee?: boolean;
}>();
</script>
<template>
@ -78,6 +80,7 @@ defineProps<{
]"
/>
<q-input
v-if="!employee"
for="input-telephone"
:dense="dense"
:outlined="readonly ? false : outlined"
@ -89,6 +92,7 @@ defineProps<{
mask="##########"
/>
<q-input
v-if="!employee"
for="input-email"
:dense="dense"
:outlined="readonly ? false : outlined"
@ -99,6 +103,7 @@ defineProps<{
v-model="email"
/>
<q-select
v-if="!employee"
id="select-gender"
:dense="dense"
:outlined="readonly ? false : outlined"
@ -167,6 +172,41 @@ defineProps<{
class="col-3"
:model-value="birthDate ? userStore.calculateAge(birthDate) : ''"
/>
<q-select
v-if="employee"
id="select-gender"
:dense="dense"
:outlined="readonly ? false : outlined"
:readonly="readonly"
:hide-dropdown-icon="readonly"
:borderless="readonly"
emit-value
map-options
:label="$t('formDialogInputGender')"
class="col-3"
option-label="label"
option-value="value"
v-model="gender"
:options="userStore.userOption.genderOpts"
/>
<q-select
v-if="employee"
id="select-nationality"
:dense="dense"
:outlined="readonly ? false : outlined"
:readonly="readonly"
:borderless="readonly"
:hide-dropdown-icon="readonly"
emit-value
map-options
options-dense
:label="$t('formDialogInputNationality')"
class="col-3"
option-label="label"
option-value="label"
v-model="nationality"
:options="userStore.userOption.nationalityOpts"
/>
</div>
<q-separator
v-if="separator"

View file

@ -5,6 +5,10 @@ const taxNo = defineModel<string | null | undefined>('taxNo');
const employerID = defineModel<string>('employerID');
// employee
const employeeID = defineModel<string>('employeeID');
const nrcNo = defineModel<string>('nrcNo');
defineProps<{
title?: string;
dense?: boolean;
@ -12,6 +16,7 @@ defineProps<{
readonly?: boolean;
separator?: boolean;
typeCustomer?: string;
employee?: boolean;
}>();
</script>
@ -19,7 +24,7 @@ defineProps<{
<div class="col-3 app-text-muted">
{{ $t(`formDialogTitleInformation`) }}
</div>
<div class="col-9 row q-col-gutter-md">
<div v-if="!employee" class="col-9 row q-col-gutter-md">
<q-input
v-if="typeCustomer === 'customerNaturalPerson'"
:dense="dense"
@ -65,6 +70,40 @@ defineProps<{
/>
</div>
<div v-if="employee" class="col-9 row q-col-gutter-md">
<q-select
:dense="dense"
:outlined="!readonly"
:readonly="readonly"
:borderless="readonly"
hide-bottom-space
class="col-3"
:label="$t('formDialogEmployerID')"
v-model="employerID"
/>
<q-input
:dense="dense"
:outlined="!readonly"
:readonly="readonly"
:borderless="readonly"
hide-bottom-space
class="col-3"
:label="$t('formDialogEmployeeID')"
v-model="employeeID"
for="input-employeeID"
/>
<q-input
:dense="dense"
:outlined="!readonly"
:readonly="readonly"
:borderless="readonly"
hide-bottom-space
class="col-6"
:label="$t('formDialogEmployeeNRCNo')"
v-model="nrcNo"
/>
</div>
<q-separator
v-if="separator"
class="col-12 q-mt-xl q-mb-md"

View file

@ -0,0 +1,257 @@
<script setup lang="ts">
import { onMounted, reactive } from 'vue';
import { dateFormat } from 'src/utils/datetime';
import useAddressStore, {
District,
Province,
SubDistrict,
} from 'src/stores/address';
const adrressStore = useAddressStore();
const addrOptions = reactive<{
provinceOps: Province[];
districtOps: District[];
subDistrictOps: SubDistrict[];
}>({
provinceOps: [],
districtOps: [],
subDistrictOps: [],
});
const checkupResult = defineModel<string>('checkupResult');
const checkupType = defineModel<string>('checkupType');
const provinceId = defineModel<string>('provinceId');
const hospitalName = defineModel<string>('hospitalName');
const remark = defineModel<string>('remark');
const medicalBenefitScheme = defineModel<string>('medicalBenefitScheme');
const insuranceCompany = defineModel<string>('insuranceCompany');
const coverageStartDate = defineModel<Date | null>('coverageStartDate');
const coverageExpireDate = defineModel<Date | null>('coverageExpireDate');
defineProps<{
title?: string;
dense?: boolean;
outlined?: boolean;
readonly?: boolean;
separator?: boolean;
typeCustomer?: string;
}>();
async function fetchProvince() {
const result = await adrressStore.fetchProvince();
if (result) addrOptions.provinceOps = result;
}
onMounted(async () => {
await fetchProvince();
});
</script>
<template>
<div class="col-3 app-text-muted">
{{ $t(`formDialogTitleHealthCheck`) }}
</div>
<div class="col-9 row q-col-gutter-md">
<q-input
:dense="dense"
:outlined="!readonly"
:readonly="readonly"
:borderless="readonly"
hide-bottom-space
class="col-6"
:label="$t('formDialogInputCheckupRes')"
v-model="checkupResult"
/>
<q-select
id="select-province"
:dense="dense"
:readonly="readonly"
:outlined="readonly ? false : outlined"
:hide-dropdown-icon="readonly"
:borderless="readonly"
hide-bottom-space
emit-value
map-options
v-model="checkupType"
option-value="id"
option-label="name"
:label="$t('formDialogInputCheckupType')"
class="col-6"
:options="addrOptions.provinceOps"
lazy-rules
/>
<q-select
id="select-province"
:dense="dense"
:readonly="readonly"
:outlined="readonly ? false : outlined"
:hide-dropdown-icon="readonly"
:borderless="readonly"
hide-bottom-space
emit-value
map-options
v-model="provinceId"
option-value="id"
option-label="nameEN"
:label="$t('province')"
class="col-3"
:options="addrOptions.provinceOps"
lazy-rules
/>
<q-input
:dense="dense"
:outlined="!readonly"
:readonly="readonly"
:borderless="readonly"
hide-bottom-space
class="col-9"
:label="$t('formDialogInputHospital')"
v-model="hospitalName"
/>
<q-input
:label="$t('formDialogInputRemark')"
:dense="dense"
:outlined="!readonly"
:readonly="readonly"
:borderless="readonly"
hide-bottom-space
class="col-12"
v-model="remark"
type="textarea"
/>
<q-select
id="select-province"
:dense="dense"
:readonly="readonly"
:outlined="readonly ? false : outlined"
:hide-dropdown-icon="readonly"
:borderless="readonly"
hide-bottom-space
emit-value
map-options
v-model="medicalBenefitScheme"
option-value="id"
option-label="name"
:label="$t('formDialogInputMedicalBenefit')"
class="col-6"
:options="addrOptions.provinceOps"
lazy-rules
/>
<q-select
id="select-province"
:dense="dense"
:readonly="readonly"
:outlined="readonly ? false : outlined"
:hide-dropdown-icon="readonly"
:borderless="readonly"
hide-bottom-space
emit-value
map-options
v-model="insuranceCompany"
option-value="id"
option-label="name"
:label="$t('formDialogInputInsuranceCompany')"
class="col-6"
:options="addrOptions.provinceOps"
lazy-rules
/>
<VueDatePicker
utc
autoApply
:teleport="true"
v-model="coverageStartDate"
:locale="'th'"
:enableTimePicker="false"
:disabled="readonly"
class="col-3"
>
<template #year="{ value }">
{{ value + 543 }}
</template>
<template #trigger>
<q-input
id="input-birth-date"
:label="$t('formDialogInputCoverageStartDate')"
:dense="dense"
:outlined="readonly ? false : outlined"
:readonly="readonly"
:borderless="readonly"
:model-value="coverageStartDate ? dateFormat(coverageStartDate) : ''"
>
<template v-slot:prepend>
<q-icon
size="xs"
name="mdi-calendar-blank-outline"
class="cursor-pointer"
color="positive"
/>
</template>
<template v-slot:append>
<q-icon
v-if="coverageStartDate && !readonly"
name="mdi-close"
class="cursor-pointer"
size="xs"
@click="coverageStartDate = undefined"
/>
</template>
</q-input>
</template>
</VueDatePicker>
<VueDatePicker
utc
autoApply
:teleport="true"
v-model="coverageExpireDate"
:locale="'th'"
:enableTimePicker="false"
:disabled="readonly"
class="col-3"
>
<template #year="{ value }">
{{ value + 543 }}
</template>
<template #trigger>
<q-input
id="input-birth-date"
:label="$t('formDialogInputCoverageExpiretDate')"
:dense="dense"
:outlined="readonly ? false : outlined"
:readonly="readonly"
:borderless="readonly"
:model-value="
coverageExpireDate ? dateFormat(coverageExpireDate) : ''
"
>
<template v-slot:prepend>
<q-icon
size="xs"
name="mdi-calendar-blank-outline"
class="cursor-pointer"
color="positive"
/>
</template>
<template v-slot:append>
<q-icon
v-if="coverageExpireDate && !readonly"
name="mdi-close"
class="cursor-pointer"
size="xs"
@click="coverageExpireDate = undefined"
/>
</template>
</q-input>
</template>
</VueDatePicker>
</div>
<q-separator
v-if="separator"
class="col-12 q-mt-xl q-mb-md"
style="padding-block: 0.5px"
/>
</template>
<style scoped></style>

View file

@ -15,6 +15,8 @@ defineProps<{
noFooter?: boolean;
noAppBox?: boolean;
maxWidth?: number;
employee?: boolean;
noAddress?: boolean;
submit?: (...args: unknown[]) => void;
close?: (...args: unknown[]) => void;
}>();
@ -26,6 +28,9 @@ const provinceId = defineModel<string | null | undefined>('provinceId');
const districtId = defineModel<string | null | undefined>('districtId');
const subDistrictId = defineModel<string | null | undefined>('subDistrictId');
const zipCode = defineModel<string>('zipCode', { default: '' });
const sameWithEmployer = defineModel<boolean>('sameWithEmployer');
const employeeTab = defineModel<string>('employeeTab');
const tabsList = defineModel<{ name: string; label: string }[]>('tabsList');
</script>
<template>
<q-dialog v-model="modal" @hide="close">
@ -79,8 +84,35 @@ const zipCode = defineModel<string>('zipCode', { default: '' });
<!-- body -->
<div
class="row form-body q-pa-lg"
:class="{ dark: $q.dark.isActive }"
v-if="tabsList && tabsList.length > 0"
class="row surface-2 q-px-md q-pt-md full-width"
style="border-bottom: 1px solid var(--brand-1)"
>
<q-tabs
dense
class="app-text-muted cancel-overflow"
v-model="employeeTab"
content-class="content-tab"
active-class="active-tab"
indicator-color="transparent"
>
<q-tab
v-for="tab in tabsList"
v-bind:key="tab.name"
class="content-tab text-capitalize"
:name="tab.name"
:label="$t(tab.label)"
style="z-index: 999"
/>
</q-tabs>
</div>
<div
class="row q-pa-lg"
:class="{
dark: $q.dark.isActive,
'surface-2': !employee,
'surface-tab': employee,
}"
:style="$q.screen.gt.sm ? '' : 'overflow-y: auto; max-height: 75vh'"
>
<!-- prepend -->
@ -96,6 +128,8 @@ const zipCode = defineModel<string>('zipCode', { default: '' });
<slot name="body"></slot>
</div>
<slot></slot>
<!-- center -->
<AppBox
v-if="!noAppBox"
@ -114,6 +148,7 @@ const zipCode = defineModel<string>('zipCode', { default: '' });
<FormAddress
dense
outlined
:employee="employee"
:title="titleFormAddress"
:separator="addressSeparator"
v-model:address="address"
@ -122,9 +157,10 @@ const zipCode = defineModel<string>('zipCode', { default: '' });
v-model:districtId="districtId"
v-model:subDistrictId="subDistrictId"
v-model:zipCode="zipCode"
v-model:same-with-employer="sameWithEmployer"
:addressTitle="addressTitle || ''"
:addressTitleEN="addressTitleEN || ''"
v-if="!$slots.address"
v-if="!$slots.address && !noAddress"
/>
</slot>
<slot name="qr-code"></slot>
@ -145,27 +181,32 @@ const zipCode = defineModel<string>('zipCode', { default: '' });
<!-- footer -->
<div
v-if="!noFooter"
class="form-footer q-py-sm q-pr-lg text-right q-gutter-x-lg"
class="form-footer q-py-sm row items-center full-width justify-between q-px-md"
>
<q-btn
dense
outline
unelevated
id="cancelBtn"
class="q-px-md app-text-negative"
:label="$t('cancel')"
@click="close"
v-close-popup
/>
<q-btn
dense
unelevated
id="submitBtn"
type="submit"
color="primary"
class="q-px-md"
:label="$t('save')"
/>
<div>
<slot name="footer"></slot>
</div>
<div class="row flex justify-end q-gutter-x-md">
<q-btn
dense
outline
unelevated
id="cancelBtn"
class="q-px-md app-text-negative"
:label="$t('cancel')"
@click="close"
v-close-popup
/>
<q-btn
dense
unelevated
id="submitBtn"
type="submit"
color="primary"
class="q-px-md"
:label="$t('save')"
/>
</div>
</div>
</q-form>
</AppBox>
@ -215,4 +256,26 @@ const zipCode = defineModel<string>('zipCode', { default: '' });
--_var-filter: grayscale(0%);
}
}
.active-tab {
color: var(--brand-1);
background-color: var(--surface-tab);
border-top: 1px solid var(--brand-1);
border-left: 1px solid var(--brand-1);
border-right: 1px solid var(--brand-1);
border-top-left-radius: var(--radius-2);
border-top-right-radius: var(--radius-2);
margin-bottom: -1.5px;
border-bottom: 3px solid var(--surface-tab);
}
.content-tab {
border-top-left-radius: var(--radius-2);
border-top-right-radius: var(--radius-2);
position: relative;
}
:deep(.q-tabs__content) {
overflow: visible;
}
</style>

View file

@ -8,6 +8,7 @@ defineProps<{
label: string;
count: number;
}[];
clickable?: boolean;
}>();
</script>
<template>
@ -18,7 +19,7 @@ defineProps<{
:key="v.label"
class="rounded"
:class="v.count === 0 ? 'disable-item' : ''"
:clickable="v.count > 0"
:clickable="v.count > 0 || clickable"
:active="selector === v.label"
:active-class="
selector === v.label

View file

@ -32,6 +32,8 @@ import {
CustomerBranch,
} from 'stores/customer/types';
import { onMounted } from 'vue';
import FormPerson from 'src/components/02_personnel-management/FormPerson.vue';
import FormEmployeeHealthCheck from 'src/components/03_customer-management/FormEmployeeHealthCheck.vue';
import { dialog } from 'src/stores/utils';
@ -75,6 +77,36 @@ const formData = ref<CustomerCreate>({
image: new File([''], 'dummy.jpg'),
});
const formDataEmployeeSameAddr = ref(false);
const formDataEmployeeTab = ref('personalInfo');
const formDataEmployee = ref({
employerId: '',
employeeId: '',
nrcNo: '',
firstName: '',
firstNameEN: '',
lastName: '',
lastNameEN: '',
nationality: '',
gender: '',
birthDate: null,
address: '',
addressEN: '',
provinceId: '',
districtId: '',
subDistrictId: '',
zipCode: '',
checkupResult: '',
checkupType: '',
provinceCheckId: '',
hospitalName: '',
remark: '',
insuranceCompany: '',
medicalBenefitScheme: '',
coverageStartDate: null,
coverageExpireDate: null,
});
const indexTab = ref<number>(0);
const statusToggle = ref<boolean>(false);
const profileSubmit = ref<boolean>(false);
@ -137,8 +169,28 @@ const customerStats = [
},
];
const employeeTab = [
{
name: 'personalInfo',
label: 'personalInfo',
},
{
name: 'healthCheck',
label: 'healthCheck',
},
{
name: 'workHistory',
label: 'workHistory',
},
{
name: 'other',
label: 'other',
},
];
const dialogCustomerType = ref<boolean>(false);
const dialogInputForm = ref<boolean>(false);
const dialogEmployee = ref<boolean>(false);
const selectorLabel = ref<string>('');
const selectorList = computed(() => [
@ -148,7 +200,7 @@ const selectorList = computed(() => [
(statsCustomerType.value?.CORP ?? 0) +
(statsCustomerType.value?.PERS ?? 0),
},
{ label: 'WORKER', count: 0 },
{ label: 'EMPLOYEE', count: 0 },
]);
const customerType = ref<
@ -162,7 +214,13 @@ function triggerCreate(type: 'customerLegalEntity' | 'customerNaturalPerson') {
}
function openDialogCustomerType() {
dialogCustomerType.value = true;
if (selectorLabel.value === 'EMPLOYER') {
dialogCustomerType.value = true;
}
if (selectorLabel.value === 'EMPLOYEE') {
dialogEmployee.value = true;
}
}
function openDialogInputForm(action: 'FORM' | 'INFO' = 'FORM', id?: string) {
@ -301,7 +359,15 @@ onMounted(async () => {
if (resultStats) statsCustomerType.value = resultStats;
console.log(resultList);
if (resultList) listCustomer.value = resultList.result;
if (
(statsCustomerType.value?.CORP ?? 0) +
(statsCustomerType.value?.PERS ?? 0) >
0
) {
selectorLabel.value = 'EMPLOYER';
}
if (resultList) listCustomer.value = resultList.result;
});
@ -316,6 +382,7 @@ onMounted(async () => {
<div v-if="isMainPage">
<div class="row full-width q-mb-md no-wrap">
<SelectorList
clickable
:list="selectorList"
v-model:selector="selectorLabel"
class="q-mr-md col-4"
@ -325,14 +392,22 @@ onMounted(async () => {
<AppBox bordered class="column full-width">
<div class="row q-pb-sm justify-between items-center">
<div class="text-weight-bold text-subtitle1">
{{ $t('customerStatTitle') }}
{{
selectorLabel === 'EMPLOYER'
? $t('customerEmployerStatTitle')
: $t('customerEmployeeStatTitle')
}}
</div>
{{ selectorLabel }}
<q-btn
id="btn-add-customer"
dense
icon="mdi-plus"
unelevated
:label="'+ ' + $t('customerAdd')"
:label="
selectorLabel === 'EMPLOYER'
? $t('customerEmployerAdd')
: $t('customerEmployeeAdd')
"
padding="4px 16px"
@click="openDialogCustomerType()"
style="background-color: var(--cyan-6); color: white"
@ -361,103 +436,110 @@ onMounted(async () => {
<!-- main -->
<AppBox bordered class="column" style="width: 100%; min-height: 70vh">
<div v-if="false" class="row q-mb-md justify-between">
<div class="col-1 self-end">
<div class="row">
<TooltipComponent
title="customerTooltipTitle"
caption="customerTooltipCaption"
imgSrc="personnel-table-"
/>
</div>
</div>
<template v-if="listCustomer && selectorLabel === 'EMPLOYER'">
<div
class="col self-center"
style="display: flex; flex-grow: 1; align-items: center"
class="row full-width customer-row"
:style="`grid-template-columns: repeat(${$q.screen.lt.sm ? '1' : '4'}, 1fr)`"
>
<AddButton
:label="'customerAdd'"
:cyanOn="true"
@trigger="openDialogCustomerType()"
<UsersDetailCardComponent
v-for="i in listCustomer"
:key="i.id"
:color="i.customerType === 'CORP' ? 'purple' : 'green'"
:metadata="{ id: '1', disabled: false }"
:badge="i.branch"
:list="{
id: i.id,
imageUrl: i.imageUrl,
type:
i.customerType === 'CORP'
? 'customerLegalEntity'
: 'customerNaturalPerson',
name: i.customerName === '' ? '-' : i.customerName,
code: i.code,
detail: [
{
label: 'customerNameTh',
value: i.customerName,
},
{
label: 'customerNameEn',
value: i.customerNameEN,
},
],
}"
@enter-card="
() => {
currentCustomerId = i.id;
isMainPage = false;
}
"
@update-card="
() => {
if (!listCustomer) return;
currentCustomerId = i.id;
assignFormData(i);
infoDrawerEdit = true;
openDialogInputForm('INFO', i.id);
}
"
@view-card="
() => {
assignFormData(i);
openDialogInputForm('INFO', i.id);
}
"
@delete-card="
dialog({
color: 'negative',
icon: 'mdi-alert',
title: $t('deleteConfirmTitle'),
actionText: $t('ok'),
persistent: true,
message: $t('deleteConfirmMessage'),
action: async () => {
await userCustomer.deleteById(i.id);
const resultList = await fetchList({ includeBranch: true });
if (resultList) listCustomer = resultList.result;
},
cancel: () => {},
})
"
/>
</div>
</div>
</template>
<div
class="row full-width customer-row"
:style="`grid-template-columns: repeat(${$q.screen.lt.sm ? '1' : '4'}, 1fr)`"
>
<UsersDetailCardComponent
v-for="i in listCustomer"
:key="i.id"
:color="i.customerType === 'CORP' ? 'purple' : 'green'"
:metadata="{ id: '1', disabled: false }"
:badge="i.branch"
:list="{
id: i.id,
imageUrl: i.imageUrl,
type:
i.customerType === 'CORP'
? 'customerLegalEntity'
: 'customerNaturalPerson',
name: i.customerName === '' ? '-' : i.customerName,
code: i.code,
detail: [
{
label: 'customerNameTh',
value: i.customerName,
},
{
label: 'customerNameEn',
value: i.customerNameEN,
},
],
}"
@enter-card="
() => {
currentCustomerId = i.id;
isMainPage = false;
}
<template v-else>
<TooltipComponent
class="self-end"
:title="
selectorLabel === 'EMPLOYER'
? 'customerEmployerTooltipTitle'
: 'customerEmployeeTooltipTitle'
"
@update-card="
() => {
if (!listCustomer) return;
currentCustomerId = i.id;
assignFormData(i);
infoDrawerEdit = true;
openDialogInputForm('INFO', i.id);
}
"
@view-card="
() => {
assignFormData(i);
openDialogInputForm('INFO', i.id);
}
"
@delete-card="
dialog({
color: 'negative',
icon: 'mdi-alert',
title: $t('deleteConfirmTitle'),
actionText: $t('ok'),
persistent: true,
message: $t('deleteConfirmMessage'),
action: async () => {
await userCustomer.deleteById(i.id);
const resultList = await fetchList({ includeBranch: true });
if (resultList) listCustomer = resultList.result;
},
cancel: () => {},
})
:caption="
selectorLabel === 'EMPLOYER'
? 'customerEmployerTooltipCaption'
: 'customerEmployeeTooltipCaption'
"
imgSrc="personnel-table-"
/>
</div>
<div class="row items-center justify-center" style="flex-grow: 1">
<AddButton
:label="
selectorLabel === 'EMPLOYER'
? 'customerEmployerAdd'
: 'customerEmployeeAdd'
"
@trigger="() => openDialogCustomerType()"
/>
</div>
</template>
</AppBox>
</div>
<div v-else>
@ -497,7 +579,7 @@ onMounted(async () => {
<FormDialog
v-model:modal="dialogInputForm"
:title="`เพิ่มนายจ้าง`"
:title="$t('customerEmployerAdd')"
:customer-label="customerType"
:submit="
() => {
@ -643,6 +725,82 @@ onMounted(async () => {
</template>
</FormDialog>
<FormDialog
employee
:noAddress="formDataEmployeeTab !== 'personalInfo'"
v-model:tabs-list="employeeTab"
v-model:employee-tab="formDataEmployeeTab"
v-model:modal="dialogEmployee"
v-model:same-with-employer="formDataEmployeeSameAddr"
v-model:address="formDataEmployee.address"
v-model:addressEN="formDataEmployee.addressEN"
v-model:provinceId="formDataEmployee.provinceId"
v-model:districtId="formDataEmployee.districtId"
v-model:subDistrictId="formDataEmployee.subDistrictId"
v-model:zipCode="formDataEmployee.zipCode"
:title="$t('customerEmployeeAdd')"
:submit="
() => {
onSubmit();
}
"
:close="() => {}"
>
<template #prepend>
<ProfileUpload
v-model:url-profile="profileUrl"
v-model:status-toggle="statusToggle"
v-model:profile-submit="profileSubmit"
@input-file="inputFile.click()"
/>
</template>
<template #person>
<FormPerson
v-if="formDataEmployeeTab === 'personalInfo'"
dense
outlined
employee
separator
v-model:firstName="formDataEmployee.firstName"
v-model:lastName="formDataEmployee.lastName"
v-model:firstNameEN="formDataEmployee.firstNameEN"
v-model:lastNameEN="formDataEmployee.lastNameEN"
v-model:gender="formDataEmployee.gender"
v-model:birthDate="formDataEmployee.birthDate"
v-model:nationality="formDataEmployee.nationality"
/>
<FormEmployeeHealthCheck
v-if="formDataEmployeeTab === 'healthCheck'"
dense
outlined
v-model:checkup-result="formDataEmployee.checkupResult"
v-model:checkup-type="formDataEmployee.checkupType"
v-model:province-id="formDataEmployee.provinceCheckId"
v-model:hospital-name="formDataEmployee.hospitalName"
v-model:remark="formDataEmployee.remark"
v-model:insurance-company="formDataEmployee.insuranceCompany"
v-model:medical-benefit-scheme="formDataEmployee.medicalBenefitScheme"
v-model:coverage-start-date="formDataEmployee.coverageStartDate"
v-model:coverage-expire-date="formDataEmployee.coverageExpireDate"
/>
</template>
<template #information>
<BasicInformation
v-if="formDataEmployeeTab === 'personalInfo'"
employee
dense
outlined
separator
:type-customer="customerType"
v-model:customer-name="formData.customerName"
v-model:customer-name-en="formData.customerNameEN"
v-model:tax-no="formData.taxNo"
/>
</template>
</FormDialog>
<DrawerInfo
title="บริษัททดสอบ"
v-model:drawer-open="infoDrawer"