feat(assessment-education): finish form entry data

finish form tambah assessment education

finish: form data and schema for content assessment eduction

todo: handler dan service
This commit is contained in:
Khafid Prayoga
2025-10-22 11:43:10 +07:00
parent 736e951f33
commit d879325496
6 changed files with 180 additions and 61 deletions
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { toTypedSchema } from '@vee-validate/zod'
import { FieldArray } from 'vee-validate'
import { Form } from '~/components/pub/ui/form'
import * as DE from '~/components/pub/my-ui/doc-entry'
@@ -17,10 +18,20 @@ import {
translatorSrcCode,
} from '~/lib/clinical.constants'
const props = defineProps<{
interface Props {
schema: any
initialValues?: any
}>()
isLoading?: boolean
isReadonly?: boolean
noteLimit?: number
}
const props = withDefaults(defineProps<Props>(), {
isLoading: false,
isReadonly: false,
noteLimit: 10,
})
const isDisabled = computed(() => props.isLoading || props.isReadonly)
const formSchema = toTypedSchema(props.schema)
const formRef = ref()
@@ -36,13 +47,21 @@ defineExpose({
<template>
<Form
ref="formRef"
v-slot="{ values }"
as=""
keep-values
:validation-schema="formSchema"
:validate-on-mount="false"
validation-mode="onSubmit"
:initial-values="initialValues ? initialValues : {}"
:initial-values="
initialValues || {
plans: [
{
id: 1,
value: '',
},
],
}
"
>
<p class="mb-2 text-sm font-semibold 2xl:mb-3 2xl:text-base">Kebutuhan Edukasi</p>
<DE.Block
@@ -53,11 +72,13 @@ defineExpose({
field-name="generalEducationNeeds"
label="Informasi Umum"
:col-span="2"
:is-disabled="isDisabled"
/>
<CheckboxSpecial
field-name="specificEducationNeeds"
label="Edukasi Khusus"
:col-span="2"
:is-disabled="isDisabled"
/>
</DE.Block>
@@ -74,37 +95,44 @@ defineExpose({
field-name="learningAbility"
label="Kemampuan Belajar"
:items="abilityCode"
:is-disabled="isDisabled"
/>
<BaseSelect
field-name="learningWillingness"
label="Kemauan Belajar"
:items="willCode"
:is-disabled="isDisabled"
/>
<BaseSelect
field-name="barrier"
label="Hambatan"
:items="medObstacleCode"
:is-disabled="isDisabled"
/>
<BaseSelect
field-name="learningMethod"
label="Metode Pembelajaran"
:items="learnMethodCode"
:is-disabled="isDisabled"
/>
<BaseSelect
field-name="language"
label="Bahasa"
:items="langClassCode"
:is-disabled="isDisabled"
/>
<BaseSelect
field-name="languageBarrier"
label="Hambatan Bahasa"
:items="translatorSrcCode"
:is-disabled="isDisabled"
/>
<BaseSelect
field-name="beliefValue"
label="Keyakinan pada Nilai-Nilai yang Dianut"
@@ -112,6 +140,7 @@ defineExpose({
ya: 'IYA',
tidak: 'TIDAK',
}"
:is-disabled="isDisabled"
/>
</DE.Block>
<div class="h-6">
@@ -119,19 +148,61 @@ defineExpose({
</div>
<p class="mb-2 text-sm font-semibold 2xl:mb-3 2xl:text-base">Rencana Edukasi</p>
<DE.Block>
<BaseTextarea
field-name="recommendation"
label="Plan A"
/>
<BaseTextarea
field-name="recommendation"
label="Plan B"
/>
<BaseTextarea
field-name="recommendation"
label="Plan Plan Pak Supir"
/>
<DE.Block
:col-count="1"
:cell-flex="false"
>
<FieldArray
v-slot="{ fields, push, remove }"
name="plans"
>
<div
:col-count="2"
v-for="(field, idx) in fields"
:key="field.key"
>
<DE.Block
:col-count="4"
:cell-flex="false"
>
<DE.Cell :col-span="3">
<BaseTextarea
:field-name="`plans[${idx}].value`"
:label="'Rencana ' + Number(idx + 1)"
/>
</DE.Cell>
<Button
type="button"
variant="outline"
size="icon"
class="mt-5 text-red-600 hover:border-red-400 hover:bg-red-50 hover:text-red-700 dark:border-red-400 dark:text-red-400 dark:hover:border-red-300 dark:hover:bg-red-900/20"
:class="{ invisible: idx === 0 }"
@click="remove(idx)"
>
<Icon
name="i-lucide-trash-2"
class="h-5 w-5"
/>
</Button>
</DE.Block>
</div>
<div class="self-center pt-3">
<Button
:disabled="fields.length >= noteLimit"
type="button"
variant="outline"
size="sm"
@click="push({ id: fields.length + 1, value: '' })"
>
<Icon
name="i-lucide-plus"
class="h-5 w-5"
/>
Tambah Kontak
</Button>
</div>
</FieldArray>
</DE.Block>
</Form>
</template>
@@ -8,6 +8,7 @@ const props = defineProps<{
label: string
fieldName: string
items: CheckItem[]
isDisabled?: boolean
colSpan?: number
}>()
@@ -33,6 +34,7 @@ const { label, fieldName, items } = props
>
<FormControl>
<Checkbox
:disabled="isDisabled"
:id="`cb-${fieldName}-${item.id}`"
:checked="value?.includes(item.id)"
@update:checked="
@@ -6,6 +6,7 @@ import { mapToCheckItems } from '~/lib/utils'
interface Props {
label: string
fieldName: string
isDisabled?: boolean
colSpan?: number
}
defineProps<Props>()
@@ -17,6 +18,7 @@ const generalItems = mapToCheckItems(generalEduCode)
<BaseCheckbox
:field-name="fieldName"
:label="label"
:is-disabled="isDisabled"
:col-span="colSpan"
:items="generalItems"
/>
@@ -39,7 +39,7 @@ defineExpose({
<div>
<p
v-if="props.title"
class="text-sm 2xl:text-base mb-2 2xl:mb-3 font-semibold"
class="mb-2 text-sm font-semibold 2xl:mb-3 2xl:text-base"
>
{{ props.title || 'Kontak Pasien' }}
</p>
@@ -1,60 +1,43 @@
<script setup lang="ts">
import * as z from 'zod'
import type { ExposedForm } from '~/types/form'
import { type AssessmentEducationFormData, AssessmentEducationSchema } from '~/schemas/assessment-education'
import Action from '~/components/pub/my-ui/nav-footer/ba-dr-su.vue'
const schema = z.object({
generalEducationNeeds: z
.array(z.string(), {
required_error: 'Mohon pilih setidaknya item',
})
.min(1, 'Mohon pilih setidaknya item'),
// Handlers
import { isReadonly, isProcessing, onResetState, handleActionSave, handleCancelForm } from '~/handlers/infra.handler'
specificEducationNeeds: z
.array(z.string(), {
required_error: 'Mohon pilih setidaknya item',
})
.min(1, 'Mohon pilih setidaknya item'),
// Helpers
import { toast } from '~/components/pub/ui/toast'
learningAbility: z.string({
required_error: 'Mohon pilih kemampuan belajar',
}),
// Services
import { getList, getDetail } from '~/services/infra.service'
learningWillingness: z.string({
required_error: 'Mohon pilih kemauan belajar',
}),
const form = ref<ExposedForm<AssessmentEducationFormData> | null>(null)
barrier: z.string({
required_error: 'Mohon pilih hambatan',
}),
async function saveData(values: AssessmentEducationFormData) {
handleActionSave(
values,
() => {
window.location.reload()
},
() => {},
toast,
)
console.log('sending data')
console.log(values)
}
learningMethod: z.string({
required_error: 'Mohon pilih metode pembelajaran',
}),
language: z.string({
required_error: 'Mohon pilih bahasa',
}),
languageBarrier: z.string({
required_error: 'Mohon pilih hambatan bahasa',
}),
beliefValue: z.string({
required_error: 'Mohon pilih keyakinan pada nilai-nilai yang dianut',
}),
})
const form = ref<ExposedForm<any> | null>(null)
async function cancelData() {}
async function handleActionClick(eventType: string) {
if (eventType === 'submit') {
const isValid = await form.value?.validate()
console.log(isValid)
const formValidate = await form.value?.validate()
if (!formValidate?.valid) return
saveData(formValidate?.values)
}
if (eventType === 'cancel') {
cancelData()
}
}
</script>
@@ -63,7 +46,11 @@ async function handleActionClick(eventType: string) {
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg font-semibold xl:text-xl">Tambah Asesmen Edukasi</div>
<AppAssessmentEducationEntryForm
ref="form"
:schema="schema"
:is-readonly="isReadonly"
:is-loading="isProcessing"
:schema="AssessmentEducationSchema"
@submit=""
@cancel=""
/>
<div class="my-2 flex justify-end py-2">
+57
View File
@@ -0,0 +1,57 @@
import * as z from 'zod'
const AssessmentEducationSchema = z.object({
generalEducationNeeds: z
.array(z.string(), {
required_error: 'Mohon pilih setidaknya item',
})
.min(1, 'Mohon pilih setidaknya item'),
specificEducationNeeds: z
.array(z.string(), {
required_error: 'Mohon pilih setidaknya item',
})
.min(1, 'Mohon pilih setidaknya item'),
learningAbility: z.string({
required_error: 'Mohon pilih kemampuan belajar',
}),
learningWillingness: z.string({
required_error: 'Mohon pilih kemauan belajar',
}),
barrier: z.string({
required_error: 'Mohon pilih hambatan',
}),
learningMethod: z.string({
required_error: 'Mohon pilih metode pembelajaran',
}),
language: z.string({
required_error: 'Mohon pilih bahasa',
}),
languageBarrier: z.string({
required_error: 'Mohon pilih hambatan bahasa',
}),
beliefValue: z.string({
required_error: 'Mohon pilih keyakinan pada nilai-nilai yang dianut',
}),
plans: z
.array(
z.object({
id: z.number(),
value: z.string().nonempty('Mohon masukkan catatan'),
}),
)
.min(1, 'Minimal 1 catatan rencana studi'),
})
type AssessmentEducationFormData = z.infer<typeof AssessmentEducationSchema>
export { AssessmentEducationSchema }
export type { AssessmentEducationFormData }