All files / js/components AuditLogTimeline.vue

0% Statements 0/14
0% Branches 0/10
0% Functions 0/5
0% Lines 0/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90                                                                                                                                                                                   
<script setup lang="ts">
import { Link } from '@inertiajs/vue3';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent } from '@/components/ui/card';
import { Calendar, User, Eye } from 'lucide-vue-next';
 
interface AuditLog {
    id: number;
    event: string;
    description: string;
    user: {
        id: number;
        name: string;
    } | null;
    created_at: string;
}
 
const props = defineProps<{
    auditLogs: AuditLog[];
    modelType?: string;
    modelId?: number;
}>();
 
function getEventBadgeVariant(event: string): string {
    const variants: Record<string, string> = {
        created: 'default',
        updated: 'secondary',
        deleted: 'destructive',
        restored: 'outline',
    };
    return variants[event] || 'default';
}
 
function formatDate(date: string): string {
    return new Date(date).toLocaleString();
}
</script>
 
<template>
    <div class="rounded-lg bg-white border border-gray-200 shadow-sm">
        <div class="border-b border-gray-200 bg-purple-50 px-6 py-4">
            <h2 class="text-lg font-semibold text-gray-900 flex items-center">
                <svg class="w-5 h-5 mr-2 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
                </svg>
                Activity History
            </h2>
            <p class="text-sm text-gray-600">Track all changes made to this record</p>
        </div>
        <div class="p-6">
            <div v-if="auditLogs.length === 0" class="py-8 text-center text-sm text-gray-500">
                <svg class="mx-auto h-12 w-12 text-gray-400 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
                </svg>
                <p>No activity history yet. Changes to this record will be tracked here.</p>
            </div>
            <div v-else class="space-y-4">
                <div
                    v-for="log in auditLogs"
                    :key="log.id"
                    class="flex items-start gap-4 border-l-2 border-gray-300 pl-4"
                >
                    <div class="flex-1">
                        <div class="mb-1 flex items-center gap-2">
                            <Badge :variant="getEventBadgeVariant(log.event)" class="text-xs">
                                {{ log.event }}
                            </Badge>
                            <span class="text-sm text-gray-500">
                                {{ formatDate(log.created_at) }}
                            </span>
                        </div>
                        <div class="mb-2 text-sm text-gray-900">{{ log.description }}</div>
                        <div v-if="log.user" class="flex items-center gap-1 text-xs text-gray-500">
                            <User class="h-3 w-3" />
                            {{ log.user.name }}
                        </div>
                    </div>
                    <Link
                        :href="`/audit-logs/${log.id}`"
                        class="text-blue-600 hover:underline"
                    >
                        <Eye class="h-4 w-4" />
                    </Link>
                </div>
            </div>
        </div>
    </div>
</template>