implemented most of the viewing training reports UI

This commit is contained in:
2025-11-17 00:21:38 -05:00
parent 1d35fe1cf5
commit 1df4893c67
2 changed files with 71 additions and 10 deletions

View File

@@ -13,3 +13,14 @@ export async function getTrainingReports(): Promise<CourseEventSummary[]> {
throw new Error("Failed to load training reports"); throw new Error("Failed to load training reports");
} }
} }
export async function getTrainingReport(id: number): Promise<CourseEventDetails> {
const res = await fetch(`${addr}/courseEvent/${id}`);
if (res.ok) {
return await res.json() as Promise<CourseEventDetails>;
} else {
console.error("Something went wrong");
throw new Error("Failed to load training reports");
}
}

View File

@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { getTrainingReports } from '@/api/trainingReport'; import { getTrainingReport, getTrainingReports } from '@/api/trainingReport';
import { trainingReportSchema, courseEventAttendeeSchema } from '@shared/schemas/trainingReportSchema' import { trainingReportSchema, courseEventAttendeeSchema } from '@shared/schemas/trainingReportSchema'
import { CourseEventDetails, CourseEventSummary } from '@shared/types/course'; import { CourseAttendee, CourseEventDetails, CourseEventSummary } from '@shared/types/course';
import { toTypedSchema } from '@vee-validate/zod'; import { toTypedSchema } from '@vee-validate/zod';
import { onMounted, ref } from 'vue'; import { computed, onMounted, ref } from 'vue';
import { import {
Table, Table,
TableBody, TableBody,
@@ -14,11 +14,28 @@ import {
TableHeader, TableHeader,
TableRow, TableRow,
} from '@/components/ui/table' } from '@/components/ui/table'
import { Separator } from '@/components/ui/separator'
import { X } from 'lucide-vue-next';
const trainingReports = ref<CourseEventSummary[] | null>(null); const trainingReports = ref<CourseEventSummary[] | null>(null);
const loaded = ref(false); const loaded = ref(false);
const focusedTrainingReport = ref<CourseEventDetails | null>(null); const focusedTrainingReport = ref<CourseEventDetails | null>(null);
const focusedTrainingTrainees = computed<CourseAttendee[] | null>(() => {
if (focusedTrainingReport == null) return null;
return focusedTrainingReport.value.attendees.filter((attendee) => attendee.attendee_role_id == 2);
})
const focusedTrainingTrainers = computed<CourseAttendee[] | null>(() => {
if (focusedTrainingReport == null) return null;
return focusedTrainingReport.value.attendees.filter((attendee) => attendee.attendee_role_id != 2);
})
async function viewTrainingReport(id: number) {
focusedTrainingReport.value = await getTrainingReport(id);
}
async function closeTrainingReport() {
focusedTrainingReport.value = null;
}
onMounted(async () => { onMounted(async () => {
trainingReports.value = await getTrainingReports(); trainingReports.value = await getTrainingReports();
@@ -27,8 +44,9 @@ onMounted(async () => {
</script> </script>
<template> <template>
<div class="max-w-5xl mx-auto"> <div class="max-w-7xl mx-auto flex">
<div> <!-- training report list -->
<div class="px-4" :class="focusedTrainingReport == null ? 'w-full' : 'w-1/2'">
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
@@ -42,18 +60,50 @@ onMounted(async () => {
</TableRow> </TableRow>
</TableHeader> </TableHeader>
<TableBody v-if="loaded"> <TableBody v-if="loaded">
<TableRow v-for="report in trainingReports" @click="console.log(report.event_id);"> <TableRow class="cursor-pointer" v-for="report in trainingReports" :key="report.event_id"
@click="viewTrainingReport(report.event_id);">
<TableCell class="font-medium">{{ report.course_name }}</TableCell> <TableCell class="font-medium">{{ report.course_name }}</TableCell>
<TableCell>{{ report.date }}</TableCell> <TableCell>{{ report.date }}</TableCell>
<TableCell class="text-right">{{ report.created_by === null ? "Unknown User" : report.created_by }}</TableCell> <TableCell class="text-right">{{ report.created_by === null ? "Unknown User" : report.created_by
}}</TableCell>
</TableRow> </TableRow>
</TableBody> </TableBody>
</Table> </Table>
</div> </div>
<!-- view training report section --> <!-- view training report section -->
<div v-if="focusedTrainingReport != null" class="px-4 border-l w-1/2">
<div class="flex justify-between my-3">
<div class="flex gap-5">
<p>{{ focusedTrainingReport.course_name }}</p>
<p class="text-muted-foreground">{{ focusedTrainingReport.event_date }}</p>
</div>
<button @click="closeTrainingReport">
<X></X>
</button>
</div>
<div class="flex flex-col gap-5">
<!-- {{ focusedTrainingReport }} -->
<div> <div>
DETAILS <label>Trainers</label>
<div v-for="person in focusedTrainingTrainers" class="grid grid-cols-4 my-2">
<p>{{ person.attendee_id }}</p>
<p class="text-right px-5">{{ person.passed }}</p>
<p class="bg-muted p-2 rounded-lg min-h-[1lh] col-span-2 text-right">{{ person.remarks }}</p>
</div>
</div>
<div>
<label>Trainees</label>
<div v-for="person in focusedTrainingTrainees" class="grid grid-cols-4 my-2">
<p>{{ person.attendee_id }}</p>
<p class="text-right px-5">{{ person.passed }}</p>
<p class="bg-muted p-2 rounded-lg min-h-[1lh] col-span-2 text-right">{{ person.remarks }}</p>
</div>
</div>
<div>
<label>Remarks</label>
<p class="bg-muted p-2 rounded-lg min-h-24"> {{ focusedTrainingReport.remarks }}</p>
</div>
</div>
</div> </div>
</div> </div>
</template> </template>