refactor: employer branch card

This commit is contained in:
Methapon2001 2024-07-05 17:35:40 +07:00
parent 1b039fd935
commit 70f3959c08
2 changed files with 152 additions and 130 deletions

View file

@ -1,30 +1,27 @@
<script setup lang="ts">
import AppBox from 'components/app/AppBox.vue';
import { CustomerBranch } from 'src/stores/customer/types';
withDefaults(
defineProps<{
inactive?: boolean;
color?: 'none' | 'CORP' | 'PERS';
metadata?: unknown;
badgeField?: string[];
fieldSelected?: string[];
footer?: boolean;
data: {
customerBranchFormTab: number;
branchName: string;
address: string;
telephone: string;
businessTypePure: string;
status: string;
totalEmployee: number;
};
}>(),
{},
);
<script lang="ts" setup>
defineProps<{
inactive?: boolean;
color?: 'none' | 'pers' | 'corp';
data: {
customerBranchFormTab: number;
branchName: string;
address: string;
telephone: string;
businessTypePure: string;
totalEmployee: number;
};
metadata?: unknown;
badgeField?: string[];
fieldSelected?: (
| 'customerBranchFormTab'
| 'branchName'
| 'address'
| 'telephone'
| 'businessTypePure'
| 'totalEmployee'
)[];
footer?: boolean;
}>();
</script>
<template>
@ -34,114 +31,135 @@ withDefaults(
'branch-card__dark': $q.dark.isActive,
'branch-card__inactive': inactive,
'branch-card__none':
color !== 'CORP' && color !== 'PERS' && (!color || color === 'none'),
'branch-card__CORP': color === 'CORP',
'branch-card__PERS': color === 'PERS',
color !== 'pers' && color !== 'corp' && (!color || color === 'none'),
'branch-card__pers': color === 'pers',
'branch-card__corp': color === 'corp',
}"
@click="$emit('open')"
>
<div
class="branch-card__row"
:class="{
'branch-card__header': i === 0,
'branch-card__footer': footer && i === Object.keys(data).length - 1,
}"
v-for="([k, v], i) in Object.entries(data).filter(
([key], idx) =>
idx === 0 || (fieldSelected ? fieldSelected.includes(key) : true),
)"
:key="k"
>
<div class="branch-card__label">
<span>{{ $t(k) }}</span>
</div>
<div
class="branch-card__value"
:class="{ 'branch-card__badge': badgeField?.includes(k) }"
style="justify-content: space-between"
>
<span>{{ v }}</span>
<q-btn
@click.stop="$emit('view-detail', metadata ?? data)"
:label="$t('viewDetail')"
rounded
outline
dense
no-caps
class="branch-card__view-detail q-px-md text-caption"
v-if="i === 0"
<div class="branch-card__header">
<div class="branch-card__icon">
<q-icon
size="md"
style="scale: 0.8"
name="mdi-office-building-outline"
/>
</div>
<div class="branch-card__name">
<b>{{ data.branchName }}</b>
<small class="branch-card__code">{{ data.branchName }}</small>
</div>
<div class="branch-card__action">
<q-btn
icon="mdi-eye-outline"
size="sm"
dense
round
flat
@click.stop="$emit('viewDetail')"
>
<slot name="action" />
</q-btn>
</div>
</div>
<div
style="
display: block;
width: 100%;
height: 1px;
background: hsla(0 0% 0% / 0.1);
margin-bottom: var(--size-2);
"
/>
<div
v-for="key in fieldSelected?.sort() || [
'customerBranchFormTab',
'branchName',
'address',
'telephone',
'businessTypePure',
'totalEmployee',
]"
class="branch-card__data"
>
<div>{{ $t(key) }}</div>
<div>{{ data[key as keyof typeof data] }}</div>
</div>
</div>
</template>
<style scoped>
.branch-card {
--_branch-card-row-fg: 0 0% 100%;
--_branch-card-row-bg: var(--blue-5-hsl);
--_branch-badge-fg: var(--green-8-hsl);
--_branch-badge-bg: var(--green-6-hsl);
--_branch-card-fg: 0 0% 100%;
--_branch-card-bg: var(--blue-5-hsl);
--_branch-status-color: var(--green-6-hsl);
display: flex;
flex-direction: column;
overflow: hidden;
box-shadow: var(--shadow-2);
padding: var(--size-3);
& > .branch-card__row {
& .branch-card__header {
display: flex;
margin-bottom: var(--size-2);
& .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.25rem;
top: calc(50% - 0.25rem);
bottom: calc(50% - 0.25rem);
background-color: hsla(var(--_branch-status-color) / 1);
}
& :deep(.q-icon) {
transform: rotate(-45deg);
color: hsla(var(--_branch-card-bg) / 1);
}
}
& .branch-card__name {
display: flex;
flex-direction: column;
flex: 1;
padding-inline: var(--size-2);
& .branch-card__code {
color: hsla(var(--text-mute) / 1);
}
}
& .branch-card__action {
margin-left: auto;
}
}
& .branch-card__data {
display: flex;
flex-wrap: nowrap;
padding-inline: var(--size-4);
padding-block: var(--size-2);
&:last-child {
flex-grow: 1;
}
&:nth-child(2n + 1) {
background-color: hsla(var(--_branch-card-row-bg) / 0.05);
}
&.branch-card__header,
&.branch-card__footer {
color: hsl(var(--_branch-card-row-fg));
background-color: hsl(var(--_branch-card-row-bg));
&:deep(*) {
font-weight: 600;
}
}
&.branch-card__header > * {
display: flex;
align-items: center;
}
& > .branch-card__label {
min-width: 120px;
width: 30%;
}
&:not(.branch-card__header) .branch-card__label {
color: hsl(var(--stone-6-hsl));
}
& > .branch-card__value {
width: 70%;
&.branch-card__badge > span {
display: inline-block;
border-radius: 999rem;
padding-inline: var(--size-2);
color: hsl(var(--_branch-badge-fg));
background-color: hsla(var(--_branch-badge-bg) / 0.1);
}
& > :first-child {
color: hsla(var(--text-mute) / 1);
width: 0%;
min-width: 40%;
}
}
&.branch-card__none {
--_branch-card-row-bg: var(--gray-3-hsl);
--_branch-card-bg: var(--gray-3-hsl);
&.branch-card__dark {
--_branch-card-row-bg: var(--gray-9-hsl);
--_branch-card-bg: var(--gray-9-hsl);
}
&:not(.branch-card__dark) .branch-card__header {
@ -153,18 +171,23 @@ withDefaults(
}
}
&.branch-card__CORP {
--_branch-card-row-bg: var(--purple-11-hsl);
&.branch-card__pers {
--_branch-card-bg: var(--pink-6-hsl);
}
&.branch-card__PERS {
--_branch-card-row-bg: var(--teal-9-hsl);
&.branch-card__corp {
--_branch-card-bg: var(--violet-11-hsl);
&.branch-card__dark {
--_branch-card-bg: var(--violet-10-hsl);
}
}
&.branch-card__inactive {
--_branch-badge-fg: var(--red-4-hsl);
--_branch-status-color: var(--red-4-hsl);
--_branch-badge-bg: var(--red-4-hsl);
filter: grayscale(40%);
filter: grayscale(1);
background-color: hsl(var(--gray-6-hsl) / 0.1);
opacity: 0.5;
}
}

View file

@ -3,6 +3,7 @@ import { ref, onMounted, watch } from 'vue';
import useCustomerStore from 'src/stores/customer';
import useFlowStore from 'src/stores/flow';
import useOptionStore from 'src/stores/options';
import { Status } from 'src/stores/types';
import { CustomerBranch, CustomerType } from 'src/stores/customer/types';
@ -45,7 +46,7 @@ const prop = withDefaults(
},
);
const emit = defineEmits<{
defineEmits<{
(e: 'back'): void;
(e: 'viewDetail', branch: CustomerBranch, index: number): void;
(e: 'dialog'): void;
@ -185,31 +186,29 @@ watch(currentStatus, async () => {
</div>
</div>
<div
class="row q-pa-lg q-col-gutter-xl"
class="row q-pa-md q-col-gutter-md"
:class="{ 'justify-center': totalBranch === 0 }"
style="min-height: 350px"
>
<NoData v-if="totalBranch === 0" :not-found="!!inputSearch" />
<div
v-for="(br, i) in branch?.sort((a, b) => a.branchNo - b.branchNo)"
:key="i"
class="col-4"
>
<div v-for="(br, i) in branch" :key="i" class="col-4">
<BranchCardCustomer
:inactive="br.status === 'INACTIVE'"
:color="customerType"
:color="customerType === 'CORP' ? 'corp' : 'pers'"
:badgeField="['status']"
:data="{
customerBranchFormTab: br.branchNo,
branchName: br.name,
address: br.address,
address:
$i18n.locale === 'en-US'
? `${br.addressEN || ''} ${br.subDistrict?.nameEN || ''} ${br.district?.nameEN || ''} ${br.province?.nameEN || ''}`
: `${br.address || ''} ${br.subDistrict?.name || ''} ${br.district?.name || ''} ${br.province?.name || ''}`,
telephone: br.telephoneNo,
businessTypePure: br.bussinessType,
status: 'ดำเนินการอยู่',
businessTypePure: useOptionStore().mapOption(br.bussinessType),
totalEmployee: br._count?.employee,
}"
@view-detail="emit('viewDetail', br, i)"
@view-detail="$emit('viewDetail', br, i)"
/>
</div>
</div>