126 lines
4.0 KiB
Vue
126 lines
4.0 KiB
Vue
<script setup lang="ts">
|
|
import { ClassroomComplianceAPIClient, type Class, type Entry, type Student, type StudentStatisticsOverview } from '@/api/classroom_compliance'
|
|
import ConfirmDialog from '@/components/ConfirmDialog.vue'
|
|
import { useAuthStore } from '@/stores/auth'
|
|
import { onMounted, ref, useTemplateRef, type Ref } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import StudentEntriesList from './StudentEntriesList.vue'
|
|
|
|
const props = defineProps<{
|
|
classId: string
|
|
studentId: string
|
|
}>()
|
|
const authStore = useAuthStore()
|
|
const router = useRouter()
|
|
|
|
const cls: Ref<Class | null> = ref(null)
|
|
const student: Ref<Student | null> = ref(null)
|
|
const entries: Ref<Entry[]> = ref([])
|
|
const statistics: Ref<StudentStatisticsOverview | null> = ref(null)
|
|
|
|
const apiClient = new ClassroomComplianceAPIClient(authStore)
|
|
const deleteConfirmDialog = useTemplateRef('deleteConfirmDialog')
|
|
onMounted(async () => {
|
|
const classIdNumber = parseInt(props.classId, 10)
|
|
cls.value = await apiClient.getClass(classIdNumber).handleErrorsWithAlert()
|
|
if (!cls.value) {
|
|
await router.replace('/classroom-compliance')
|
|
return
|
|
}
|
|
const studentIdNumber = parseInt(props.studentId, 10)
|
|
student.value = await apiClient.getStudent(classIdNumber, studentIdNumber).handleErrorsWithAlert()
|
|
if (!student.value) {
|
|
await router.replace(`/classroom-compliance/classes/${cls.value.id}`)
|
|
return
|
|
}
|
|
|
|
apiClient.getStudentEntries(cls.value.id, student.value.id).handleErrorsWithAlert()
|
|
.then(values => {
|
|
if (values !== null) {
|
|
entries.value = values
|
|
}
|
|
})
|
|
apiClient.getStudentStatisticsOverview(cls.value.id, student.value.id).handleErrorsWithAlert()
|
|
.then(stats => statistics.value = stats)
|
|
})
|
|
|
|
async function deleteThisStudent() {
|
|
if (!cls.value || !student.value) return
|
|
const choice = await deleteConfirmDialog.value?.show()
|
|
if (!choice) return
|
|
await apiClient.deleteStudent(cls.value.id, student.value.id)
|
|
await router.replace(`/classroom-compliance/classes/${cls.value.id}`)
|
|
}
|
|
</script>
|
|
<template>
|
|
<div v-if="student" class="centered-content">
|
|
<h2 class="align-center" v-text="student.name"></h2>
|
|
<p class="align-center">
|
|
From
|
|
<RouterLink :to="'/classroom-compliance/classes/' + classId">
|
|
<span v-text="'class ' + cls?.number + ', ' + cls?.schoolYear"></span>
|
|
</RouterLink>
|
|
</p>
|
|
|
|
<div class="button-bar align-center">
|
|
<button type="button"
|
|
@click="router.push(`/classroom-compliance/classes/${student.classId}/edit-student?studentId=${student.id}`)">Edit</button>
|
|
<button type="button" @click="deleteThisStudent">Delete</button>
|
|
</div>
|
|
|
|
<table class="student-properties-table">
|
|
<tbody>
|
|
<tr>
|
|
<th>Desk Number</th>
|
|
<td>{{ student.deskNumber }}</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Removed</th>
|
|
<td>{{ student.removed ? 'True' : 'False' }}</td>
|
|
</tr>
|
|
<tr v-if="statistics">
|
|
<th>Attendance Rate</th>
|
|
<td>{{ (statistics.attendanceRate * 100).toFixed(1) }}%</td>
|
|
</tr>
|
|
<tr v-if="statistics">
|
|
<th>Phone Compliance Rate</th>
|
|
<td>{{ (statistics.phoneComplianceRate * 100).toFixed(1) }}%</td>
|
|
</tr>
|
|
<tr v-if="statistics">
|
|
<th>Behavior Score</th>
|
|
<td>{{ (statistics.behaviorScore * 100).toFixed(1) }}%</td>
|
|
</tr>
|
|
<tr v-if="statistics">
|
|
<th>Total Entries</th>
|
|
<td>{{ statistics.entryCount }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<StudentEntriesList :student="student" />
|
|
|
|
<ConfirmDialog ref="deleteConfirmDialog">
|
|
<p>
|
|
Are you sure you want to delete <span v-text="student.name"></span>? This will permanently
|
|
delete all records for them.
|
|
</p>
|
|
<p>This <strong>cannot</strong> be undone!</p>
|
|
</ConfirmDialog>
|
|
</div>
|
|
</template>
|
|
<style scoped>
|
|
.student-properties-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
}
|
|
|
|
.student-properties-table :is(th, td) {
|
|
border: 1px solid gray;
|
|
padding: 0.25em;
|
|
}
|
|
|
|
.student-properties-table td {
|
|
text-align: right;
|
|
}
|
|
</style>
|