79 lines
2.4 KiB
Vue
79 lines
2.4 KiB
Vue
<template>
|
|
<div class="p-6">
|
|
<h2 class="text-2xl font-bold mb-6">📆 Student Attendance Records</h2>
|
|
|
|
<div v-if="loading" class="text-gray-500">Loading attendance...</div>
|
|
|
|
<div v-else-if="records.length">
|
|
<table class="min-w-full bg-white shadow-md rounded-lg overflow-hidden">
|
|
<thead class="bg-gray-100">
|
|
<tr>
|
|
<th class="text-left px-4 py-2">#</th>
|
|
<th class="text-left px-4 py-2">Student Name</th>
|
|
<th class="text-left px-4 py-2">Class</th>
|
|
<th class="text-left px-4 py-2">Date</th>
|
|
<th class="text-left px-4 py-2">Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="(record, index) in records" :key="record.id" class="border-t">
|
|
<td class="px-4 py-2">{{ index + 1 }}</td>
|
|
<td class="px-4 py-2">{{ record.student_id?.name || '—' }}</td>
|
|
<td class="px-4 py-2">{{ record.student_id?.class_id?.name || '—' }} {{ record.student_id?.class_id?.section }}</td>
|
|
<td class="px-4 py-2">{{ record.date }}</td>
|
|
<td class="px-4 py-2">
|
|
<span
|
|
:class="record.status === 'present' ? 'text-green-600 font-semibold' : 'text-red-600 font-semibold'"
|
|
>
|
|
{{ record.status }}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div v-else class="text-gray-500 mt-4">No attendance records found.</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue'
|
|
import { useDirectus } from '../../app/composables/useDirectus'
|
|
|
|
const directus = useDirectus()
|
|
const records = ref([])
|
|
const loading = ref(true)
|
|
|
|
onMounted(async () => {
|
|
try {
|
|
const { data } = await directus.items('attendance').readByQuery({
|
|
fields: [
|
|
'id',
|
|
'date',
|
|
'status',
|
|
'student_id.id',
|
|
'student_id.name',
|
|
'student_id.class_id.name',
|
|
'student_id.class_id.section'
|
|
],
|
|
sort: ['-date']
|
|
})
|
|
records.value = data
|
|
} catch (err) {
|
|
console.error('Error fetching attendance:', err)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
table {
|
|
border-collapse: collapse;
|
|
}
|
|
th, td {
|
|
border-bottom: 1px solid #e5e7eb;
|
|
}
|
|
</style>
|
|
|