diff --git a/app/components/flow/satusehat/list.vue b/app/components/flow/satusehat/list.vue index eb9b9616..b2512432 100644 --- a/app/components/flow/satusehat/list.vue +++ b/app/components/flow/satusehat/list.vue @@ -2,86 +2,80 @@ import type { ServiceStatus } from '~/components/pub/base/service-status.type' import type { Summary } from '~/components/pub/base/summary-card.type' import type { HeaderPrep, RefSearchNav } from '~/components/pub/nav/types' -import { CircleCheckBig, CircleDashed, CircleX, Download, Ellipsis, ListFilter, Search, Send } from 'lucide-vue-next' +import { CircleCheckBig, CircleDashed, CircleX, Ellipsis, Search, Send } from 'lucide-vue-next' -const data = ref([ - { - id: 'RSC001', - resource_type: 'Encounter', - patient: { - name: 'Ahmad Wepe', - mrn: 'RM001234', - }, - status: 2, - updated_at: '2025-03-12', - fhir_id: 'ENC-00123', - }, - { - id: 'RSC002', - resource_type: 'Encounter', - patient: { - name: 'Siti Aminah', - mrn: 'RM001235', - }, - status: 1, - updated_at: '2025-03-10', - fhir_id: 'ENC-001235', - }, - { - id: 'RSC003', - resource_type: 'Encounter', - patient: { - name: 'Budi Antono', - mrn: 'RM001236', - }, - status: 0, - updated_at: '2025-03-11', - fhir_id: 'ENC-001236', - }, - { - id: 'RSC001', - resource_type: 'Encounter', - patient: { - name: 'Ahmad Wepe', - mrn: 'RM001234', - }, - status: 2, - updated_at: '2025-03-12', - fhir_id: 'ENC-00123', - }, - { - id: 'RSC001', - resource_type: 'Encounter', - patient: { - name: 'Ahmad Wepe', - mrn: 'RM001234', - }, - status: 2, - updated_at: '2025-03-12', - fhir_id: 'ENC-00123', - }, - { - id: 'RSC001', - resource_type: 'Encounter', - patient: { - name: 'Ahmad Wepe', - mrn: 'RM001234', - }, - status: 2, - updated_at: '2025-03-12', - fhir_id: 'ENC-00123', - }, -]) +// State management +const data = ref([]) +const isLoading = reactive({ + satusehatConn: true, + dataList: false, +}) + +// Filter states +const filters = reactive({ + search: '', + status: '', + resource_type: 'all', + date_from: '', + date_to: '', + page: 1, + limit: 10, +}) + +// Pagination state +const pagination = ref({ + total: 0, + page: 1, + limit: 10, + total_pages: 0, + has_next: false, + has_prev: false, +}) + +// API function to fetch data +async function fetchData() { + try { + isLoading.dataList = true + const response: any = await $fetch('/api/v1/satusehat/list', { + method: 'POST', + body: { + status: filters.status !== '' ? Number(filters.status) : undefined, + resource_type: filters.resource_type, + date_from: filters.date_from, + date_to: filters.date_to, + search: filters.search, + page: filters.page, + limit: filters.limit, + }, + }) + + if (response.success) { + data.value = response.data + pagination.value = response.meta + } + } catch (error) { + console.error('Error fetching data:', error) + } finally { + isLoading.dataList = false + } +} + +// Debounced search function +const debouncedFetchData = useDebounceFn(fetchData, 500) const refSearchNav: RefSearchNav = { onClick: () => { // open filter modal }, - onInput: (_val: string) => { - // filter patient list + onInput: (val: string) => { + filters.search = val + filters.page = 1 + debouncedFetchData() }, onClear: () => { - // clear url param + filters.search = '' + filters.page = 1 + fetchData() }, } @@ -89,10 +83,25 @@ const recId = ref(0) const recAction = ref('') const recItem = ref(null) -// Loading state management -const isLoading = reactive({ - satusehatConn: true, -}) +// Filter change handlers +function onStatusChange(status: string) { + filters.status = status + filters.page = 1 + fetchData() +} + +function onResourceTypeChange(resourceType: string) { + filters.resource_type = resourceType + filters.page = 1 + fetchData() +} + +function onDateRangeChange(dateFrom: string, dateTo: string) { + filters.date_from = dateFrom + filters.date_to = dateTo + filters.page = 1 + fetchData() +} const headerPrep: HeaderPrep = { title: 'SATUSEHAT Integration', @@ -157,16 +166,20 @@ async function callSatuSehat() { } } -onMounted(() => { - callSatuSehat() +// Watch for tab changes +watch(() => filters.resource_type, (newType) => { + onResourceTypeChange(newType) +}) + +onMounted(async () => { + await callSatuSehat() + await fetchData() }) provide('rec_id', recId) provide('rec_action', recAction) provide('rec_item', recItem) -const listTitle = 'FHIR Resource' - const tabs = [ { value: 'all', @@ -186,15 +199,12 @@ const tabs = [ }, ] -const form = [ - { - value: 'search', - label: 'Cari pasien' - }, - { - value: 'date-picker', - label: 'Filter berdasarkan tanggal', - }, +// Status filter options +const statusOptions = [ + { value: '', label: 'Semua Status' }, + { value: '0', label: 'Failed' }, + { value: '1', label: 'Pending' }, + { value: '2', label: 'Success' }, ] const actions = [ { @@ -210,7 +220,13 @@ const actions = [ }, ] -const activeTabFilter = ref('all') +// Sync activeTabFilter with filters.resource_type +const activeTabFilter = computed({ + get: () => filters.resource_type, + set: (value) => { + filters.resource_type = value + }, +})