852 lines
26 KiB
Vue
852 lines
26 KiB
Vue
<script setup lang="ts">
|
|
import { ref, watch, onMounted, nextTick, reactive } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useQuasar } from 'quasar';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
import { canAccess } from 'stores/utils';
|
|
|
|
import type { District, Province, SubDistrict } from 'src/stores/address';
|
|
import useCustomerStore from 'stores/customer';
|
|
import useEmployeeStore from 'stores/employee';
|
|
import useAddressStore from 'src/stores/address';
|
|
import useFlowStore from 'stores/flow';
|
|
import { dialog } from 'stores/utils';
|
|
import { useNavigator } from 'src/stores/navigator';
|
|
import { Status } from 'stores/types';
|
|
import {
|
|
CustomerStats,
|
|
Customer,
|
|
CustomerBranch,
|
|
CustomerType,
|
|
} from 'stores/customer/types';
|
|
|
|
import { SaveButton } from 'components/button';
|
|
import TabCustomer from './TabCustomer.vue';
|
|
import FloatingActionButton from 'components/FloatingActionButton.vue';
|
|
import StatCardComponent from 'components/StatCardComponent.vue';
|
|
import BranchPage from './BranchPage.vue';
|
|
import SelectBusinessType from 'src/components/shared/select/SelectBusinessType.vue';
|
|
import AdvanceSearch from 'src/components/shared/AdvanceSearch.vue';
|
|
import TabEmployee from './TabEmployee.vue';
|
|
import SelectInput from 'src/components/shared/SelectInput.vue';
|
|
|
|
import { columnsCustomer, columnsEmployee } from './constant';
|
|
import { useCustomerForm, useEmployeeForm } from './form';
|
|
import { storeToRefs } from 'pinia';
|
|
|
|
const { t, locale } = useI18n();
|
|
const $q = useQuasar();
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
const flowStore = useFlowStore();
|
|
const navigatorStore = useNavigator();
|
|
const addressStore = useAddressStore();
|
|
const customerStore = useCustomerStore();
|
|
const employeeStore = useEmployeeStore();
|
|
const customerFormStore = useCustomerForm();
|
|
const employeeFormStore = useEmployeeForm();
|
|
|
|
const { state: customerFormState, currentFormData: customerFormData } =
|
|
storeToRefs(customerFormStore);
|
|
const { state: employeeFormState, statusEmployeeCreate } =
|
|
storeToRefs(employeeFormStore);
|
|
|
|
// NOTE: Component ref
|
|
const refTabCustomer = ref<InstanceType<typeof TabCustomer>>();
|
|
const refTabEmployee = ref<InstanceType<typeof TabEmployee>>();
|
|
|
|
// NOTE: Page Data
|
|
const currentCustomer = ref<Customer>();
|
|
|
|
// NOTE: Page State
|
|
const hideStats = ref(false);
|
|
const gridView = ref(false);
|
|
const employeeStats = ref(0);
|
|
const inputSearch = ref('');
|
|
const filterBusinessType = ref('');
|
|
const searchDate = ref<string[]>([]);
|
|
const currentTab = ref<'employer' | 'employee'>('employer');
|
|
const currentStatus = ref<Status | 'All'>('All');
|
|
const customerTypeSelected = ref<{
|
|
label: string;
|
|
value: 'all' | 'customerLegalEntity' | 'customerNaturalPerson';
|
|
}>({
|
|
label: t('general.all'),
|
|
value: 'all',
|
|
});
|
|
const statsCustomerType = ref<CustomerStats>({
|
|
CORP: 0,
|
|
PERS: 0,
|
|
});
|
|
const fieldDisplayCustomer = ref<
|
|
{
|
|
label: string;
|
|
value: string;
|
|
}[]
|
|
>(
|
|
columnsCustomer
|
|
.filter((v) => v.name !== 'action')
|
|
.map((v) => ({ label: v.label, value: v.name })),
|
|
);
|
|
const fieldDisplayEmployee = ref<
|
|
{
|
|
label: string;
|
|
value: string;
|
|
}[]
|
|
>(
|
|
columnsEmployee
|
|
.filter((v) => v.name !== 'action')
|
|
.map((v) => ({ label: v.label, value: v.name })),
|
|
);
|
|
const fieldSelected = ref<string[]>(
|
|
[
|
|
...columnsEmployee.map((v) => v.name),
|
|
...columnsCustomer.map((v) => v.name),
|
|
].filter((v, index, self) => self.indexOf(v) === index),
|
|
);
|
|
const filterAddress = reactive({
|
|
provinceId: '',
|
|
districtId: '',
|
|
subDistrictId: '',
|
|
});
|
|
const addressOpt = reactive<{
|
|
provinceOpt: Province[];
|
|
districtOpt: District[];
|
|
subDistrictOpt: SubDistrict[];
|
|
}>({
|
|
provinceOpt: [],
|
|
districtOpt: [],
|
|
subDistrictOpt: [],
|
|
});
|
|
const fieldCustomer = [
|
|
'all',
|
|
'customerLegalEntity',
|
|
'customerNaturalPerson',
|
|
] as const;
|
|
|
|
// image
|
|
const imageList = ref<{ selectedImage: string; list: string[] }>();
|
|
const branch = ref<CustomerBranch[]>();
|
|
|
|
async function triggerChangeStatus(
|
|
id: string,
|
|
status: string,
|
|
employeeName?: string,
|
|
) {
|
|
return await new Promise((resolve, reject) => {
|
|
dialog({
|
|
color: status !== 'INACTIVE' ? 'warning' : 'info',
|
|
icon:
|
|
status !== 'INACTIVE' ? 'mdi-alert' : 'mdi-message-processing-outline',
|
|
title: t('dialog.title.confirmChangeStatus'),
|
|
actionText:
|
|
status !== 'INACTIVE' ? t('general.close') : t('general.open'),
|
|
message:
|
|
status !== 'INACTIVE'
|
|
? t('dialog.message.confirmChangeStatusOff')
|
|
: t('dialog.message.confirmChangeStatusOn'),
|
|
action: async () => {
|
|
if (currentTab.value === 'employee') {
|
|
await refTabEmployee.value
|
|
?.toggleStatusEmployee(
|
|
id,
|
|
status === 'INACTIVE' ? false : true,
|
|
employeeName,
|
|
)
|
|
.then(resolve)
|
|
.catch(reject);
|
|
} else {
|
|
await refTabCustomer.value
|
|
?.toggleStatusCustomer(id, status === 'INACTIVE' ? false : true)
|
|
.then(resolve)
|
|
.catch(reject);
|
|
}
|
|
},
|
|
cancel: () => {},
|
|
});
|
|
});
|
|
}
|
|
|
|
async function createCustomerForm(customerType: 'CORP' | 'PERS') {
|
|
customerFormState.value.dialogModal = true;
|
|
customerFormState.value.dialogType = 'create';
|
|
customerFormData.value.customerType =
|
|
customerType === 'CORP' ? CustomerType.Corporate : CustomerType.Person;
|
|
}
|
|
|
|
function createEmployeeForm() {
|
|
employeeFormStore.resetFormDataEmployee(true);
|
|
employeeFormState.value.dialogType = 'create';
|
|
employeeFormState.value.dialogModal = true;
|
|
employeeFormState.value.isEmployeeEdit = true;
|
|
}
|
|
|
|
async function fetchImageList(
|
|
id: string,
|
|
selectedName: string,
|
|
type: 'customer' | 'employee',
|
|
) {
|
|
const res =
|
|
type === 'customer'
|
|
? await customerStore.fetchImageListById(id)
|
|
: await employeeStore.fetchImageListById(id);
|
|
imageList.value = {
|
|
selectedImage: selectedName,
|
|
list: res.map((n: string) => `${type}/${id}/image/${n}`),
|
|
};
|
|
|
|
return res;
|
|
}
|
|
|
|
async function triggerExport() {
|
|
switch (currentTab.value) {
|
|
case 'employer':
|
|
customerStore.customerExport({
|
|
pageSize: 10000,
|
|
startDate: searchDate.value[0],
|
|
endDate: searchDate.value[1],
|
|
businessType: filterBusinessType.value,
|
|
province: filterAddress.provinceId || undefined,
|
|
district: filterAddress.districtId || undefined,
|
|
subDistrict: filterAddress.subDistrictId || undefined,
|
|
customerType:
|
|
customerTypeSelected.value.value === 'customerLegalEntity'
|
|
? CustomerType.Corporate
|
|
: customerTypeSelected.value.value === 'customerNaturalPerson'
|
|
? CustomerType.Person
|
|
: undefined,
|
|
});
|
|
|
|
break;
|
|
|
|
case 'employee':
|
|
employeeStore.employeeExport({
|
|
pageSize: 10000,
|
|
startDate: searchDate.value[0],
|
|
endDate: searchDate.value[1],
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
|
|
async function fetchAddressData(type: 'province' | 'district' | 'subDistrict') {
|
|
let result;
|
|
|
|
if (type === 'province') {
|
|
result = await addressStore.fetchProvince();
|
|
if (result) addressOpt.provinceOpt = result;
|
|
}
|
|
|
|
if (type === 'district') {
|
|
if (!filterAddress.provinceId) return;
|
|
result = await addressStore.fetchDistrictByProvinceId(
|
|
filterAddress.provinceId,
|
|
);
|
|
if (result) addressOpt.districtOpt = result;
|
|
}
|
|
|
|
if (type === 'subDistrict') {
|
|
if (!filterAddress.districtId) return;
|
|
result = await addressStore.fetchSubDistrictByProvinceId(
|
|
filterAddress.districtId,
|
|
);
|
|
if (result) addressOpt.subDistrictOpt = result;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
async function handleSelectAddress(type: 'province' | 'district') {
|
|
if (type === 'province') {
|
|
filterAddress.districtId = filterAddress.subDistrictId = '';
|
|
addressOpt.districtOpt = addressOpt.subDistrictOpt = [];
|
|
|
|
await fetchAddressData('district');
|
|
}
|
|
|
|
if (type === 'district') {
|
|
filterAddress.subDistrictId = '';
|
|
await fetchAddressData('subDistrict');
|
|
}
|
|
}
|
|
|
|
async function init() {
|
|
navigatorStore.current.title = 'menu.customer';
|
|
navigatorStore.current.path = [
|
|
{
|
|
text: 'menu.customerCaption',
|
|
i18n: true,
|
|
handler: () => router.push('/customer-management'),
|
|
},
|
|
];
|
|
|
|
gridView.value = $q.screen.lt.md ? true : false;
|
|
|
|
if (route.query.tab === 'customer') {
|
|
currentTab.value = 'employer';
|
|
if (route.query.id)
|
|
refTabCustomer.value?.openSpecificCustomer(route.query.id as string);
|
|
} else if (route.query.tab === 'employee') {
|
|
currentTab.value = 'employee';
|
|
if (route.query.id)
|
|
refTabEmployee.value?.openSpecificEmployee(route.query.id as string);
|
|
}
|
|
|
|
if (
|
|
route.name === 'CustomerBranchManagement' &&
|
|
typeof route.params.customerId === 'string'
|
|
) {
|
|
const _data = await customerStore.fetchById(route.params.customerId);
|
|
|
|
if (_data) {
|
|
currentCustomer.value = _data;
|
|
navigatorStore.current.path.push({
|
|
text: `${
|
|
_data.customerType === 'CORP'
|
|
? _data.branch[0].registerName
|
|
: locale.value === 'eng'
|
|
? _data.branch[0].firstNameEN + ' ' + _data.branch[0].lastNameEN
|
|
: _data.branch[0].firstName + ' ' + _data.branch[0].lastName
|
|
}`,
|
|
i18n: false,
|
|
});
|
|
} else {
|
|
router.push('/customer-management');
|
|
}
|
|
}
|
|
|
|
await fetchAddressData('province');
|
|
|
|
flowStore.rotate();
|
|
}
|
|
|
|
watch(() => route.name, init);
|
|
|
|
watch(locale, () => {
|
|
customerTypeSelected.value = {
|
|
label: `${customerTypeSelected.value.label}`,
|
|
value: customerTypeSelected.value?.value,
|
|
};
|
|
});
|
|
|
|
watch(
|
|
() => $q.screen.lt.md,
|
|
() => $q.screen.lt.md && (gridView.value = true),
|
|
);
|
|
|
|
onMounted(async () => await init());
|
|
</script>
|
|
|
|
<template>
|
|
<FloatingActionButton
|
|
style="z-index: 999"
|
|
:hide-icon="currentTab === 'employee'"
|
|
v-if="$route.name === 'CustomerManagement' && canAccess('customer', 'edit')"
|
|
@click="
|
|
() => {
|
|
if (currentTab === 'employee') {
|
|
createEmployeeForm();
|
|
}
|
|
}
|
|
"
|
|
>
|
|
<q-fab-action
|
|
v-if="currentTab === 'employer'"
|
|
id="add-customer-legal-entity"
|
|
style="color: white; background-color: hsla(var(--violet-11-hsl))"
|
|
@click="createCustomerForm('CORP')"
|
|
padding="xs"
|
|
icon="mdi-office-building-outline"
|
|
:label="$t('general.add') + ' ' + $t('customer.employerLegalEntity')"
|
|
external-label
|
|
label-position="left"
|
|
/>
|
|
<q-fab-action
|
|
v-if="currentTab === 'employer'"
|
|
id="add-customer-natural-person"
|
|
:label="$t('general.add') + ' ' + $t('customer.employerNaturalPerson')"
|
|
external-label
|
|
label-position="left"
|
|
@click="createCustomerForm('PERS')"
|
|
style="color: white; background-color: hsla(var(--teal-10-hsl))"
|
|
padding="xs"
|
|
icon="mdi-account-plus-outline"
|
|
/>
|
|
</FloatingActionButton>
|
|
|
|
<div class="column full-height no-wrap">
|
|
<!-- หน้า table -->
|
|
<div
|
|
v-show="$route.name === 'CustomerManagement'"
|
|
class="column full-height"
|
|
>
|
|
<div class="text-body-2 text-weight-medium q-mb-xs flex items-center">
|
|
{{ $t('general.dataSum') }}
|
|
<q-badge
|
|
rounded
|
|
class="q-ml-sm"
|
|
style="
|
|
background-color: hsla(var(--info-bg) / 0.15);
|
|
color: hsl(var(--info-bg));
|
|
"
|
|
>
|
|
{{
|
|
currentTab === 'employer'
|
|
? statsCustomerType.PERS + statsCustomerType.CORP
|
|
: employeeStats
|
|
}}
|
|
</q-badge>
|
|
<q-btn
|
|
class="q-ml-sm"
|
|
icon="mdi-pin-outline"
|
|
color="primary"
|
|
size="sm"
|
|
flat
|
|
dense
|
|
rounded
|
|
@click="hideStats = !hideStats"
|
|
:style="hideStats ? 'rotate: 90deg' : ''"
|
|
style="transition: 0.1s ease-in-out"
|
|
/>
|
|
</div>
|
|
|
|
<!-- stat -->
|
|
<div class="row full-width">
|
|
<transition name="slide">
|
|
<div v-if="!hideStats" class="col-12 q-mb-md">
|
|
<div class="scroll">
|
|
<StatCardComponent
|
|
v-if="statsCustomerType"
|
|
label-i18n
|
|
:branch="
|
|
currentTab === 'employer'
|
|
? [
|
|
{
|
|
count: statsCustomerType.CORP ?? 0,
|
|
label: 'customer.employerLegalEntity',
|
|
icon: 'mdi-office-building-outline',
|
|
color: 'purple',
|
|
},
|
|
{
|
|
count: statsCustomerType.PERS ?? 0,
|
|
label: 'customer.employerNaturalPerson',
|
|
icon: 'mdi-account-outline',
|
|
color: 'green',
|
|
},
|
|
]
|
|
: [
|
|
{
|
|
label: 'customer.employee',
|
|
count: employeeStats,
|
|
icon: 'mdi-account-outline',
|
|
color: 'pink',
|
|
},
|
|
]
|
|
"
|
|
:dark="$q.dark.isActive"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</transition>
|
|
</div>
|
|
|
|
<!-- main -->
|
|
<div
|
|
class="surface-2 bordered rounded col column full-width overflow-hidden"
|
|
>
|
|
<!-- tabs -->
|
|
<div class="column">
|
|
<div
|
|
class="row q-px-md q-py-sm justify-between full-width surface-3 bordered-b"
|
|
>
|
|
<q-input
|
|
for="input-search"
|
|
outlined
|
|
dense
|
|
:label="$t('general.search')"
|
|
class="col col-md-3 q-mr-sm"
|
|
:bg-color="$q.dark.isActive ? 'dark' : 'white'"
|
|
v-model="inputSearch"
|
|
debounce="200"
|
|
>
|
|
<template #prepend>
|
|
<q-icon name="mdi-magnify" />
|
|
</template>
|
|
<template v-slot:append>
|
|
<q-separator vertical inset class="q-mr-xs" />
|
|
<AdvanceSearch
|
|
v-model="searchDate"
|
|
:active="
|
|
($q.screen.lt.md && currentStatus !== 'All') ||
|
|
!!filterBusinessType ||
|
|
!!filterAddress.provinceId
|
|
"
|
|
>
|
|
<div
|
|
v-if="$q.screen.lt.md"
|
|
class="q-mt-sm text-weight-medium"
|
|
>
|
|
{{ $t('general.status') }}
|
|
</div>
|
|
<q-select
|
|
v-if="$q.screen.lt.md"
|
|
id="select-status"
|
|
for="select-status"
|
|
v-model="currentStatus"
|
|
outlined
|
|
dense
|
|
autocomplete="off"
|
|
option-value="value"
|
|
option-label="label"
|
|
map-options
|
|
emit-value
|
|
:options="[
|
|
{ label: $t('general.all'), value: 'All' },
|
|
{ label: $t('status.ACTIVE'), value: 'ACTIVE' },
|
|
{ label: $t('status.INACTIVE'), value: 'INACTIVE' },
|
|
]"
|
|
/>
|
|
<template v-if="currentTab === 'employer'">
|
|
<div class="q-mt-sm text-weight-medium">
|
|
{{ $t('customer.form.businessType') }}
|
|
</div>
|
|
<SelectBusinessType
|
|
v-model:value="filterBusinessType"
|
|
clearable
|
|
/>
|
|
<div class="q-mt-sm text-weight-medium">
|
|
{{ $t('customer.form.address') }}
|
|
</div>
|
|
<SelectInput
|
|
clearable
|
|
v-model="filterAddress.provinceId"
|
|
option-value="id"
|
|
:label="$t('form.province')"
|
|
:option="addressOpt.provinceOpt"
|
|
:option-label="locale === 'eng' ? 'nameEN' : 'name'"
|
|
@update:model-value="handleSelectAddress('province')"
|
|
/>
|
|
<SelectInput
|
|
clearable
|
|
class="q-mt-sm"
|
|
option-value="id"
|
|
v-model="filterAddress.districtId"
|
|
:option="addressOpt.districtOpt"
|
|
:label="$t('form.district')"
|
|
:option-label="locale === 'eng' ? 'nameEN' : 'name'"
|
|
@update:model-value="handleSelectAddress('district')"
|
|
/>
|
|
<SelectInput
|
|
clearable
|
|
class="q-mt-sm"
|
|
option-value="id"
|
|
v-model="filterAddress.subDistrictId"
|
|
:option="addressOpt.subDistrictOpt"
|
|
:label="$t('form.subDistrict')"
|
|
:option-label="locale === 'eng' ? 'nameEN' : 'name'"
|
|
/>
|
|
</template>
|
|
</AdvanceSearch>
|
|
</template>
|
|
</q-input>
|
|
|
|
<SaveButton
|
|
icon-only
|
|
class="q-mr-auto"
|
|
:icon="'material-symbols:download'"
|
|
@click.stop="triggerExport()"
|
|
/>
|
|
|
|
<div class="row col-md-5" style="white-space: nowrap">
|
|
<q-select
|
|
v-if="$q.screen.gt.sm"
|
|
id="select-status"
|
|
for="select-status"
|
|
v-model="currentStatus"
|
|
outlined
|
|
dense
|
|
autocomplete="off"
|
|
option-value="value"
|
|
option-label="label"
|
|
:class="{ 'offset-md-5': gridView }"
|
|
class="col"
|
|
map-options
|
|
emit-value
|
|
:hide-dropdown-icon="$q.screen.lt.sm"
|
|
:options="[
|
|
{ label: $t('general.all'), value: 'All' },
|
|
{ label: $t('status.ACTIVE'), value: 'ACTIVE' },
|
|
{ label: $t('status.INACTIVE'), value: 'INACTIVE' },
|
|
]"
|
|
/>
|
|
<q-select
|
|
v-if="!gridView"
|
|
id="select-field"
|
|
for="select-field"
|
|
class="q-ml-sm col"
|
|
:options="
|
|
currentTab === 'employer'
|
|
? gridView
|
|
? fieldDisplayCustomer.filter((v) => {
|
|
return (
|
|
v.value !== 'orderNumber' &&
|
|
v.value !== 'titleName' &&
|
|
v.value !== 'address' &&
|
|
v.value !== 'contactName'
|
|
);
|
|
})
|
|
: fieldDisplayCustomer
|
|
: fieldDisplayEmployee
|
|
"
|
|
:display-value="$t('general.displayField')"
|
|
:hide-dropdown-icon="$q.screen.lt.sm"
|
|
v-model="fieldSelected"
|
|
:option-label="(l) => $t(l.label)"
|
|
option-value="value"
|
|
autocomplete="off"
|
|
map-options
|
|
emit-value
|
|
outlined
|
|
multiple
|
|
dense
|
|
/>
|
|
|
|
<q-btn-toggle
|
|
id="btn-mode"
|
|
v-model="gridView"
|
|
dense
|
|
class="no-shadow bordered rounded surface-1 q-ml-sm"
|
|
:toggle-color="$q.dark.isActive ? 'grey-9' : 'grey-2'"
|
|
size="xs"
|
|
:options="[
|
|
{ value: true, slot: 'folder' },
|
|
{ value: false, slot: 'list' },
|
|
]"
|
|
>
|
|
<template v-slot:folder>
|
|
<q-icon
|
|
id="icon-mode-grid"
|
|
name="mdi-view-grid-outline"
|
|
size="16px"
|
|
class="q-px-sm q-py-xs rounded"
|
|
:style="{
|
|
color: $q.dark.isActive
|
|
? gridView
|
|
? '#C9D3DB '
|
|
: '#787B7C'
|
|
: gridView
|
|
? '#787B7C'
|
|
: '#C9D3DB',
|
|
}"
|
|
/>
|
|
</template>
|
|
<template v-slot:list>
|
|
<q-icon
|
|
id="icon-mode-list"
|
|
name="mdi-format-list-bulleted"
|
|
class="q-px-sm q-py-xs rounded"
|
|
size="16px"
|
|
:style="{
|
|
color: $q.dark.isActive
|
|
? gridView === false
|
|
? '#C9D3DB'
|
|
: '#787B7C'
|
|
: gridView === false
|
|
? '#787B7C'
|
|
: '#C9D3DB',
|
|
}"
|
|
/>
|
|
</template>
|
|
</q-btn-toggle>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="surface-2 bordered-b q-px-md">
|
|
<q-tabs
|
|
dense
|
|
v-model="currentTab"
|
|
align="left"
|
|
class="full-height"
|
|
active-color="info"
|
|
>
|
|
<q-tab
|
|
name="employer"
|
|
class="text-capitalize"
|
|
id="tab-employer"
|
|
@click="
|
|
() => {
|
|
inputSearch = '';
|
|
currentStatus = 'All';
|
|
flowStore.rotate();
|
|
}
|
|
"
|
|
>
|
|
<div
|
|
class="row"
|
|
:class="
|
|
currentTab === 'employer' ? 'text-bold' : 'app-text-muted'
|
|
"
|
|
>
|
|
{{ $t('customer.employer') }}
|
|
</div>
|
|
</q-tab>
|
|
<q-tab
|
|
name="employee"
|
|
id="tab-employee"
|
|
class="text-capitalize"
|
|
@click="
|
|
() => {
|
|
inputSearch = '';
|
|
currentStatus = 'All';
|
|
flowStore.rotate();
|
|
}
|
|
"
|
|
>
|
|
<div
|
|
class="row"
|
|
:class="
|
|
currentTab === 'employee' ? 'text-bold' : 'app-text-muted'
|
|
"
|
|
>
|
|
{{ $t('customer.employee') }}
|
|
</div>
|
|
</q-tab>
|
|
</q-tabs>
|
|
</div>
|
|
|
|
<div
|
|
v-if="$q.screen.lt.md && currentTab === 'employer'"
|
|
class="q-px-md row q-gutter-x-sm items-center"
|
|
>
|
|
<nav
|
|
class="col rounded q-pa-sm text-center app-text-muted text-caption"
|
|
:class="{
|
|
'active-tab-sm': customerTypeSelected.value === v,
|
|
'bordered surface-1': customerTypeSelected.value !== v,
|
|
}"
|
|
v-for="v in fieldCustomer"
|
|
:key="v"
|
|
@click="customerTypeSelected = { label: v, value: v }"
|
|
id="`btn-sm-${v}`"
|
|
>
|
|
{{
|
|
$t(
|
|
{
|
|
all: 'general.all',
|
|
customerLegalEntity: 'customer.employerLegalEntity',
|
|
customerNaturalPerson: 'customer.employerNaturalPerson',
|
|
}[v],
|
|
)
|
|
}}
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- body -->
|
|
<TabCustomer
|
|
v-if="currentTab === 'employer'"
|
|
ref="refTabCustomer"
|
|
v-model:customer-type-selected="customerTypeSelected"
|
|
v-model:stats-customer-type="statsCustomerType"
|
|
v-model:img-list="imageList"
|
|
:filter-address="filterAddress"
|
|
:filter-business-type="filterBusinessType"
|
|
:gridView
|
|
:searchDate
|
|
:currentTab
|
|
:inputSearch
|
|
:currentStatus
|
|
:fieldSelected
|
|
:fetchImageList
|
|
:triggerChangeStatus
|
|
/>
|
|
|
|
<TabEmployee
|
|
v-if="currentTab === 'employee'"
|
|
ref="refTabEmployee"
|
|
v-model:employee-stats="employeeStats"
|
|
v-model:img-list="imageList"
|
|
:gridView
|
|
:searchDate
|
|
:currentTab
|
|
:inputSearch
|
|
:currentStatus
|
|
:fieldSelected
|
|
:fetchImageList
|
|
:triggerChangeStatus
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- หน้า id ลูกค้า -->
|
|
<div
|
|
class="col column rounded bordered"
|
|
style="overflow: hidden"
|
|
v-if="$route.name === 'CustomerBranchManagement'"
|
|
>
|
|
<BranchPage
|
|
v-model:status-employee-create="statusEmployeeCreate"
|
|
v-model:status-employee-edit="employeeFormState.drawerModal"
|
|
v-if="currentCustomer"
|
|
:customer-type="currentCustomer.customerType"
|
|
:current-customer-name="
|
|
currentCustomer.customerType === 'PERS'
|
|
? locale === 'eng'
|
|
? `${currentCustomer.branch[0]?.firstNameEN} ${currentCustomer.branch[0]?.lastNameEN}`
|
|
: `${currentCustomer.branch[0]?.firstName} ${currentCustomer.branch[0]?.lastName}`
|
|
: locale === 'eng'
|
|
? currentCustomer.branch[0]?.registerNameEN
|
|
: currentCustomer.branch[0]?.registerName
|
|
"
|
|
:current-citizen-id="currentCustomer.branch[0]?.citizenId"
|
|
:count-employee="currentCustomer._count.employee"
|
|
:selected-image="currentCustomer.selectedImage"
|
|
:gender="currentCustomer.branch[0]?.gender"
|
|
v-model:customer-id="currentCustomer.id"
|
|
v-model:mode-view="gridView"
|
|
@back="$router.push('/customer-management')"
|
|
@add-employee="
|
|
async (currentBranch) => {
|
|
createEmployeeForm();
|
|
await nextTick();
|
|
employeeFormState.currentBranchId = currentBranch.id;
|
|
}
|
|
"
|
|
v-model:branch="branch"
|
|
v-model:current-customer-url-image="currentCustomer.imageUrl"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.slide-enter-active {
|
|
transition: all 0.1s ease-out;
|
|
}
|
|
|
|
.slide-leave-active {
|
|
transition: all 0.1s cubic-bezier(1, 0.5, 0.8, 1);
|
|
}
|
|
|
|
.slide-enter-from,
|
|
.slide-leave-to {
|
|
transform: translateY(-20px);
|
|
opacity: 0;
|
|
}
|
|
|
|
.status-active {
|
|
--_branch-status-color: var(--green-6-hsl);
|
|
}
|
|
|
|
.status-inactive {
|
|
--_branch-status-color: var(--stone-5-hsl);
|
|
--_branch-badge-bg: var(--stone-5-hsl);
|
|
filter: grayscale(0.5);
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.active-tab-sm {
|
|
color: hsla(var(--info-bg) / 1);
|
|
background-color: hsla(var(--info-bg) / 0.1);
|
|
}
|
|
</style>
|