wip: init form entry education assessment
import clinical const from sheets wip: form entry add education assessment done: checkbox wip: add select Asesmen Kemampuan dan Kemauan Belajar
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
<script setup lang="ts">
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import { Form } from '~/components/pub/ui/form'
|
||||
|
||||
import * as DE from '~/components/pub/my-ui/doc-entry'
|
||||
import Separator from '~/components/pub/ui/separator/Separator.vue'
|
||||
|
||||
import { BaseSelect, BaseTextarea, CheckboxGeneral, CheckboxSpecial } from './field'
|
||||
|
||||
// constant
|
||||
import {
|
||||
abilityCode,
|
||||
willCode,
|
||||
medObstacleCode,
|
||||
learnMethodCode,
|
||||
langClassCode,
|
||||
translatorSrcCode,
|
||||
} from '~/lib/clinical.constants'
|
||||
|
||||
const props = defineProps<{
|
||||
schema: any
|
||||
initialValues?: any
|
||||
}>()
|
||||
|
||||
const formSchema = toTypedSchema(props.schema)
|
||||
const formRef = ref()
|
||||
|
||||
defineExpose({
|
||||
validate: () => formRef.value?.validate(),
|
||||
resetForm: () => formRef.value?.resetForm(),
|
||||
setValues: (values: any, shouldValidate = true) => formRef.value?.setValues(values, shouldValidate),
|
||||
values: computed(() => formRef.value?.values),
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Form
|
||||
ref="formRef"
|
||||
v-slot="{ values }"
|
||||
as=""
|
||||
keep-values
|
||||
:validation-schema="formSchema"
|
||||
:validate-on-mount="false"
|
||||
validation-mode="onSubmit"
|
||||
:initial-values="initialValues ? initialValues : {}"
|
||||
>
|
||||
<p class="mb-2 text-sm font-semibold 2xl:mb-3 2xl:text-base">Kebutuhan Edukasi</p>
|
||||
<DE.Block
|
||||
:col-count="4"
|
||||
:cell-flex="false"
|
||||
>
|
||||
<CheckboxGeneral
|
||||
field-name="generalEducationNeeds"
|
||||
label="Informasi Umum"
|
||||
:col-span="2"
|
||||
/>
|
||||
<CheckboxSpecial
|
||||
field-name="specificEducationNeeds"
|
||||
label="Edukasi Khusus"
|
||||
:col-span="2"
|
||||
/>
|
||||
</DE.Block>
|
||||
|
||||
<div class="h-6">
|
||||
<Separator />
|
||||
</div>
|
||||
|
||||
<p class="mb-2 text-sm font-semibold 2xl:mb-3 2xl:text-base">Asesmen Kemampuan dan Kemauan Belajar</p>
|
||||
<DE.Block
|
||||
:col-count="3"
|
||||
:cell-flex="false"
|
||||
>
|
||||
<BaseSelect
|
||||
field-name="learningAbility"
|
||||
label="Kemampuan Belajar"
|
||||
:items="abilityCode"
|
||||
/>
|
||||
|
||||
<BaseSelect
|
||||
field-name="learningWillingness"
|
||||
label="Kemauan Belajar"
|
||||
:items="willCode"
|
||||
/>
|
||||
|
||||
<BaseSelect
|
||||
field-name="barrier"
|
||||
label="Hambatan"
|
||||
:items="medObstacleCode"
|
||||
/>
|
||||
|
||||
<BaseSelect
|
||||
field-name="learningMethod"
|
||||
label="Metode Pembelajaran"
|
||||
:items="learnMethodCode"
|
||||
/>
|
||||
|
||||
<BaseSelect
|
||||
field-name="language"
|
||||
label="Bahasa"
|
||||
:items="langClassCode"
|
||||
/>
|
||||
|
||||
<BaseSelect
|
||||
field-name="languageBarrier"
|
||||
label="Hambatan Bahasa"
|
||||
:items="translatorSrcCode"
|
||||
/>
|
||||
<BaseSelect
|
||||
field-name="beliefValue"
|
||||
label="Keyakinan pada Nilai-Nilai yang Dianut"
|
||||
:items="{
|
||||
ya: 'IYA',
|
||||
tidak: 'TIDAK',
|
||||
}"
|
||||
/>
|
||||
</DE.Block>
|
||||
<div class="h-6">
|
||||
<Separator />
|
||||
</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>
|
||||
</Form>
|
||||
</template>
|
||||
@@ -0,0 +1,64 @@
|
||||
<script setup lang="ts">
|
||||
import * as DE from '~/components/pub/my-ui/doc-entry'
|
||||
import { Checkbox } from '~/components/pub/ui/checkbox'
|
||||
|
||||
import type { CheckItem } from '~/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
label: string
|
||||
fieldName: string
|
||||
items: CheckItem[]
|
||||
colSpan?: number
|
||||
}>()
|
||||
|
||||
const { label, fieldName, items } = props
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DE.Cell :col-span="colSpan || 1">
|
||||
<DE.Label :label-for="fieldName">
|
||||
{{ label }}
|
||||
</DE.Label>
|
||||
|
||||
<DE.Field :id="fieldName">
|
||||
<FormField
|
||||
:name="fieldName"
|
||||
v-slot="{ value, handleChange }"
|
||||
>
|
||||
<FormItem>
|
||||
<div
|
||||
v-for="item in items"
|
||||
:key="item.id"
|
||||
class="ml-1 flex flex-row items-start space-x-3 space-y-0"
|
||||
>
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
:id="`cb-${fieldName}-${item.id}`"
|
||||
:checked="value?.includes(item.id)"
|
||||
@update:checked="
|
||||
(checked) => {
|
||||
const newValue = [...(value || [])]
|
||||
if (checked) {
|
||||
if (!newValue.includes(item.id)) newValue.push(item.id)
|
||||
} else {
|
||||
const idx = newValue.indexOf(item.id)
|
||||
if (idx > -1) newValue.splice(idx, 1)
|
||||
}
|
||||
handleChange(newValue)
|
||||
}
|
||||
"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel
|
||||
:for="`cb-${fieldName}-${item.id}`"
|
||||
class="font-normal leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 md:!text-xs 2xl:text-sm"
|
||||
>
|
||||
{{ item.label }}
|
||||
</FormLabel>
|
||||
</div>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</DE.Field>
|
||||
</DE.Cell>
|
||||
</template>
|
||||
@@ -0,0 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '~/components/pub/my-ui/form/select.vue'
|
||||
import { cn, mapToComboboxOptList } from '~/lib/utils'
|
||||
|
||||
import * as DE from '~/components/pub/my-ui/doc-entry'
|
||||
|
||||
const props = defineProps<{
|
||||
fieldName: string
|
||||
label: string
|
||||
items: Record<string, string>
|
||||
placeholder?: string
|
||||
class?: string
|
||||
selectClass?: string
|
||||
fieldGroupClass?: string
|
||||
labelClass?: string
|
||||
isRequired?: boolean
|
||||
}>()
|
||||
|
||||
const { placeholder = 'Pilih', class: containerClass, selectClass, fieldGroupClass, labelClass } = props
|
||||
|
||||
const religionOptions = mapToComboboxOptList(props.items)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DE.Cell :class="cn('select-field-group', fieldGroupClass, containerClass)">
|
||||
<DE.Label
|
||||
:label-for="fieldName"
|
||||
:class="cn('select-field-label', labelClass)"
|
||||
:is-required="isRequired"
|
||||
>
|
||||
{{ label }}
|
||||
</DE.Label>
|
||||
<DE.Field
|
||||
:id="fieldName"
|
||||
:class="cn('select-field-wrapper')"
|
||||
>
|
||||
<FormField
|
||||
v-slot="{ componentField }"
|
||||
:name="fieldName"
|
||||
>
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Select
|
||||
:id="fieldName"
|
||||
v-bind="componentField"
|
||||
:items="religionOptions"
|
||||
:placeholder="placeholder"
|
||||
:preserve-order="false"
|
||||
:class="
|
||||
cn(
|
||||
'text-sm transition-all duration-200 focus:outline-none focus:ring-1 focus:ring-black focus:ring-offset-0',
|
||||
selectClass,
|
||||
)
|
||||
"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</DE.Field>
|
||||
</DE.Cell>
|
||||
</template>
|
||||
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import * as DE from '~/components/pub/my-ui/doc-entry'
|
||||
|
||||
const props = defineProps<{
|
||||
label: string
|
||||
fieldName: string
|
||||
placeholder?: string
|
||||
colSpan?: number
|
||||
}>()
|
||||
|
||||
const { label, fieldName, placeholder = 'Masukkan catatan' } = props
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DE.Cell :col-span="colSpan || 1">
|
||||
<DE.Label :label-for="fieldName">
|
||||
{{ label }}
|
||||
</DE.Label>
|
||||
<DE.Field :id="fieldName">
|
||||
<FormField
|
||||
v-slot="{ componentField }"
|
||||
:name="fieldName"
|
||||
>
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Textarea
|
||||
v-bind="componentField"
|
||||
:placeholder="placeholder"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</DE.Field>
|
||||
</DE.Cell>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import BaseCheckbox from './base-checkbox.vue'
|
||||
import { generalEduCode } from '~/lib/clinical.constants'
|
||||
import { mapToCheckItems } from '~/lib/utils'
|
||||
|
||||
interface Props {
|
||||
label: string
|
||||
fieldName: string
|
||||
colSpan?: number
|
||||
}
|
||||
defineProps<Props>()
|
||||
|
||||
const generalItems = mapToCheckItems(generalEduCode)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BaseCheckbox
|
||||
:field-name="fieldName"
|
||||
:label="label"
|
||||
:col-span="colSpan"
|
||||
:items="generalItems"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import BaseCheckbox from './base-checkbox.vue'
|
||||
import { specialEduCode } from '~/lib/clinical.constants'
|
||||
import { mapToCheckItems } from '~/lib/utils'
|
||||
interface Props {
|
||||
label: string
|
||||
fieldName: string
|
||||
colSpan?: number
|
||||
}
|
||||
defineProps<Props>()
|
||||
|
||||
const specialItems = mapToCheckItems(specialEduCode)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BaseCheckbox
|
||||
:field-name="fieldName"
|
||||
:label="label"
|
||||
:col-span="colSpan"
|
||||
:items="specialItems"
|
||||
/>
|
||||
</template>
|
||||
@@ -0,0 +1,5 @@
|
||||
export { default as BaseSelect } from './base-select.vue'
|
||||
export { default as BaseTextarea } from './base-textarea.vue'
|
||||
export { default as CheckboxGeneral } from './checkbox-general.vue'
|
||||
export { default as CheckboxSpecial } from './checkbox-special.vue'
|
||||
export { default as SelectAssessmentCode } from './select-assessment-code.vue'
|
||||
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import * as DE from '~/components/pub/my-ui/doc-entry'
|
||||
|
||||
const props = defineProps<{
|
||||
label: string
|
||||
fieldName: string
|
||||
placeholder?: string
|
||||
colSpan?: number
|
||||
}>()
|
||||
|
||||
const { label, fieldName, placeholder = 'Masukkan catatan' } = props
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DE.Cell :col-span="colSpan || 1">
|
||||
<DE.Label :label-for="fieldName">
|
||||
{{ label }}
|
||||
</DE.Label>
|
||||
<DE.Field :id="fieldName">
|
||||
<FormField
|
||||
v-slot="{ componentField }"
|
||||
:name="fieldName"
|
||||
>
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Textarea
|
||||
v-bind="componentField"
|
||||
:placeholder="placeholder"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</DE.Field>
|
||||
</DE.Cell>
|
||||
</template>
|
||||
@@ -0,0 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import * as z from 'zod'
|
||||
import type { ExposedForm } from '~/types/form'
|
||||
|
||||
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'),
|
||||
|
||||
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',
|
||||
}),
|
||||
})
|
||||
|
||||
const form = ref<ExposedForm<any> | null>(null)
|
||||
|
||||
async function handleActionClick(eventType: string) {
|
||||
if (eventType === 'submit') {
|
||||
const isValid = await form.value?.validate()
|
||||
console.log(isValid)
|
||||
}
|
||||
|
||||
if (eventType === 'cancel') {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<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"
|
||||
/>
|
||||
|
||||
<div class="my-2 flex justify-end py-2">
|
||||
<Action @click="handleActionClick" />
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user