|
@@ -34,11 +77,17 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
-
+
@@ -50,11 +99,17 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
-
+
@@ -66,11 +121,17 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
-
+
@@ -79,88 +140,141 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
|
-
-
-
+
+
|
|
-
+
|
-
+
|
-
+
|
-
+
|
-
+
|
-
+
|
-
+
|
-
+
|
-
+
|
-
+
|
@@ -171,9 +285,10 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
+ + Pilih Diagnosa
+
@@ -183,9 +298,10 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
+ + Pilih Prosedur
+
@@ -199,21 +315,30 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
-
+
|
diff --git a/app/components/app/soapi/early-rehab-entry.vue b/app/components/app/soapi/early-rehab-entry.vue
index 61beb0f3..2cafbcac 100644
--- a/app/components/app/soapi/early-rehab-entry.vue
+++ b/app/components/app/soapi/early-rehab-entry.vue
@@ -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 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
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({
- 'prim-compl': '',
- 'sec-compl': '',
- 'cur-disea-hist': '',
- 'pas-disea-hist': '',
- 'fam-disea-hist': '',
- 'alg-hist': '',
- 'alg-react': '',
- 'med-hist': '',
- 'blood-type': '',
+// 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 [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)
@@ -36,8 +100,11 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
-
+
+
|
@@ -46,21 +113,30 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
-
+
|
@@ -77,22 +153,36 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
-
+
+
|
-
+
|
-
+
|
@@ -100,14 +190,21 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
props.excludeFields?.includes(key)
|
-
+
|
@@ -144,21 +244,30 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
-
+
|
@@ -166,13 +275,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
@@ -187,13 +302,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
@@ -201,13 +322,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
@@ -222,13 +349,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
@@ -236,13 +369,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
@@ -256,7 +395,10 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
@@ -271,7 +413,10 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
@@ -286,13 +431,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
@@ -316,21 +467,30 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
-
+
|
@@ -338,13 +498,19 @@ const isExcluded = (key: string) => props.excludeFields?.includes(key)
-
+
|
-
+
|
diff --git a/app/components/app/soapi/entry.vue b/app/components/app/soapi/entry.vue
index ced3e3d8..2ee2cefb 100644
--- a/app/components/app/soapi/entry.vue
+++ b/app/components/app/soapi/entry.vue
@@ -1,28 +1,47 @@
-
+
diff --git a/app/components/app/soapi/function-entry.vue b/app/components/app/soapi/function-entry.vue
index 98d35663..3e192c47 100644
--- a/app/components/app/soapi/function-entry.vue
+++ b/app/components/app/soapi/function-entry.vue
@@ -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 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
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({
- 'prim-compl': '',
- 'sec-compl': '',
- 'cur-disea-hist': '',
- 'pas-disea-hist': '',
- 'fam-disea-hist': '',
- 'alg-hist': '',
- 'alg-react': '',
- 'med-hist': '',
- 'blood-type': '',
+// 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 [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 disorders = ref([])
const therapies = ref([])
@@ -55,8 +119,11 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
-
+
+
|
@@ -65,14 +132,20 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
@@ -86,7 +159,7 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
@@ -100,7 +173,10 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
@@ -108,14 +184,20 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
@@ -123,13 +205,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
@@ -137,13 +225,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
@@ -151,13 +245,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
@@ -172,7 +272,10 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
@@ -183,19 +286,28 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
-
+
|
@@ -204,19 +316,28 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
-
+
|
@@ -227,13 +348,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
@@ -250,19 +377,28 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
|
-
+
|
-
+
|
-
+
|
@@ -281,19 +417,28 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
-
+
|
@@ -312,19 +457,28 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
-
+
|
@@ -332,13 +486,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
@@ -348,13 +508,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
@@ -369,13 +535,19 @@ const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', '
-
+
|
-
+
|
diff --git a/app/components/content/encounter/list.vue b/app/components/content/encounter/list.vue
index 967bcf11..76f32415 100644
--- a/app/components/content/encounter/list.vue
+++ b/app/components/content/encounter/list.vue
@@ -95,14 +95,22 @@ provide('table_data_loader', isLoading)
-
+
+
-
diff --git a/app/components/content/encounter/process.vue b/app/components/content/encounter/process.vue
index d0eddd31..8179b1ce 100644
--- a/app/components/content/encounter/process.vue
+++ b/app/components/content/encounter/process.vue
@@ -3,12 +3,11 @@
import { computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
-// 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 { getDetail } from '~/services/encounter.service'
-import type { Encounter } from '~/models/encounter'
+
+// Components
+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/content/encounter/status.vue'
import AssesmentFunctionList from '~/components/content/assesment-function/list.vue'
@@ -29,7 +28,10 @@ const activeTab = computed({
})
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 data = dataResBody?.data ?? null
diff --git a/app/components/content/soapi/entry.vue b/app/components/content/soapi/entry.vue
index 42800d8f..7b4ab9d4 100644
--- a/app/components/content/soapi/entry.vue
+++ b/app/components/content/soapi/entry.vue
@@ -1,7 +1,7 @@
+
+import { z } from 'zod'
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 { 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 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({
isTableLoading: false,
})
@@ -21,19 +78,45 @@ onMounted(() => {
getPatientList()
})
-function handleClick(type: string) {
+function handleOpen(type: string) {
console.log(type)
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)
+
+import { z } from 'zod'
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 { 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 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({
isTableLoading: false,
})
@@ -21,16 +51,51 @@ onMounted(() => {
getPatientList()
})
-function handleClick(type: string) {
+function handleOpen(type: string) {
console.log(type)
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)
-
-
+
+
+
diff --git a/app/composables/useRBAC.ts b/app/composables/useRBAC.ts
index 543c3b90..ced57e3e 100644
--- a/app/composables/useRBAC.ts
+++ b/app/composables/useRBAC.ts
@@ -9,13 +9,12 @@ export function useRBAC() {
const checkRole = (roleAccess: RoleAccess, _userRoles?: string[]): boolean => {
const roles = authStore.userRole
- return roles.some((role: string) => role in roleAccess)
+ return roles.some((role: string) => (role in roleAccess) || role === 'system') // system by-passes this check
}
const checkPermission = (roleAccess: RoleAccess, permission: Permission, _userRoles?: string[]): boolean => {
const roles = authStore.userRole
- // const roles = ['admisi']
- return roles.some((role: string) => roleAccess[role]?.includes(permission))
+ return roles.some((role: string) => roleAccess[role]?.includes(permission) || role === 'system') // system by-passes this check
}
const getUserPermissions = (roleAccess: RoleAccess, _userRoles?: string[]): Permission[] => {
@@ -23,7 +22,7 @@ export function useRBAC() {
// const roles = ['admisi']
const permissions = new Set()
- roles.forEach((role) => {
+ roles.forEach((role: string) => {
if (roleAccess[role]) {
roleAccess[role].forEach((permission) => permissions.add(permission))
}
diff --git a/app/handlers/soapi-early.handler.ts b/app/handlers/soapi-early.handler.ts
new file mode 100644
index 00000000..3a07108e
--- /dev/null
+++ b/app/handlers/soapi-early.handler.ts
@@ -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,
+})
diff --git a/app/models/soapi.ts b/app/models/soapi.ts
index 0289b342..02b4dcd5 100644
--- a/app/models/soapi.ts
+++ b/app/models/soapi.ts
@@ -1,4 +1,4 @@
-import { type Base, genBase } from "./_base"
+import { type Base, genBase } from './_base'
export interface Soapi extends Base {
encounter_id: number
@@ -16,3 +16,175 @@ export function genSoapi(): Soapi {
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
+}
+
+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: '',
+ },
+ }
+}
diff --git a/app/pages/(features)/rehab/encounter/index.vue b/app/pages/(features)/rehab/encounter/index.vue
index 9d06c9e0..7a8564a8 100644
--- a/app/pages/(features)/rehab/encounter/index.vue
+++ b/app/pages/(features)/rehab/encounter/index.vue
@@ -5,7 +5,7 @@ import { PAGE_PERMISSIONS } from '~/lib/page-permission'
definePageMeta({
middleware: ['rbac'],
- roles: ['doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
+ roles: ['system', 'doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
title: 'Daftar Kunjungan',
contentFrame: 'cf-full-width',
})
diff --git a/app/schemas/soapi.schema.ts b/app/schemas/soapi.schema.ts
new file mode 100644
index 00000000..50ade93e
--- /dev/null
+++ b/app/schemas/soapi.schema.ts
@@ -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 & Partial
diff --git a/app/services/soapi-early.service.ts b/app/services/soapi-early.service.ts
new file mode 100644
index 00000000..7c55c979
--- /dev/null
+++ b/app/services/soapi-early.service.ts
@@ -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)
+}
diff --git a/app/stores/user.ts b/app/stores/user.ts
index a9ed35c1..14ab7134 100644
--- a/app/stores/user.ts
+++ b/app/stores/user.ts
@@ -5,7 +5,13 @@ export const useUserStore = defineStore(
// const token = useCookie('authentication')
const isAuthenticated = computed(() => !!user.value)
- // const userRole = computed(() => user.value?.user_position_code || '')
+ const userRole = computed(() => {
+ const roles = user.value?.roles || []
+ return roles.map((input: string) => {
+ const parts = input.split('-')
+ return parts.length > 1 ? parts[1]: parts[0]
+ })
+ })
const login = async (userData: any) => {
user.value = userData
@@ -18,7 +24,7 @@ export const useUserStore = defineStore(
return {
user,
isAuthenticated,
- userRole: ['doctor'],
+ userRole,
login,
logout,
}
diff --git a/nuxt.config.ts b/nuxt.config.ts
index c5ac4c6c..55cdb6bf 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -1,4 +1,3 @@
-
import process from 'node:process'
// 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',
public: {
API_ORIGIN: process.env.NUXT_API_ORIGIN || 'http://localhost:3000',
- }
+ },
},
ssr: false,
| |