201 lines
5.5 KiB
Vue
201 lines
5.5 KiB
Vue
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue'
|
||
|
||
// Types
|
||
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
|
||
import type { PatientEntity } from '~/models/patient'
|
||
|
||
// Services
|
||
import { getPatientDetail, getPatients } from '~/services/patient.service'
|
||
import { getList as getVclaimMonitoringVisitList } from '~/services/vclaim-monitoring-visit.service'
|
||
import { getList as getVclaimMonitoringHistoryList } from '~/services/vclaim-monitoring-history.service'
|
||
|
||
const openPatient = ref(false)
|
||
const openLetter = ref(false)
|
||
const openHistory = ref(false)
|
||
const selectedPatient = ref('')
|
||
const selectedPatientObject = ref<PatientEntity | null>(null)
|
||
const selectedLetter = ref('SK22334442')
|
||
|
||
// patients used by AppSepTableSearchPatient (will be filled from API)
|
||
const patients = ref<Array<{ id: string; identity: string; number: string; bpjs: string; name: string }>>([])
|
||
const isPatientsLoading = ref(false)
|
||
const paginationMeta = ref<PaginationMeta>({
|
||
recordCount: 0,
|
||
page: 1,
|
||
pageSize: 10,
|
||
totalPage: 5,
|
||
hasNext: false,
|
||
hasPrev: false,
|
||
})
|
||
|
||
function mapPatientToRow(patient: PatientEntity) {
|
||
// Defensive mapping: try common field names that might be returned by the API
|
||
const identity = patient?.person?.residentIdentityNumber || '-'
|
||
const number = patient?.number || '-'
|
||
const bpjs = '-'
|
||
const name = patient?.person?.name || '-'
|
||
return { id: patient.id ? String(patient.id) : '-', identity, number, bpjs, name }
|
||
}
|
||
|
||
function mapPaginationMetaToRow(meta: any) {
|
||
const recordCount = meta['record_totalCount'] ? Number(meta['record_totalCount']) : 0
|
||
const currentCount = meta['record_currentCount'] ? Number(meta['record_currentCount']) : 0
|
||
const page = meta['page_number'] ? Number(meta['page_number']) : 1
|
||
const pageSize = meta['page_size'] ? Number(meta['page_size']) : 10
|
||
const totalPage = Math.ceil(recordCount / pageSize)
|
||
|
||
return {
|
||
recordCount,
|
||
page,
|
||
pageSize,
|
||
totalPage,
|
||
hasNext: currentCount < recordCount && page < totalPage,
|
||
hasPrev: page > 1,
|
||
}
|
||
}
|
||
|
||
async function fetchPatients(params: any = { 'page-size': 10 }) {
|
||
try {
|
||
isPatientsLoading.value = true
|
||
patients.value = []
|
||
paginationMeta.value = {} as PaginationMeta
|
||
const result = await getPatients(params)
|
||
if (result && result.success && result.body && Array.isArray(result.body.data)) {
|
||
const meta = result.body.meta
|
||
patients.value = result.body.data.map(mapPatientToRow)
|
||
paginationMeta.value = mapPaginationMetaToRow(meta)
|
||
} else {
|
||
// fallback to empty array
|
||
patients.value = []
|
||
}
|
||
} catch (err) {
|
||
console.error('Failed to fetch patients for SEP search:', err)
|
||
patients.value = []
|
||
} finally {
|
||
isPatientsLoading.value = false
|
||
}
|
||
}
|
||
|
||
const letters = [
|
||
{
|
||
noSurat: 'SK22334442',
|
||
tglRencana: '12 Agustus 2025',
|
||
noSep: 'SEP3232332',
|
||
namaPasien: 'Ahmad Baidowi',
|
||
noBpjs: '33442331214',
|
||
klinik: 'Penyakit Dalam',
|
||
dokter: 'dr. Andi Prasetyo, Sp.PD-KHOM',
|
||
},
|
||
{
|
||
noSurat: 'SK99120039',
|
||
tglRencana: '12 Agustus 2025',
|
||
noSep: 'SEP4443232',
|
||
namaPasien: 'Bian Maulana',
|
||
noBpjs: '33442367656',
|
||
klinik: 'Gigi',
|
||
dokter: 'dr. Achmad Suparjo',
|
||
},
|
||
]
|
||
|
||
const histories = [
|
||
{
|
||
no_sep: 'SP23311224',
|
||
tgl_sep: '12 Agustus 2025',
|
||
no_rujukan: '123444',
|
||
diagnosis: 'C34.9 – Karsinoma Paru',
|
||
pelayanan: 'Rawat Jalan',
|
||
kelas: 'Kelas II',
|
||
},
|
||
{
|
||
no_sep: 'SP23455667',
|
||
tgl_sep: '11 Agustus 2025',
|
||
no_rujukan: '2331221',
|
||
diagnosis: 'K35 – Apendisitis akut',
|
||
pelayanan: 'Rawat Jalan',
|
||
kelas: 'Kelas II',
|
||
},
|
||
]
|
||
|
||
function handleSavePatient() {
|
||
const getPatient = async () => {
|
||
try {
|
||
const result = await getPatientDetail(Number(selectedPatient.value))
|
||
if (result && result.success && result.body && result.body.data) {
|
||
const patient = result.body.data || null
|
||
selectedPatientObject.value = patient
|
||
}
|
||
} catch (err) {
|
||
console.error('Failed to fetch patient:', err)
|
||
}
|
||
}
|
||
getPatient()
|
||
}
|
||
|
||
function handleSaveLetter() {
|
||
console.log('Letter dipilih:', selectedLetter.value)
|
||
}
|
||
|
||
function handleEvent(value: string) {
|
||
if (value === 'search-patient') {
|
||
// fetch patients from API then open the dialog
|
||
fetchPatients({ 'page-size': 10, includes: 'person' }).then(() => {
|
||
openPatient.value = true
|
||
})
|
||
return
|
||
}
|
||
if (value === 'search-letter') {
|
||
openLetter.value = true
|
||
return
|
||
}
|
||
if (value === 'history-sep') {
|
||
openHistory.value = true
|
||
return
|
||
}
|
||
if (value === 'back') {
|
||
navigateTo('/bpjs/sep')
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
getVclaimMonitoringHistoryList({ nop: '0002078925513', tglawal: '2025-07-20', tglakhir: '2025-10-10' }).then(
|
||
(value) => {
|
||
console.log('value:', value)
|
||
},
|
||
)
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
||
<Icon
|
||
name="i-lucide-panel-bottom"
|
||
class="me-2"
|
||
/>
|
||
<span class="font-semibold">Tambah</span>
|
||
SEP
|
||
</div>
|
||
<AppSepEntryForm
|
||
:patient="selectedPatientObject"
|
||
@event="handleEvent"
|
||
/>
|
||
<AppSepTableSearchPatient
|
||
v-model:open="openPatient"
|
||
v-model:selected="selectedPatient"
|
||
:patients="patients"
|
||
:pagination-meta="paginationMeta"
|
||
@fetch="(value) => fetchPatients({ ...value, 'page-size': 10, includes: 'person' })"
|
||
@save="handleSavePatient"
|
||
/>
|
||
<AppSepTableSearchLetter
|
||
v-model:open="openLetter"
|
||
v-model:selected="selectedLetter"
|
||
:letters="letters"
|
||
@save="handleSaveLetter"
|
||
/>
|
||
<AppSepTableHistorySep
|
||
v-model:open="openHistory"
|
||
:histories="histories"
|
||
/>
|
||
</template>
|