NuxtAuthDashboardRepository/frontend/pages/students/index.vue

94 lines
2.8 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="p-6">
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-bold">👨🎓 Students List</h2>
<NuxtLink to="/students/add" class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">
Add Student
</NuxtLink>
</div>
<div v-if="loading" class="text-gray-500">Loading students...</div>
<div v-else-if="students.length">
<table class="min-w-full bg-white shadow-md rounded 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">Name</th>
<th class="text-left px-4 py-2">Email</th>
<th class="text-left px-4 py-2">Class</th>
<th class="text-left px-4 py-2">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="(student, index) in students" :key="student.id" class="border-t">
<td class="px-4 py-2">{{ index + 1 }}</td>
<td class="px-4 py-2">{{ student.name }}</td>
<td class="px-4 py-2">{{ student.email }}</td>
<td class="px-4 py-2">
{{ student.class_id?.name }} - {{ student.class_id?.section }}
</td>
<td class="px-4 py-2 flex gap-2">
<NuxtLink :to="`/students?id=${student.id}`" class="text-sm text-blue-600 hover:underline">View</NuxtLink>
<NuxtLink :to="`/students/edit?id=${student.id}`" class="text-sm text-yellow-600 hover:underline">Edit
</NuxtLink>
<button @click="deleteStudent(student.id)" class="text-sm text-red-600 hover:underline">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
<div v-else class="text-gray-500">No students found.</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useDirectus } from '../../app/composables/useDirectus'
const { fetchCollection, deleteItem } = useDirectus()
const students = ref([])
const loading = ref(true)
const fetchStudents = async () => {
try {
students.value = await fetchCollection('students', {
fields: ['id', 'name', 'email', 'class_id.name', 'class_id.section'],
sort: ['name']
})
} catch (err) {
console.error('Failed to fetch students:', err)
} finally {
loading.value = false
}
}
const deleteStudent = async (id) => {
if (!confirm('Are you sure you want to delete this student?')) return
try {
await deleteItem('students', id)
students.value = students.value.filter((s) => s.id !== id)
alert('Student deleted!')
} catch (err) {
console.error('Error deleting student:', err)
alert('Failed to delete student.')
}
}
onMounted(fetchStudents)
</script>
<style scoped>
table {
border-collapse: collapse;
}
th,
td {
border-bottom: 1px solid #e5e7eb;
}
</style>