store/resources/js/components/admin/system/activity-logs/ActivityLogDetailModal.vue

95 lines
3.6 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import type { ActivityLogListItem } from '@/types/activity-log';
const open = defineModel<boolean>('open', { default: false });
const props = defineProps<{
activityLog?: ActivityLogListItem | null;
}>();
const hasChanges = computed(() => (props.activityLog?.changes.length ?? 0) > 0);
function formatValue(value: unknown): string {
if (value === null || value === undefined || value === '') {
return '-';
}
if (typeof value === 'boolean') {
return value ? 'Ya' : 'Tidak';
}
if (typeof value === 'object') {
return JSON.stringify(value);
}
return String(value);
}
</script>
<template>
<Dialog v-model:open="open">
<DialogContent class="max-h-[85vh] overflow-y-auto sm:max-w-lg">
<DialogHeader>
<DialogTitle>Detail Log Aktivitas</DialogTitle>
</DialogHeader>
<div v-if="activityLog" class="space-y-4 text-sm">
<div class="grid gap-3 sm:grid-cols-2">
<div>
<p class="text-muted-foreground">Waktu</p>
<p class="font-medium">{{ activityLog.created_at_formatted ?? '-' }}</p>
</div>
<div>
<p class="text-muted-foreground">Pengguna</p>
<p class="font-medium">{{ activityLog.causer_name }}</p>
</div>
<div>
<p class="text-muted-foreground">Aksi</p>
<p class="font-medium">{{ activityLog.event_label }}</p>
</div>
<div>
<p class="text-muted-foreground">Modul</p>
<p class="font-medium">{{ activityLog.subject_label }}</p>
</div>
</div>
<div>
<p class="text-muted-foreground">Deskripsi</p>
<p class="font-medium">{{ activityLog.description }}</p>
</div>
<div v-if="hasChanges" class="space-y-2">
<p class="font-medium">Perubahan Data</p>
<div class="overflow-hidden rounded-md border">
<table class="w-full text-sm">
<thead class="bg-muted/50">
<tr>
<th class="px-3 py-2 text-left font-medium">Field</th>
<th class="px-3 py-2 text-left font-medium">Sebelum</th>
<th class="px-3 py-2 text-left font-medium">Sesudah</th>
</tr>
</thead>
<tbody>
<tr v-for="change in activityLog.changes" :key="change.field" class="border-t">
<td class="px-3 py-2 align-top font-medium">{{ change.field }}</td>
<td class="px-3 py-2 align-top text-muted-foreground">{{ formatValue(change.old) }}</td>
<td class="px-3 py-2 align-top">{{ formatValue(change.new) }}</td>
</tr>
</tbody>
</table>
</div>
</div>
<p v-else class="text-muted-foreground">Tidak ada perubahan data yang tercatat.</p>
</div>
</DialogContent>
</Dialog>
</template>