Files
simrsx-fe/app/components/app/soapi/early-entry.vue
T
2025-10-30 20:47:11 +07:00

348 lines
9.3 KiB
Vue

<script setup lang="ts">
import Block from '~/components/pub/my-ui/doc-entry/block.vue'
import Cell from '~/components/pub/my-ui/doc-entry/cell.vue'
import Field from '~/components/pub/my-ui/doc-entry/field.vue'
import Label from '~/components/pub/my-ui/doc-entry/label.vue'
// Helpers
import type z from 'zod'
import { toTypedSchema } from '@vee-validate/zod'
import { useForm } from 'vee-validate'
import { genBase } from '~/models/_base'
const props = defineProps<{
modelValue: any
schema: z.ZodSchema<any>
excludeFields?: string[]
isReadonly?: boolean
}>()
const emit = defineEmits<{
(e: 'update:modelValue', val: any): void
(e: 'submit', val: any): void
}>()
// Setup form
const {
validate: _validate,
defineField,
handleSubmit,
errors,
values,
} = useForm({
validationSchema: toTypedSchema(props.schema),
initialValues: props.modelValue,
})
watch(values, (val) => emit('update:modelValue', val), { deep: true })
const [primaryComplaint, primaryComplaintAttrs] = defineField('prim-compl')
const [curDiseaseHistory, curDiseaseHistoryAttrs] = defineField('cur-disea-hist')
const [systolic, systolicAttrs] = defineField('syst-bp')
const [diastolic, diastolicAttrs] = defineField('diast-bp')
const [pulse, pulseAttrs] = defineField('pulse')
const [respiratoryRate, respiratoryRateAttrs] = defineField('resp-rate')
const [temperature, temperatureAttrs] = defineField('temp')
const [weight, weightAttrs] = defineField('weight')
const [height, heightAttrs] = defineField('height')
const [bloodGroup, bloodGroupAttrs] = defineField('reflect-fisio')
const [physicalExamination, physicalExaminationAttrs] = defineField('reflect-pato')
const [diagnosisMedical, diagnosisMedicalAttrs] = defineField('autonom-neuron')
const [medicalPlan, medicalPlanAttrs] = defineField('medical-act')
const [therapy, therapyAttrs] = defineField('therapy')
const validate = async () => {
const result = await _validate()
console.log('Component validate() result:', result)
return {
valid: true,
data: result.values,
errors: result.errors,
}
}
defineExpose({ validate })
const icdPreview = inject('icdPreview')
const isExcluded = (key: string) => props.excludeFields?.includes(key)
</script>
<template>
<form id="entry-form">
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
<Block>
<Cell>
<Label dynamic>Sudah Vaksin</Label>
<Field>
<RadioGroup class="flex gap-4">
<div class="flex items-center space-x-2">
<RadioGroupItem
id="vaksin-yes"
value="yes"
/>
<Label for="vaksin-yes">Sudah</Label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem
id="vaksin-no"
value="no"
/>
<Label for="vaksin-no">Belum</Label>
</div>
</RadioGroup>
</Field>
</Cell>
<Cell>
<Label dynamic>Kasus</Label>
<Field>
<RadioGroup class="flex gap-4">
<div class="flex items-center space-x-2">
<RadioGroupItem
id="kasus-baru"
value="baru"
/>
<Label for="kasus-baru">Baru</Label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem
id="kasus-lama"
value="lama"
/>
<Label for="kasus-lama">Lama</Label>
</div>
</RadioGroup>
</Field>
</Cell>
<Cell>
<Label dynamic>Kunjungan</Label>
<Field>
<RadioGroup class="flex gap-4">
<div class="flex items-center space-x-2">
<RadioGroupItem
id="kunjungan-baru"
value="baru"
/>
<Label for="kunjungan-baru">Baru</Label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem
id="kunjungan-lama"
value="lama"
/>
<Label for="kunjungan-lama">Lama</Label>
</div>
</RadioGroup>
</Field>
</Cell>
</Block>
<Block :colCount="2">
<Cell>
<Label dynamic>Keluhan Utama</Label>
<Field :errMessage="errors['prim-compl']">
<Textarea
placeholder="Masukkan anamnesa pasien"
v-model="primaryComplaint"
v-bind="primaryComplaintAttrs"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Riwayat Penyakit</Label>
<Field>
<Textarea
placeholder=".."
v-model="curDiseaseHistory"
v-bind="curDiseaseHistoryAttrs"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>SpO₂</Label>
<Field>
<Input
type="number"
placeholder="%"
v-model="spo2"
v-bind="spo2Attrs"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Tekanan Darah Sistol</Label>
<Field>
<Input
type="number"
placeholder="mmHg"
v-model="systolic"
v-bind="systolicAttrs"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Tekanan Darah Diastol</Label>
<Field>
<Input
v-model="diastolic"
v-bind="diastolicAttrs"
type="number"
placeholder="mmHg"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Respirasi</Label>
<Field>
<Input
v-model="respiratoryRate"
v-bind="respiratoryRateAttrs"
type="number"
placeholder="kali/menit"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Nadi</Label>
<Field>
<Input
v-model="pulse"
v-bind="pulseAttrs"
type="number"
placeholder="kali/menit"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Temperatur</Label>
<Field>
<Input
v-model="temperature"
v-bind="temperatureAttrs"
type="number"
placeholder="℃"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Berat Badan</Label>
<Field>
<Input
v-model="weight"
v-bind="weightAttrs"
type="number"
placeholder="Kg"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Tinggi Badan</Label>
<Field>
<Input
v-model="height"
v-bind="heightAttrs"
type="number"
placeholder="Cm"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Golongan Darah</Label>
<Field>
<Select
:options="bloodGroups"
v-model="bloodGroup"
v-bind="bloodGroupAttrs"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Pemeriksaan Fisik (Yang Mendukung)</Label>
<Field>
<Textarea
placeholder="Masukkan pemeriksaan fisik"
v-model="physicalExamination"
v-bind="physicalExaminationAttrs"
/>
</Field>
</Cell>
<!-- Prosedur -->
<Cell>
<Label dynamic>Diagnosa (ICD-X)</Label>
<Field>
<Button
class="rounded bg-orange-100 px-3 py-1 text-orange-600"
type="button"
@click="emit('modal', 'diagnosa')"
>
+ Pilih Diagnosa
</Button>
</Field>
</Cell>
<!-- Diagnosa -->
<Cell>
<Label dynamic>Diagnosa (ICD-X)</Label>
<Field>
<Button
class="rounded bg-orange-100 px-3 py-1 text-orange-600"
type="button"
@click="emit('modal', 'prosedur')"
>
+ Pilih Prosedur
</Button>
</Field>
</Cell>
</Block>
<div class="mb-8 grid grid-cols-2 gap-4">
<AppIcdPreview v-model="icdPreview.diagnoses" />
<AppIcdPreview v-model="icdPreview.procedures" />
</div>
<Block :colCount="3">
<Cell>
<Label dynamic>Diagnosa Medis</Label>
<Field>
<Textarea
v-model="diagnosisMedical"
v-bind="diagnosisMedicalAttrs"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Rencana Awal Medis</Label>
<Field>
<Textarea
v-model="medicalPlan"
v-bind="medicalPlanAttrs"
/>
</Field>
</Cell>
<Cell>
<Label dynamic>Terapi</Label>
<Field>
<Textarea
v-model="therapy"
v-bind="therapyAttrs"
/>
</Field>
</Cell>
</Block>
</div>
</form>
</template>