-
-
+
+
+
+
+
+
+
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/my-ui/nav-footer/ok.vue b/app/components/pub/my-ui/nav-footer/ok.vue
new file mode 100644
index 00000000..da2f69ea
--- /dev/null
+++ b/app/components/pub/my-ui/nav-footer/ok.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
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/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/pages/(features)/rehab/encounter/index.vue b/app/pages/(features)/rehab/encounter/index.vue
index 81d919ea..9deaeb1f 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/services/employee.service.ts b/app/services/employee.service.ts
index d3691c83..366ef71e 100644
--- a/app/services/employee.service.ts
+++ b/app/services/employee.service.ts
@@ -31,7 +31,7 @@ export async function getValueLabelList(params: any = null): Promise<{ value: st
const resultData = result.body?.data || []
data = resultData.map((item: any) => ({
value: item.id ? Number(item.id) : item.code,
- label: item.name,
+ label: item.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/stores/user.ts b/app/stores/user.ts
index cbe92a69..14ab7134 100644
--- a/app/stores/user.ts
+++ b/app/stores/user.ts
@@ -7,7 +7,10 @@ export const useUserStore = defineStore(
const isAuthenticated = computed(() => !!user.value)
const userRole = computed(() => {
const roles = user.value?.roles || []
- return roles.map((v) => v.split('-')[1])
+ return roles.map((input: string) => {
+ const parts = input.split('-')
+ return parts.length > 1 ? parts[1]: parts[0]
+ })
})
const login = async (userData: any) => {