diff --git a/app/components/app/procedure-room-order-item/list-detail.cfg.ts b/app/components/app/procedure-room-order-item/list-detail.cfg.ts
new file mode 100644
index 00000000..cf0f6dab
--- /dev/null
+++ b/app/components/app/procedure-room-order-item/list-detail.cfg.ts
@@ -0,0 +1,16 @@
+import type { Config } from '~/components/pub/my-ui/data-table'
+import { defineAsyncComponent } from 'vue'
+
+export const config: Config = {
+ cols: [{}, {}, { classVal: '!p-0.5' }],
+
+ headers: [
+ [
+ { label: 'Kode' },
+ { label: 'Nama' },
+ { label: 'Catatan' },
+ ],
+ ],
+
+ keys: ['procedureRoom.code', 'procedureRoom.infra.name', 'note'],
+}
diff --git a/app/components/app/procedure-room-order-item/list-detail.vue b/app/components/app/procedure-room-order-item/list-detail.vue
new file mode 100644
index 00000000..75727a72
--- /dev/null
+++ b/app/components/app/procedure-room-order-item/list-detail.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+ Daftar Order Ruang
+
+
+
+
diff --git a/app/components/app/procedure-room-order-item/list-entry.cfg.ts b/app/components/app/procedure-room-order-item/list-entry.cfg.ts
new file mode 100644
index 00000000..2afcd855
--- /dev/null
+++ b/app/components/app/procedure-room-order-item/list-entry.cfg.ts
@@ -0,0 +1,43 @@
+import type { Config } from '~/components/pub/my-ui/data-table'
+import { defineAsyncComponent } from 'vue'
+
+const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-dud.vue'))
+const input = defineAsyncComponent(() => import('~/components/pub/ui/input/Input.vue'))
+
+export const config: Config = {
+ cols: [{}, {}, { classVal: '!p-0.5' }, { width: 50 }],
+
+ headers: [
+ [
+ { label: 'Kode' },
+ { label: 'Nama' },
+ { label: 'Catatan' },
+ { label: '' },
+ ],
+ ],
+
+ keys: ['procedureRoom.code', 'procedureRoom.infra.name', 'note'],
+
+ delKeyNames: [
+ { key: 'mcuSrc.name', label: 'Nama' },
+ ],
+
+ components: {
+ note(rec, idx) {
+ return {
+ idx,
+ rec: rec as object,
+ component: input,
+ }
+ },
+ action(rec, idx) {
+ return {
+ idx,
+ rec: rec as object,
+ component: action,
+ }
+ },
+ },
+
+ htmls: {},
+}
diff --git a/app/components/app/procedure-room-order-item/list-entry.vue b/app/components/app/procedure-room-order-item/list-entry.vue
new file mode 100644
index 00000000..f86a0b8e
--- /dev/null
+++ b/app/components/app/procedure-room-order-item/list-entry.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+ Daftar Order Ruang
+
+
+
+
+
+
+
diff --git a/app/components/app/procedure-room-order/detail.vue b/app/components/app/procedure-room-order/detail.vue
new file mode 100644
index 00000000..23d0dc75
--- /dev/null
+++ b/app/components/app/procedure-room-order/detail.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+ Detail Order
+
+
+
+ No. Order
+
+ ORT-{{ data.id }}
+
+
+ Tgl. Order
+
+ {{ data.createdAt?.substring(0, 10) }}
+
+
+
+
diff --git a/app/components/app/procedure-room-order/form.vue b/app/components/app/procedure-room-order/form.vue
new file mode 100644
index 00000000..ff6c3835
--- /dev/null
+++ b/app/components/app/procedure-room-order/form.vue
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/app/components/app/procedure-room-order/list.cfg.ts b/app/components/app/procedure-room-order/list.cfg.ts
new file mode 100644
index 00000000..e415e26f
--- /dev/null
+++ b/app/components/app/procedure-room-order/list.cfg.ts
@@ -0,0 +1,61 @@
+import type { Config, RecComponent } from '~/components/pub/my-ui/data-table'
+import { defineAsyncComponent } from 'vue'
+import type { ProcedureRoomOrder } from '~/models/procedure-room-order'
+
+const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-dsd.vue'))
+
+export const config: Config = {
+ cols: [{}, {}, {}, {}, {}, { width: 50 }],
+
+ headers: [[
+ { label: 'Tgl. Order' },
+ { label: 'No. Order' },
+ { label: 'Ruangan' },
+ { label: 'Status' },
+ { label: 'Resume' },
+ { label: '' },
+ ]],
+
+ keys: ['date', 'number', 'room', 'status_code', 'resume', 'action'],
+
+ delKeyNames: [
+ { key: 'createdAt', label: 'Tgl. Order' },
+ { key: 'id', label: 'No. Order' },
+ ],
+
+ parses: {
+ date: (rec: any) => {
+ const recX = rec as ProcedureRoomOrder
+ return recX.createdAt ? recX.createdAt.substring(0, 10) : ''
+
+ },
+ number: (rec: any) => {
+ const recX = rec as ProcedureRoomOrder
+ return `ORT-${recX.id}`
+ },
+ room: (rec: any) => {
+ const recX = rec as ProcedureRoomOrder
+ let result = ''
+ if (recX.items && recX.items.length > 0) {
+ recX.items.forEach((item, idx) => {
+ result += item.infra?.name ? `
${item.infra.name}
` : ''
+ })
+ }
+ // recX.ite
+ return ''
+ },
+ },
+
+ components: {
+ action(rec, idx) {
+ const res: RecComponent = {
+ idx,
+ rec: rec as object,
+ component: action,
+ }
+ return res
+ },
+ },
+
+ htmls: {},
+}
diff --git a/app/components/app/procedure-room-order/list.vue b/app/components/app/procedure-room-order/list.vue
new file mode 100644
index 00000000..bdbfe1be
--- /dev/null
+++ b/app/components/app/procedure-room-order/list.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
diff --git a/app/components/app/procedure-room/multi-opt-picker.vue b/app/components/app/procedure-room/multi-opt-picker.vue
new file mode 100644
index 00000000..ecdd945a
--- /dev/null
+++ b/app/components/app/procedure-room/multi-opt-picker.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+ Daftar Pilihan Ruang Tindakan
+
+
+
+
+
+
+
+
Tidak ada data ruang tindakan.
+
+
+
+
diff --git a/app/components/app/procedure-room/picker.vue b/app/components/app/procedure-room/picker.vue
new file mode 100644
index 00000000..3660e0cb
--- /dev/null
+++ b/app/components/app/procedure-room/picker.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+ Daftar Pilihan Ruang Tindakan
+
+
+
+
+
+
+
+
Tidak ada data ruang tindakan.
+
+
+
+
diff --git a/app/components/app/procedure-room/single-opt-picker.vue b/app/components/app/procedure-room/single-opt-picker.vue
new file mode 100644
index 00000000..ecdd945a
--- /dev/null
+++ b/app/components/app/procedure-room/single-opt-picker.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+ Daftar Pilihan Ruang Tindakan
+
+
+
+
+
+
+
+
Tidak ada data ruang tindakan.
+
+
+
+
diff --git a/app/components/app/procedure-room/switcher.vue b/app/components/app/procedure-room/switcher.vue
new file mode 100644
index 00000000..fdd80e7d
--- /dev/null
+++ b/app/components/app/procedure-room/switcher.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+ Jenis Ruang Tindakan
+
+
+
+
+
+
diff --git a/app/components/app/procedure-src/list.vue b/app/components/app/procedure-src/list.vue
index 1be60a60..d976b660 100644
--- a/app/components/app/procedure-src/list.vue
+++ b/app/components/app/procedure-src/list.vue
@@ -7,13 +7,16 @@ import type { PaginationMeta } from '~/components/pub/my-ui/pagination/paginatio
// Configs
import { config } from './list-cfg'
+import type { Config } from '~/components/pub/my-ui/data-table'
interface Props {
data: any[]
paginationMeta: PaginationMeta
+ tableConfig?: Config
}
-
-defineProps
()
+const props = withDefaults(defineProps(), {
+ tableConfig: () => config,
+})
const emit = defineEmits<{
pageChange: [page: number]
@@ -27,7 +30,7 @@ function handlePageChange(page: number) {
diff --git a/app/components/app/sep/action-history.vue b/app/components/app/sep/action-history.vue
new file mode 100644
index 00000000..8ca652b1
--- /dev/null
+++ b/app/components/app/sep/action-history.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
diff --git a/app/components/app/sep/entry-form.vue b/app/components/app/sep/entry-form.vue
index 35956ad7..594d2f02 100644
--- a/app/components/app/sep/entry-form.vue
+++ b/app/components/app/sep/entry-form.vue
@@ -24,11 +24,11 @@ import { useForm } from 'vee-validate'
import { refDebounced } from '@vueuse/core'
const props = defineProps<{
+ mode?: string
isLoading?: boolean
isReadonly?: boolean
isService?: boolean
- isShowPatient?: boolean;
- mode?: string
+ isShowPatient?: boolean
doctors: any[]
diagnoses: any[]
facilitiesFrom: any[]
@@ -102,14 +102,17 @@ const titleLetterNumber = computed(() => (admissionType.value === '3' ? 'Surat K
const titleLetterDate = computed(() =>
admissionType.value === '3' ? 'Tanggal Surat Kontrol' : 'Tanggal Surat Rujukan',
)
+const mode = props.mode !== undefined ? props.mode : 'add'
+const attendingDoctorName = ref('')
+const diagnosisName = ref('')
const isAccidentally = computed(() => accident.value === '1' || accident.value === '2')
const isProvinceSelected = computed(() => accidentProvince.value !== '')
const isCitySelected = computed(() => accidentCity.value !== '')
-const mode = props.mode !== undefined ? props.mode : 'add'
const isLoading = props.isLoading !== undefined ? props.isLoading : false
const isReadonly = props.isReadonly !== undefined ? props.isReadonly : false
const isService = ref(props.isService || false)
const isShowPatient = ref(props.isShowPatient || false)
+const isShowSpecialist = ref(false)
const isDateReload = ref(false)
// Debounced search for bpjsNumber and nationalId
@@ -129,28 +132,138 @@ async function onFetchChildren(parentId: string): Promise
{
console.log('onFetchChildren', parentId)
}
+const onBack = () => {
+ emit('event', 'back')
+}
+
+const onSaveNumber = () => {
+ emit('event', 'save-sep-number', { sepNumber: props?.objects?.sepNumber || '' })
+}
+
// Submit handler
const onSubmit = handleSubmit((values) => {
- console.log('✅ Validated form values:', JSON.stringify(values, null, 2))
emit('event', 'save-sep', values)
})
+const onInitialized = (objects: any) => {
+ sepDate.value = objects?.registerDate || new Date().toISOString().substring(0, 10)
+ cardNumber.value = objects?.cardNumber || '-'
+ nationalId.value = objects?.nationalIdentity || '-'
+ medicalRecordNumber.value = objects?.medicalRecordNumber || '-'
+ patientName.value = objects?.patientName || '-'
+ phoneNumber.value = objects?.phoneNumber || '-'
+ if (objects?.sepType === 'internal') {
+ admissionType.value = '4'
+ }
+ if (objects?.sepType === 'external') {
+ admissionType.value = '1'
+ }
+ if (objects?.diagnosisName) {
+ diagnosisName.value = objects?.diagnosisName
+ }
+ // Patient data
+ if (objects?.serviceType) {
+ serviceType.value = objects?.serviceType
+ }
+ if (objects?.fromClinic) {
+ fromClinic.value = objects?.fromClinic
+ }
+ if (objects?.destinationClinic) {
+ destinationClinic.value = objects?.destinationClinic
+ }
+ // Doctor & Support data
+ if (objects?.attendingDoctor) {
+ attendingDoctor.value = objects?.attendingDoctor
+ }
+ if (objects?.attendingDoctorName) {
+ attendingDoctorName.value = objects?.attendingDoctorName
+ }
+ if (objects?.cob) {
+ cob.value = objects?.cob
+ }
+ if (objects?.cataract) {
+ cataract.value = objects?.cataract
+ }
+ if (objects?.clinicExcecutive) {
+ clinicExcecutive.value = objects?.clinicExcecutive
+ }
+ if (objects?.procedureType) {
+ procedureType.value = objects?.procedureType
+ }
+ if (objects?.supportCode) {
+ supportCode.value = objects?.supportCode
+ }
+ // Class & Payment data
+ if (objects?.classLevel) {
+ classLevel.value = objects?.classLevel
+ }
+ if (objects?.classLevelUpgrade) {
+ classLevelUpgrade.value = objects?.classLevelUpgrade
+ }
+ if (objects?.classPaySource) {
+ classPaySource.value = objects?.classPaySource
+ }
+ if (objects?.responsiblePerson) {
+ responsiblePerson.value = objects?.responsiblePerson
+ }
+ // Accident data
+ if (objects?.trafficAccident) {
+ accident.value = objects?.trafficAccident
+ }
+ if (objects?.lpNumber) {
+ lpNumber.value = objects?.lpNumber
+ }
+ if (objects?.accidentDate) {
+ accidentDate.value = objects?.accidentDate
+ }
+ if (objects?.accidentNote) {
+ accidentNote.value = objects?.accidentNote
+ }
+ if (objects?.accidentProvince) {
+ accidentProvince.value = objects?.accidentProvince
+ }
+ if (objects?.accidentCity) {
+ accidentCity.value = objects?.accidentCity
+ }
+ if (objects?.accidentDistrict) {
+ accidentDistrict.value = objects?.accidentDistrict
+ }
+ if (objects?.suplesi) {
+ suplesi.value = objects?.suplesi
+ }
+ if (objects?.suplesiNumber) {
+ suplesiNumber.value = objects?.suplesiNumber
+ }
+ // Visit purpose & Assessment
+ if (objects?.purposeOfVisit) {
+ purposeOfVisit.value = objects?.purposeOfVisit
+ }
+ if (objects?.serviceAssessment) {
+ serviceAssessment.value = objects?.serviceAssessment
+ }
+ // Note & Specialist
+ if (objects?.note) {
+ note.value = objects?.note
+ }
+ if (objects?.subSpecialistId) {
+ subSpecialistId.value = objects?.subSpecialistId
+ }
+ // Referral letter
+ if (objects?.referralLetterNumber) {
+ referralLetterNumber.value = objects?.referralLetterNumber
+ }
+}
+
watch(props, (value) => {
const objects = value.objects || ({} as any)
if (Object.keys(objects).length > 0) {
- sepDate.value = objects?.registerDate || new Date().toISOString().substring(0, 10)
- cardNumber.value = objects?.cardNumber || '-'
- nationalId.value = objects?.nationalIdentity || '-'
- medicalRecordNumber.value = objects?.medicalRecordNumber || '-'
- patientName.value = objects?.patientName || '-'
- if (objects?.sepType === 'internal') {
- admissionType.value = '4'
- }
- if (objects?.sepType === 'external') {
- admissionType.value = '1'
- }
+ onInitialized(objects)
isDateReload.value = true
setTimeout(() => {
+ if (objects?.sepDate) {
+ sepDate.value = objects?.sepDate
+ referralLetterDate.value = objects?.sepDate
+ }
if (objects?.letterDate) {
referralLetterDate.value = objects?.letterDate
}
@@ -176,6 +289,9 @@ onMounted(() => {
if (!isService.value) {
serviceType.value = '2'
}
+ if (!admissionType.value) {
+ admissionType.value = '1'
+ }
})
@@ -199,10 +315,11 @@ onMounted(() => {
@@ -277,7 +394,7 @@ onMounted(() => {
id="cardNumber"
v-model="cardNumber"
v-bind="cardNumberAttrs"
- :disabled="false"
+ :disabled="isLoading || isReadonly"
/>
@@ -292,7 +409,7 @@ onMounted(() => {
id="nationalId"
v-model="nationalId"
v-bind="nationalIdAttrs"
- :disabled="false"
+ :disabled="isLoading || isReadonly"
/>
@@ -371,6 +488,7 @@ onMounted(() => {
"
/>
-
{
"
@save="handleSavePatient"
/>
-
+
-import { computed } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
-
-import { getDetail } from '~/services/encounter.service'
-
-import type { TabItem } from '~/components/pub/my-ui/comp-tab/type'
-import CompTab from '~/components/pub/my-ui/comp-tab/comp-tab.vue'
-
-// PLASE ORDER BY TAB POSITION
-import Status from '~/components/content/encounter/status.vue'
-import AssesmentFunctionList from '~/components/content/assesment-function/list.vue'
-import EarlyMedicalAssesmentList from '~/components/content/soapi/entry.vue'
-import EarlyMedicalRehabList from '~/components/content/soapi/entry.vue'
-import PrescriptionList from '~/components/content/prescription/list.vue'
-import Consultation from '~/components/content/consultation/list.vue'
-import ProtocolList from '~/components/app/chemotherapy/list.protocol.vue'
-import MedicineProtocolList from '~/components/app/chemotherapy/list.medicine.vue'
-
-const route = useRoute()
-const router = useRouter()
-
-const props = defineProps<{
- classes?: string
-}>()
-
-// activeTab selalu sinkron dengan query param
-const activeTab = computed({
- get: () => (route.query?.tab && typeof route.query.tab === 'string' ? route.query.tab : 'status'),
- set: (val: string) => {
- router.replace({ path: route.path, query: { tab: val } })
- },
-})
-
-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 dataResBody = dataRes.body ?? null
-// const data = dataResBody?.data ?? null
-
-// Dummy data so AppEncounterQuickInfo can render in development/storybook
-// Replace with real API result when available (see commented fetch below)
-const data = ref({
- patient: {
- number: 'RM-2025-0001',
- person: {
- name: 'John Doe',
- birthDate: '1980-01-01T00:00:00Z',
- gender_code: 'M',
- addresses: [{ address: 'Jl. Contoh No.1, Jakarta' }],
- frontTitle: '',
- endTitle: '',
- },
- },
- visitDate: new Date().toISOString(),
- unit: { name: 'Onkologi' },
- responsible_doctor: null,
- appointment_doctor: { employee: { person: { name: 'Dr. Clara Smith', frontTitle: 'Dr.', endTitle: 'Sp.OG' } } },
-})
-
-// Dummy rows for ProtocolList (matches keys expected by list-cfg.protocol)
-const protocolRows = [
- {
- number: '1',
- tanggal: new Date().toISOString().substring(0, 10),
- siklus: 'I',
- periode: 'Siklus I',
- kehadiran: 'Hadir',
- action: '',
- },
- {
- number: '2',
- tanggal: new Date().toISOString().substring(0, 10),
- siklus: 'II',
- periode: 'Siklus II',
- kehadiran: 'Tidak Hadir',
- action: '',
- },
-]
-
-const paginationMeta = {
- recordCount: protocolRows.length,
- page: 1,
- pageSize: 10,
- totalPage: 1,
- hasNext: false,
- hasPrev: false,
-}
-
-const tabsRaws: TabItem[] = [
- {
- value: 'status',
- label: 'Status Masuk/Keluar',
- groups: ['ambulatory', 'rehabilitation', 'chemotherapy'],
- component: Status,
- props: { encounter: data },
- },
- {
- value: 'early-medical-assessment',
- label: 'Pengkajian Awal Medis',
- groups: ['ambulatory', 'rehabilitation', 'chemotherapy'],
- component: EarlyMedicalAssesmentList,
- },
- {
- value: 'rehab-medical-assessment',
- label: 'Pengkajian Awal Medis Rehabilitasi Medis',
- groups: ['ambulatory', 'rehabilitation', 'chemotherapy'],
- component: EarlyMedicalRehabList,
- },
- {
- value: 'function-assessment',
- label: 'Asesmen Fungsi',
- groups: ['ambulatory', 'rehabilitation'],
- component: AssesmentFunctionList,
- },
- { value: 'therapy-protocol', groups: ['ambulatory', 'rehabilitation'], label: 'Protokol Terapi' },
- {
- value: 'chemotherapy-protocol',
- label: 'Protokol Kemoterapi',
- groups: ['chemotherapy'],
- component: ProtocolList,
- props: { data: protocolRows, paginationMeta },
- },
- {
- value: 'chemotherapy-medicine',
- label: 'Protokol Obat Kemoterapi',
- groups: ['chemotherapy'],
- component: MedicineProtocolList,
- props: { data: protocolRows, paginationMeta },
- },
- { value: 'report', label: 'Laporan Tindakan', groups: ['chemotherapy'] },
- { value: 'patient-note', label: 'CPRJ', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- {
- value: 'education-assessment',
- label: 'Asesmen Kebutuhan Edukasi',
- groups: ['ambulatory', 'rehabilitation', 'chemotherapy'],
- },
- { value: 'consent', label: 'General Consent', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- { value: 'patient-note', label: 'CPRJ', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- {
- value: 'prescription',
- label: 'Order Obat',
- groups: ['ambulatory', 'rehabilitation', 'chemotherapy'],
- component: PrescriptionList,
- },
- { value: 'device', label: 'Order Alkes', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- { value: 'mcu-radiology', label: 'Order Radiologi', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- { value: 'mcu-lab-pc', label: 'Order Lab PK', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- { value: 'mcu-lab-micro', label: 'Order Lab Mikro', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- { value: 'mcu-lab-pa', label: 'Order Lab PA', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- { value: 'medical-action', label: 'Order Ruang Tindakan', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- { value: 'mcu-result', label: 'Hasil Penunjang', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- {
- value: 'consultation',
- label: 'Konsultasi',
- groups: ['ambulatory', 'rehabilitation', 'chemotherapy'],
- component: Consultation,
- props: { encounter: data },
- },
- { value: 'resume', label: 'Resume', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- { value: 'control', label: 'Surat Kontrol', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- { value: 'screening', label: 'Skrinning MPP', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
- { value: 'supporting-document', label: 'Upload Dokumen Pendukung', groups: ['ambulatory', 'rehabilitation'] },
- { value: 'price-list', label: 'Tarif Tindakan', groups: ['ambulatory', 'rehabilitation', 'chemotherapy'] },
-]
-
-const tabs = computed(() => {
- return tabsRaws
- .filter((tab: TabItem) => tab.groups ? tab.groups.some((group: string) => props.classes?.includes(group)) : true)
- .map((tab: TabItem) => {
- return { ...tab, props: { ...tab.props, encounter: data } }
- })
-})
-
-
-
-
-
diff --git a/app/components/content/encounter/list.vue b/app/components/content/encounter/list.vue
index 655a553d..3aeb1254 100644
--- a/app/components/content/encounter/list.vue
+++ b/app/components/content/encounter/list.vue
@@ -1,31 +1,51 @@
-
-
+
+ {}"
+ @onExportExcel="() => {}"
+ @nExportCsv="() => {}"
+ />
+
-
-
-
+
+
-
+
+
+
+
+ Nama:
+ {{ record.patient.person.name }}
+
+
+ No RM:
+ {{ record.medical_record_number }}
+
+
+
+
+
+
+
@@ -258,4 +333,11 @@ onMounted(() => {
+
diff --git a/app/components/content/encounter/process-bu.vue b/app/components/content/encounter/process-bu.vue
new file mode 100644
index 00000000..8285d5e6
--- /dev/null
+++ b/app/components/content/encounter/process-bu.vue
@@ -0,0 +1,116 @@
+
+
+
+
+
diff --git a/app/components/content/encounter/process.vue b/app/components/content/encounter/process.vue
index 4e0da61b..fcfc3671 100644
--- a/app/components/content/encounter/process.vue
+++ b/app/components/content/encounter/process.vue
@@ -1,15 +1,22 @@
-
diff --git a/app/components/content/encounter/status.vue b/app/components/content/encounter/status.vue
index 513a7ab5..371008e4 100644
--- a/app/components/content/encounter/status.vue
+++ b/app/components/content/encounter/status.vue
@@ -5,6 +5,7 @@ import { getValueLabelList as getEmployeeValueLabelList } from '~/services/emplo
import { getValueLabelList as getUnitValueLabelList } from '~/services/unit.service'
import type { CheckInFormData, CheckOutFormData } from '~/schemas/encounter.schema'
import { CheckInSchema, CheckOutSchema } from '~/schemas/encounter.schema'
+import { getEncounterData } from '~/handlers/encounter-process.handler'
//
import Dialog from '~/components/pub/my-ui/modal/dialog.vue'
@@ -18,10 +19,12 @@ import { checkIn } from '~/services/encounter.service'
//
const props = defineProps<{
encounter: Encounter
+ canUpdate?: boolean
}>()
// doctors
-const doctors = await getDoctorValueLabelList({'includes': 'employee,employee-person'})
+const localEncounter = ref
(props.encounter)
+const doctors = await getDoctorValueLabelList({'includes': 'employee,employee-person'}, true)
const employees = await getEmployeeValueLabelList({'includes': 'person', 'position-code': 'reg'})
const units = await getUnitValueLabelList()
@@ -32,7 +35,7 @@ const checkInValues = ref({
// registeredAt: '',
})
const checkInIsLoading = ref(false)
-const checkInIsReadonly = ref(false)
+const checkInIsReadonly = ref(props.canUpdate )
const checkInDialogOpen = ref(false)
// check out
@@ -49,8 +52,15 @@ function editCheckIn() {
checkInDialogOpen.value = true
}
-function submitCheckIn(values: CheckInFormData) {
- checkIn(props.encounter.id, values)
+async function submitCheckIn(values: CheckInFormData) {
+ const res = await checkIn(props.encounter.id, values)
+ if (res.success) {
+ checkInDialogOpen.value = false
+ const resEnc = await getEncounterData(props.encounter.id)
+ if (resEnc.success) {
+ localEncounter.value = resEnc.body.data
+ }
+ }
}
function editCheckOut() {
@@ -67,9 +77,8 @@ function submitCheckOut(values: CheckOutFormData) {
@@ -77,9 +86,8 @@ function submitCheckOut(values: CheckOutFormData) {
Informasi Keluar
@@ -122,4 +130,4 @@ function submitCheckOut(values: CheckOutFormData) {
@cancel="checkInDialogOpen = false"
/>
-
\ No newline at end of file
+
diff --git a/app/components/content/initial-nursing/entry.vue b/app/components/content/initial-nursing/entry.vue
new file mode 100644
index 00000000..5769e967
--- /dev/null
+++ b/app/components/content/initial-nursing/entry.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
diff --git a/app/components/content/initial-nursing/form.vue b/app/components/content/initial-nursing/form.vue
new file mode 100644
index 00000000..006b1dc0
--- /dev/null
+++ b/app/components/content/initial-nursing/form.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
diff --git a/app/components/content/initial-nursing/list.vue b/app/components/content/initial-nursing/list.vue
new file mode 100644
index 00000000..0c867b96
--- /dev/null
+++ b/app/components/content/initial-nursing/list.vue
@@ -0,0 +1,210 @@
+
+
+
+
+
+
+
+ C. Daftar Masalah Keperawatan
+
+
+
+
+
+ handleActionRemove(recId, getMyList, toast)"
+ @cancel=""
+ >
+
+
+
+ ID:
+ {{ record?.id }}
+
+
+ Nama:
+ {{ record.name }}
+
+
+ Kode:
+ {{ record.code }}
+
+
+
+
+
diff --git a/app/components/content/kfr/entry.vue b/app/components/content/kfr/entry.vue
new file mode 100644
index 00000000..a2352c1a
--- /dev/null
+++ b/app/components/content/kfr/entry.vue
@@ -0,0 +1,146 @@
+
+
+
+
+ {{ props.mode === "add" ? `Tambah` : `Update` }} Formulir Rawat Jalan KFR
+
+
+
+
+
+
+
diff --git a/app/components/content/kfr/list.vue b/app/components/content/kfr/list.vue
new file mode 100644
index 00000000..4a4613e9
--- /dev/null
+++ b/app/components/content/kfr/list.vue
@@ -0,0 +1,372 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ID:
+ {{ record?.id }}
+
+
+ Nama:
+ {{ record.firstName }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/components/content/mcu-order/entry.vue b/app/components/content/mcu-order/entry.vue
new file mode 100644
index 00000000..f07310b3
--- /dev/null
+++ b/app/components/content/mcu-order/entry.vue
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/content/mcu-order/list.vue b/app/components/content/mcu-order/list.vue
new file mode 100644
index 00000000..6fcff867
--- /dev/null
+++ b/app/components/content/mcu-order/list.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+ handleActionRemove(recId, getMyList, toast)"
+ @cancel=""
+ >
+
+
+
+ handleActionSubmit(recId, getMyList, toast)"
+ @cancel=""
+ >
+
+
+
diff --git a/app/components/content/mcu-order/main.vue b/app/components/content/mcu-order/main.vue
new file mode 100644
index 00000000..033d093f
--- /dev/null
+++ b/app/components/content/mcu-order/main.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/app/components/content/micro-lab-order/entry.vue b/app/components/content/micro-lab-order/entry.vue
new file mode 100644
index 00000000..e6ef9600
--- /dev/null
+++ b/app/components/content/micro-lab-order/entry.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/app/components/content/micro-lab-order/list.vue b/app/components/content/micro-lab-order/list.vue
new file mode 100644
index 00000000..c2bda748
--- /dev/null
+++ b/app/components/content/micro-lab-order/list.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/app/components/content/micro-lab-order/main.vue b/app/components/content/micro-lab-order/main.vue
new file mode 100644
index 00000000..033d093f
--- /dev/null
+++ b/app/components/content/micro-lab-order/main.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/app/components/content/prb/bpjs-list.vue b/app/components/content/prb/bpjs-list.vue
new file mode 100644
index 00000000..8ce0d050
--- /dev/null
+++ b/app/components/content/prb/bpjs-list.vue
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ID:
+ {{ record?.id }}
+
+
+ Nama:
+ {{ record.firstName }}
+
+
+ Kode:
+ {{ record.cellphone }}
+
+
+
+
+
+
diff --git a/app/components/content/prb/detail.vue b/app/components/content/prb/detail.vue
new file mode 100644
index 00000000..4de8f260
--- /dev/null
+++ b/app/components/content/prb/detail.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
+
diff --git a/app/components/content/prb/entry.vue b/app/components/content/prb/entry.vue
new file mode 100644
index 00000000..244c49b0
--- /dev/null
+++ b/app/components/content/prb/entry.vue
@@ -0,0 +1,160 @@
+
+
+
+ Update Program Rujuk Balik
+
+
+
+
+
+
+
+
diff --git a/app/components/content/prb/list.vue b/app/components/content/prb/list.vue
new file mode 100644
index 00000000..a1c09696
--- /dev/null
+++ b/app/components/content/prb/list.vue
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+
+
Obat
+
+
+
+
+
+
+
+
+
+
+ ID:
+ {{ record?.id }}
+
+
+ Nama:
+ {{ record.firstName }}
+
+
+ Kode:
+ {{ record.cellphone }}
+
+
+
+
+
+
diff --git a/app/components/content/procedure-room-order/entry.vue b/app/components/content/procedure-room-order/entry.vue
new file mode 100644
index 00000000..ad780e5b
--- /dev/null
+++ b/app/components/content/procedure-room-order/entry.vue
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/content/procedure-room-order/list.vue b/app/components/content/procedure-room-order/list.vue
new file mode 100644
index 00000000..d742941c
--- /dev/null
+++ b/app/components/content/procedure-room-order/list.vue
@@ -0,0 +1,191 @@
+
+
+
+
+
+
+
+ handleActionRemove(recId, getMyList, toast)"
+ @cancel=""
+ >
+
+
Tanggal
+
:
+
{{ recItem.createdAt?.substring(0, 10) }}
+
+
+
DPJP
+
:
+
{{ recItem.doctor?.employee?.person?.name }}
+
+
+
+ handleActionSubmit(recId, getMyList, toast)"
+ @cancel=""
+ >
+
+
Tanggal
+
:
+
{{ recItem.createdAt.substring(0, 10) }}
+
+
+
DPJP
+
:
+
{{ recItem.doctor?.employee?.person?.name }}
+
+
+
diff --git a/app/components/content/procedure-room-order/main.vue b/app/components/content/procedure-room-order/main.vue
new file mode 100644
index 00000000..61250fe1
--- /dev/null
+++ b/app/components/content/procedure-room-order/main.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+ {{ crudQueryParams.mode }}
+
diff --git a/app/components/content/radiology-order/list.vue b/app/components/content/radiology-order/list.vue
index b2c8571d..47c822e9 100644
--- a/app/components/content/radiology-order/list.vue
+++ b/app/components/content/radiology-order/list.vue
@@ -13,7 +13,6 @@ import {
recAction,
recItem,
isReadonly,
- isFormEntryDialogOpen,
isRecordConfirmationOpen,
handleActionSave,
handleActionRemove,
@@ -28,6 +27,7 @@ const route = useRoute()
const { setQueryParams } = useQueryParam()
const title = ref('')
+const addTrigger = ref(false)
const plainEid = route.params.id
const encounter_id = (plainEid && typeof plainEid == 'string') ? parseInt(plainEid) : 0 // here the
@@ -74,7 +74,7 @@ const headerPrep: HeaderPrep = {
onClick: () => {
recItem.value = null
recId.value = 0
- isFormEntryDialogOpen.value = true
+ addTrigger.value = true
isReadonly.value = false
},
},
@@ -90,7 +90,7 @@ const getMyDetail = async (id: number | string) => {
if (result.success) {
const currentValue = result.body?.data || {}
recItem.value = currentValue
- isFormEntryDialogOpen.value = true
+ addTrigger.value = true
}
}
@@ -113,10 +113,10 @@ watch([recId, recAction], () => {
}
})
-watch([isFormEntryDialogOpen], async () => {
- if (isFormEntryDialogOpen.value) {
- isFormEntryDialogOpen.value = false;
- const saveResp = await handleActionSave({ encounter_id }, getMyList, () =>{}, toast)
+watch([addTrigger], async () => {
+ if (addTrigger.value) {
+ addTrigger.value = false;
+ const saveResp = await handleActionSave({ encounter_id, "scope_code": "rad" }, getMyList, () =>{}, toast)
if (saveResp.success) {
setQueryParams({
'mode': 'entry',
diff --git a/app/components/content/sep/entry.vue b/app/components/content/sep/entry.vue
index 3a916c4d..d1d6599a 100644
--- a/app/components/content/sep/entry.vue
+++ b/app/components/content/sep/entry.vue
@@ -1,486 +1,73 @@
@@ -490,12 +77,13 @@ onMounted(async () => {
name="i-lucide-panel-bottom"
class="me-2"
/>
- Tambah
- SEP
+ {{ ['detail', 'link'].includes(props.mode) ? 'Detail' : 'Tambah' }} SEP
// Components
-import type { DataTableLoader } from '~/components/pub/my-ui/data-table/type'
-import type { HeaderPrep, RefSearchNav } from '~/components/pub/my-ui/data/types'
-import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
import Header from '~/components/pub/my-ui/nav-header/prep.vue'
import {
DropdownMenu,
@@ -11,156 +8,95 @@ import {
DropdownMenuItem,
} from '~/components/pub/ui/dropdown-menu'
import AppSepList from '~/components/app/sep/list.vue'
+import RangeCalendar from '~/components/pub/ui/range-calendar/RangeCalendar.vue'
// Icons
import { X, Check } from 'lucide-vue-next'
-// Types
-import type { VclaimSepData } from '~/models/vclaim'
+// Handlers
+import { useIntegrationSepList } from '~/handlers/integration-sep-list.handler'
-// Services
-import { getList as geMonitoringVisitList } from '~/services/vclaim-monitoring-visit.service'
+// Helpers
+import { refDebounced } from '@vueuse/core'
-const search = ref('')
-const dateRange = ref('12 Agustus 2025 - 31 Agustus 2025')
-const open = ref(false)
+// use handler to provide state and functions
+const {
+ recId,
+ recAction,
+ recItem,
+ data,
+ dateSelection,
+ dateRange,
+ serviceType,
+ serviceTypesList,
+ search,
+ open,
+ sepData,
+ headerPrep,
+ paginationMeta,
+ isLoading,
+ getSepList,
+ setServiceTypes,
+ setDateRange,
+ handleExportCsv,
+ handleExportExcel,
+ handleRowSelected,
+ handlePageChange,
+ handleRemove,
+} = useIntegrationSepList()
-const sepData = {
- no_sep: 'SP23311224',
- kartu: '001234',
- nama: 'Kenzie',
-}
-
-const paginationMeta = reactive({
- recordCount: 0,
- page: 1,
- pageSize: 10,
- totalPage: 5,
- hasNext: false,
- hasPrev: false,
-})
-
-function handlePageChange(page: number) {
- console.log('pageChange', page)
-}
-
-const data = ref([])
-
-const refSearchNav: RefSearchNav = {
- onClick: () => {
- // open filter modal
- },
- onInput: (_val: string) => {
- // filter patient list
- },
- onClear: () => {
- // clear url param
- },
-}
-
-const isLoading = reactive({
- isTableLoading: false,
-})
-
-const recId = ref(0)
-const recAction = ref('')
-const recItem = ref(null)
-
-const headerPrep: HeaderPrep = {
- title: 'Daftar SEP Prosedur',
- icon: 'i-lucide-panel-bottom',
- addNav: {
- label: 'Tambah',
- onClick: () => {
- navigateTo('/integration/bpjs/sep/add')
- },
- },
-}
-
-async function getMonitoringVisitMappers() {
- isLoading.dataListLoading = true
- data.value = []
-
- const dateFirst = new Date()
- const result = await geMonitoringVisitList({
- date: dateFirst.toISOString().substring(0, 10),
- serviceType: 1,
- })
-
- if (result && result.success && result.body) {
- const visitsRaw = result.body?.response?.sep || []
-
- if (!visitsRaw) {
- isLoading.dataListLoading = false
- return
- }
-
- visitsRaw.forEach((result: any) => {
- // Format pelayanan: "R.Inap" -> "Rawat Inap", "1" -> "Rawat Jalan", dll
- let serviceType = result.jnsPelayanan || '-'
- if (serviceType === 'R.Inap') {
- serviceType = 'Rawat Inap'
- } else if (serviceType === '1' || serviceType === 'R.Jalan') {
- serviceType = 'Rawat Jalan'
- }
-
- data.value.push({
- letterDate: result.tglSep || '-',
- letterNumber: result.noSep || '-',
- serviceType: serviceType,
- flow: '-',
- medicalRecordNumber: '-',
- patientName: result.nama || '-',
- cardNumber: result.noKartu || '-',
- controlLetterNumber: result.noRujukan || '-',
- controlLetterDate: result.tglPlgSep || '-',
- clinicDestination: result.poli || '-',
- attendingDoctor: '-',
- diagnosis: result.diagnosa || '-',
- careClass: result.kelasRawat || '-',
- })
- })
- }
-
- isLoading.dataListLoading = false
-}
-
-async function getSepList() {
- await getMonitoringVisitMappers()
-}
-
-function exportCsv() {
- console.log('Ekspor CSV dipilih')
- // tambahkan logic untuk generate CSV
-}
-
-function exportExcel() {
- console.log('Ekspor Excel dipilih')
- // tambahkan logic untuk generate Excel
-}
-
-function handleDelete() {
- console.log('Data dihapus:', sepData)
- open.value = false
-}
-
-watch(
- () => recAction.value,
- () => {
- if (recAction.value === 'showConfirmDel') {
- open.value = true
- }
- },
-)
-
-onMounted(() => {
- getSepList()
-})
+const dataFiltered = ref([])
+const debouncedSearch = refDebounced(search, 500)
+// expose provides so component can also use provide/inject if needed
provide('rec_id', recId)
provide('rec_action', recAction)
provide('rec_item', recItem)
provide('table_data_loader', isLoading)
+
+watch([recId, recAction], () => {
+ if (recAction.value === 'showConfirmDel') {
+ open.value = true
+ }
+ if (recAction.value === 'showDetail') {
+ navigateTo(`/integration/bpjs-vclaim/sep/${recItem.value?.letterNumber}/detail`)
+ }
+})
+
+watch(debouncedSearch, (newValue) => {
+ if (newValue && newValue !== '-' && newValue.length >= 3) {
+ dataFiltered.value = data.value.filter(
+ (item: any) =>
+ item.patientName.toLowerCase().includes(newValue.toLowerCase()) ||
+ item.letterNumber.toLowerCase().includes(newValue.toLowerCase()) ||
+ item.cardNumber.toLowerCase().includes(newValue.toLowerCase()),
+ )
+ }
+})
+
+watch(
+ () => dateSelection.value,
+ async (val) => {
+ if (!val) return
+ setDateRange()
+ await getSepList()
+ dataFiltered.value = [...data.value]
+ },
+ { deep: true },
+)
+
+watch(
+ () => serviceType.value,
+ () => {
+ getSepList()
+ },
+)
+
+onMounted(async () => {
+ setServiceTypes()
+ await getSepList()
+ dataFiltered.value = [...data.value]
+})
@@ -175,6 +111,17 @@ provide('table_data_loader', isLoading)
class="w-72"
/>
+
+
+
+
+
@@ -190,7 +137,7 @@ provide('table_data_loader', isLoading)
-
+
@@ -209,8 +156,8 @@ provide('table_data_loader', isLoading)
- Ekspor CSV
- Ekspor Excel
+ Ekspor CSV
+ Ekspor Excel
@@ -218,7 +165,8 @@ provide('table_data_loader', isLoading)