feat: add attachment tab and improve layout for product and customer management pages

This commit is contained in:
puriphatt 2025-01-07 12:42:19 +07:00
parent 9590467d0f
commit 4f5320cb36
4 changed files with 164 additions and 130 deletions

View file

@ -100,20 +100,22 @@ withDefaults(
</script>
<template>
<div class="row col-12">
<div class="row col-12 full-width">
<div class="col-12 q-pb-sm row items-center">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-sm"
color="info"
name="mdi-cash"
style="background-color: var(--surface-3)"
/>
<span class="text-body1 text-weight-bold">
{{ $t('productService.product.priceInformation') }}
</span>
<section class="q-px-md">
<div :class="{ 'col-12': $q.screen.lt.sm }">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-sm"
color="info"
name="mdi-cash"
style="background-color: var(--surface-3)"
/>
<span class="text-body1 q-pr-md text-weight-bold">
{{ $t('productService.product.priceInformation') }}
</span>
</div>
<section class="q-pr-md">
<input
id="input-calc-vat"
type="checkbox"

View file

@ -269,7 +269,7 @@ const smallBanner = ref(false);
v-bind:key="tab.name"
class="content-tab text-capitalize"
:name="tab.name"
:label="$t(tab.label)"
:label="tab.label"
/>
</q-tabs>
</div>
@ -283,12 +283,12 @@ const smallBanner = ref(false);
v-if="(!$q.screen.gt.sm && smallBanner) || smallBanner || $q.screen.lt.sm"
fit="cover"
class="cover rounded bordered relative-position"
:style="`height: 45px`"
:style="`height: ${tabsList ? '100' : '45'}px`"
:src="coverUrl || fallbackCover || '/blank-cover.png'"
@error="coverUrl = ''"
>
<nav
class="full-width full-height row no-wrap items-center"
class="full-width full-height column"
:style="`background-image: linear-gradient(
90deg, ${
$q.dark.isActive
@ -298,124 +298,148 @@ const smallBanner = ref(false);
)`"
>
<!-- profile -->
<div class="flex items-center full-height q-pl-lg" style="z-index: 1">
<div
class="surface-1"
style="border-radius: 50%; border: 2px solid var(--surface-1)"
>
<q-avatar
size="35px"
font-size="20px"
class="relative-position"
style="z-index: 1; box-shadow: var(--shadow-2)"
:style="{
color: `${color || 'white'}`,
cursor: `${noImageAction ? 'default' : 'pointer'}`,
}"
@mouseover="showOverlay = true"
@mouseleave="showOverlay = false"
@click.stop="$emit('view')"
<span class="row col items-center">
<div class="flex items-center full-height q-pl-lg" style="z-index: 1">
<div
class="surface-1"
style="border-radius: 50%; border: 2px solid var(--surface-1)"
>
<div
v-if="img"
class="full-width full-height"
<q-avatar
size="35px"
font-size="20px"
class="relative-position"
style="z-index: 1; box-shadow: var(--shadow-2)"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
cursor: `${noImageAction ? 'default' : 'pointer'}`,
}"
>
<q-img id="profile-view" :src="img" :ratio="1">
<template #error>
<q-img
v-if="fallbackImg"
:src="fallbackImg"
:ratio="1"
style="background-color: transparent"
>
<template #error>
<div
class="full-width full-height flex items-center justify-center"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<Icon
class="full-width full-height flex items-center justify-center"
:icon="icon || 'mdi-account'"
/>
</div>
</template>
</q-img>
<div
v-else
class="full-width full-height flex items-center justify-center"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<Icon
class="full-width full-height flex items-center justify-center"
:icon="icon || 'mdi-account'"
/>
</div>
</template>
</q-img>
</div>
<div
v-else
class="full-width full-height flex items-center justify-center"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<Icon
class="full-width full-height flex items-center justify-center"
:icon="icon || 'mdi-account'"
/>
</div>
<div
v-if="!hideActive"
class="absolute-bottom-right"
style="
border-radius: 50%;
width: 10px;
height: 10px;
z-index: 2;
background: var(--surface-1);
"
@mouseover="showOverlay = true"
@mouseleave="showOverlay = false"
@click.stop="$emit('view')"
>
<div
class="absolute-center"
style="border-radius: 50%; width: 8px; height: 8px"
:style="`background: hsl(var(${active ? '--positive-bg' : '--text-mute'}))`"
/>
</div>
</q-avatar>
</div>
</div>
v-if="img"
class="full-width full-height"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<q-img id="profile-view" :src="img" :ratio="1">
<template #error>
<q-img
v-if="fallbackImg"
:src="fallbackImg"
:ratio="1"
style="background-color: transparent"
>
<template #error>
<div
class="full-width full-height flex items-center justify-center"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<Icon
class="full-width full-height flex items-center justify-center"
:icon="icon || 'mdi-account'"
/>
</div>
</template>
</q-img>
<div
v-else
class="full-width full-height flex items-center justify-center"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<Icon
class="full-width full-height flex items-center justify-center"
:icon="icon || 'mdi-account'"
/>
</div>
</template>
</q-img>
</div>
<div
v-else
class="full-width full-height flex items-center justify-center"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<Icon
class="full-width full-height flex items-center justify-center"
:icon="icon || 'mdi-account'"
/>
</div>
<div class="col column full-height text-caption q-ml-md">
<span class="text-bold ellipsis absolute" style="bottom: 16px">
{{ title }}
<q-tooltip anchor="bottom left" self="center left" :delay="300">
<div
v-if="!hideActive"
class="absolute-bottom-right"
style="
border-radius: 50%;
width: 10px;
height: 10px;
z-index: 2;
background: var(--surface-1);
"
>
<div
class="absolute-center"
style="border-radius: 50%; width: 8px; height: 8px"
:style="`background: hsl(var(${active ? '--positive-bg' : '--text-mute'}))`"
/>
</div>
</q-avatar>
</div>
</div>
<div class="col column full-height justify-center text-caption q-ml-md">
<span class="text-bold ellipsis" style="bottom: 16px">
{{ title }}
</q-tooltip>
</span>
<span
v-if="title"
class="absolute"
:class="$q.dark.isActive ? 'foreground' : 'app-text-muted'"
style="font-size: 10px; bottom: 4px"
<q-tooltip anchor="bottom left" self="center left" :delay="300">
{{ title }}
</q-tooltip>
</span>
<span
v-if="title"
:class="$q.dark.isActive ? 'foreground' : 'app-text-muted'"
style="font-size: 10px; bottom: 4px"
>
{{ caption }}
</span>
</div>
</span>
<span class="row full-width" v-if="tabsList && currentTab">
<q-tabs
dense
inline-label
mobile-arrows
v-model="currentTab"
active-class="active-tab text-weight-bold"
class="app-text-muted full-width"
align="left"
v-if="typeof tabsList === 'object'"
>
{{ caption }}
</span>
</div>
<q-tab
v-for="tab in tabsList"
:id="`${prefix}-tab-${tab.label}`"
v-bind:key="tab.name"
class="content-tab text-capitalize"
:name="tab.name"
:label="tab.label"
/>
</q-tabs>
</span>
<q-btn
v-if="$q.screen.gt.xs"
class="absolute-top-right q-ma-xs"
color="primary"
flat

View file

@ -4322,25 +4322,25 @@ const emptyCreateDialog = ref(false);
:tabs-list="[
{
name: 'personalInfo',
label: 'customerEmployee.form.group.personalInfo',
label: $t('customerEmployee.form.group.personalInfo'),
},
{
name: 'passport',
label: 'customerEmployee.fileType.passport',
label: $t('customerEmployee.fileType.passport'),
},
{
name: 'visa',
label: 'customerEmployee.form.group.visa',
label: $t('customerEmployee.form.group.visa'),
},
{
name: 'healthCheck',
label: 'customerEmployee.form.group.healthCheck',
label: $t('customerEmployee.form.group.healthCheck'),
},
{
name: 'workHistory',
label: 'customerEmployee.form.group.workHistory',
label: $t('customerEmployee.form.group.workHistory'),
},
{ name: 'other', label: 'customerEmployee.form.group.other' },
{ name: 'other', label: $t('customerEmployee.form.group.other') },
]"
:toggle-title="$t('status.title')"
/>

View file

@ -3709,6 +3709,10 @@ watch(
name: 2,
label: $t('productService.product.priceInformation'),
},
{
name: 3,
label: $t('general.attachment'),
},
]
"
v-model:current-tab="productTab"
@ -3871,6 +3875,10 @@ watch(
name: 2,
label: $t('productService.product.priceInformation'),
},
{
name: 3,
label: $t('general.attachment'),
},
]
"
v-model:currentTab="productTab"
@ -3878,7 +3886,7 @@ watch(
</div>
<div
class="col surface-1 rounded bordered scroll row relative-position"
class="col surface-1 rounded bordered scroll row relative-position full-width"
id="product-form"
:class="{
'q-mb-lg q-mx-lg ': $q.screen.gt.sm,