diff --git a/app/components/app/surgery-report/_common/select-billing-code.vue b/app/components/app/surgery-report/_common/select-billing-code.vue new file mode 100644 index 00000000..321c2d33 --- /dev/null +++ b/app/components/app/surgery-report/_common/select-billing-code.vue @@ -0,0 +1,71 @@ + + + + + + {{ label }} + + + + + + + + + + + + + diff --git a/app/components/app/surgery-report/_common/select-birth-desc.vue b/app/components/app/surgery-report/_common/select-birth-desc.vue new file mode 100644 index 00000000..2b19f3bc --- /dev/null +++ b/app/components/app/surgery-report/_common/select-birth-desc.vue @@ -0,0 +1,71 @@ + + + + + + {{ label }} + + + + + + + + + + + + + diff --git a/app/components/app/surgery-report/_common/select-birth-place-desc.vue b/app/components/app/surgery-report/_common/select-birth-place-desc.vue new file mode 100644 index 00000000..c6f2ed06 --- /dev/null +++ b/app/components/app/surgery-report/_common/select-birth-place-desc.vue @@ -0,0 +1,71 @@ + + + + + + {{ label }} + + + + + + + + + + + + + diff --git a/app/components/app/surgery-report/_common/select-date.vue b/app/components/app/surgery-report/_common/select-date.vue new file mode 100644 index 00000000..0468c752 --- /dev/null +++ b/app/components/app/surgery-report/_common/select-date.vue @@ -0,0 +1,117 @@ + + + + + + {{ label }} + + + + + + { + const dateStr = typeof value === 'number' ? String(value) : value + patientAge = calculateAge(dateStr) + } + " + /> + + + + + + + diff --git a/app/components/app/surgery-report/_common/select-dissection-type.vue b/app/components/app/surgery-report/_common/select-dissection-type.vue new file mode 100644 index 00000000..45708dac --- /dev/null +++ b/app/components/app/surgery-report/_common/select-dissection-type.vue @@ -0,0 +1,71 @@ + + + + + + {{ label }} + + + + + + + + + + + + + diff --git a/app/components/app/surgery-report/_common/select-dpjp-anastesi.vue b/app/components/app/surgery-report/_common/select-dpjp-anastesi.vue new file mode 100644 index 00000000..b649c28f --- /dev/null +++ b/app/components/app/surgery-report/_common/select-dpjp-anastesi.vue @@ -0,0 +1,87 @@ + + + + + + {{ label }} + + + + + + + + + + + + + diff --git a/app/components/app/surgery-report/_common/select-dpjp-bedah.vue b/app/components/app/surgery-report/_common/select-dpjp-bedah.vue new file mode 100644 index 00000000..b649c28f --- /dev/null +++ b/app/components/app/surgery-report/_common/select-dpjp-bedah.vue @@ -0,0 +1,87 @@ + + + + + + {{ label }} + + + + + + + + + + + + + diff --git a/app/components/app/surgery-report/_common/select-specimen-type.vue b/app/components/app/surgery-report/_common/select-specimen-type.vue new file mode 100644 index 00000000..e1017e76 --- /dev/null +++ b/app/components/app/surgery-report/_common/select-specimen-type.vue @@ -0,0 +1,71 @@ + + + + + + {{ label }} + + + + + + + + + + + + + diff --git a/app/components/app/surgery-report/_common/select-surgery-order.vue b/app/components/app/surgery-report/_common/select-surgery-order.vue new file mode 100644 index 00000000..ff48d195 --- /dev/null +++ b/app/components/app/surgery-report/_common/select-surgery-order.vue @@ -0,0 +1,71 @@ + + + + + + {{ label }} + + + + + + + + + + + + + diff --git a/app/components/app/surgery-report/_common/select-surgery-system-type.vue b/app/components/app/surgery-report/_common/select-surgery-system-type.vue new file mode 100644 index 00000000..745904eb --- /dev/null +++ b/app/components/app/surgery-report/_common/select-surgery-system-type.vue @@ -0,0 +1,71 @@ + + + + + + {{ label }} + + + + + + + + + + + + + diff --git a/app/components/app/surgery-report/_common/select-surgery-type.vue b/app/components/app/surgery-report/_common/select-surgery-type.vue new file mode 100644 index 00000000..e396fe7d --- /dev/null +++ b/app/components/app/surgery-report/_common/select-surgery-type.vue @@ -0,0 +1,71 @@ + + + + + + {{ label }} + + + + + + + + + + + + + diff --git a/app/components/app/surgery-report/detail.vue b/app/components/app/surgery-report/detail.vue new file mode 100644 index 00000000..e10a2b91 --- /dev/null +++ b/app/components/app/surgery-report/detail.vue @@ -0,0 +1,54 @@ + + + + + {{ props.instance?.date ? new Date(props.instance?.date).toLocaleDateString('id-ID') : '-' }} + {{ props.instance?.unit.name || '-' }} + {{ props.instance?.specialist.name || '-' }} + {{ props.instance?.subspecialist.name || '-' }} + {{ props.instance?.doctor.employee.person.name || '-' }} + {{ 'SEP INTERNAL' }} + + + + + + + diff --git a/app/components/app/surgery-report/entry.vue b/app/components/app/surgery-report/entry.vue new file mode 100644 index 00000000..e3862ee5 --- /dev/null +++ b/app/components/app/surgery-report/entry.vue @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lama Operasi + {{ 1 }} Jam {{ 1 }} Menit + + + + + Lama Pembiusan + {{ 1 }} Jam {{ 1 }} Menit + + + + + + + + + + + diff --git a/app/components/app/surgery-report/list.cfg.ts b/app/components/app/surgery-report/list.cfg.ts new file mode 100644 index 00000000..6a63af13 --- /dev/null +++ b/app/components/app/surgery-report/list.cfg.ts @@ -0,0 +1,57 @@ +import type { Config } from '~/components/pub/my-ui/data-table' +import type { Patient } from '~/models/patient' +import { defineAsyncComponent } from 'vue' +import { educationCodes, genderCodes } from '~/lib/constants' +import { calculateAge } from '~/lib/utils' + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-dud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, {}, {}, {},], + + headers: [ + [ + { label: 'Tgl Laporan' }, + { label: 'DPJP Bedah' }, + { label: 'DPJP Anastesi' }, + { label: 'Tgl Pembedahan' }, + { label: 'Jenis Operasi' }, + { label: 'Kode Billing' }, + { label: 'Sistem Operasi' }, + { label: 'Action' }, + ], + ], + + keys: ['date', 'doctor.employee.person.name', 'doctor.employee.person.name', 'date', 'name', 'name', 'name', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + date: (rec: unknown): unknown => { + const date = (rec as any).date + if (typeof date == 'object' && date) { + return (date as Date).toLocaleDateString('id-ID') + } else if (typeof date == 'string') { + return (date as string).substring(0, 10) + } + return date + }, + }, + + components: { + action(rec, idx) { + return { + idx, + rec: rec as object, + component: action, + } + }, + }, + + htmls: { + + }, +} diff --git a/app/components/app/surgery-report/list.vue b/app/components/app/surgery-report/list.vue new file mode 100644 index 00000000..8274e752 --- /dev/null +++ b/app/components/app/surgery-report/list.vue @@ -0,0 +1,31 @@ + + + + + + + + diff --git a/app/components/app/surgery-report/multiselect-picker.vue b/app/components/app/surgery-report/multiselect-picker.vue new file mode 100644 index 00000000..98a146ce --- /dev/null +++ b/app/components/app/surgery-report/multiselect-picker.vue @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/app/components/app/surgery-report/operative-action-list.cfg.ts b/app/components/app/surgery-report/operative-action-list.cfg.ts new file mode 100644 index 00000000..2d0a6637 --- /dev/null +++ b/app/components/app/surgery-report/operative-action-list.cfg.ts @@ -0,0 +1,56 @@ +import type { Config } from '~/components/pub/my-ui/data-table' +import type { Patient } from '~/models/patient' +import { defineAsyncComponent } from 'vue' +import { educationCodes, genderCodes } from '~/lib/constants' +import { calculateAge } from '~/lib/utils' + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-dud.vue')) + +export const config: Config = { + cols: [{}, {}, {}, {}, {}, {}, {}, ], + + headers: [ + [ + { label: 'Tgl Laporan' }, + { label: 'DPJP Bedah' }, + { label: 'DPJP Anastesi' }, + { label: 'Tgl Pembedahan' }, + { label: 'Jenis Operasi' }, + { label: 'Kode Billing' }, + { label: 'Sistem Operasi' }, + ], + ], + + keys: ['date', 'doctor.employee.person.name', 'doctor.employee.person.name', 'date', 'name', 'name', 'name'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + date: (rec: unknown): unknown => { + const date = (rec as any).date + if (typeof date == 'object' && date) { + return (date as Date).toLocaleDateString('id-ID') + } else if (typeof date == 'string') { + return (date as string).substring(0, 10) + } + return date + }, + }, + + components: { + // action(rec, idx) { + // return { + // idx, + // rec: rec as object, + // component: action, + // } + // }, + }, + + htmls: { + + }, +} diff --git a/app/components/content/encounter/process.vue b/app/components/content/encounter/process.vue index 02fc7495..2e03029c 100644 --- a/app/components/content/encounter/process.vue +++ b/app/components/content/encounter/process.vue @@ -26,6 +26,7 @@ import DocUploadList from '~/components/content/document-upload/list.vue' import GeneralConsentList from '~/components/content/general-consent/entry.vue' import ResumeList from '~/components/content/resume/list.vue' import ControlLetterList from '~/components/content/control-letter/list.vue' +import SurgeryReportList from '~/components/content/surgery-report/list.vue' const route = useRoute() const router = useRouter() @@ -90,6 +91,7 @@ const tabs: TabItem[] = [ { value: 'resume', label: 'Resume', component: ResumeList, props: { encounter: data } }, { value: 'control', label: 'Surat Kontrol', component: ControlLetterList, props: { encounter: data } }, { value: 'screening', label: 'Skrinning MPP' }, + { value: 'surgery-report', label: 'Laporan Operasi', component: SurgeryReportList, props: { encounter: data } }, { value: 'supporting-document', label: 'Upload Dokumen Pendukung', diff --git a/app/components/content/surgery-report/detail.vue b/app/components/content/surgery-report/detail.vue new file mode 100644 index 00000000..00d15f21 --- /dev/null +++ b/app/components/content/surgery-report/detail.vue @@ -0,0 +1,77 @@ + + + + + + + diff --git a/app/components/content/surgery-report/entry.vue b/app/components/content/surgery-report/entry.vue new file mode 100644 index 00000000..d36fcec1 --- /dev/null +++ b/app/components/content/surgery-report/entry.vue @@ -0,0 +1,194 @@ + + + + Update Laporan Operasi + + + + + + + + + + + + + + + + + + + + + diff --git a/app/components/content/surgery-report/list.vue b/app/components/content/surgery-report/list.vue new file mode 100644 index 00000000..eddd10c7 --- /dev/null +++ b/app/components/content/surgery-report/list.vue @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + aaaaaaa + + + + + + + ID: + {{ record?.id }} + + + Nama: + {{ record.firstName }} + + + Kode: + {{ record.cellphone }} + + + + + + diff --git a/app/components/pub/my-ui/nav-header/filter.vue b/app/components/pub/my-ui/nav-header/filter.vue index 74f6d8dc..f4fef2b3 100644 --- a/app/components/pub/my-ui/nav-header/filter.vue +++ b/app/components/pub/my-ui/nav-header/filter.vue @@ -101,7 +101,7 @@ function onFilterClick() { - + Ekspor diff --git a/app/handlers/surgery-report.handler.ts b/app/handlers/surgery-report.handler.ts new file mode 100644 index 00000000..e24ab442 --- /dev/null +++ b/app/handlers/surgery-report.handler.ts @@ -0,0 +1,24 @@ +// Handlers +import { genCrudHandler } from '~/handlers/_handler' + +// Services +import { create, update, remove } from '~/services/surgery-report.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 48fb5c8c..c676a799 100644 --- a/app/lib/constants.ts +++ b/app/lib/constants.ts @@ -425,3 +425,65 @@ export const supportingDocOpt = [ { label: 'Data Penunjang', value: 'encounter-support' }, { label: 'Lain - Lain', value: 'encounter-other' }, ] + + +export type SurgeryType = "kecil" | "sedang" | "besar" | "khusus" +export const SurgeryTypeOptList: { label: string; value: SurgeryType }[] = [ + { label: 'Kecil', value: 'kecil' }, + { label: 'Sedang', value: 'sedang' }, + { label: 'Besar', value: 'besar' }, + { label: 'Khusus', value: 'khusus' }, +] + +export type BillingCodeType = "general" | "regional" | "local" +export const BillingCodeTypeOptList: { label: string; value: BillingCodeType }[] = [ + { label: 'General', value: 'general' }, + { label: 'Regional', value: 'regional' }, + { label: 'Local', value: 'local' }, +] + +export type SurgerySystemType = "cito" | "urgent" | "efektif" | "khusus" +export const SurgerySystemTypeOptList: { label: string; value: SurgerySystemType }[] = [ + { label: 'Cito', value: 'cito' }, + { label: 'Urgent', value: 'urgent' }, + { label: 'Efektif', value: 'efektif' }, + { label: 'Khusus', value: 'khusus' }, +] + +export type DissectionType = "bersih" | "bersih terkontaminasi" | "terkontaminasi kotor" | "kotor" +export const DissectionTypeOptList: { label: string; value: DissectionType }[] = [ + { label: 'Bersih', value: 'bersih' }, + { label: 'Bersih terkontaminasi', value: 'bersih terkontaminasi' }, + { label: 'Terkontaminasi kotor', value: 'terkontaminasi kotor' }, + { label: 'Kotor', value: 'kotor' }, +] + +export type SurgeryOrderType = "satu" | "ulangan" +export const SurgeryOrderTypeOptList: { label: string; value: SurgeryOrderType }[] = [ + { label: 'Satu', value: 'satu' }, + { label: 'Ulangan', value: 'ulangan' }, +] + +export type BirthDescriptionType = "lahir hidup" | "lahir mati" +export const BirthDescriptionTypeOptList: { label: string; value: BirthDescriptionType }[] = [ + { label: 'Lahir Hidup', value: 'lahir hidup' }, + { label: 'Lahir Mati', value: 'lahir mati' }, +] + +export type BirthPlaceDescriptionType = "rssa" | "bidan luar" | "dokter luar" | "dukun bayi" | "puskesmas" | "paramedis luar" +export const BirthPlaceDescriptionTypeOptList: { label: string; value: BirthPlaceDescriptionType }[] = [ + { label: 'RSSA', value: 'rssa' }, + { label: 'Bidan luar', value: 'bidan luar' }, + { label: 'Dokter luar', value: 'dokter luar' }, + { label: 'Dukun bayi', value: 'dukun bayi' }, + { label: 'Puskesmas', value: 'puskesmas' }, + { label: 'Paramedis luar', value: 'paramedis luar' }, +] + +export type SpecimenType = "pa" | "mikrobiologi" | "laborat" | "tidak perlu" +export const SpecimenTypeOptList: { label: string; value: SpecimenType }[] = [ + { label: 'PA', value: 'pa' }, + { label: 'Mikrobiologi', value: 'mikrobiologi' }, + { label: 'Laborat', value: 'laborat' }, + { label: 'Tidak perlu', value: 'tidak perlu' }, +] \ No newline at end of file diff --git a/app/models/surgery-report.ts b/app/models/surgery-report.ts new file mode 100644 index 00000000..8eb0edef --- /dev/null +++ b/app/models/surgery-report.ts @@ -0,0 +1,37 @@ +import { type Base, genBase } from "./_base" +import { genDoctor, type Doctor } from "./doctor" +import { genEncounter, type Encounter } from "./encounter" +import { genSpecialist, type Specialist } from "./specialist" +import { genSubspecialist, type Subspecialist } from "./subspecialist" +import { genUnit, type Unit } from "./unit" + +export interface SurgeryReport extends Base { + encounter_id: number + encounter: Encounter + unit_id: number + unit: Unit + specialist_id: number + specialist: Specialist + subspecialist_id: number + subspecialist: Subspecialist + doctor_id: number + doctor: Doctor + date: '' +} + +export function genSurgeryReport(): SurgeryReport { + return { + ...genBase(), + encounter_id: 0, + encounter: genEncounter(), + unit_id: 0, + unit: genUnit(), + specialist_id: 0, + specialist: genSpecialist(), + subspecialist_id: 0, + subspecialist: genSubspecialist(), + doctor_id: 0, + doctor: genDoctor(), + date: '' + } +} diff --git a/app/pages/(features)/rehab/encounter/[id]/surgery-report/[surgery_report_id]/edit.vue b/app/pages/(features)/rehab/encounter/[id]/surgery-report/[surgery_report_id]/edit.vue new file mode 100644 index 00000000..a90f1d10 --- /dev/null +++ b/app/pages/(features)/rehab/encounter/[id]/surgery-report/[surgery_report_id]/edit.vue @@ -0,0 +1,41 @@ + + + + + + + + + + diff --git a/app/pages/(features)/rehab/encounter/[id]/surgery-report/[surgery_report_id]/index.vue b/app/pages/(features)/rehab/encounter/[id]/surgery-report/[surgery_report_id]/index.vue new file mode 100644 index 00000000..7d9db6bd --- /dev/null +++ b/app/pages/(features)/rehab/encounter/[id]/surgery-report/[surgery_report_id]/index.vue @@ -0,0 +1,41 @@ + + + + + + + + + + diff --git a/app/pages/(features)/rehab/encounter/[id]/surgery-report/add.vue b/app/pages/(features)/rehab/encounter/[id]/surgery-report/add.vue new file mode 100644 index 00000000..58faedef --- /dev/null +++ b/app/pages/(features)/rehab/encounter/[id]/surgery-report/add.vue @@ -0,0 +1,41 @@ + + + + + + + + + + diff --git a/app/schemas/surgery-report.schema.ts b/app/schemas/surgery-report.schema.ts new file mode 100644 index 00000000..5c1a024b --- /dev/null +++ b/app/schemas/surgery-report.schema.ts @@ -0,0 +1,47 @@ +import { z } from 'zod' + +const SurgeryReportSchema = z.object({ + sepStatus: z.string({ + required_error: 'Mohon isi status SEP', + }).default('SEP Internal'), + unit_code: z.string({ + required_error: 'Mohon isi Unit', + }), + specialist_code: z.string({ + required_error: 'Mohon isi Spesialis', + }), + subspecialist_code: z.string({ + required_error: 'Mohon isi Sub Spesialis', + }), + doctor_code: z.string({ + required_error: 'Mohon isi DPJP', + }), + encounter_code: z.string().optional(), + date: z.string({ + required_error: 'Mohon lengkapi Tanggal Kontrol', + }) + .refine( + (date) => { + // Jika kosong, return false untuk required validation + if (!date || date.trim() === '') return false + + // Jika ada isi, validasi format tanggal + try { + const dateObj = new Date(date) + // Cek apakah tanggal valid dan tahun >= 1900 + return !isNaN(dateObj.getTime()) && dateObj.getFullYear() >= 1900 + } catch { + return false + } + }, + { + message: 'Mohon lengkapi Tanggal Kontrol dengan format yang valid', + }, + ) + .transform((dateStr) => new Date(dateStr).toISOString()), +}) + +type SurgeryReportFormData = z.infer + +export { SurgeryReportSchema } +export type { SurgeryReportFormData } diff --git a/app/services/surgery-report.service.ts b/app/services/surgery-report.service.ts new file mode 100644 index 00000000..e53874de --- /dev/null +++ b/app/services/surgery-report.service.ts @@ -0,0 +1,28 @@ +// Base +import * as base from './_crud-base' + +// Constants +import { encounterClassCodes } from '~/lib/constants' + +const path = '/api/v1/surgery-report' +const name = 'surgery-report' + +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, params?: any) { + return base.getDetail(path, id, name, params) +} + +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) +} \ No newline at end of file
Lama Operasi
Lama Pembiusan
+ ID: + {{ record?.id }} +
+ Nama: + {{ record.firstName }} +
+ Kode: + {{ record.cellphone }} +