store/resources/js/components/admin/hr/attendances/AttendanceDetailDialog.vue

134 lines
4.4 KiB
Vue

<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { Trash2 } from '@lucide/vue';
import { ref } from 'vue';
import { toast } from 'vue-sonner';
import AttendancePhotoCell from '@/components/admin/hr/attendances/attendance-photo-cell.vue';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { useCan } from '@/composables/useCan';
import type { AttendanceListItem } from '@/types/attendance';
const open = defineModel<boolean>('open', { required: true });
const props = defineProps<{
attendance: AttendanceListItem | null;
}>();
const { can } = useCan();
const deleteConfirmOpen = ref(false);
const deleteProcessing = ref(false);
function destroyAttendance() {
if (!props.attendance) {
return;
}
deleteProcessing.value = true;
router.delete(`/admin/hr/attendances/${props.attendance.id}`, {
preserveScroll: true,
onSuccess: () => {
deleteConfirmOpen.value = false;
open.value = false;
},
onError: () => {
toast.error('Gagal menghapus data presensi.');
},
onFinish: () => {
deleteProcessing.value = false;
},
});
}
</script>
<template>
<Dialog v-model:open="open">
<DialogContent class="sm:max-w-lg">
<DialogHeader>
<DialogTitle>Detail Presensi</DialogTitle>
<DialogDescription v-if="attendance">
{{ attendance.attendance_date_formatted }}
<template v-if="attendance.employee_name">
{{ attendance.employee_name }}
</template>
</DialogDescription>
</DialogHeader>
<div v-if="attendance" class="space-y-4">
<dl class="grid grid-cols-2 gap-x-4 gap-y-3 text-sm">
<div>
<dt class="text-muted-foreground">
Masuk
</dt>
<dd class="font-medium">
{{ attendance.check_in_at_formatted }}
</dd>
</div>
<div>
<dt class="text-muted-foreground">
Pulang
</dt>
<dd class="font-medium">
{{ attendance.check_out_at_formatted ?? '-' }}
</dd>
</div>
<div class="col-span-2">
<dt class="text-muted-foreground">
Durasi
</dt>
<dd class="font-medium">
{{ attendance.work_duration_formatted ?? '-' }}
</dd>
</div>
</dl>
<div>
<p class="text-muted-foreground mb-2 text-sm">
Foto
</p>
<AttendancePhotoCell
:check-in-photo-url="attendance.check_in_photo_url"
:check-out-photo-url="attendance.check_out_photo_url"
:check-in-location-tag="attendance.check_in_location_tag"
:check-out-location-tag="attendance.check_out_location_tag"
/>
</div>
<div v-if="can('attendances.delete')" class="flex justify-end border-t pt-4">
<Button
variant="destructive"
size="sm"
@click="deleteConfirmOpen = true"
>
<Trash2 class="size-4" />
Hapus
</Button>
</div>
</div>
</DialogContent>
</Dialog>
<ConfirmDialog
v-if="can('attendances.delete') && attendance"
v-model:open="deleteConfirmOpen"
title="Hapus data presensi?"
:description="`Presensi tanggal ${attendance.attendance_date_formatted} akan dihapus secara permanen.`"
confirm-label="Hapus"
cancel-label="Batal"
destructive
:loading="deleteProcessing"
@confirm="destroyAttendance"
/>
</template>