266 lines
7.3 KiB
Vue
266 lines
7.3 KiB
Vue
<script setup lang="ts">
|
|
import { ref } from 'vue';
|
|
import AppBox from 'components/app/AppBox.vue';
|
|
import { dateFormat } from 'src/utils/datetime';
|
|
|
|
import { formatNumberDecimal } from 'src/stores/utils';
|
|
|
|
const addedProduct = ref<boolean>(false);
|
|
|
|
import {
|
|
ServiceAndProduct,
|
|
ProductList,
|
|
Service,
|
|
} from 'src/stores/product-service/types';
|
|
|
|
const baseUrl = ref<string>(import.meta.env.VITE_API_BASE_URL);
|
|
|
|
withDefaults(
|
|
defineProps<{
|
|
data?: ServiceAndProduct;
|
|
title?: string;
|
|
|
|
dense?: boolean;
|
|
outlined?: boolean;
|
|
readonly?: boolean;
|
|
separator?: boolean;
|
|
typeProduct?: string;
|
|
|
|
isAddProduct?: boolean;
|
|
isSelected?: boolean;
|
|
|
|
index?: number;
|
|
isDisabled?: boolean;
|
|
}>(),
|
|
{
|
|
isSelected: false,
|
|
},
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
bordered
|
|
:class="{ 'is-add-product': isAddProduct }"
|
|
class="column bordered rounded q-pa-sm no-wrap"
|
|
style="box-shadow: var(--shadow-3); height: 20rem"
|
|
@click="$emit('select', data)"
|
|
>
|
|
<div class="row flex justify-between text-bold">
|
|
<div class="col-9" :class="{ inactive: isDisabled }">
|
|
{{ title ?? 'title' }}
|
|
</div>
|
|
<div
|
|
v-if="isSelected === false"
|
|
class="col-3 relative-position"
|
|
style="left: 10px; bottom: 10px"
|
|
>
|
|
<q-btn
|
|
flat
|
|
round
|
|
padding="sm"
|
|
class="absolute-top-right dots-btn"
|
|
icon="mdi-dots-vertical"
|
|
size="sm"
|
|
@click.stop=""
|
|
>
|
|
<q-menu class="bordered">
|
|
<q-list v-close-popup>
|
|
<q-item
|
|
clickable
|
|
dense
|
|
class="row q-py-sm"
|
|
style="white-space: nowrap"
|
|
@click="$emit('menuViewDetail')"
|
|
>
|
|
<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
|
|
v-if="!isDisabled"
|
|
dense
|
|
clickable
|
|
class="row q-py-sm"
|
|
style="white-space: nowrap"
|
|
@click="$emit('menuEdit')"
|
|
v-close-popup
|
|
>
|
|
<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 dense>
|
|
<q-item-section class="q-py-sm">
|
|
<div class="q-pa-sm surface-2 rounded">
|
|
<q-toggle
|
|
dense
|
|
size="sm"
|
|
@click="$emit('toggleStatus', data?.id)"
|
|
:model-value="!isDisabled"
|
|
val="xs"
|
|
padding="none"
|
|
>
|
|
<div class="q-ml-xs">
|
|
{{
|
|
!isDisabled
|
|
? $t('switchOnLabel')
|
|
: $t('switchOffLabel')
|
|
}}
|
|
</div>
|
|
</q-toggle>
|
|
</div>
|
|
</q-item-section>
|
|
</q-item>
|
|
</q-list>
|
|
</q-menu>
|
|
</q-btn>
|
|
</div>
|
|
|
|
<q-avatar
|
|
v-if="isAddProduct"
|
|
:style="`background-color: var(${data?.type === 'product' ? '--teal-10' : '--orange-5'})`"
|
|
size="18px"
|
|
text-color="white"
|
|
>
|
|
{{ (index ?? 0) + 1 }}
|
|
</q-avatar>
|
|
</div>
|
|
|
|
<div :class="{ inactive: isDisabled }" class="column col">
|
|
<div class="app-text-muted">{{ data?.code ?? 'code' }}</div>
|
|
<div class="flex justify-start text-bold">
|
|
<div
|
|
v-if="data?.type === 'service'"
|
|
class="bordered q-pa-xs row surface-0"
|
|
style="font-size: 12px; border-radius: 5px; width: 80px"
|
|
>
|
|
<div class="col ellipsis-2-lines">งาน</div>
|
|
<q-space />
|
|
<div class="col text-center">{{ data?.work.length }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="data?.type === 'product'" class="flex">
|
|
<div
|
|
class="row full-width text-right"
|
|
style="font-size: 10px; color: hsl(var(--stone-4-hsl))"
|
|
>
|
|
<div class="col-4">ราคาขาย</div>
|
|
<div class="col-4">ราคาตัวแทน</div>
|
|
<div class="col-4">ราคาค่าดำเนินการ</div>
|
|
</div>
|
|
|
|
<div
|
|
class="row full-width text-right items-center"
|
|
style="margin-top: -5px"
|
|
>
|
|
<div
|
|
class="col-4 text-weight-bold"
|
|
style="font-size: 14px; color: hsl(var(--orange-5-hsl))"
|
|
>
|
|
฿{{ formatNumberDecimal(data?.price, 2) }}
|
|
</div>
|
|
<div
|
|
class="col-4 text-weight-bold"
|
|
style="font-size: 14px; color: hsl(var(--purple-9-hsl))"
|
|
>
|
|
฿{{ formatNumberDecimal(data?.agentPrice, 2) }}
|
|
</div>
|
|
<div
|
|
class="col-4"
|
|
style="font-size: 12px; color: hsl(var(--pink-7-hsl))"
|
|
>
|
|
฿{{ formatNumberDecimal(data?.serviceCharge, 2) }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<q-img
|
|
class="col rounded q-my-md items-center justify-center flex"
|
|
style="background-color: transparent"
|
|
loading="lazy"
|
|
:src="`${baseUrl}/${data?.type === 'service' ? 'service' : 'product'}/${data?.id}/image?ts=${Date.now()}`"
|
|
>
|
|
<template #error>
|
|
<div
|
|
class="full-width full-height items-center justify-center flex"
|
|
:class="{
|
|
card__green: data?.type === 'product',
|
|
card__orange: data?.type === 'service',
|
|
}"
|
|
>
|
|
<q-img
|
|
:src="
|
|
data?.type === 'product'
|
|
? '/shop-image.png'
|
|
: '/service-image.png'
|
|
"
|
|
width="5rem"
|
|
/>
|
|
</div>
|
|
</template>
|
|
</q-img>
|
|
|
|
<div class="row justify-between items-center q-mb-xs">
|
|
<div class="q-pr-md" v-if="data?.type === 'service'">
|
|
<q-icon
|
|
name="mdi-calendar-month"
|
|
class="surface-0 rounded q-pa-xs app-text-muted"
|
|
size="20px"
|
|
/>
|
|
{{ dateFormat(data?.createdAt) }}
|
|
</div>
|
|
|
|
<div class="q-pr-md" v-if="data?.type === 'product'">
|
|
<q-icon
|
|
name="mdi-clock-outline"
|
|
class="surface-0 rounded q-pa-xs app-text-muted"
|
|
size="20px"
|
|
/>
|
|
{{ data?.process }} วัน
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.inactive {
|
|
opacity: 0.4;
|
|
}
|
|
|
|
.is-add-product {
|
|
border-color: var(--green-10);
|
|
}
|
|
|
|
.card__green {
|
|
background-color: hsla(var(--teal-10-hsl) / 0.1);
|
|
|
|
&.dark {
|
|
background-color: hsla(var(--teal-7-hsl) / 0.1);
|
|
}
|
|
}
|
|
|
|
.card__orange {
|
|
background-color: hsla(var(--orange-5-hsl) / 0.1);
|
|
|
|
&.dark {
|
|
background-color: hsla(var(--orange-8-hsl) / 0.1);
|
|
}
|
|
}
|
|
</style>
|