-
-
+
+
+
+
+
+
+
diff --git a/app/components/pub/my-ui/nav-footer/ca-ed-su.vue b/app/components/pub/my-ui/nav-footer/ca-ed-su.vue
new file mode 100644
index 00000000..1f0f5915
--- /dev/null
+++ b/app/components/pub/my-ui/nav-footer/ca-ed-su.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/pub/my-ui/nav-footer/ca-sa.vue b/app/components/pub/my-ui/nav-footer/ca-sa.vue
new file mode 100644
index 00000000..cbd5ef7f
--- /dev/null
+++ b/app/components/pub/my-ui/nav-footer/ca-sa.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/pub/my-ui/nav-footer/cl-sa.vue b/app/components/pub/my-ui/nav-footer/cl-sa.vue
new file mode 100644
index 00000000..fea6fc56
--- /dev/null
+++ b/app/components/pub/my-ui/nav-footer/cl-sa.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/pub/ui/button/index.ts b/app/components/pub/ui/button/index.ts
index c1aa89a8..c4063089 100644
--- a/app/components/pub/ui/button/index.ts
+++ b/app/components/pub/ui/button/index.ts
@@ -12,7 +12,7 @@ export const buttonVariants = cva(
destructive:
'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
outline:
- 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
+ 'border border-slate-300 dark:border-slate-600 bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
secondary:
'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
diff --git a/app/components/pub/ui/dialog/DialogContent.vue b/app/components/pub/ui/dialog/DialogContent.vue
index 5e9e8538..0c0fbf6b 100644
--- a/app/components/pub/ui/dialog/DialogContent.vue
+++ b/app/components/pub/ui/dialog/DialogContent.vue
@@ -34,7 +34,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
v-bind="forwarded"
:class="
cn(
- 'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-5 2xl:p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
+ 'fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-2 2x:gap-3 border bg-background p-5 2xl:p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
props.class,
)"
>
diff --git a/app/components/pub/ui/dialog/DialogDescription.vue b/app/components/pub/ui/dialog/DialogDescription.vue
index 3444c492..c7ac62d1 100644
--- a/app/components/pub/ui/dialog/DialogDescription.vue
+++ b/app/components/pub/ui/dialog/DialogDescription.vue
@@ -19,7 +19,7 @@ const forwardedProps = useForwardProps(delegatedProps)
diff --git a/app/composables/useQueryParam.ts b/app/composables/useQueryParam.ts
new file mode 100644
index 00000000..29674b88
--- /dev/null
+++ b/app/composables/useQueryParam.ts
@@ -0,0 +1,32 @@
+import { useRoute, useRouter } from 'vue-router'
+
+export function useQueryParam(key: string = 'mode') {
+ const route = useRoute()
+ const router = useRouter()
+
+ const getQueryParam = (key: string) => {
+ return route.query[key]
+ }
+
+ const setQueryParam = (key: string, val: string) => {
+ router.replace({
+ path: route.path,
+ query: {
+ ...route.query,
+ [key]: val === 'list' ? undefined : val,
+ },
+ })
+ }
+
+ const setQueryParams = (keyVal: Record) => {
+ router.replace({
+ path: route.path,
+ query: {
+ ...route.query,
+ ...keyVal,
+ },
+ })
+ }
+
+ return { getQueryParam, setQueryParam, setQueryParams}
+}
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/lib/constants.ts b/app/lib/constants.ts
index 59dd9bf5..3a52b22e 100644
--- a/app/lib/constants.ts
+++ b/app/lib/constants.ts
@@ -66,9 +66,26 @@ export const timeUnitCodes: Record = {
year: 'Tahun',
}
+export const bigTimeUnitCodes: Record = {
+ day: 'Hari',
+ week: 'Minggu',
+ month: 'Bulan',
+ year: 'Tahun',
+}
+
export const dischargeMethodCodes: Record = {
- home: 'Home',
- 'home-request': 'Home Request',
+ home: "Pulang",
+ "home-request": "Pulang Atas Permintaan Sendiri",
+ "consul-back": "Konsultasi Balik / Lanjutan",
+ "consul-poly": "Konsultasi Poliklinik Lain",
+ "consul-executive": "Konsultasi Antar Dokter Eksekutif",
+ "consul-ch-day": "Konsultasi Hari Lain",
+ emergency: "Rujuk IGD",
+ "emergency-covid": "Rujuk IGD Covid",
+ inpatient: "Rujuk Rawat Inap",
+ external: "Rujuk Faskes Lain",
+ death: "Meninggal",
+ "death-on-arrival": "Meninggal Saat Tiba"
}
export const genderCodes: Record = {
diff --git a/app/models/death-cause.ts b/app/models/death-cause.ts
new file mode 100644
index 00000000..0f04609a
--- /dev/null
+++ b/app/models/death-cause.ts
@@ -0,0 +1,6 @@
+export interface DeathCause {
+ id: bigint;
+ encounter_id: bigint;
+ value: any; // json mapped to 'any' type
+}
+
\ No newline at end of file
diff --git a/app/models/encounter.ts b/app/models/encounter.ts
index 681a2ac9..fb2c0b04 100644
--- a/app/models/encounter.ts
+++ b/app/models/encounter.ts
@@ -1,5 +1,7 @@
+import type { DeathCause } from "./death-cause"
import { type Doctor, genDoctor } from "./doctor"
import { genEmployee, type Employee } from "./employee"
+import type { InternalReference } from "./internal-reference"
import { type Patient, genPatient } from "./patient"
import type { Specialist } from "./specialist"
import type { Subspecialist } from "./subspecialist"
@@ -29,8 +31,11 @@ export interface Encounter {
earlyEducation?: string
medicalDischargeEducation: string
admDischargeEducation?: string
- dischargeMethod_code?: string
+ discharge_method_code?: string
discharge_reason?: string
+ discharge_date?: string
+ internalReferences?: InternalReference[]
+ deathCause?: DeathCause
status_code: string
}
diff --git a/app/models/internal-reference.ts b/app/models/internal-reference.ts
new file mode 100644
index 00000000..8af315a8
--- /dev/null
+++ b/app/models/internal-reference.ts
@@ -0,0 +1,12 @@
+export interface InternalReference {
+ id: number;
+ encounter_id: number;
+ unit_id: number; // smallint mapped to number
+ doctor_id: number; // int mapped to number
+}
+
+export interface CreateDto {
+ encounter_id: number;
+ unit_id: number; // smallint mapped to number
+ doctor_id: number; // int mapped to number
+}
\ No newline at end of file
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/encounter.schema.ts b/app/schemas/encounter.schema.ts
new file mode 100644
index 00000000..e3c9affc
--- /dev/null
+++ b/app/schemas/encounter.schema.ts
@@ -0,0 +1,48 @@
+import { z } from 'zod'
+import { InternalReferenceSchema } from './internal-reference.schema'
+
+// Check In
+const CheckInSchema = z.object({
+ // registeredAt: z.string({ required_error: 'Tanggal masuk harus diisi' }),
+ responsible_doctor_id: z.number({ required_error: 'Dokter harus diisi' }).gt(0, 'Dokter harus diisi'),
+ adm_employee_id: z.number({ required_error: 'PJA harus diisi' }).gt(0, 'PJA harus diisi'),
+})
+type CheckInFormData = z.infer
+
+// Checkout
+const CheckOutSchema = z.object({
+ discharge_method_code: z.string({ required_error: 'Metode pulang harus diisi' }),
+ discharge_date: z.string({ required_error: 'Tanggal pulang harus diisi' }),
+})
+type CheckOutFormData = z.infer
+
+// CheckoutDeath
+const CheckOutDeathSchema = z.object({
+ discharge_method_code: z.string({ required_error: 'Metode pulang harus diisi' }),
+ discharge_date: z.string({ required_error: 'Tanggal pulang harus diisi' }),
+ death_cause: z.array(z.string()).nonempty(),
+})
+type CheckOutDeathFormData = z.infer
+
+// CheckoutDeath
+const CheckOutInternalReferenceSchema = z.object({
+ discharge_method_code: z.string({ required_error: 'Metode pulang harus diisi' }),
+ discharge_date: z.string({ required_error: 'Tanggal pulang harus diisi' }),
+ internalReferences: z.array(InternalReferenceSchema).nonempty(),
+})
+type CheckOutInternalReferenceFormData = z.infer
+
+
+// Exports
+export {
+ CheckInSchema,
+ CheckOutSchema,
+ CheckOutDeathSchema,
+ CheckOutInternalReferenceSchema
+}
+export type {
+ CheckInFormData,
+ CheckOutFormData,
+ CheckOutDeathFormData,
+ CheckOutInternalReferenceFormData
+}
diff --git a/app/schemas/internal-reference.schema.ts b/app/schemas/internal-reference.schema.ts
new file mode 100644
index 00000000..eae75319
--- /dev/null
+++ b/app/schemas/internal-reference.schema.ts
@@ -0,0 +1,12 @@
+import { z } from 'zod'
+import type { InternalReference } from '~/models/internal-reference'
+
+const InternalReferenceSchema = z.object({
+ 'unit_id': z.number({ required_error: 'Kode harus diisi' }).min(1, 'Kode minimum 1 karakter'),
+ 'doctor_id': z.number({ required_error: 'Kode harus diisi' }).min(1, 'Kode minimum 1 karakter'),
+})
+
+type InternalReferenceFormData = z.infer & Partial
+
+export { InternalReferenceSchema }
+export type { InternalReferenceFormData }
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/doctor.service.ts b/app/services/doctor.service.ts
new file mode 100644
index 00000000..64ab22e9
--- /dev/null
+++ b/app/services/doctor.service.ts
@@ -0,0 +1,39 @@
+// Base
+import * as base from './_crud-base'
+import type { Doctor } from "~/models/doctor";
+
+const path = '/api/v1/doctor'
+const name = 'device'
+
+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)
+}
+
+export async function getValueLabelList(params: any = null): Promise<{ value: string; label: string }[]> {
+ let data: { value: string; label: string }[] = []
+ const result = await getList(params)
+ if (result.success) {
+ const resultData = result.body?.data || []
+ data = resultData.map((item: Doctor) => ({
+ value: item.id,
+ label: item.employee.person.name,
+ }))
+ }
+ return data
+}
diff --git a/app/services/encounter.service.ts b/app/services/encounter.service.ts
index cd7c28ed..6e42fd41 100644
--- a/app/services/encounter.service.ts
+++ b/app/services/encounter.service.ts
@@ -1,4 +1,5 @@
// Base
+import type { CheckInFormData } from '~/schemas/encounter.schema'
import * as base from './_crud-base'
// Constants
@@ -46,3 +47,16 @@ export function getValueLabelListConstants() {
.filter(([key]) => allowed.includes(key))
.map(([key, value]) => ({ value: key, label: value }))
}
+
+export async function checkIn(id: number, data: CheckInFormData) {
+ try {
+ const resp = await xfetch(`${path}/${id}/check-in`, 'PATCH', data)
+ const result: any = {}
+ result.success = resp.success
+ result.body = (resp.body as Record) || {}
+ return result
+ } catch (error) {
+ console.error(`Error putting ${name}:`, error)
+ throw new Error(`Failed to put ${name}`)
+ }
+}
\ No newline at end of file
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,