ปรับ ui checkin

This commit is contained in:
Tanyalak 2024-01-19 15:34:09 +07:00
parent 4dbf1de05d
commit f9ec074f03
10 changed files with 705 additions and 695 deletions

View file

@ -10,7 +10,6 @@ import config from '@/app.config'
// import Type
import type { FormRef } from '@/interface/response/checkin'
import type { notiType } from '@/interface/index/Main'
// import components
import MapCheck from '@/components/AscGISMap.vue'
@ -24,10 +23,7 @@ const {
showLoader,
hideLoader,
messageError,
dialogRemove,
success,
} = mixin
const router = useRouter()
const $q = useQuasar()
const dialogTime = ref<boolean>(false)
@ -51,79 +47,6 @@ async function fetchCheckTime() {
})
}
const notiTrigger = ref<boolean>(false)
const notiList = ref<notiType[]>([])
const totalNotiList = ref<number>(0)
/** function เรียกข้อมุลแจ้งเตือน */
async function fetchNotifications(index: number, type: string) {
showLoader()
await http
.get(config.API.msgNotificate + `?page=${index}&pageSize=${20}`)
.then((res) => {
const response = res.data.result.data
const list: notiType[] = []
if (type === 'DEL') {
totalNotiList.value = res.data.result.total
if (notiList.value.length === 14) {
notiList.value = []
response.map((e: any) => {
list.push({
id: e.id,
sender:
e.createdFullName == '' || e.createdFullName == null
? 'เจ้าหน้าที่'[0]
: e.createdFullName[0],
body: e.body ?? '',
timereceive: e.receiveDate ? date2Thai(e.receiveDate) : '-',
})
})
notiList.value.push(...list)
}
} else {
response.map((e: any) => {
list.push({
id: e.id,
sender:
e.createdFullName == '' || e.createdFullName == null
? 'เจ้าหน้าที่'[0]
: e.createdFullName[0],
body: e.body ?? '',
timereceive: e.receiveDate ? date2Thai(e.receiveDate) : '-',
})
})
notiList.value.push(...list)
totalNotiList.value = res.data.result.total
}
})
.catch((err) => {
messageError($q, err)
})
.finally(() => {
hideLoader()
})
}
/**
* function ลบรายการแจงเตอน
* @param id noti
*/
async function onClickDelete(id: string, index: number) {
dialogRemove($q, async () => {
await http
.delete(config.API.msgId(id))
.then(() => {
notiList.value.splice(index, 1)
success($q, 'ลบข้อมูลสำเร็จ')
})
.catch((e) => {
messageError($q, e)
})
.finally(async () => {
fetchNotifications(1, 'DEL')
hideLoader()
})
})
}
/** ref อัพเดทเวลา*/
const dateNow = ref<Date>(new Date())
@ -307,27 +230,6 @@ async function onClickConfirm() {
dialogTime.value = false
}
/** function logout*/
function onClickLogout() {
$q.dialog({
title: 'ยืนยันการออกจากระบบ',
message: `ต้องการออกจากระบบใช้หรือไม่?`,
cancel: 'ยกเลิก',
ok: 'ยืนยัน',
persistent: true,
}).onOk(() => {
keycloak.logout()
})
}
function onLoad(index: any, done: any) {
if (notiList.value.length < totalNotiList.value) {
setTimeout(() => {
fetchNotifications(index + 1, 'NOMAL')
done()
}, 2000)
}
}
// class
const getClass = (val: boolean) => {
@ -341,11 +243,6 @@ const fullName = ref<string>('')
/** Hook*/
onMounted(async () => {
await fetchCheckTime()
await fetchNotifications(1, 'NOMAL')
if (keycloak.tokenParsed != null) {
fullName.value = keycloak.tokenParsed.name
}
updateClock()
})
</script>
@ -356,283 +253,16 @@ onMounted(async () => {
<q-card flat class="row col-12 cardNone">
<!-- <q-header elevated class="bg-purple"> -->
<q-toolbar :class="getClass(stetusCheckin)">
<q-btn
icon="history"
unelevated
rounded
dense
flat
color="white"
:label="$q.screen.gt.xs ? 'ประวัติการลงเวลา' : ''"
:class="$q.screen.gt.xs ? 'q-px-md' : ''"
@click="router.push('/history')"
/>
<q-space />
<strong v-if="stetusCheckin" style="font-size: 1rem">
ลงเวลาเขางาน
</strong>
<strong v-else style="font-size: 1rem">ลงเวลาออกงาน</strong>
<q-space />
<q-btn
round
dense
flat
size="13px"
class="q-mx-md"
:disable="totalNotiList == 0"
>
<q-icon name="notifications" size="24px" color="white" />
<q-badge
rounded
v-show="totalNotiList !== 0"
color="negative"
text-color="white"
floating
>{{ totalNotiList }}</q-badge
>
<q-menu v-model="notiTrigger" max-width="480px" :offset="[0, 10]">
<div class="q-px-md q-py-sm row col-12 items-center">
<div class="text-subtitle1 text-weight-medium">
การแจงเตอน
</div>
</div>
<q-infinite-scroll @load="onLoad" :offset="250">
<div
v-for="(item, index) in notiList"
:key="index"
class="caption"
>
<q-item v-ripple class="mytry q-py-sm" dense>
<q-item-section avatar top style="min-width: 10px">
<q-avatar
rounded
color="primary"
size="25px"
text-color="white"
>
<span class="text-weight-medium text-uppercase">{{
item.sender[0]
}}</span>
</q-avatar>
</q-item-section>
<q-item-section>
<q-item-label caption class="text-black">{{
item.body
}}</q-item-label>
<q-item-label
caption
class="row items-center text-grey-7"
style="font-size: 12px"
>{{ item.timereceive }}</q-item-label
>
</q-item-section>
<div>
<q-btn
size="sm"
unelevated
dense
icon="mdi-close"
class="mybtn q-mx-xs"
@click="onClickDelete(item.id, index)"
></q-btn>
</div>
</q-item>
</div>
<template v-slot:loading v-if="notiList.length < totalNotiList">
<div class="row justify-center q-my-md">
<q-spinner-dots color="primary" size="40px" />
</div>
</template>
</q-infinite-scroll>
<!-- <q-list
style="min-width: 300px"
v-for="n in notiList"
:key="n.id"
>
<q-item v-ripple class="mytry q-py-xs" dense>
<q-item-section avatar top style="min-width: 40px">
<q-avatar color="primary" size="22px" text-color="white">
<span class="text-weight-medium text-uppercase">{{
n.sender
}}</span>
</q-avatar>
</q-item-section>
<q-item-section>
<q-item-label caption class="text-black">{{
n.body
}}</q-item-label>
<q-item-label
caption
class="row items-center text-grey-7"
>{{ date2Thai(n.timereceive) }}</q-item-label
>
</q-item-section>
<q-btn
size="sm"
unelevated
dense
icon="mdi-close"
class="mybtn q-mx-xs"
@click="onClickDelete(n.id)"
></q-btn>
</q-item>
<q-separator color="grey-2" />
</q-list> -->
</q-menu>
</q-btn>
<q-btn round dense flat icon="account_circle" style="font-size: 16px">
<q-menu>
<div class="q-pa-md" style="max-width: 500px">
<q-list>
<q-item>
<q-item-section avatar>
<q-icon color="primary" name="account_circle" />
</q-item-section>
<q-item-section>{{ fullName }}</q-item-section>
</q-item>
<q-item class="text-center">
<q-item-section>
<q-item-label>
<q-btn
color="primary"
label="ออกจากระบบ"
push
size="sm"
@click="onClickLogout"
/></q-item-label>
</q-item-section>
</q-item>
</q-list>
</div> </q-menu
></q-btn>
<div class="row col-12 justify-center">
<strong v-if="stetusCheckin" style="font-size: 1rem">
ลงเวลาเขางาน
</strong>
<strong v-else style="font-size: 1rem">ลงเวลาออกงาน</strong>
</div>
</q-toolbar>
<!-- </q-header> -->
<!-- <div :class="getClass(stetusCheckin)">
<div class="col-2">
<q-btn
icon="history"
unelevated
rounded
dense
flat
color="white"
:label="$q.screen.gt.xs ? 'ประวัติการลงเวลา' : ''"
:class="$q.screen.gt.xs ? 'q-px-md' : ''"
@click="router.push('/history')"
/>
</div>
<span class="text-body1 text-weight-bold col-8 text-center">
<span v-if="stetusCheckin">ลงเวลาเข้างาน</span>
<span v-else>ลงเวลาออกงาน</span>
</span>
<div class="col-2 text-right">
<q-btn
round
dense
flat
size="13px"
class="q-mx-md"
:disable="notiList.length === 0"
>
<q-icon name="notifications" size="24px" color="white" />
<q-badge
rounded
v-show="notiList.length > 0"
color="negative"
text-color="white"
floating
>{{ notiList.length }}</q-badge
>
<q-menu v-model="notiTrigger" max-width="480px" :offset="[0, 10]">
<div class="q-px-md q-py-sm row col-12 items-center">
<div class="text-subtitle1 text-weight-medium">
การแจงเตอน
</div>
</div>
<q-list
style="min-width: 300px"
v-for="n in notiList"
:key="n.id"
>
<q-item v-ripple class="mytry q-py-xs" dense>
<q-item-section avatar top style="min-width: 40px">
<q-avatar color="primary" size="22px" text-color="white">
<span class="text-weight-medium text-uppercase">{{
n.sender
}}</span>
</q-avatar>
</q-item-section>
<q-item-section>
<q-item-label caption class="text-black">{{
n.body
}}</q-item-label>
<q-item-label
caption
class="row items-center text-grey-7"
>{{ date2Thai(n.timereceive) }}</q-item-label
>
</q-item-section>
<q-btn
size="sm"
unelevated
dense
icon="mdi-close"
class="mybtn q-mx-xs"
@click="onClickDelete(n.id)"
></q-btn>
</q-item>
<q-separator color="grey-2" />
</q-list>
</q-menu>
</q-btn>
<q-btn
round
dense
flat
icon="account_circle"
style="font-size: 16px"
>
<q-menu>
<div class="q-pa-md" style="max-width: 500px">
<q-list>
<q-item>
<q-item-section avatar>
<q-icon color="primary" name="account_circle" />
</q-item-section>
<q-item-section>{{ fullName }}</q-item-section>
</q-item>
<q-item class="text-center">
<q-item-section>
<q-item-label>
<q-btn
color="primary"
label="ออกจากระบบ"
push
size="sm"
@click="onClickLogout"
/></q-item-label>
</q-item-section>
</q-item>
</q-list>
</div> </q-menu
></q-btn>
</div>
</div> -->
<div class="col-12 q-pa-md text-grey-9">
<div class="col-12 text-grey-9">
<div class="col-12 row justify-center">
<div class="col-12 row q-py-sm justify-center">
<div class="col-12 row q-pt-md justify-center">
<div
class="col-xs-12 col-sm-10 text-h6 text-center text-weight-bold"
>
@ -654,13 +284,12 @@ onMounted(async () => {
</div>
</div>
</div>
<div class="col-xs-12 col-md-11 row q-col-gutter-md">
<div class="col-12 col-sm-8">
<MapCheck @update:location="updateLocation" />
<div class="col-xs-12 col-md-11 q-pa-md q-col-gutter-md row">
<div class="col-xs-12 col-sm-8">
<MapCheck @update:location="updateLocation" class="col-12" />
<!-- <AscMaps /> -->
</div>
<div class="col-12 col-sm-4">
<div class="col-xs-12 col-sm-4">
<q-card flat bordered class="card-container">
<div
v-if="!cameraIsOn && img == null"
@ -676,7 +305,7 @@ onMounted(async () => {
/>
</div>
</div>
<div>
<div class="col-12 row items-center">
<!-- แสดงกลองตอนกดถายภาพ -->
<Camera
:resolution="{ width: photoWidth, height: photoHeight }"
@ -717,7 +346,7 @@ onMounted(async () => {
</q-card>
</div>
<div class="col-12 q-mb-md">
<div class="col-xs-12 col-sm-12 items-center">
<q-card
bordered
flat
@ -765,6 +394,7 @@ onMounted(async () => {
:rules="[(val) => !!val || 'กรุณาระบุสถานที่']"
lazy-rules
@update:model-value="selectLocation()"
hide-bottom-space
/>
</div>
<div
@ -783,45 +413,55 @@ onMounted(async () => {
/>
</div>
</q-card>
<q-card bordered flat class="q-pa-sm">
<div class="col-12">
</div>
<div class="col-xs-12 col-sm-12">
<q-card
bordered
flat
:class="
$q.screen.gt.xs
? 'q-px-md q-py-sm row items-center shadow-0'
: 'q-pa-md row items-center shadow-0'
"
>
<div class="text-weight-bold">หมายเหต</div>
<div class="col-12 q-pt-sm">
<q-input
outlined
v-model="remark"
label="หมายเหตุ"
lazy-rules
dense
/>
</div>
</q-card>
<div class="col-12 text-right">
<q-separator />
<div class="col-12 q-pa-md">
<p
:class="
$q.screen.gt.xs
? 'text-red text-caption '
: 'text-red text-caption text-center'
"
>
*หมายเหต คลกลงเวลาเขางานแลวระบบจะลงเวลาทนท
</p>
<q-btn
:label="
stetusCheckin == true ? 'ลงเวลาเข้างาน' : 'ลงเวลาออกงาน'
"
:color="img == null ? 'grey-6' : 'primary'"
push
size="14px"
:class="$q.screen.gt.xs ? 'q-px-md' : 'full-width'"
:disable="camera && img ? false : true"
@click="validateForm"
/>
</div>
</div>
</div>
</div>
</div>
<div class="col-12 text-right">
<q-separator />
<div class="col-12 q-pa-md">
<p
:class="
$q.screen.gt.xs
? 'text-red text-caption '
: 'text-red text-caption text-center'
"
>
*หมายเหต คลกลงเวลาเขางานแลวระบบจะลงเวลาทนท
</p>
<q-btn
:label="
stetusCheckin == true ? 'ลงเวลาเข้างาน' : 'ลงเวลาออกงาน'
"
:color="img == null ? 'grey-6' : 'primary'"
push
size="18px"
:class="$q.screen.gt.xs ? 'q-px-md' : 'full-width q-pa-sm'"
:disable="camera && img ? false : true"
@click="validateForm"
/>
</div>
</div>
</div>
@ -889,8 +529,9 @@ onMounted(async () => {
.card-container {
position: relative;
overflow: hidden;
height: 39vh; /* Adjust as needed */
height: autu; /* Adjust as needed */
background: #f6f5f5;
height: 35vh !important;
}
.image-container {
position: absolute;
@ -904,7 +545,7 @@ onMounted(async () => {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 5px; /* Adjust as needed */
border-radius: 8px; /* Adjust as needed */
}
.preview-placeholder {