First pass of training report form, lacks attendees
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { trainingReportSchema, courseEventAttendeeSchema } from '@shared/schemas/trainingReportSchema'
|
||||
import { Course } from '@shared/types/course'
|
||||
import { useForm, useFieldArray } from 'vee-validate'
|
||||
import { Course, CourseAttendee } from '@shared/types/course'
|
||||
import { useForm, useFieldArray, FieldArray as VeeFieldArray, ErrorMessage, Field as VeeField } from 'vee-validate'
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import {
|
||||
FormControl,
|
||||
@@ -13,72 +13,85 @@ import {
|
||||
} from '@/components/ui/form'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { getAllTrainings } from '@/api/trainingReport'
|
||||
import { Member } from '@/api/member'
|
||||
import { getMembers, Member } from '@/api/member'
|
||||
import FieldGroup from '../ui/field/FieldGroup.vue'
|
||||
import Field from '../ui/field/Field.vue'
|
||||
import FieldLabel from '../ui/field/FieldLabel.vue'
|
||||
import Input from '../ui/input/Input.vue'
|
||||
import FieldError from '../ui/field/FieldError.vue'
|
||||
import Button from '../ui/button/Button.vue'
|
||||
import Textarea from '../ui/textarea/Textarea.vue'
|
||||
|
||||
console.log(trainingReportSchema instanceof z.ZodType)
|
||||
|
||||
const form = useForm({ validationSchema: toTypedSchema(trainingReportSchema) });
|
||||
|
||||
const { fields: attendeeFields, push, remove } = useFieldArray({
|
||||
name: 'attendees',
|
||||
const { handleSubmit, resetForm } = useForm({
|
||||
validationSchema: toTypedSchema(trainingReportSchema),
|
||||
initialValues: {
|
||||
course_id: null,
|
||||
event_date: "",
|
||||
remarks: "",
|
||||
}
|
||||
})
|
||||
|
||||
function onSubmit(vals) {
|
||||
console.log(vals);
|
||||
// TODO: move this date conversion to a date library
|
||||
const clean = {
|
||||
...vals,
|
||||
event_date: new Date(vals.event_date).toISOString(),
|
||||
}
|
||||
|
||||
console.log("SUBMITTED:", clean)
|
||||
}
|
||||
|
||||
import z from 'zod'
|
||||
const schema = z.object({ x: z.string() })
|
||||
const typed = toTypedSchema(schema)
|
||||
console.log(typed)
|
||||
|
||||
|
||||
const trainings = ref<Course[] | null>(null);
|
||||
const members = ref<Member[] | null>(null);
|
||||
|
||||
onMounted(async () => {
|
||||
trainings.value = await getAllTrainings();
|
||||
members.value = await getMembers();
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<form @submit="form.handleSubmit(onSubmit)">
|
||||
<form id="trainingForm" @submit.prevent="handleSubmit(onSubmit)" class="flex flex-col gap-5">
|
||||
<FieldGroup>
|
||||
<VeeField v-slot="{ field, errors }" name="course_id">
|
||||
<Field :data-invalid="!!errors.length">
|
||||
<FieldLabel>Training Course</FieldLabel>
|
||||
|
||||
<!-- Training report fields here -->
|
||||
<select v-bind="field" class="border rounded p-2 w-full">
|
||||
<option value="" disabled>Select a course</option>
|
||||
<option v-for="course in trainings" :key="course.id" :value="course.id">
|
||||
{{ course.name }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<div class="my-6">
|
||||
<h2 class="font-semibold text-lg mb-4">Attendees</h2>
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</Field>
|
||||
</VeeField>
|
||||
</FieldGroup>
|
||||
<FieldGroup>
|
||||
<VeeField v-slot="{ field, errors }" name="event_date">
|
||||
<Field :data-invalid="!!errors.length">
|
||||
<FieldLabel>Event Date</FieldLabel>
|
||||
|
||||
<div v-for="(field, idx) in attendeeFields" :key="field.key" class="mb-4 p-4 border rounded">
|
||||
<input type="date" v-bind="field" class="border rounded p-2 w-full" />
|
||||
|
||||
<!-- attendee_id -->
|
||||
<FormField name="attendees[idx].attendee_id" v-slot="{ componentField }">
|
||||
<FormItem>
|
||||
<FormLabel>Attendee ID</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="number" v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<!-- passed -->
|
||||
<FormField name="attendees[idx].passed" v-slot="{ componentField }">
|
||||
<FormItem>
|
||||
<FormLabel>Passed</FormLabel>
|
||||
<FormControl>
|
||||
<Checkbox v-bind="componentField" />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
|
||||
<Button variant="destructive" @click.prevent="remove(idx)">Remove</Button>
|
||||
</div>
|
||||
|
||||
<Button @click.prevent="push({ attendee_id: null, attendee_role_id: null, passed: false, remarks: null })">
|
||||
Add Attendee
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Button type="submit">Submit Report</Button>
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</Field>
|
||||
</VeeField>
|
||||
</FieldGroup>
|
||||
|
||||
<FieldGroup>
|
||||
<VeeField v-slot="{ field, errors }" name="remarks">
|
||||
<Field :data-invalid="!!errors.length">
|
||||
<FieldLabel>Remarks</FieldLabel>
|
||||
<Textarea v-bind="field" placeholder="Any remarks about this training event..."
|
||||
autocomplete="off" />
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</Field>
|
||||
</VeeField>
|
||||
</FieldGroup>
|
||||
<Field orientation="horizontal">
|
||||
<Button type="button" variant="outline" @click="resetForm">Reset</Button>
|
||||
<Button type="submit" form="trainingForm">Submit</Button>
|
||||
</Field>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user