hooked up UI to API

This commit is contained in:
2025-11-19 13:58:37 -05:00
parent 403a8b394c
commit 7850767967
4 changed files with 47 additions and 30 deletions

View File

@@ -67,19 +67,5 @@ eventRouter.post('/', async (req: Request, res: Response) => {
} }
}) })
// //insert a new latest rank for a user
// ur.post('/', async (req, res) => {
// try {
// const change = req.body?.change;
// await insertMemberRank(change.member_id, change.rank_id, change.date);
// res.sendStatus(201);
// } catch (err) {
// console.error('Insert failed:', err);
// res.status(500).json({ error: 'Failed to update ranks' });
// }
// });
module.exports.courseRouter = courseRouter; module.exports.courseRouter = courseRouter;
module.exports.eventRouter = eventRouter; module.exports.eventRouter = eventRouter;

View File

@@ -61,14 +61,15 @@ export async function getCourseEventDetails(id: number): Promise<CourseEventDeta
} }
export async function insertCourseEvent(event: CourseEventDetails): Promise<number> { export async function insertCourseEvent(event: CourseEventDetails): Promise<number> {
console.log(event);
const con = await pool.getConnection(); const con = await pool.getConnection();
try { try {
await con.beginTransaction(); await con.beginTransaction();
const res = await con.execute("INSERT INTO course_events (course_id, event_date, remarks) VALUES (?, ?, ?);", [event.course_id, event.event_date, event.remarks]); const res = await con.query("INSERT INTO course_events (course_id, event_date, remarks) VALUES (?, ?, ?);", [event.course_id, event.event_date, event.remarks]);
var eventID: number = res.insertId; var eventID: number = res.insertId;
for (const attendee of event.attendees) { for (const attendee of event.attendees) {
await con.execute(`INSERT INTO course_attendees ( await con.query(`INSERT INTO course_attendees (
attendee_id, attendee_id,
course_event_id, course_event_id,
attendee_role_id, attendee_role_id,
@@ -78,12 +79,12 @@ export async function insertCourseEvent(event: CourseEventDetails): Promise<numb
VALUES (?, ?, ?, ?, ?);`, [attendee.attendee_id, eventID, attendee.attendee_role_id, attendee.passed, attendee.remarks]); VALUES (?, ?, ?, ?, ?);`, [attendee.attendee_id, eventID, attendee.attendee_role_id, attendee.passed, attendee.remarks]);
} }
await con.commit(); await con.commit();
} catch (error) {
await con.rollback();
throw error;
} finally {
await con.release(); await con.release();
return eventID; return eventID;
} catch (error) {
await con.rollback();
await con.release();
throw error;
} }
} }

View File

@@ -45,4 +45,21 @@ export async function getAllAttendeeRoles(): Promise<CourseAttendeeRole[]> {
console.error("Something went wrong"); console.error("Something went wrong");
throw new Error("Failed to load attendee roles"); throw new Error("Failed to load attendee roles");
} }
} }
export async function postTrainingReport(report: CourseEventDetails) {
const res = await fetch(`${addr}/courseEvent`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(report),
});
if (!res.ok) {
const errorText = await res.text();
throw new Error(`Failed to post training report: ${res.status} ${errorText}`);
}
return res.json(); // expected to return the inserted report or new ID
}

View File

@@ -1,10 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { trainingReportSchema, courseEventAttendeeSchema } from '@shared/schemas/trainingReportSchema' import { trainingReportSchema, courseEventAttendeeSchema } from '@shared/schemas/trainingReportSchema'
import { Course, CourseAttendee, CourseAttendeeRole } from '@shared/types/course' import { Course, CourseAttendee, CourseAttendeeRole, CourseEventDetails } from '@shared/types/course'
import { useForm, useFieldArray, FieldArray as VeeFieldArray, ErrorMessage, Field as VeeField } from 'vee-validate' import { useForm, useFieldArray, FieldArray as VeeFieldArray, ErrorMessage, Field as VeeField } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod' import { toTypedSchema } from '@vee-validate/zod'
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import { getAllAttendeeRoles, getAllTrainings } from '@/api/trainingReport' import { getAllAttendeeRoles, getAllTrainings, postTrainingReport } from '@/api/trainingReport'
import { getMembers, Member } from '@/api/member' import { getMembers, Member } from '@/api/member'
import FieldGroup from '../ui/field/FieldGroup.vue' import FieldGroup from '../ui/field/FieldGroup.vue'
import Field from '../ui/field/Field.vue' import Field from '../ui/field/Field.vue'
@@ -30,14 +30,27 @@ const { handleSubmit, resetForm, errors } = useForm({
const submitForm = handleSubmit(onSubmit); const submitForm = handleSubmit(onSubmit);
function onSubmit(vals) { function toMySQLDateTime(date: Date): string {
// TODO: move this date conversion to a date library return date
const clean = { .toISOString() // 2025-11-19T00:00:00.000Z
...vals, .slice(0, 23) // keep milliseconds → 2025-11-19T00:00:00.000
event_date: new Date(vals.event_date).toISOString(), .replace("T", " ") + "000"; // becomes → 2025-11-19 00:00:00.000000
} }
console.log("SUBMITTED:", clean)
function onSubmit(vals) {
try {
const clean: CourseEventDetails = {
...vals,
event_date: toMySQLDateTime(new Date(vals.event_date)),
}
postTrainingReport(clean);
console.log("SUBMITTED:", clean)
} catch(err) {
console.log("There was an error submitting the training report", err);
}
} }
const { remove, push, fields } = useFieldArray('attendees'); const { remove, push, fields } = useFieldArray('attendees');