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:
@@ -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">
|
||||
|
||||
@@ -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 }
|
||||
Reference in New Issue
Block a user