refactor: clean up attendance-related components by removing unused permissions and optimizing template structure for better readability
This commit is contained in:
parent
0b4418862d
commit
33ddf5b73d
@ -197,7 +197,6 @@ public function permissions(): array
|
|||||||
|
|
||||||
Permission::ATTENDANCES_VIEW,
|
Permission::ATTENDANCES_VIEW,
|
||||||
Permission::ATTENDANCES_CREATE,
|
Permission::ATTENDANCES_CREATE,
|
||||||
Permission::ATTENDANCES_DELETE,
|
|
||||||
|
|
||||||
Permission::LEAVE_REQUESTS_VIEW,
|
Permission::LEAVE_REQUESTS_VIEW,
|
||||||
Permission::LEAVE_REQUESTS_CREATE,
|
Permission::LEAVE_REQUESTS_CREATE,
|
||||||
|
|||||||
@ -17,12 +17,18 @@ const props = defineProps<{
|
|||||||
const hasCoordinates = computed(() => props.checkInLat != null && props.checkInLng != null);
|
const hasCoordinates = computed(() => props.checkInLat != null && props.checkInLng != null);
|
||||||
|
|
||||||
const checkInSrc = computed(() => {
|
const checkInSrc = computed(() => {
|
||||||
if (props.checkInLat == null || props.checkInLng == null) return '';
|
if (props.checkInLat == null || props.checkInLng == null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
return `https://www.google.com/maps?q=${props.checkInLat},${props.checkInLng}&z=18&t=k&output=embed`;
|
return `https://www.google.com/maps?q=${props.checkInLat},${props.checkInLng}&z=18&t=k&output=embed`;
|
||||||
});
|
});
|
||||||
|
|
||||||
const checkOutSrc = computed(() => {
|
const checkOutSrc = computed(() => {
|
||||||
if (props.checkOutLat == null || props.checkOutLng == null) return '';
|
if (props.checkOutLat == null || props.checkOutLng == null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
return `https://www.google.com/maps?q=${props.checkOutLat},${props.checkOutLng}&z=18&t=k&output=embed`;
|
return `https://www.google.com/maps?q=${props.checkOutLat},${props.checkOutLng}&z=18&t=k&output=embed`;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -38,18 +44,13 @@ function escapeHtml(value: string): string {
|
|||||||
function buildLabel(
|
function buildLabel(
|
||||||
title: string,
|
title: string,
|
||||||
color: string,
|
color: string,
|
||||||
time: string,
|
|
||||||
locationTag: string | null,
|
locationTag: string | null,
|
||||||
lat: number | null,
|
|
||||||
lng: number | null,
|
|
||||||
): string {
|
): string {
|
||||||
const lines: string[] = [];
|
const lines: string[] = [];
|
||||||
lines.push(`<strong style="color:${color}">${title}</strong>`);
|
lines.push(`<strong style="color:${color}">${title}</strong>`);
|
||||||
if (props.employeeName) lines.push(`<span>Karyawan: <b>${escapeHtml(props.employeeName)}</b></span>`);
|
|
||||||
lines.push(`<span>Tanggal: ${escapeHtml(props.attendanceDateFormatted)}</span>`);
|
|
||||||
lines.push(`<span>Jam: <b>${escapeHtml(time)}</b></span>`);
|
|
||||||
lines.push(`<span>Lokasi: ${escapeHtml(locationTag ?? '-')}</span>`);
|
lines.push(`<span>Lokasi: ${escapeHtml(locationTag ?? '-')}</span>`);
|
||||||
lines.push(`<span style="font-family:monospace;font-size:11px">Koordinat: ${lat}, ${lng}</span>`);
|
|
||||||
return lines.join('<br>');
|
return lines.join('<br>');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -62,34 +63,16 @@ function buildLabel(
|
|||||||
|
|
||||||
<!-- Check-in map -->
|
<!-- Check-in map -->
|
||||||
<div class="space-y-1.5">
|
<div class="space-y-1.5">
|
||||||
<div
|
<div class="text-xs font-medium" v-html="buildLabel('Masuk', '#16a34a', checkInLocationTag)" />
|
||||||
class="text-xs font-medium"
|
<iframe :src="checkInSrc" class="h-56 w-full overflow-hidden rounded-lg" style="border: 0" allowfullscreen
|
||||||
v-html="buildLabel('Masuk', '#16a34a', checkInAtFormatted, checkInLocationTag, checkInLat, checkInLng)"
|
loading="lazy" referrerpolicy="no-referrer-when-downgrade" />
|
||||||
/>
|
|
||||||
<iframe
|
|
||||||
:src="checkInSrc"
|
|
||||||
class="h-56 w-full overflow-hidden rounded-lg"
|
|
||||||
style="border: 0"
|
|
||||||
allowfullscreen
|
|
||||||
loading="lazy"
|
|
||||||
referrerpolicy="no-referrer-when-downgrade"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Check-out map -->
|
<!-- Check-out map -->
|
||||||
<div v-if="checkOutLat != null && checkOutLng != null" class="space-y-1.5">
|
<div v-if="checkOutLat != null && checkOutLng != null" class="space-y-1.5">
|
||||||
<div
|
<div class="text-xs font-medium" v-html="buildLabel('Pulang', '#dc2626', checkOutLocationTag)" />
|
||||||
class="text-xs font-medium"
|
<iframe :src="checkOutSrc" class="h-56 w-full overflow-hidden rounded-lg" style="border: 0" allowfullscreen
|
||||||
v-html="buildLabel('Pulang', '#dc2626', checkOutAtFormatted ?? '-', checkOutLocationTag, checkOutLat, checkOutLng)"
|
loading="lazy" referrerpolicy="no-referrer-when-downgrade" />
|
||||||
/>
|
|
||||||
<iframe
|
|
||||||
:src="checkOutSrc"
|
|
||||||
class="h-56 w-full overflow-hidden rounded-lg"
|
|
||||||
style="border: 0"
|
|
||||||
allowfullscreen
|
|
||||||
loading="lazy"
|
|
||||||
referrerpolicy="no-referrer-when-downgrade"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -29,31 +29,17 @@ function openPreview(url: string, title: string, locationTag: string | null | un
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="checkInPhotoUrl || checkOutPhotoUrl" class="flex flex-wrap gap-2">
|
<div v-if="checkInPhotoUrl || checkOutPhotoUrl" class="flex flex-wrap gap-2">
|
||||||
<button
|
<button v-if="checkInPhotoUrl" type="button" class="group flex flex-col items-center gap-1"
|
||||||
v-if="checkInPhotoUrl"
|
@click="openPreview(checkInPhotoUrl, 'Foto Presensi Masuk', checkInLocationTag)">
|
||||||
type="button"
|
<img :src="checkInPhotoUrl" alt="Foto presensi masuk"
|
||||||
class="group flex flex-col items-center gap-1"
|
class="size-12 rounded-md border object-cover transition-opacity group-hover:opacity-80" />
|
||||||
@click="openPreview(checkInPhotoUrl, 'Foto Presensi Masuk', checkInLocationTag)"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
:src="checkInPhotoUrl"
|
|
||||||
alt="Foto presensi masuk"
|
|
||||||
class="size-12 rounded-md border object-cover transition-opacity group-hover:opacity-80"
|
|
||||||
/>
|
|
||||||
<span class="text-muted-foreground text-[10px] font-medium">Masuk</span>
|
<span class="text-muted-foreground text-[10px] font-medium">Masuk</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button v-if="checkOutPhotoUrl" type="button" class="group flex flex-col items-center gap-1"
|
||||||
v-if="checkOutPhotoUrl"
|
@click="openPreview(checkOutPhotoUrl, 'Foto Presensi Pulang', checkOutLocationTag)">
|
||||||
type="button"
|
<img :src="checkOutPhotoUrl" alt="Foto presensi pulang"
|
||||||
class="group flex flex-col items-center gap-1"
|
class="size-12 rounded-md border object-cover transition-opacity group-hover:opacity-80" />
|
||||||
@click="openPreview(checkOutPhotoUrl, 'Foto Presensi Pulang', checkOutLocationTag)"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
:src="checkOutPhotoUrl"
|
|
||||||
alt="Foto presensi pulang"
|
|
||||||
class="size-12 rounded-md border object-cover transition-opacity group-hover:opacity-80"
|
|
||||||
/>
|
|
||||||
<span class="text-muted-foreground text-[10px] font-medium">Pulang</span>
|
<span class="text-muted-foreground text-[10px] font-medium">Pulang</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -68,17 +54,9 @@ function openPreview(url: string, title: string, locationTag: string | null | un
|
|||||||
|
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<div class="overflow-hidden rounded-lg border bg-muted">
|
<div class="overflow-hidden rounded-lg border bg-muted">
|
||||||
<img
|
<img v-if="previewUrl" :src="previewUrl" :alt="previewTitle"
|
||||||
v-if="previewUrl"
|
class="max-h-[70vh] w-full object-contain" />
|
||||||
:src="previewUrl"
|
|
||||||
:alt="previewTitle"
|
|
||||||
class="max-h-[70vh] w-full object-contain"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p v-if="previewLocationTag" class="text-muted-foreground text-xs whitespace-pre-line">
|
|
||||||
{{ previewLocationTag }}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user