refactor: เพิ่ม list ของนายจ้าง

This commit is contained in:
Net 2024-07-08 11:05:07 +07:00
parent 769106d8d3
commit ff7b4d1f76

View file

@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, ref, watch, toRaw } from 'vue';
import type { QTableProps } from 'quasar';
import useCustomerStore from 'src/stores/customer';
import useEmployeeStore from 'src/stores/employee';
@ -67,6 +68,46 @@ const useMyBranch = useMyBranchStore();
const { fetchListOptionBranch } = useMyBranch;
const columns = [
{
name: 'customerName',
align: 'left',
label: 'corporation',
field: 'customerName',
sortable: true,
},
{
name: 'customerType',
align: 'left',
label: 'type',
field: 'customerType',
sortable: true,
},
{
name: 'personName',
align: 'left',
label: 'name',
field: 'personName',
},
{
name: 'telephoneNo',
align: 'left',
label: 'telephone',
field: 'branch[0].telephoneNo',
},
{
name: 'branchEmail',
align: 'left',
label: 'formDialogInputEmail',
field: 'branch[0].email',
},
] satisfies QTableProps['columns'];
const {
create,
getStatsCustomer,
@ -130,8 +171,58 @@ const fieldSelectedCustomer = ref<{ label: string; value: string }>({
value: 'all',
});
const fieldSelected = ref();
const fieldDisplay = ref();
const fieldDisplay = ref<
{
label: string;
value: string;
}[]
>([
{
label: t('corporation'),
value: 'customerName',
},
{
label: t('type'),
value: 'customerType',
},
{
label: t('name'),
value: 'personName',
},
{
label: t('telephone'),
value: 'telephoneNo',
},
{
label: t('formDialogInputEmail'),
value: 'branchEmail',
},
]);
const fieldSelected = ref<
(
| 'customerName'
| 'customerType'
| 'personName'
| 'telephoneNo'
| 'branchEmail'
)[]
>([ 'customerName',
'customerType',
'personName',
'telephoneNo',
'branchEmail']);
const splitterModel = ref(15);
const modeView = ref(true);
const currentEmployee = ref<Employee | undefined>();
@ -774,6 +865,8 @@ async function toggleStatusEmployee(id: string, status: boolean) {
}
async function toggleStatusCustomer(id: string, status: boolean) {
await editById(id, { status: !status ? 'ACTIVE' : 'INACTIVE' });
await fetchListCustomer();
@ -1221,7 +1314,6 @@ watch(locale, () => {
watch(fieldSelectedCustomer, async () => {
let resultList;
console.log('asd');
if (fieldSelectedCustomer.value.value === 'all') {
resultList = await fetchList({ includeBranch: true });
@ -1459,12 +1551,10 @@ watch([inputSearch, currentStatus], async () => {
></q-select>
<q-select
v-if="modeView === false"
id="select-field"
for="select-field"
:options="[
{ label: 'กันว่าง 1', value: 'กันว่าง 1' },
{ label: 'กันว่าง 2', value: 'กันว่าง 2' },
]"
:options="fieldDisplay"
:display-value="$t('displayField')"
v-model="fieldSelected"
option-label="label"
@ -1643,10 +1733,363 @@ watch([inputSearch, currentStatus], async () => {
>
<div
class="row full-width customer-row"
:style="`grid-template-columns: repeat(${$q.screen.lt.sm ? '2' : $q.screen.lt.md ? '3' : $q.screen.lt.lg ? '5' : '6'}, 1fr)`"
style="min-height: 250px"
>
<UsersDetailCardComponent
<q-table
flat
bordered
:grid="modeView"
:rows="listCustomer"
:columns="columns"
card-container-class=" q-col-gutter-md"
row-key="name"
:rows-per-page-options="[0]"
hide-pagination
:visible-columns="fieldSelected"
>
<template v-slot:header="props">
<q-tr class="surface-2" :props="props">
<q-th
v-for="col in props.cols"
:key="col.name"
:props="props"
>
{{ $t(col.label) }}
</q-th>
<q-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr
:class="{
'app-text-muted': props.row.status === 'INACTIVE',
}"
:props="props"
@click="
() => {
currentCustomerName = props.row.customerName;
customerType = props.row.customerType;
currentCustomerUrlImage = props.row.imageUrl;
currentCustomerId = props.row.id;
const { branch, ...payload } = props.row;
currentCustomer = payload;
isMainPage = false;
}
"
>
<q-td
v-if="fieldSelected.includes('customerName')"
>
<div class="row items-center">
<div
:class="{
'status-active':
props.row.status !== 'INACTIVE',
'status-inactive':
props.row.status === 'INACTIVE',
'branch-card__hq': props.row.isHeadOffice,
'branch-card__br': !props.row.isHeadOffice,
}"
style="
width: 50px;
display: flex;
margin-bottom: var(--size-2);
"
>
<div class="branch-card__icon">
<q-avatar size="md">
<q-img :src="props.row.imageUrl ?? '/no-profile.png'">
<template #error>
<q-img src="/no-profile.png"/>
</template>
</q-img>
</q-avatar>
<!-- <q-icon
size="md"
style="scale: 0.8"
:name="props.row.imageUrl"
/> -->
</div>
</div>
<div class="col">
<div class="col">{{ props.row.customerName || '-' }}</div>
<div class="col app-text-muted">
{{ props.row.customerNameEN || '-' }}
</div>
</div>
</div>
</q-td>
<q-td
v-if="fieldSelected.includes('customerType')"
>
<span
class="tags"
:class="{ [`tags__${props.row.customerType === 'CORP'? 'purple' : 'green'}`]: true }"
>
{{props.row.customerType === 'CORP' ? $t('customerLegalEntity') : $t('customerNaturalPerson')}}
</span>
</q-td>
<q-td v-if="fieldSelected.includes('personName')">
{{ props.row.personName }}
</q-td>
<q-td v-if="fieldSelected.includes('telephoneNo')">
{{ props.row.branch[0].telephoneNo || '-' }}
</q-td>
<q-td
v-if="fieldSelected.includes('branchEmail')"
>
{{ props.row.branch[0].email || '-' }}
</q-td>
<q-td>
<q-btn
icon="mdi-eye"
size="sm"
dense
round
flat
@click.stop="
() => {
const { branch, ...payload } = props.row;
currentCustomer = payload;
currentCustomerId = props.row.id;
customerType = props.row.customerType;
assignFormData(props.row.id);
openDialogInputForm('INFO', props.row.id);
}
"
/>
<q-btn
icon="mdi-dots-vertical"
size="sm"
dense
round
flat
@click.stop
:key="props.row.id"
>
<q-menu class="bordered" >
<q-list v-close-popup>
<q-item
:id="`view-detail-btn-${props.row.name}-view`"
@click.stop="
() => {
const { branch, ...payload } =
props.row;
currentCustomer = payload;
currentCustomerId = props.row.id;
customerType = props.row.customerType;
assignFormData(props.row.id);
openDialogInputForm(
'INFO',
props.row.id,
);
}
"
clickable
dense
class="row q-py-sm"
style="white-space: nowrap"
>
<q-icon
name="mdi-eye-outline"
class="col-3"
size="xs"
style="color: hsl(var(--green-6-hsl))"
/>
<span
class="col-9 q-px-md flex items-center"
>
{{ $t('viewDetail') }}
</span>
</q-item>
<q-item
:id="`view-detail-btn-${props.row.name}-edit`"
clickable
dense
class="row q-py-sm"
style="white-space: nowrap"
@click="
() => {
if (!listCustomer) return;
customerType = props.row.customerType;
const { branch, ...payload } =
props.row;
currentCustomer = payload;
currentCustomerId = props.row.id;
assignFormData(props.row.id);
infoDrawerEdit = true;
openDialogInputForm(
'INFO',
props.row.id,
);
}
"
>
<q-icon
name="mdi-pencil-outline"
class="col-3"
size="xs"
style="color: hsl(var(--cyan-6-hsl))"
/>
<span
class="col-9 q-px-md flex items-center"
>
{{ $t('edit') }}
</span>
</q-item>
<q-item
:id="`view-detail-btn-${props.row.name}-delete`"
dense
:clickable="props.row.status === 'CREATED'"
class="row"
:class="{
'surface-3':
props.row.status !== 'CREATED',
'app-text-muted':
props.row.status !== 'CREATED',
}"
style="white-space: nowrap"
@click="deleteCustomerById(props.row.id)"
>
<q-icon
name="mdi-trash-can-outline"
size="xs"
class="col-3"
:class="{
'app-text-negative':
props.row.status === 'CREATED',
}"
/>
<span
class="col-9 q-px-md flex items-center"
>
{{ $t('delete') }}
</span>
</q-item>
<q-item dense>
<q-item-section class="q-py-sm">
<div class="q-pa-sm surface-2 rounded">
<q-toggle
:id="`view-detail-btn-${props.row.name}-status`"
dense
size="sm"
:label="
props.row.status !== 'INACTIVE'
? $t('switchOnLabel')
: $t('switchOffLabel')
"
@click="
async () => {
toggleStatusCustomer(
props.row.id,
props.row.status === 'ACTIVE'
? true
: false,
);
}
"
:model-value="
props.row.status !== 'INACTIVE'
"
/>
</div>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</q-td>
</q-tr>
</template>
<template v-slot:item="props">
<div class="col-3">
<PersonCard
:field-selected="fieldSelected"
history
:data="{
code: props.row.code,
name:
$i18n.locale === 'en-US'
? `${props.row.customerName} `.trim()
: `${props.row.customerNameEN} `.trim(),
img: props.row.imageUrl,
male: props.row.gender === 'male',
female: props.row.gender === 'female',
detail: [
{
icon: 'mdi-cellphone',
value: props.row.branch[0].telephoneNo,
},
{
icon: 'mdi-account',
value: props.row.personName,
},
],
}"
@history="openHistory(props.row.id)"
@update-card="
()=>{
if (!listCustomer) return;
customerType = props.row.customerType
const { branch, ...payload } = props.row
currentCustomer = payload
currentCustomerId = props.row.id
assignFormData(props.row.id)
infoDrawerEdit = true
openDialogInputForm('INFO', props.row.id)
}
"
@enter-card="()=>{
currentCustomerName = props.row.customerName;
customerType = props.row.customerType;
currentCustomerUrlImage = props.row.imageUrl;
currentCustomerId = props.row.id;
const { branch, ...payload } = props.row;
currentCustomer = payload;
isMainPage = false;
}"
@delete-card="deleteCustomerById(props.row.id)"
@toggle-status="
toggleStatusCustomer(
props.row.id,
props.row.status === 'ACTIVE' ? true : false,
);
"
/>
</div>
</template>
</q-table>
<!-- <UsersDetailCardComponent
v-for="i in listCustomer"
:key="i.id"
class="hover-card"
@ -1724,7 +2167,7 @@ watch([inputSearch, currentStatus], async () => {
);
}
"
/>
/> -->
</div>
</div>
@ -1810,40 +2253,7 @@ watch([inputSearch, currentStatus], async () => {
class="col column justify-between q-px-md q-pt-md scroll"
v-if="listEmployee.length !== 0"
>
<!-- <PersonCard -->
<!-- history -->
<!-- :list=" -->
<!-- listEmployee.map((v: Employee) => ({ -->
<!-- disabled: v.status === 'INACTIVE', -->
<!-- img: v.profileImageUrl, -->
<!-- id: v.id, -->
<!-- name: -->
<!-- $i18n.locale === 'en-US' -->
<!-- ? `${v.firstNameEN} ${v.lastNameEN}` -->
<!-- : `${v.firstName} ${v.lastName}`, -->
<!-- male: v.gender === 'male', -->
<!-- female: v.gender === 'female', -->
<!-- badge: v.code, -->
<!-- detail: [ -->
<!-- { -->
<!-- label: $t('personnelCardNationality'), -->
<!-- value: v.nationality, -->
<!-- }, -->
<!-- { -->
<!-- label: $t('personnelCardAge'), -->
<!-- value: calculateAge(v.dateOfBirth), -->
<!-- }, -->
<!-- ], -->
<!-- })) -->
<!-- " -->
<!-- @history="openHistory" -->
<!-- @update-card="openDialogInputForm" -->
<!-- @enter-card="openDialogInputForm" -->
<!-- @delete-card="onDelete" -->
<!-- @toggle-status=" -->
<!-- (id, status) => toggleStatusEmployee(id, status) -->
<!-- " -->
<!-- /> -->
<!-- eeee -->
</div>
<div
v-if="listEmployee.length !== 0"
@ -3068,7 +3478,7 @@ watch([inputSearch, currentStatus], async () => {
<!-- no-hover -->
<!-- no-action -->
<!-- no-detail -->
<!-- no-bg -->
<!-- :list="infoEmployeePersonCard ? infoEmployeePersonCard : []" -->
<!-- :gridColumns="1" -->
<!-- @edit-profile=" -->
@ -3240,4 +3650,66 @@ watch([inputSearch, currentStatus], async () => {
background-color: hsla(var(--info-bg) / 0.1);
color: hsl(var(--info-bg));
}
.tags {
display: inline-block;
color: hsla(var(--_color) / 1);
background: hsla(var(--_color) / 0.15);
border-radius: var(--radius-2);
padding-inline: var(--size-2);
}
.tags__purple {
--_color: var(--violet-11-hsl);
}
.tags__green {
--_color: var(--teal-10-hsl);
}
.dark .tags__purple {
--_color: var(--violet-10-hsl);
}
.dark .tags__green {
--_color: var(--teal-8-hsl);
}
.status-active {
--_branch-status-color: var(--green-6-hsl);
}
.status-inactive {
--_branch-status-color: var(--red-4-hsl);
--_branch-badge-bg: var(--red-4-hsl);
filter: grayscale(1);
background-color: hsl(var(--gray-6-hsl) / 0.1);
opacity: 0.5;
}
.branch-card__icon {
background-color: hsla(var(--_branch-card-bg) / 0.15);
border-radius: 50%;
padding: var(--size-1);
position: relative;
transform: rotate(45deg);
&::after {
content: ' ';
display: block;
block-size: 0.5rem;
aspect-ratio: 1;
position: absolute;
border-radius: 50%;
right: -0.1rem;
top: calc(50% - 0.25rem);
bottom: calc(50% - 0.25rem);
background-color: hsla(var(--_branch-status-color) / 1);
}
& :deep(.q-avatar) {
transform: rotate(-45deg);
color: hsla(var(--_branch-card-bg) / 1);
}
}
</style>