Merge branch 'dev' into fe-prescription-56

This commit is contained in:
Andrian Roshandy
2025-10-24 12:40:59 +07:00
19 changed files with 1340 additions and 181 deletions
+1
View File
@@ -1,3 +1,4 @@
NUXT_MAIN_API_ORIGIN= NUXT_MAIN_API_ORIGIN=
NUXT_BPJS_API_ORIGIN= NUXT_BPJS_API_ORIGIN=
NUXT_SYNC_API_ORIGIN= NUXT_SYNC_API_ORIGIN=
NUXT_API_ORIGIN=
+15 -3
View File
@@ -27,19 +27,31 @@ const data = computed({
<FieldGroup :column="2"> <FieldGroup :column="2">
<Label>Status</Label> <Label>Status</Label>
<Field> <Field>
<Select v-model="data.type" :items="items" placeholder="Pilih jenis" /> <Select
v-model="data.type"
:items="items"
placeholder="Pilih jenis"
/>
</Field> </Field>
</FieldGroup> </FieldGroup>
<FieldGroup :column="2"> <FieldGroup :column="2">
<Label>Position</Label> <Label>Position</Label>
<Field> <Field>
<Select v-model="data.type" :items="items" placeholder="Pilih jenis" /> <Select
v-model="data.type"
:items="items"
placeholder="Pilih jenis"
/>
</Field> </Field>
</FieldGroup> </FieldGroup>
<FieldGroup :column="2"> <FieldGroup :column="2">
<Label>Divisi</Label> <Label>Divisi</Label>
<Field> <Field>
<Select v-model="data.type" :items="items" placeholder="Pilih jenis" /> <Select
v-model="data.type"
:items="items"
placeholder="Pilih jenis"
/>
</Field> </Field>
</FieldGroup> </FieldGroup>
</Block> </Block>
+26 -11
View File
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import * as DE from '~/components/pub/my-ui/doc-entry'; import * as DE from '~/components/pub/my-ui/doc-entry'
import type { Encounter } from '~/models/encounter'; import type { Encounter } from '~/models/encounter'
const props = defineProps<{ const props = defineProps<{
data: Encounter data: Encounter
@@ -8,27 +8,31 @@ const props = defineProps<{
let address = '' let address = ''
if (props.data.patient.person.addresses) { if (props.data.patient.person.addresses) {
address = props.data.patient.person.addresses.map(a => a.address).join(', ') address = props.data.patient.person.addresses.map((a) => a.address).join(', ')
} }
let dpjp = ''; let dpjp = ''
if (props.data.responsible_doctor) { if (props.data.responsible_doctor) {
const dp = props.data.responsible_doctor.employee.person const dp = props.data.responsible_doctor.employee.person
dpjp = `${dp.frontTitle} ${dp.name} ${dp.endTitle}` dpjp = `${dp.frontTitle} ${dp.name} ${dp.endTitle}`
} else if (props.data.appointment_doctor) { } else if (props.data.appointment_doctor) {
dpjp = props.data.appointment_doctor.employee.person.name dpjp = props.data.appointment_doctor.employee.person.name
} }
</script> </script>
<template> <template>
<div class="w-full rounded-md border bg-white dark:bg-neutral-950 p-4 shadow-sm"> <div class="w-full rounded-md border bg-white p-4 shadow-sm dark:bg-neutral-950">
<!-- Data Pasien --> <!-- Data Pasien -->
<h2 class="mb-2 md:text-base 2xl:text-lg font-semibold">{{ data.patient.person.name }} - {{ data.patient.number }}</h2> <h2 class="mb-2 font-semibold md:text-base 2xl:text-lg">
{{ data.patient.person.name }} - {{ data.patient.number }}
</h2>
<div class="grid grid-cols-3"> <div class="grid grid-cols-3">
<div> <div>
<DE.Block mode="preview" labelSize="large"> <DE.Block
mode="preview"
labelSize="large"
>
<DE.Cell> <DE.Cell>
<DE.Label class="font-semibold">No. RM</DE.Label> <DE.Label class="font-semibold">No. RM</DE.Label>
<DE.Field> <DE.Field>
@@ -50,7 +54,10 @@ if (props.data.responsible_doctor) {
</DE.Block> </DE.Block>
</div> </div>
<div> <div>
<DE.Block mode="preview" labelSize="large"> <DE.Block
mode="preview"
labelSize="large"
>
<DE.Cell> <DE.Cell>
<DE.Label class="font-semibold">Tgl. Kunjungan</DE.Label> <DE.Label class="font-semibold">Tgl. Kunjungan</DE.Label>
<DE.Field> <DE.Field>
@@ -72,9 +79,17 @@ if (props.data.responsible_doctor) {
</DE.Block> </DE.Block>
</div> </div>
<div> <div>
<DE.Block mode="preview" labelSize="large"> <DE.Block
mode="preview"
labelSize="large"
>
<DE.Cell> <DE.Cell>
<DE.Label position="dynamic" class="!text-base 2xl:!text-lg font-semibold">Billing</DE.Label> <DE.Label
position="dynamic"
class="!text-base font-semibold 2xl:!text-lg"
>
Billing
</DE.Label>
<DE.Field class="text-base 2xl:text-lg"> <DE.Field class="text-base 2xl:text-lg">
Rp. 000.000 Rp. 000.000
<!-- {{ data }} --> <!-- {{ data }} -->
+163 -38
View File
@@ -4,29 +4,72 @@ import Cell from '~/components/pub/my-ui/doc-entry/cell.vue'
import Field from '~/components/pub/my-ui/doc-entry/field.vue' import Field from '~/components/pub/my-ui/doc-entry/field.vue'
import Label from '~/components/pub/my-ui/doc-entry/label.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<{ const props = defineProps<{
modelValue: any
schema: z.ZodSchema<any>
excludeFields?: string[] excludeFields?: string[]
isReadonly?: boolean
}>() }>()
const emits = defineEmits(['click']) const emit = defineEmits<{
(e: 'update:modelValue', val: any): void
(e: 'submit', val: any): void
}>()
const subject = ref({ // Setup form
'prim-compl': '', const {
'sec-compl': '', validate: _validate,
'cur-disea-hist': '', defineField,
'pas-disea-hist': '', handleSubmit,
'fam-disea-hist': '', errors,
'alg-hist': '', values,
'alg-react': '', } = useForm({
'med-hist': '', validationSchema: toTypedSchema(props.schema),
'blood-type': '', 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 isExcluded = (key: string) => props.excludeFields?.includes(key) const isExcluded = (key: string) => props.excludeFields?.includes(key)
</script> </script>
<template> <template>
<form id="entry-form"> <form id="entry-form">
{{ errors }}
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl"> <div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
<Block> <Block>
<Cell> <Cell>
@@ -34,11 +77,17 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Field> <Field>
<RadioGroup class="flex gap-4"> <RadioGroup class="flex gap-4">
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<RadioGroupItem id="vaksin-yes" value="yes" /> <RadioGroupItem
id="vaksin-yes"
value="yes"
/>
<Label for="vaksin-yes">Sudah</Label> <Label for="vaksin-yes">Sudah</Label>
</div> </div>
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<RadioGroupItem id="vaksin-no" value="no" /> <RadioGroupItem
id="vaksin-no"
value="no"
/>
<Label for="vaksin-no">Belum</Label> <Label for="vaksin-no">Belum</Label>
</div> </div>
</RadioGroup> </RadioGroup>
@@ -50,11 +99,17 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Field> <Field>
<RadioGroup class="flex gap-4"> <RadioGroup class="flex gap-4">
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<RadioGroupItem id="kasus-baru" value="baru" /> <RadioGroupItem
id="kasus-baru"
value="baru"
/>
<Label for="kasus-baru">Baru</Label> <Label for="kasus-baru">Baru</Label>
</div> </div>
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<RadioGroupItem id="kasus-lama" value="lama" /> <RadioGroupItem
id="kasus-lama"
value="lama"
/>
<Label for="kasus-lama">Lama</Label> <Label for="kasus-lama">Lama</Label>
</div> </div>
</RadioGroup> </RadioGroup>
@@ -66,11 +121,17 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Field> <Field>
<RadioGroup class="flex gap-4"> <RadioGroup class="flex gap-4">
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<RadioGroupItem id="kunjungan-baru" value="baru" /> <RadioGroupItem
id="kunjungan-baru"
value="baru"
/>
<Label for="kunjungan-baru">Baru</Label> <Label for="kunjungan-baru">Baru</Label>
</div> </div>
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<RadioGroupItem id="kunjungan-lama" value="lama" /> <RadioGroupItem
id="kunjungan-lama"
value="lama"
/>
<Label for="kunjungan-lama">Lama</Label> <Label for="kunjungan-lama">Lama</Label>
</div> </div>
</RadioGroup> </RadioGroup>
@@ -79,88 +140,141 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
</Block> </Block>
<Block :colCount="2"> <Block :colCount="2">
<!-- Riwayat Penyakit -->
<Cell> <Cell>
<Label dynamic>Keluhan Utama</Label> <Label dynamic>Keluhan Utama</Label>
<Field> <Field :errMessage="errors['prim-compl']">
<Textarea placeholder="Masukkan anamnesa pasien" /> <Textarea
placeholder="Masukkan anamnesa pasien"
v-model="primaryComplaint"
v-bind="primaryComplaintAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Riwayat Penyakit</Label> <Label dynamic>Riwayat Penyakit</Label>
<Field> <Field>
<Textarea <Textarea
placeholder="Masukkan anamnesa pasien (Riwayat Penyakit Sekarang, Dahulu, Pengobatan, Keluarga, dll)" placeholder=".."
v-model="curDiseaseHistory"
v-bind="curDiseaseHistoryAttrs"
/> />
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>SpO₂</Label> <Label dynamic>SpO₂</Label>
<Field> <Field>
<Input type="number" placeholder="%" /> <Input
type="number"
placeholder="%"
v-model="spo2"
v-bind="spo2Attrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Tekanan Darah Sistol</Label> <Label dynamic>Tekanan Darah Sistol</Label>
<Field> <Field>
<Input type="number" placeholder="mmHg" /> <Input
type="number"
placeholder="mmHg"
v-model="systolic"
v-bind="systolicAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Tekanan Darah Diastol</Label> <Label dynamic>Tekanan Darah Diastol</Label>
<Field> <Field>
<Input type="number" placeholder="mmHg" /> <Input
v-model="diastolic"
v-bind="diastolicAttrs"
type="number"
placeholder="mmHg"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Respirasi</Label> <Label dynamic>Respirasi</Label>
<Field> <Field>
<Input type="number" placeholder="kali/menit" /> <Input
v-model="respiratoryRate"
v-bind="respiratoryRateAttrs"
type="number"
placeholder="kali/menit"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Nadi</Label> <Label dynamic>Nadi</Label>
<Field> <Field>
<Input type="number" placeholder="kali/menit" /> <Input
v-model="pulse"
v-bind="pulseAttrs"
type="number"
placeholder="kali/menit"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Temperatur</Label> <Label dynamic>Temperatur</Label>
<Field> <Field>
<Input type="number" placeholder="℃" /> <Input
v-model="temperature"
v-bind="temperatureAttrs"
type="number"
placeholder="℃"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Berat Badan</Label> <Label dynamic>Berat Badan</Label>
<Field> <Field>
<Input type="number" placeholder="Kg" /> <Input
v-model="weight"
v-bind="weightAttrs"
type="number"
placeholder="Kg"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Tinggi Badan</Label> <Label dynamic>Tinggi Badan</Label>
<Field> <Field>
<Input type="number" placeholder="Cm" /> <Input
v-model="height"
v-bind="heightAttrs"
type="number"
placeholder="Cm"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Golongan Darah</Label> <Label dynamic>Golongan Darah</Label>
<Field> <Field>
<Select :options="bloodGroups" /> <Select
:options="bloodGroups"
v-model="bloodGroup"
v-bind="bloodGroupAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Pemeriksaan Fisik (Yang Mendukung)</Label> <Label dynamic>Pemeriksaan Fisik (Yang Mendukung)</Label>
<Field> <Field>
<Textarea placeholder="Masukkan pemeriksaan fisik" /> <Textarea
placeholder="Masukkan pemeriksaan fisik"
v-model="physicalExamination"
v-bind="physicalExaminationAttrs"
/>
</Field> </Field>
</Cell> </Cell>
@@ -171,9 +285,10 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Button <Button
class="rounded bg-orange-100 px-3 py-1 text-orange-600" class="rounded bg-orange-100 px-3 py-1 text-orange-600"
type="button" type="button"
@click="emits('click', 'diagnosa')" @click="emits('modal', 'diagnosa')"
>+ Pilih Diagnosa</Button
> >
+ Pilih Diagnosa
</Button>
</Field> </Field>
</Cell> </Cell>
<!-- Diagnosa --> <!-- Diagnosa -->
@@ -183,9 +298,10 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Button <Button
class="rounded bg-orange-100 px-3 py-1 text-orange-600" class="rounded bg-orange-100 px-3 py-1 text-orange-600"
type="button" type="button"
@click="emits('click', 'prosedur')" @click="emits('modal', 'prosedur')"
>+ Pilih Prosedur</Button
> >
+ Pilih Prosedur
</Button>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -199,21 +315,30 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Diagnosa Medis</Label> <Label dynamic>Diagnosa Medis</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="diagnosisMedical"
v-bind="diagnosisMedicalAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Rencana Awal Medis</Label> <Label dynamic>Rencana Awal Medis</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="medicalPlan"
v-bind="medicalPlanAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Terapi</Label> <Label dynamic>Terapi</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="therapy"
v-bind="therapyAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
+211 -45
View File
@@ -4,24 +4,88 @@ import Cell from '~/components/pub/my-ui/doc-entry/cell.vue'
import Field from '~/components/pub/my-ui/doc-entry/field.vue' import Field from '~/components/pub/my-ui/doc-entry/field.vue'
import Label from '~/components/pub/my-ui/doc-entry/label.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<{ const props = defineProps<{
modelValue: any
schema: z.ZodSchema<any>
excludeFields?: string[] excludeFields?: string[]
isReadonly?: boolean
}>() }>()
const emits = defineEmits(['click']) const emit = defineEmits<{
(e: 'update:modelValue', val: any): void
(e: 'submit', val: any): void
}>()
const subject = ref({ // Setup form
'prim-compl': '', const {
'sec-compl': '', validate: _validate,
'cur-disea-hist': '', defineField,
'pas-disea-hist': '', handleSubmit,
'fam-disea-hist': '', errors,
'alg-hist': '', values,
'alg-react': '', } = useForm({
'med-hist': '', validationSchema: toTypedSchema(props.schema),
'blood-type': '', initialValues: props.modelValue,
}) })
watch(values, (val) => emit('update:modelValue', val), { deep: true })
const [primaryComplaint, primaryComplaintAttrs] = defineField('prim-compl')
const [medicalPlan, medicalPlanAttrs] = defineField('medical-plan')
const [diagnosisMedical, diagnosisMedicalAttrs] = defineField('diagnosis-medical')
const [rehabTrouble, rehabTroubleAttrs] = defineField('rehab-trouble')
const [medicalTrouble, medicalTroubleAttrs] = defineField('medical-trouble')
const [physicModal, physicModalAttrs] = defineField('physic-modal')
const [exercise, exerciseAttrs] = defineField('exercise')
const [orthoPesa, orthoPesaAttrs] = defineField('ortho-pesa')
const [education, educationAttrs] = defineField('education')
const [other, otherAttrs] = defineField('other')
const [cranialis, cranialisAttrs] = defineField('cranialis')
const [sensoris, sensorisAttrs] = defineField('sensoris')
const [reflectFisio, reflectFisioAttrs] = defineField('reflect-fisio')
const [reflectPato, reflectPatoAttrs] = defineField('reflect-pato')
const [otonom, otonomAttrs] = defineField('otonom')
const [localis, localisAttrs] = defineField('localis')
const [medicalTrial, medicalTrialAttrs] = defineField('medical-trial')
const [therapy, therapyAttrs] = defineField('therapy')
const [systolic, systolicAttrs] = defineField('syst-bp')
const [diastolic, diastolicAttrs] = defineField('diast-bp')
const [pulse, pulseAttrs] = defineField('pulse')
const [gcs, gcsAttrs] = defineField('gcs')
const [respiratoryRate, respiratoryRateAttrs] = defineField('respiratory-rate')
const [temperature, temperatureAttrs] = defineField('temperature')
const [weight, weightAttrs] = defineField('weight')
const [height, heightAttrs] = defineField('height')
const [ambulance, ambulanceAttrs] = defineField('ambulance')
const [gait, gaitAttrs] = defineField('gait')
const [neckRom, neckRomAttrs] = defineField('neck-rom')
const [bodyRom, bodyRomAttrs] = defineField('body-rom')
const [agaRom, agaRomAttrs] = defineField('aga-rom')
const [agbRom, agbRomAttrs] = defineField('agb-rom')
const [neckMmt, neckMmtAttrs] = defineField('neck-mmt')
const [bodyMmt, bodyMmtAttrs] = defineField('body-mmt')
const [agaMmt, agaMmtAttrs] = defineField('aga-mmt')
const [agbMmt, agbMmtAttrs] = defineField('agb-mmt')
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 isExcluded = (key: string) => props.excludeFields?.includes(key) const isExcluded = (key: string) => props.excludeFields?.includes(key)
</script> </script>
@@ -36,8 +100,11 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Block> <Block>
<Cell> <Cell>
<Label dynamic>Keluhan Utama</Label> <Label dynamic>Keluhan Utama</Label>
<Field> <Field :errMessage="errors['prim-compl']">
<Textarea /> <Textarea
v-model="primaryComplaint"
v-bind="primaryComplaintAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -46,21 +113,30 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Diagnosa Medis</Label> <Label dynamic>Diagnosa Medis</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="diagnosisMedical"
v-bind="diagnosisMedicalAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Rencana Awal Medis</Label> <Label dynamic>Rencana Awal Medis</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="medicalPlan"
v-bind="medicalPlanAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Terapi</Label> <Label dynamic>Terapi</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="therapy"
v-bind="therapyAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -77,22 +153,36 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Tekanan Darah</Label> <Label dynamic>Tekanan Darah</Label>
<Field> <Field>
<Input placeholder="Sistolik" /> <Input
<Input placeholder="Diastolik" /> placeholder="Sistolik"
v-model="systolic"
v-bind="systolicAttrs"
/>
<Input
placeholder="Diastolik"
v-model="diastolic"
v-bind="diastolicAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Nadi</Label> <Label dynamic>Nadi</Label>
<Field> <Field>
<Input /> <Input
v-model="pulse"
v-bind="pulseAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>GCS</Label> <Label dynamic>GCS</Label>
<Field> <Field>
<Input /> <Input
v-model="gcs"
v-bind="gcsAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -100,14 +190,21 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>RR</Label> <Label dynamic>RR</Label>
<Field> <Field>
<Input /> <Input
v-model="respiratoryRate"
v-bind="respiratoryRateAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Ambulasi</Label> <Label dynamic>Ambulasi</Label>
<Field> <Field>
<RadioGroup class="flex gap-4"> <RadioGroup
class="flex gap-4"
v-model="ambulance"
v-bind="ambulanceAttrs"
>
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<RadioGroupItem <RadioGroupItem
id="vaksin-yes" id="vaksin-yes"
@@ -129,7 +226,10 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Gait</Label> <Label dynamic>Gait</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="gait"
v-bind="gaitAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -144,21 +244,30 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>N. Cranialis</Label> <Label dynamic>N. Cranialis</Label>
<Field> <Field>
<Input /> <Input
v-model="cranialis"
v-bind="cranialisAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Sensoris</Label> <Label dynamic>Sensoris</Label>
<Field> <Field>
<Input /> <Input
v-model="sensoris"
v-bind="sensorisAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Reflek Fisilogis</Label> <Label dynamic>Reflek Fisilogis</Label>
<Field> <Field>
<Input /> <Input
v-model="reflectFisio"
v-bind="reflectFisioAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -166,13 +275,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Reflek Patologis</Label> <Label dynamic>Reflek Patologis</Label>
<Field> <Field>
<Input /> <Input
v-model="reflectPato"
v-bind="reflectPatoAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Saraf Otonom</Label> <Label dynamic>Saraf Otonom</Label>
<Field> <Field>
<Input /> <Input
v-model="otonom"
v-bind="otonomAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -187,13 +302,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Leher</Label> <Label dynamic>Leher</Label>
<Field> <Field>
<Input /> <Input
v-model="neckRom"
v-bind="neckRomAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Batang Tubuh</Label> <Label dynamic>Batang Tubuh</Label>
<Field> <Field>
<Input /> <Input
v-model="bodyRom"
v-bind="bodyRomAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -201,13 +322,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>AGA</Label> <Label dynamic>AGA</Label>
<Field> <Field>
<Input /> <Input
v-model="agaRom"
v-bind="agaRomAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>AGB</Label> <Label dynamic>AGB</Label>
<Field> <Field>
<Input /> <Input
v-model="agbRom"
v-bind="agbRomAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -222,13 +349,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Leher</Label> <Label dynamic>Leher</Label>
<Field> <Field>
<Input /> <Input
v-model="neckMmt"
v-bind="neckMmtAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Batang Tubuh</Label> <Label dynamic>Batang Tubuh</Label>
<Field> <Field>
<Input /> <Input
v-model="bodyMmt"
v-bind="bodyMmtAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -236,13 +369,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>AGA</Label> <Label dynamic>AGA</Label>
<Field> <Field>
<Input /> <Input
v-model="agaMmt"
v-bind="agaMmtAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>AGB</Label> <Label dynamic>AGB</Label>
<Field> <Field>
<Input /> <Input
v-model="agbMmt"
v-bind="agbMmtAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -256,7 +395,10 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Deskripsi Temuan Fisik</Label> <Label dynamic>Deskripsi Temuan Fisik</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="localis"
v-bind="localisAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -271,7 +413,10 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Catatan Pemeriksaan Penunjang</Label> <Label dynamic>Catatan Pemeriksaan Penunjang</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="medicalTrial"
v-bind="medicalTrialAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -286,13 +431,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Masalah Medik</Label> <Label dynamic>Masalah Medik</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="medicalTrouble"
v-bind="medicalTroubleAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Masalah Rehabilitasi Medik</Label> <Label dynamic>Masalah Rehabilitasi Medik</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="rehabTrouble"
v-bind="rehabTroubleAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -316,21 +467,30 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Modalitas Fisik</Label> <Label dynamic>Modalitas Fisik</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="physicModal"
v-bind="physicModalAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Latihan</Label> <Label dynamic>Latihan</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="exercise"
v-bind="exerciseAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Ortesa Protesa</Label> <Label dynamic>Ortesa Protesa</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="orthoPesa"
v-bind="orthoPesaAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -338,13 +498,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
<Cell> <Cell>
<Label dynamic>Edukasi</Label> <Label dynamic>Edukasi</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="education"
v-bind="educationAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Lain-Lain</Label> <Label dynamic>Lain-Lain</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="other"
v-bind="otherAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
+26 -7
View File
@@ -1,28 +1,47 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { ref, computed } from 'vue'
import EarlyEntry from './early-entry.vue' import EarlyEntry from './early-entry.vue'
import EarlyRehabEntry from './early-rehab-entry.vue' import EarlyRehabEntry from './early-rehab-entry.vue'
import FunctionEntry from './function-entry.vue' import FunctionEntry from './function-entry.vue'
/**
* Props:
* - excludeFields: daftar nama field yang ingin disembunyikan
*/
const props = defineProps<{ const props = defineProps<{
type: 'early' | 'early-rehab' | 'function' type: 'early' | 'early-rehab' | 'function'
excludeFields?: string[] excludeFields?: string[]
}>() }>()
const emits = defineEmits(['click', 'submit', 'cancel'])
const componentMap = { const componentMap = {
early: EarlyEntry, early: EarlyEntry,
'early-rehab': EarlyRehabEntry, 'early-rehab': EarlyRehabEntry,
function: FunctionEntry, function: FunctionEntry,
} }
// Komponen aktif berdasarkan type
const ActiveComponent = computed(() => componentMap[props.type]) const ActiveComponent = computed(() => componentMap[props.type])
const childRef = ref()
const validate = async () => {
if (childRef.value?.validate) {
const result = await childRef.value.validate()
console.log('[Wrapper] Result from child validate:', result)
return result
} else {
console.warn('validate() not found in child component')
return { valid: false, data: null, errors: {} }
}
}
defineExpose({ validate })
</script> </script>
<template> <template>
<component :is="ActiveComponent" :exclude-fields="excludeFields" /> <component
ref="childRef"
:is="ActiveComponent"
:exclude-fields="excludeFields"
@click="$emit('click', $event)"
@submit="$emit('submit', $event)"
@cancel="$emit('cancel', $event)"
/>
</template> </template>
+221 -49
View File
@@ -4,24 +4,88 @@ import Cell from '~/components/pub/my-ui/doc-entry/cell.vue'
import Field from '~/components/pub/my-ui/doc-entry/field.vue' import Field from '~/components/pub/my-ui/doc-entry/field.vue'
import Label from '~/components/pub/my-ui/doc-entry/label.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<{ const props = defineProps<{
modelValue: any
schema: z.ZodSchema<any>
excludeFields?: string[] excludeFields?: string[]
isReadonly?: boolean
}>() }>()
const emits = defineEmits(['click']) const emit = defineEmits<{
(e: 'update:modelValue', val: any): void
(e: 'submit', val: any): void
}>()
const subject = ref({ // Setup form
'prim-compl': '', const {
'sec-compl': '', validate: _validate,
'cur-disea-hist': '', defineField,
'pas-disea-hist': '', handleSubmit,
'fam-disea-hist': '', errors,
'alg-hist': '', values,
'alg-react': '', } = useForm({
'med-hist': '', validationSchema: toTypedSchema(props.schema),
'blood-type': '', initialValues: props.modelValue,
}) })
watch(values, (val) => emit('update:modelValue', val), { deep: true })
const [primaryComplaint, primaryComplaintAttrs] = defineField('prim-compl')
const [pastDisease, pastDiseaseAttrs] = defineField('past-disease')
const [currentDisease, currentDiseaseAttrs] = defineField('current-disease')
const [gcs, gcsAttrs] = defineField('gcs')
const [respiratoryRate, respiratoryRateAttrs] = defineField('respiratory-rate')
const [respiratoryRateType, respiratoryRateTypeAttrs] = defineField('respiratory-rate-type')
const [pulse, pulseAttrs] = defineField('pulse')
const [pulseType, pulseTypeAttrs] = defineField('pulse-type')
const [rightArmBp, rightArmBpAttrs] = defineField('right-arm-bp')
const [leftArmBp, leftArmBpAttrs] = defineField('left-arm-bp')
const [axillaryTemp, axillaryTempAttrs] = defineField('axillary-temp')
const [rektalTemp, rektalTempAttrs] = defineField('rektal-temp')
const [skin, skinAttrs] = defineField('skin')
const [head, headAttrs] = defineField('head')
const [ear, earAttrs] = defineField('ear')
const [nose, noseAttrs] = defineField('nose')
const [oralCavity, oralCavityAttrs] = defineField('oral-cavity')
const [eye, eyeAttrs] = defineField('eye')
const [otherBodyPart, otherBodyPartAttrs] = defineField('other-body-part')
const [neck, neckAttrs] = defineField('neck')
const [thyroid, thyroidAttrs] = defineField('thyroid')
const [thorax, thoraxAttrs] = defineField('thorax')
const [heart, heartAttrs] = defineField('heart')
const [lung, lungAttrs] = defineField('lung')
const [abdomen, abdomenAttrs] = defineField('abdomen')
const [heart2, heart2Attrs] = defineField('heart2')
const [lien, lienAttrs] = defineField('lien')
const [back, backAttrs] = defineField('back')
const [extremity, extremityAttrs] = defineField('extremity')
const [gender, genderAttrs] = defineField('gender')
const [rectum, rectumAttrs] = defineField('rectum')
const [systemSyaraf, systemSyarafAttrs] = defineField('system-syaraf')
const [nervousSystem, nervousSystemAttrs] = defineField('nervous-system')
const [cardioRespiratory, cardioRespiratoryAttrs] = defineField('cardio-respiratory')
const [imaging, imagingAttrs] = defineField('imaging')
const [laboratory, laboratoryAttrs] = defineField('laboratory')
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 isExcluded = (key: string) => props.excludeFields?.includes(key) const isExcluded = (key: string) => props.excludeFields?.includes(key)
const disorders = ref<string[]>([]) const disorders = ref<string[]>([])
const therapies = ref<string[]>([]) const therapies = ref<string[]>([])
@@ -55,8 +119,11 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Block> <Block>
<Cell> <Cell>
<Label dynamic>Keluhan Utama</Label> <Label dynamic>Keluhan Utama</Label>
<Field> <Field :errMessage="errors['prim-compl']">
<Textarea /> <Textarea
v-model="primaryComplaint"
v-bind="primaryComplaintAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -65,14 +132,20 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Riwayat Penyakit Dahulu</Label> <Label dynamic>Riwayat Penyakit Dahulu</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="pastDisease"
v-bind="pastDiseaseAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Riwayat Penyakit Sekarang</Label> <Label dynamic>Riwayat Penyakit Sekarang</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="currentDisease"
v-bind="currentDiseaseAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -86,7 +159,7 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Umum</Label> <Label dynamic>Umum</Label>
<Field> <Field>
<Input placeholder="Sistolik" /> <Input placeholder="" />
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -100,7 +173,10 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Kesadaran (GCS)</Label> <Label dynamic>Kesadaran (GCS)</Label>
<Field> <Field>
<Input /> <Input
v-model="gcs"
v-bind="gcsAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -108,14 +184,20 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Pernapasan</Label> <Label dynamic>Pernapasan</Label>
<Field> <Field>
<Input /> <Input
v-model="respiratoryRate"
v-bind="respiratoryRateAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Jenis</Label> <Label dynamic>Jenis</Label>
<Field> <Field>
<Input /> <Input
v-model="respiratoryRateType"
v-bind="respiratoryRateTypeAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -123,13 +205,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Nadi</Label> <Label dynamic>Nadi</Label>
<Field> <Field>
<Input /> <Input
v-model="pulse"
v-bind="pulseAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Jenis</Label> <Label dynamic>Jenis</Label>
<Field> <Field>
<Input /> <Input
v-model="pulseType"
v-bind="pulseTypeAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -137,13 +225,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Tekanan Darah Lengan Kanan</Label> <Label dynamic>Tekanan Darah Lengan Kanan</Label>
<Field> <Field>
<Input /> <Input
v-model="rightArmBp"
v-bind="rightArmBpAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Tekanan Darah Lengan Kiri</Label> <Label dynamic>Tekanan Darah Lengan Kiri</Label>
<Field> <Field>
<Input /> <Input
v-model="leftArmBp"
v-bind="leftArmBpAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -151,13 +245,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Suhu Aksila</Label> <Label dynamic>Suhu Aksila</Label>
<Field> <Field>
<Input /> <Input
v-model="axillaryTemp"
v-bind="axillaryTempAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Suhu Rektal</Label> <Label dynamic>Suhu Rektal</Label>
<Field> <Field>
<Input /> <Input
v-model="rektalTemp"
v-bind="rektalTempAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -172,7 +272,10 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Kulit</Label> <Label dynamic>Kulit</Label>
<Field> <Field>
<Input /> <Input
v-model="skin"
v-bind="skinAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -183,19 +286,28 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Kepala</Label> <Label dynamic>Kepala</Label>
<Field> <Field>
<Input /> <Input
v-model="head"
v-bind="headAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Telinga</Label> <Label dynamic>Telinga</Label>
<Field> <Field>
<Input /> <Input
v-model="ear"
v-bind="earAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Hidung</Label> <Label dynamic>Hidung</Label>
<Field> <Field>
<Input /> <Input
v-model="nose"
v-bind="noseAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -204,19 +316,28 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Rongga Mulut/Tenggorokan</Label> <Label dynamic>Rongga Mulut/Tenggorokan</Label>
<Field> <Field>
<Input /> <Input
v-model="oralCavity"
v-bind="oralCavityAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Mata</Label> <Label dynamic>Mata</Label>
<Field> <Field>
<Input /> <Input
v-model="eye"
v-bind="eyeAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Lain-Lain</Label> <Label dynamic>Lain-Lain</Label>
<Field> <Field>
<Input /> <Input
v-model="otherBodyPart"
v-bind="otherBodyPartAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -227,13 +348,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Leher</Label> <Label dynamic>Leher</Label>
<Field> <Field>
<Input /> <Input
v-model="neck"
v-bind="neckAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Kelenjar Tiroid</Label> <Label dynamic>Kelenjar Tiroid</Label>
<Field> <Field>
<Input /> <Input
v-model="thyroid"
v-bind="thyroidAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
@@ -250,19 +377,28 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Thorax</Label> <Label dynamic>Thorax</Label>
<Field> <Field>
<Input /> <Input
v-model="thorax"
v-bind="thoraxAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Jantung</Label> <Label dynamic>Jantung</Label>
<Field> <Field>
<Input /> <Input
v-model="heart"
v-bind="heartAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Paru-Paru</Label> <Label dynamic>Paru-Paru</Label>
<Field> <Field>
<Input /> <Input
v-model="lung"
v-bind="lungAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -281,19 +417,28 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Abdomen</Label> <Label dynamic>Abdomen</Label>
<Field> <Field>
<Input /> <Input
v-model="abdomen"
v-bind="abdomenAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Hati</Label> <Label dynamic>Hati</Label>
<Field> <Field>
<Input /> <Input
v-model="heart2"
v-bind="heart2Attrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Lien</Label> <Label dynamic>Lien</Label>
<Field> <Field>
<Input /> <Input
v-model="lien"
v-bind="lienAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -312,19 +457,28 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Punggung</Label> <Label dynamic>Punggung</Label>
<Field> <Field>
<Input /> <Input
v-model="back"
v-bind="backAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Ekstremitas</Label> <Label dynamic>Ekstremitas</Label>
<Field> <Field>
<Input /> <Input
v-model="extremity"
v-bind="extremityAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Kelamin</Label> <Label dynamic>Kelamin</Label>
<Field> <Field>
<Input /> <Input
v-model="gender"
v-bind="genderAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -332,13 +486,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Rectum</Label> <Label dynamic>Rectum</Label>
<Field> <Field>
<Input /> <Input
v-model="rectum"
v-bind="rectumAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>System Syaraf</Label> <Label dynamic>System Syaraf</Label>
<Field> <Field>
<Input /> <Input
v-model="nervousSystem"
v-bind="nervousSystemAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -348,13 +508,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Neuromoskuloskeletal</Label> <Label dynamic>Neuromoskuloskeletal</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="neuromoskuloskeletal"
v-bind="neuromoskuloskeletalAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Kardiorespirasi</Label> <Label dynamic>Kardiorespirasi</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="cardioRespiratory"
v-bind="cardioRespiratoryAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
@@ -369,13 +535,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
<Cell> <Cell>
<Label dynamic>Pencitraan</Label> <Label dynamic>Pencitraan</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="imaging"
v-bind="imagingAttrs"
/>
</Field> </Field>
</Cell> </Cell>
<Cell> <Cell>
<Label dynamic>Laboratorium</Label> <Label dynamic>Laboratorium</Label>
<Field> <Field>
<Textarea /> <Textarea
v-model="laboratory"
v-bind="laboratoryAttrs"
/>
</Field> </Field>
</Cell> </Cell>
</Block> </Block>
+11 -3
View File
@@ -95,14 +95,22 @@ provide('table_data_loader', isLoading)
</script> </script>
<template> <template>
<Header :prep="{ ...hreaderPrep }" :ref-search-nav="refSearchNav" /> <Header
:prep="{ ...hreaderPrep }"
:ref-search-nav="refSearchNav"
/>
<Separator class="my-4 xl:my-5" />
<Filter :ref-search-nav="refSearchNav" /> <Filter :ref-search-nav="refSearchNav" />
<AppEncounterList :data="data" /> <AppEncounterList :data="data" />
<Dialog v-model:open="isFormEntryDialogOpen" title="Filter" size="lg" prevent-outside> <Dialog
v-model:open="isFormEntryDialogOpen"
title="Filter"
size="lg"
prevent-outside
>
<AppEncounterFilter /> <AppEncounterFilter />
</Dialog> </Dialog>
<!-- <Pagination :pagination-meta="paginationMeta" @page-change="handlePageChange" /> -->
</template> </template>
+8 -9
View File
@@ -5,18 +5,14 @@ import { useRoute, useRouter } from 'vue-router'
import { getDetail } from '~/services/encounter.service' import { getDetail } from '~/services/encounter.service'
import type { Encounter } from '~/models/encounter'
// Components // Components
import CompTab from '~/components/pub/my-ui/comp-tab/comp-tab.vue'
import type { TabItem } from '~/components/pub/my-ui/comp-tab/type' import type { TabItem } from '~/components/pub/my-ui/comp-tab/type'
import CompTab from '~/components/pub/my-ui/comp-tab/comp-tab.vue'
import Status from '~/components/app/encounter/status.vue' import AssesmentFunctionList from '~/components/content/soapi/entry.vue'
import AssesmentFunctionList from '~/components/content/assesment-function/list.vue'
import EarlyMedicalAssesmentList from '~/components/content/soapi/entry.vue' import EarlyMedicalAssesmentList from '~/components/content/soapi/entry.vue'
// import AssesmentFunctionList from '~/components/content/assesment-function/list.vue'
import Prescription from '~/components/content/prescription/main.vue'
import EarlyMedicalRehabList from '~/components/content/soapi/entry.vue' import EarlyMedicalRehabList from '~/components/content/soapi/entry.vue'
import Prescription from '~/components/content/prescription/main.vue'
import Status from '~/components/app/encounter/status.vue'
import Consultation from '~/components/content/consultation/list.vue' import Consultation from '~/components/content/consultation/list.vue'
const route = useRoute() const route = useRoute()
@@ -31,7 +27,10 @@ const activeTab = computed({
}) })
const id = typeof route.params.id == 'string' ? parseInt(route.params.id) : 0 const id = typeof route.params.id == 'string' ? parseInt(route.params.id) : 0
const dataRes = await getDetail(id, { includes: 'patient,patient-person,patient-person-addresses,unit,Appointment_Doctor,Appointment_Doctor-employee,Appointment_Doctor-employee-person'}) const dataRes = await getDetail(id, {
includes:
'patient,patient-person,patient-person-addresses,unit,Appointment_Doctor,Appointment_Doctor-employee,Appointment_Doctor-employee-person',
})
const dataResBody = dataRes.body ?? null const dataResBody = dataRes.body ?? null
const data = dataResBody?.data ?? null const data = dataResBody?.data ?? null
+1 -1
View File
@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { computed } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { useQueryMode } from '@/composables/useQueryMode' // asumsikan ini ada import { useQueryMode } from '@/composables/useQueryMode'
import SoapiList from './list.vue' import SoapiList from './list.vue'
import EarlyForm from './form.vue' import EarlyForm from './form.vue'
+81 -3
View File
@@ -1,9 +1,61 @@
<script setup lang="ts"> <script setup lang="ts">
import { z } from 'zod'
import Entry from '~/components/app/soapi/entry.vue' import Entry from '~/components/app/soapi/entry.vue'
import Action from '~/components/pub/my-ui/nav-footer/ba-dr-su.vue'
import Dialog from '~/components/pub/my-ui/modal/dialog.vue' import Dialog from '~/components/pub/my-ui/modal/dialog.vue'
import { FunctionSoapiSchema } from '~/schemas/soapi.schema'
import { toast } from '~/components/pub/ui/toast'
import { handleActionSave, handleActionEdit } from '~/handlers/soapi-early.handler'
const route = useRoute()
const isOpen = ref(false) const isOpen = ref(false)
const data = ref([]) const data = ref([])
const schema = FunctionSoapiSchema
const payload = ref({
encounter_id: 0,
time: '',
typeCode: 'function',
value: '',
})
const model = ref({
'prim-compl': '',
'past-disease': '',
'current-disease': '',
gcs: '',
'respiratory-rate': '',
'respiratory-rate-type': '',
pulse: '',
'pulse-type': '',
'right-arm-bp': '',
'left-arm-bp': '',
'axillary-temp': '',
'rektal-temp': '',
skin: '',
head: '',
ear: '',
nose: '',
'oral-cavity': '',
eye: '',
'other-body-part': '',
neck: '',
thyroid: '',
thorax: '',
heart: '',
lung: '',
abdomen: '',
heart2: '',
lien: '',
back: '',
extremity: '',
gender: '',
rectum: '',
'system-syaraf': '',
'nervous-system': '',
'cardio-respiratory': '',
imaging: '',
laboratory: '',
})
const isLoading = reactive<DataTableLoader>({ const isLoading = reactive<DataTableLoader>({
isTableLoading: false, isTableLoading: false,
}) })
@@ -21,19 +73,45 @@ onMounted(() => {
getPatientList() getPatientList()
}) })
function handleClick(type: string) { function handleOpen(type: string) {
console.log(type) console.log(type)
isOpen.value = true isOpen.value = true
} }
const entryRehabRef = ref()
async function actionHandler(type: string) {
console.log(type)
const result = await entryRehabRef.value?.validate()
if (result?.valid) {
console.log('data', result.data)
handleActionSave(
{
...payload.value,
value: JSON.stringify(result.data),
encounter_id: +route.params.id,
time: new Date().toISOString(),
},
{},
toast,
)
} else {
console.log('Ada error di form', result)
}
}
provide('table_data_loader', isLoading) provide('table_data_loader', isLoading)
</script> </script>
<template> <template>
<Entry <Entry
ref="entryRehabRef"
v-model="model"
:schema="schema"
type="function" type="function"
:exclude-fields="['prim-compl', 'sec-compl']" @modal="handleOpen"
@click="handleClick"
/> />
<div class="my-2 flex justify-end py-2">
<Action @click="actionHandler" />
</div>
<Dialog <Dialog
v-model:open="isOpen" v-model:open="isOpen"
title="Pilih Prosedur" title="Pilih Prosedur"
+86 -3
View File
@@ -1,9 +1,66 @@
<script setup lang="ts"> <script setup lang="ts">
import { z } from 'zod'
import Entry from '~/components/app/soapi/entry.vue' import Entry from '~/components/app/soapi/entry.vue'
import Action from '~/components/pub/my-ui/nav-footer/ba-dr-su.vue'
import Dialog from '~/components/pub/my-ui/modal/dialog.vue' import Dialog from '~/components/pub/my-ui/modal/dialog.vue'
import { EarlyRehabSchema } from '~/schemas/soapi.schema'
import { toast } from '~/components/pub/ui/toast'
import { handleActionSave, handleActionEdit } from '~/handlers/soapi-early.handler'
const route = useRoute()
const isOpen = ref(false) const isOpen = ref(false)
const data = ref([]) const data = ref([])
const schema = EarlyRehabSchema
const payload = ref({
encounter_id: 0,
time: '',
typeCode: 'early-rehab',
value: '',
})
const model = ref({
'prim-compl': '',
'medical-plan': '',
'diagnosis-medical': '',
'rehab-trouble': '',
'medical-trouble': '',
'physic-modal': '',
exercise: '',
'ortho-pesa': '',
education: '',
other: '',
cranialis: '',
sensoris: '',
'reflect-fisio': '',
'reflect-pato': '',
otonom: '',
localis: '',
'medical-trial': '',
therapy: '',
'syst-bp': '',
'diast-bp': '',
pulse: '',
gcs: '',
'respiratory-rate': '',
temperature: '',
ambulance: '',
gait: '',
'neck-rom': '',
'body-rom': '',
'aga-rom': '',
'agb-rom': '',
'neck-mmt': '',
'body-mmt': '',
'aga-mmt': '',
'agb-mmt': '',
localis: '',
'medical-trouble': '',
'rehab-trouble': '',
temp: '',
spo2: '',
weight: '',
height: '',
})
const isLoading = reactive<DataTableLoader>({ const isLoading = reactive<DataTableLoader>({
isTableLoading: false, isTableLoading: false,
}) })
@@ -21,19 +78,45 @@ onMounted(() => {
getPatientList() getPatientList()
}) })
function handleClick(type: string) { function handleOpen(type: string) {
console.log(type) console.log(type)
isOpen.value = true isOpen.value = true
} }
const entryRehabRef = ref()
async function actionHandler(type: string) {
console.log(type)
const result = await entryRehabRef.value?.validate()
if (result?.valid) {
console.log('data', result.data)
handleActionSave(
{
...payload.value,
value: JSON.stringify(result.data),
encounter_id: +route.params.id,
time: new Date().toISOString(),
},
{},
toast,
)
} else {
console.log('Ada error di form', result)
}
}
provide('table_data_loader', isLoading) provide('table_data_loader', isLoading)
</script> </script>
<template> <template>
<Entry <Entry
ref="entryRehabRef"
v-model="model"
:schema="schema"
type="early-rehab" type="early-rehab"
:exclude-fields="['prim-compl', 'sec-compl']" @modal="handleOpen"
@click="handleClick"
/> />
<div class="my-2 flex justify-end py-2">
<Action @click="actionHandler" />
</div>
<Dialog <Dialog
v-model:open="isOpen" v-model:open="isOpen"
title="Pilih Prosedur" title="Pilih Prosedur"
+68 -3
View File
@@ -1,9 +1,39 @@
<script setup lang="ts"> <script setup lang="ts">
import { z } from 'zod'
import Entry from '~/components/app/soapi/entry.vue' import Entry from '~/components/app/soapi/entry.vue'
import Action from '~/components/pub/my-ui/nav-footer/ba-dr-su.vue'
import Dialog from '~/components/pub/my-ui/modal/dialog.vue' import Dialog from '~/components/pub/my-ui/modal/dialog.vue'
import { EarlySchema } from '~/schemas/soapi.schema'
import { toast } from '~/components/pub/ui/toast'
import { handleActionSave, handleActionEdit } from '~/handlers/soapi-early.handler'
const route = useRoute()
const isOpen = ref(false) const isOpen = ref(false)
const data = ref([]) const data = ref([])
const schema = EarlySchema
const payload = ref({
encounter_id: 0,
time: '',
typeCode: 'early',
value: '',
})
const model = ref({
'prim-compl': '',
'cur-disea-hist': '',
'syst-bp': '',
'diast-bp': '',
pulse: '',
'resp-rate': '',
temp: '',
weight: '',
height: '',
'reflect-fisio': '',
'reflect-pato': '',
'autonom-neuron': '',
'medical-act': '',
therapy: '',
})
const isLoading = reactive<DataTableLoader>({ const isLoading = reactive<DataTableLoader>({
isTableLoading: false, isTableLoading: false,
}) })
@@ -21,16 +51,51 @@ onMounted(() => {
getPatientList() getPatientList()
}) })
function handleClick(type: string) { function handleOpen(type: string) {
console.log(type) console.log(type)
isOpen.value = true isOpen.value = true
} }
const entryRef = ref()
async function actionHandler(type: string) {
console.log(type)
const result = await entryRef.value?.validate()
if (result?.valid) {
console.log('data', result.data)
handleActionSave(
{
...payload.value,
value: JSON.stringify(result.data),
encounter_id: +route.params.id,
time: new Date().toISOString(),
},
{},
toast,
)
} else {
console.log('Ada error di form', result)
}
}
provide('table_data_loader', isLoading) provide('table_data_loader', isLoading)
</script> </script>
<template> <template>
<Entry type="early" :exclude-fields="['prim-compl', 'sec-compl']" @click="handleClick" /> <Entry
<Dialog v-model:open="isOpen" title="Pilih Prosedur" size="xl" prevent-outside> ref="entryRef"
v-model="model"
:schema="schema"
type="early"
@modal="handleOpen"
/>
<div class="my-2 flex justify-end py-2">
<Action @click="actionHandler" />
</div>
<Dialog
v-model:open="isOpen"
title="Pilih Prosedur"
size="xl"
prevent-outside
>
<AppIcdMultiselectPicker :data="data" /> <AppIcdMultiselectPicker :data="data" />
</Dialog> </Dialog>
</template> </template>
+24
View File
@@ -0,0 +1,24 @@
// Handlers
import { genCrudHandler } from '~/handlers/_handler'
// Services
import { create, update, remove } from '~/services/soapi-early.service'
export const {
recId,
recAction,
recItem,
isReadonly,
isProcessing,
isFormEntryDialogOpen,
isRecordConfirmationOpen,
onResetState,
handleActionSave,
handleActionEdit,
handleActionRemove,
handleCancelForm,
} = genCrudHandler({
create,
update,
remove,
})
+173 -1
View File
@@ -1,4 +1,4 @@
import { type Base, genBase } from "./_base" import { type Base, genBase } from './_base'
export interface Soapi extends Base { export interface Soapi extends Base {
encounter_id: number encounter_id: number
@@ -16,3 +16,175 @@ export function genSoapi(): Soapi {
value: '', value: '',
} }
} }
export interface DiagnosisCode {
code: string
name: string
}
export interface AssessmentSection {
note: string
codes: DiagnosisCode[]
}
export interface Subject {
note: string
'prim-compl': string
'sec-compl': string
'pri-complain': string
'sec-complain': string
'cur-disea-hist': string
'pas-disea-hist': string
'fam-disea-hist': string
'alg-hist': string
'alg-react': string
'med-hist': string
'blood-type': string
}
export interface ObjectSection {
note: string
'consc-level': string
'consc-level-det': string
'syst-bp': string
'diast-bp': string
pulse: string
'resp-rate': string
'hear-rt': string
'neuro-cranialis': string
sensoris: string
'reflect-fisio': string
'reflect-pato': string
'autonom-neuron': string
'neck-rom': string
'body-rom': string
'aga-rom': string
'agb-rom': string
'neck-mmt': string
'body-mmt': string
'aga-mmt': string
'agb-mmt': string
localis: string
'medical-trouble': string
'rehab-medic-trouble': string
temp: string
spo2: string
weight: string
height: string
'head-to-toe': Record<string, string>
}
export interface Assessment {
'early-diag': AssessmentSection
'late-diag': AssessmentSection
'sec-diag': AssessmentSection
}
export interface InstructionCodeGroup {
note: string
codes: DiagnosisCode[]
}
export interface Instruction {
detail: string
'medical-act': InstructionCodeGroup
'supporting-exam': DiagnosisCode[]
therapy: string
medication: DiagnosisCode[]
material: DiagnosisCode[]
'rehab-program': string
'physic-modal': string
exercise: string
'ortes-protesa': string
education: string
other: string
}
export interface Soap extends Base {
subject: Subject
object: ObjectSection
assessment: Assessment
plan: string
instruction: Instruction
}
// ---- Generators ----
function genDiagnosisCode(): DiagnosisCode {
return { code: '', name: '' }
}
function genAssessmentSection(): AssessmentSection {
return { note: '', codes: [genDiagnosisCode()] }
}
export function genSoap(): Soap {
return {
...genBase(),
subject: {
note: '',
'prim-compl': '',
'sec-compl': '',
'pri-complain': '',
'sec-complain': '',
'cur-disea-hist': '',
'pas-disea-hist': '',
'fam-disea-hist': '',
'alg-hist': '',
'alg-react': '',
'med-hist': '',
'blood-type': '',
},
object: {
note: '',
'consc-level': '',
'consc-level-det': '',
'syst-bp': '',
'diast-bp': '',
pulse: '',
'resp-rate': '',
'hear-rt': '',
'neuro-cranialis': '',
sensoris: '',
'reflect-fisio': '',
'reflect-pato': '',
'autonom-neuron': '',
'neck-rom': '',
'body-rom': '',
'aga-rom': '',
'agb-rom': '',
'neck-mmt': '',
'body-mmt': '',
'aga-mmt': '',
'agb-mmt': '',
localis: '',
'medical-trouble': '',
'rehab-medic-trouble': '',
temp: '',
spo2: '',
weight: '',
height: '',
'head-to-toe': {},
},
assessment: {
'early-diag': genAssessmentSection(),
'late-diag': genAssessmentSection(),
'sec-diag': genAssessmentSection(),
},
plan: '',
instruction: {
detail: '',
'medical-act': { note: '', codes: [genDiagnosisCode()] },
'supporting-exam': [genDiagnosisCode()],
therapy: '',
medication: [genDiagnosisCode()],
material: [genDiagnosisCode()],
'rehab-program': '',
'physic-modal': '',
exercise: '',
'ortes-protesa': '',
education: '',
other: '',
},
}
}
+190
View File
@@ -0,0 +1,190 @@
import { z } from 'zod'
import type { Soap } from '~/models/soapi'
const DiagnosisCodeSchema = z.object({
code: z.string().default(''),
name: z.string().default(''),
})
const AssessmentSectionSchema = z.object({
note: z.string().default(''),
codes: z.array(DiagnosisCodeSchema).default([]),
})
export const EarlySchema = z.object({
'prim-compl': z.string({ required_error: 'Keluhan utama harus diisi' }).min(1, 'Keluhan utama harus diisi'),
'cur-disea-hist': z.string().default(''),
'syst-bp': z.string().default(''),
'diast-bp': z.string().default(''),
pulse: z.string().default(''),
'resp-rate': z.string().default(''),
temp: z.string().default(''),
weight: z.string().default(''),
height: z.string().default(''),
'reflect-fisio': z.string().default(''),
'reflect-pato': z.string().default(''),
'autonom-neuron': z.string().default(''),
'medical-act': z.string().default(''),
therapy: z.string().default(''),
})
export const EarlyRehabSchema = z.object({
'prim-compl': z.string({ required_error: 'Keluhan utama harus diisi' }).min(1, 'Keluhan utama harus diisi'),
'medical-plan': z.string().default(''),
'diagnosis-medical': z.string().default(''),
'rehab-trouble': z.string().default(''),
'medical-trouble': z.string().default(''),
'physic-modal': z.string().default(''),
exercise: z.string().default(''),
'ortho-pesa': z.string().default(''),
education: z.string().default(''),
other: z.string().default(''),
cranialis: z.string().default(''),
sensoris: z.string().default(''),
'reflect-fisio': z.string().default(''),
'reflect-pato': z.string().default(''),
otonom: z.string().default(''),
localis: z.string().default(''),
'medical-trial': z.string().default(''),
therapy: z.string().default(''),
'syst-bp': z.string().default(''),
'diast-bp': z.string().default(''),
pulse: z.string().default(''),
gcs: z.string().default(''),
'respiratory-rate': z.string().default(''),
temp: z.string().default(''),
weight: z.string().default(''),
height: z.string().default(''),
ambulance: z.string().default(''),
gait: z.string().default(''),
'neck-rom': z.string().default(''),
'body-rom': z.string().default(''),
'aga-rom': z.string().default(''),
'agb-rom': z.string().default(''),
'neck-mmt': z.string().default(''),
'body-mmt': z.string().default(''),
'aga-mmt': z.string().default(''),
'agb-mmt': z.string().default(''),
})
export const FunctionSoapiSchema = z.object({
'prim-compl': z.string({ required_error: 'Keluhan utama harus diisi' }).min(1, 'Keluhan utama harus diisi'),
'past-disease': z.string().default(''),
'current-disease': z.string().default(''),
gcs: z.string().default(''),
'respiratory-rate': z.string().default(''),
'respiratory-rate-type': z.string().default(''),
pulse: z.string().default(''),
'pulse-type': z.string().default(''),
'right-arm-bp': z.string().default(''),
'left-arm-bp': z.string().default(''),
'axillary-temp': z.string().default(''),
'rektal-temp': z.string().default(''),
skin: z.string().default(''),
head: z.string().default(''),
ear: z.string().default(''),
nose: z.string().default(''),
'oral-cavity': z.string().default(''),
eye: z.string().default(''),
'other-body-part': z.string().default(''),
neck: z.string().default(''),
thyroid: z.string().default(''),
thorax: z.string().default(''),
heart: z.string().default(''),
lung: z.string().default(''),
abdomen: z.string().default(''),
heart2: z.string().default(''),
lien: z.string().default(''),
back: z.string().default(''),
extremity: z.string().default(''),
gender: z.string().default(''),
rectum: z.string().default(''),
'system-syaraf': z.string().default(''),
'nervous-system': z.string().default(''),
'cardio-respiratory': z.string().default(''),
imaging: z.string().default(''),
laboratory: z.string().default(''),
})
export const SubjectSchema = z.object({
note: z.string().default(''),
'prim-compl': z.string({ required_error: 'Keluhan utama harus diisi' }).min(1, 'Keluhan utama harus diisi'),
'sec-compl': z.string().default(''),
'pri-complain': z.string().default(''),
'sec-complain': z.string().default(''),
'cur-disea-hist': z.string().default(''),
'pas-disea-hist': z.string().default(''),
'fam-disea-hist': z.string().default(''),
'alg-hist': z.string().default(''),
'alg-react': z.string().default(''),
'med-hist': z.string().default(''),
'blood-type': z.string().default(''),
})
export const ObjectSchema = z.object({
note: z.string().default(''),
'consc-level': z.string().default(''),
'consc-level-det': z.string().default(''),
'syst-bp': z.string().default(''),
'diast-bp': z.string().default(''),
pulse: z.string().default(''),
'resp-rate': z.string().default(''),
'hear-rt': z.string().default(''),
'neuro-cranialis': z.string().default(''),
sensoris: z.string().default(''),
'reflect-fisio': z.string().default(''),
'reflect-pato': z.string().default(''),
'autonom-neuron': z.string().default(''),
'neck-rom': z.string().default(''),
'body-rom': z.string().default(''),
'aga-rom': z.string().default(''),
'agb-rom': z.string().default(''),
'neck-mmt': z.string().default(''),
'body-mmt': z.string().default(''),
'aga-mmt': z.string().default(''),
'agb-mmt': z.string().default(''),
localis: z.string().default(''),
'medical-trouble': z.string().default(''),
'rehab-medic-trouble': z.string().default(''),
temp: z.string().default(''),
spo2: z.string().default(''),
weight: z.string().default(''),
height: z.string().default(''),
'head-to-toe': z.record(z.string()).default({}),
})
const AssessmentSchema = z.object({
'early-diag': AssessmentSectionSchema,
'late-diag': AssessmentSectionSchema,
'sec-diag': AssessmentSectionSchema,
})
const InstructionCodeGroupSchema = z.object({
note: z.string().default(''),
codes: z.array(DiagnosisCodeSchema).default([]),
})
const InstructionSchema = z.object({
detail: z.string().default(''),
'medical-act': InstructionCodeGroupSchema,
'supporting-exam': z.array(DiagnosisCodeSchema).default([]),
therapy: z.string().default(''),
medication: z.array(DiagnosisCodeSchema).default([]),
material: z.array(DiagnosisCodeSchema).default([]),
'rehab-program': z.string().default(''),
'physic-modal': z.string().default(''),
exercise: z.string().default(''),
'ortes-protesa': z.string().default(''),
education: z.string().default(''),
other: z.string().default(''),
})
export const SoapSchema = z.object({
subject: SubjectSchema,
object: ObjectSchema,
assessment: AssessmentSchema,
plan: z.string().default(''),
instruction: InstructionSchema,
})
export type SoapiFormData = z.infer<typeof SoapSchema> & Partial<Soap>
+28
View File
@@ -0,0 +1,28 @@
// Base
import * as base from './_crud-base'
// Types
import type { Soapi } from '~/models/soapi'
const path = '/api/v1/soapi'
const name = 'soapi'
export function create(data: any) {
return base.create(path, data, name)
}
export function getList(params: any = null) {
return base.getList(path, params, name)
}
export function getDetail(id: number | string) {
return base.getDetail(path, id, name)
}
export function update(id: number | string, data: any) {
return base.update(path, id, data, name)
}
export function remove(id: number | string) {
return base.remove(path, id, name)
}
+5 -2
View File
@@ -5,7 +5,10 @@ export const useUserStore = defineStore(
// const token = useCookie('authentication') // const token = useCookie('authentication')
const isAuthenticated = computed(() => !!user.value) const isAuthenticated = computed(() => !!user.value)
// const userRole = computed(() => user.value?.user_position_code || '') const userRole = computed(() => {
const roles = user.value?.roles || []
return roles.map((v) => v.split('-')[1])
})
const login = async (userData: any) => { const login = async (userData: any) => {
user.value = userData user.value = userData
@@ -18,7 +21,7 @@ export const useUserStore = defineStore(
return { return {
user, user,
isAuthenticated, isAuthenticated,
userRole: ['doctor'], userRole,
login, login,
logout, logout,
} }
+1 -2
View File
@@ -1,4 +1,3 @@
import process from 'node:process' import process from 'node:process'
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
@@ -8,7 +7,7 @@ export default defineNuxtConfig({
API_ORIGIN: process.env.NUXT_API_ORIGIN || 'http://localhost:3000', API_ORIGIN: process.env.NUXT_API_ORIGIN || 'http://localhost:3000',
public: { public: {
API_ORIGIN: process.env.NUXT_API_ORIGIN || 'http://localhost:3000', API_ORIGIN: process.env.NUXT_API_ORIGIN || 'http://localhost:3000',
} },
}, },
ssr: false, ssr: false,