Major style pass to the form
This commit is contained in:
@@ -73,46 +73,54 @@ onMounted(async () => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<form id="trainingForm" @submit.prevent="submitForm" class="flex flex-col gap-5 pl-2">
|
<form id="trainingForm" @submit.prevent="submitForm" class="flex flex-col gap-5">
|
||||||
|
|
||||||
<FieldGroup>
|
<div class="flex gap-5">
|
||||||
<VeeField v-slot="{ field, errors }" name="course_id">
|
<div class="flex-1">
|
||||||
<Field :data-invalid="!!errors.length">
|
<FieldGroup>
|
||||||
<FieldLabel>Training Course</FieldLabel>
|
<VeeField v-slot="{ field, errors }" name="course_id">
|
||||||
|
<Field :data-invalid="!!errors.length">
|
||||||
<select v-bind="field"
|
<FieldLabel class="scroll-m-20 text-lg tracking-tight">Training Course</FieldLabel>
|
||||||
class="border rounded p-2 w-full focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] bg-background outline-none">
|
<select v-bind="field"
|
||||||
<option value="" disabled>Select a course</option>
|
class="h-9 border rounded p-2 w-auto focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] bg-background outline-none">
|
||||||
<option v-for="course in trainings" :key="course.id" :value="course.id">
|
<option value="" disabled>Select a course</option>
|
||||||
{{ course.name }}
|
<option v-for="course in trainings" :key="course.id" :value="course.id">
|
||||||
</option>
|
{{ course.name }}
|
||||||
</select>
|
</option>
|
||||||
|
</select>
|
||||||
<FieldError v-if="errors.length" :errors="errors" />
|
<div class="h-4">
|
||||||
</Field>
|
<FieldError v-if="errors.length" :errors="errors" />
|
||||||
</VeeField>
|
</div>
|
||||||
</FieldGroup>
|
</Field>
|
||||||
<FieldGroup>
|
</VeeField>
|
||||||
<VeeField v-slot="{ field, errors }" name="event_date">
|
</FieldGroup>
|
||||||
<Field :data-invalid="!!errors.length">
|
</div>
|
||||||
<FieldLabel>Event Date</FieldLabel>
|
<div class="w-[150px]">
|
||||||
<input type="date" v-bind="field"
|
<FieldGroup>
|
||||||
class="border rounded p-2 w-full focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] bg-background outline-none" />
|
<VeeField v-slot="{ field, errors }" name="event_date">
|
||||||
<FieldError v-if="errors.length" :errors="errors" />
|
<Field :data-invalid="!!errors.length">
|
||||||
</Field>
|
<FieldLabel class="scroll-m-20 text-lg tracking-tight">Event Date</FieldLabel>
|
||||||
</VeeField>
|
<input type="date" v-bind="field"
|
||||||
</FieldGroup>
|
class="h-9 border rounded p-2 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] bg-background outline-none" />
|
||||||
|
<div class="h-4">
|
||||||
|
<FieldError v-if="errors.length" :errors="errors" />
|
||||||
|
</div>
|
||||||
|
</Field>
|
||||||
|
</VeeField>
|
||||||
|
</FieldGroup>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<VeeFieldArray name="attendees" v-slot="{ fields, push, remove }">
|
<VeeFieldArray name="attendees" v-slot="{ fields, push, remove }">
|
||||||
<FieldSet class="gap-4">
|
<FieldSet class="gap-4">
|
||||||
<FieldLegend>Attendees</FieldLegend>
|
<FieldLegend class="scroll-m-20 text-lg tracking-tight">Attendees</FieldLegend>
|
||||||
<FieldDescription>Add members who attended this session.</FieldDescription>
|
<FieldDescription>Add members who attended this session.</FieldDescription>
|
||||||
|
|
||||||
<FieldGroup class="gap-4">
|
<FieldGroup class="gap-4">
|
||||||
|
|
||||||
<!-- Column Headers -->
|
<!-- Column Headers -->
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-[180px_160px_50px_50px_1fr_auto] gap-3 font-medium text-sm text-muted-foreground px-1">
|
class="grid grid-cols-[180px_150px_65px_45px_1fr_auto] gap-3 font-medium text-sm text-muted-foreground px-1">
|
||||||
<div>Member</div>
|
<div>Member</div>
|
||||||
<div>Role</div>
|
<div>Role</div>
|
||||||
<div>Bookwork</div>
|
<div>Bookwork</div>
|
||||||
@@ -137,7 +145,9 @@ onMounted(async () => {
|
|||||||
{{ m.member_name }}
|
{{ m.member_name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<FieldError v-if="e.length" :errors="e" />
|
<div class="h-4">
|
||||||
|
<FieldError v-if="e.length" :errors="e" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</VeeField>
|
</VeeField>
|
||||||
|
|
||||||
@@ -151,14 +161,16 @@ onMounted(async () => {
|
|||||||
{{ r.name }}
|
{{ r.name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<FieldError v-if="e.length" :errors="e" />
|
<div class="h-4">
|
||||||
|
<FieldError v-if="e.length" :errors="e" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</VeeField>
|
</VeeField>
|
||||||
|
|
||||||
<!-- Passed Checkbox -->
|
<!-- Passed Checkbox -->
|
||||||
<VeeField v-slot="{ field }" :name="`attendees[${index}].passed_bookwork`" type="checkbox"
|
<VeeField v-slot="{ field }" :name="`attendees[${index}].passed_bookwork`" type="checkbox"
|
||||||
:value="true" :unchecked-value="false">
|
:value="true" :unchecked-value="false">
|
||||||
<div class="flex justify-center">
|
<div class="flex flex-col items-center">
|
||||||
<div class="relative inline-flex items-center group">
|
<div class="relative inline-flex items-center group">
|
||||||
|
|
||||||
<Checkbox :disabled="!selectedCourse?.hasBookwork"
|
<Checkbox :disabled="!selectedCourse?.hasBookwork"
|
||||||
@@ -174,13 +186,15 @@ onMounted(async () => {
|
|||||||
This course does not have bookwork
|
This course does not have bookwork
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="h-4">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</VeeField>
|
</VeeField>
|
||||||
|
|
||||||
<!-- Passed Checkbox -->
|
<!-- Passed Checkbox -->
|
||||||
<VeeField v-slot="{ field }" :name="`attendees[${index}].passed_qual`" type="checkbox"
|
<VeeField v-slot="{ field }" :name="`attendees[${index}].passed_qual`" type="checkbox"
|
||||||
:value="true" :unchecked-value="false">
|
:value="true" :unchecked-value="false">
|
||||||
<div class="flex justify-center">
|
<div class="flex flex-col items-center">
|
||||||
<div class="relative inline-flex items-center group">
|
<div class="relative inline-flex items-center group">
|
||||||
<Checkbox :disabled="!selectedCourse?.hasQual"
|
<Checkbox :disabled="!selectedCourse?.hasQual"
|
||||||
:name="`attendees[${index}].passed_qual`" v-bind="field"></Checkbox>
|
:name="`attendees[${index}].passed_qual`" v-bind="field"></Checkbox>
|
||||||
@@ -194,6 +208,8 @@ onMounted(async () => {
|
|||||||
This course does not have a qualification
|
This course does not have a qualification
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="h-4">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</VeeField>
|
</VeeField>
|
||||||
|
|
||||||
@@ -203,14 +219,21 @@ onMounted(async () => {
|
|||||||
<textarea v-bind="f"
|
<textarea v-bind="f"
|
||||||
class="h-[38px] resize-none border rounded p-2 w-full focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] bg-background outline-none"
|
class="h-[38px] resize-none border rounded p-2 w-full focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] bg-background outline-none"
|
||||||
placeholder="Optional remarks"></textarea>
|
placeholder="Optional remarks"></textarea>
|
||||||
<FieldError v-if="e.length" :errors="e" />
|
<div class="h-4">
|
||||||
|
<FieldError v-if="e.length" :errors="e" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</VeeField>
|
</VeeField>
|
||||||
|
|
||||||
<!-- Remove button -->
|
<div>
|
||||||
<Button type="button" variant="ghost" size="sm" @click="remove(index)" class="self-center">
|
<!-- Remove button -->
|
||||||
<X :size="10" />
|
<Button type="button" variant="ghost" size="sm" @click="remove(index)"
|
||||||
</Button>
|
class="self-center">
|
||||||
|
<X :size="10" />
|
||||||
|
</Button>
|
||||||
|
<div class="h-4">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</FieldGroup>
|
</FieldGroup>
|
||||||
@@ -224,19 +247,19 @@ onMounted(async () => {
|
|||||||
</FieldSet>
|
</FieldSet>
|
||||||
</VeeFieldArray>
|
</VeeFieldArray>
|
||||||
|
|
||||||
<FieldGroup>
|
<FieldGroup class="pt-3">
|
||||||
<VeeField v-slot="{ field, errors }" name="remarks">
|
<VeeField v-slot="{ field, errors }" name="remarks">
|
||||||
<Field :data-invalid="!!errors.length">
|
<Field :data-invalid="!!errors.length">
|
||||||
<FieldLabel>Remarks</FieldLabel>
|
<FieldLabel class="scroll-m-20 text-lg tracking-tight">Remarks</FieldLabel>
|
||||||
<Textarea v-bind="field" placeholder="Any remarks about this training event..."
|
<Textarea v-bind="field" placeholder="Any remarks about this training event..."
|
||||||
autocomplete="off" />
|
autocomplete="off" />
|
||||||
<FieldError v-if="errors.length" :errors="errors" />
|
<FieldError v-if="errors.length" :errors="errors" />
|
||||||
</Field>
|
</Field>
|
||||||
</VeeField>
|
</VeeField>
|
||||||
</FieldGroup>
|
</FieldGroup>
|
||||||
<Field orientation="horizontal">
|
<div class="flex gap-3 justify-end">
|
||||||
<Button type="button" variant="outline" @click="resetForm">Reset</Button>
|
<Button type="button" variant="outline" @click="resetForm">Reset</Button>
|
||||||
<Button type="submit" form="trainingForm">Submit</Button>
|
<Button type="submit" form="trainingForm">Submit</Button>
|
||||||
</Field>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from '@/components/ui/table'
|
} from '@/components/ui/table'
|
||||||
import { X } from 'lucide-vue-next';
|
import { Plus, X } from 'lucide-vue-next';
|
||||||
import Button from '@/components/ui/button/Button.vue';
|
import Button from '@/components/ui/button/Button.vue';
|
||||||
import TrainingReportForm from '@/components/trainingReport/trainingReportForm.vue';
|
import TrainingReportForm from '@/components/trainingReport/trainingReportForm.vue';
|
||||||
import Checkbox from '@/components/ui/checkbox/Checkbox.vue';
|
import Checkbox from '@/components/ui/checkbox/Checkbox.vue';
|
||||||
@@ -56,12 +56,12 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="max-w-7xl mx-auto flex mt-5">
|
<div class="px-20 mx-auto max-w-[100rem] flex mt-5">
|
||||||
<!-- training report list -->
|
<!-- training report list -->
|
||||||
<div class="px-4" :class="sidePanel == sidePanelState.closed ? 'w-full' : 'w-2/5'">
|
<div class="px-4 my-3" :class="sidePanel == sidePanelState.closed ? 'w-full' : 'w-2/5'">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<p class="scroll-m-20 text-2xl font-semibold tracking-tight">Training Reports</p>
|
<p class="scroll-m-20 text-2xl font-semibold tracking-tight">Training Reports</p>
|
||||||
<Button @click="createTrainingReport">New Training Report</Button>
|
<Button @click="createTrainingReport"><Plus></Plus> New Training Report</Button>
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-y-auto max-h-[70vh] mt-5 scrollbar-themed">
|
<div class="overflow-y-auto max-h-[70vh] mt-5 scrollbar-themed">
|
||||||
<Table>
|
<Table>
|
||||||
@@ -72,7 +72,7 @@ onMounted(async () => {
|
|||||||
</TableHead>
|
</TableHead>
|
||||||
<TableHead>Date</TableHead>
|
<TableHead>Date</TableHead>
|
||||||
<TableHead class="text-right">
|
<TableHead class="text-right">
|
||||||
Posted By
|
Posted By
|
||||||
</TableHead>
|
</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
@@ -90,7 +90,7 @@ onMounted(async () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- view training report section -->
|
<!-- view training report section -->
|
||||||
<div v-if="sidePanel == sidePanelState.view" class="px-4 border-l w-3/5">
|
<div v-if="sidePanel == sidePanelState.view" class="px-4 my-3 border-l w-3/5">
|
||||||
<div class="flex justify-between my-3">
|
<div class="flex justify-between my-3">
|
||||||
<div class="flex gap-5">
|
<div class="flex gap-5">
|
||||||
<p>{{ focusedTrainingReport.course_name }}</p>
|
<p>{{ focusedTrainingReport.course_name }}</p>
|
||||||
@@ -132,17 +132,17 @@ onMounted(async () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="sidePanel == sidePanelState.create" class="px-4 border-l w-3/5">
|
<div v-if="sidePanel == sidePanelState.create" class="pl-7 border-l w-3/5 max-w-5xl">
|
||||||
<div class="flex justify-between my-3">
|
<div class="flex justify-between my-3">
|
||||||
<div class="flex gap-5">
|
<div class="flex pl-2 gap-5">
|
||||||
<p>New Training Report</p>
|
<p class="scroll-m-20 text-2xl font-semibold tracking-tight">New Training Report</p>
|
||||||
</div>
|
</div>
|
||||||
<button @click="closeTrainingReport" class="cursor-pointer">
|
<button @click="closeTrainingReport" class="cursor-pointer">
|
||||||
<X></X>
|
<X></X>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-y-auto max-h-[70vh] mt-5 scrollbar-themed">
|
<div class="overflow-y-auto max-h-[70vh] mt-5 scrollbar-themed">
|
||||||
<TrainingReportForm class="w-full"
|
<TrainingReportForm class="w-full pl-2"
|
||||||
@submit="(newID) => { viewTrainingReport(newID); loadTrainingReports() }"></TrainingReportForm>
|
@submit="(newID) => { viewTrainingReport(newID); loadTrainingReports() }"></TrainingReportForm>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user