233 lines
5.9 KiB
Vue
233 lines
5.9 KiB
Vue
<script setup lang="ts">
|
|
// Components
|
|
import Header from '~/components/pub/my-ui/nav-header/prep.vue'
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuTrigger,
|
|
DropdownMenuContent,
|
|
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'
|
|
|
|
// Handlers
|
|
import { useIntegrationSepList } from '~/handlers/integration-sep-list.handler'
|
|
|
|
// Helpers
|
|
import { refDebounced } from '@vueuse/core'
|
|
|
|
// 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 dataFiltered = ref<any>([])
|
|
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]
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="p-4">
|
|
<Header :prep="{ ...headerPrep }" />
|
|
<!-- Filter Bar -->
|
|
<div class="my-2 flex flex-wrap items-center gap-2">
|
|
<!-- Search -->
|
|
<Input
|
|
v-model="search"
|
|
placeholder="Cari No. SEP / No. Kartu BPJS..."
|
|
class="w-72"
|
|
/>
|
|
|
|
<!-- Filter -->
|
|
<div class="w-72">
|
|
<Select
|
|
id="serviceType"
|
|
icon-name="i-lucide-chevron-down"
|
|
v-model="serviceType"
|
|
:items="serviceTypesList"
|
|
placeholder="Pilih Pelayanan"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Date Range -->
|
|
<Popover>
|
|
<PopoverTrigger as-child>
|
|
<Button
|
|
variant="outline"
|
|
class="h-[40px] w-72 border-gray-400 bg-white text-right font-normal"
|
|
>
|
|
{{ dateRange }}
|
|
<Icon
|
|
name="i-lucide-calendar"
|
|
class="h-5 w-5"
|
|
/>
|
|
</Button>
|
|
</PopoverTrigger>
|
|
<PopoverContent class="p-2">
|
|
<RangeCalendar v-model="dateSelection" />
|
|
</PopoverContent>
|
|
</Popover>
|
|
|
|
<!-- Export -->
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger as-child>
|
|
<Button
|
|
variant="outline"
|
|
class="ml-auto h-[40px] w-[120px] rounded-md border-green-600 text-green-600 hover:bg-green-50"
|
|
>
|
|
<Icon
|
|
name="i-lucide-download"
|
|
class="h-5 w-5"
|
|
/>
|
|
Ekspor
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent class="w-40">
|
|
<DropdownMenuItem @click="handleExportCsv">Ekspor CSV</DropdownMenuItem>
|
|
<DropdownMenuItem @click="handleExportExcel">Ekspor Excel</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</div>
|
|
|
|
<div class="mt-4">
|
|
<AppSepList
|
|
v-if="!isLoading.dataListLoading"
|
|
:data="dataFiltered"
|
|
@update:modelValue="handleRowSelected"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
<template v-if="paginationMeta">
|
|
<div v-if="paginationMeta.totalPage > 1">
|
|
<PubMyUiPagination
|
|
:pagination-meta="paginationMeta"
|
|
@page-change="handlePageChange"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- Trigger button -->
|
|
<Dialog v-model:open="open">
|
|
<DialogTrigger as-child></DialogTrigger>
|
|
<DialogContent class="sm:max-w-md">
|
|
<DialogHeader>
|
|
<DialogTitle>Hapus SEP</DialogTitle>
|
|
</DialogHeader>
|
|
<DialogDescription class="text-gray-700">Apakah anda yakin ingin menghapus SEP dengan data:</DialogDescription>
|
|
<div class="mt-4 space-y-2 text-sm">
|
|
<p>
|
|
<strong>No. SEP:</strong>
|
|
{{ sepData.sepNumber }}
|
|
</p>
|
|
<p>
|
|
<strong>No. Kartu BPJS:</strong>
|
|
{{ sepData.cardNumber }}
|
|
</p>
|
|
<p>
|
|
<strong>Nama Pasien:</strong>
|
|
{{ sepData.patientName }}
|
|
</p>
|
|
</div>
|
|
<DialogFooter class="mt-6 flex justify-end gap-3">
|
|
<Button
|
|
variant="outline"
|
|
class="border-green-600 text-green-600 hover:bg-green-50"
|
|
@click="
|
|
() => {
|
|
recId = 0
|
|
recAction = ''
|
|
open = false
|
|
}
|
|
"
|
|
>
|
|
<X class="mr-1 h-4 w-4" />
|
|
Tidak
|
|
</Button>
|
|
<Button
|
|
variant="destructive"
|
|
class="bg-red-600 hover:bg-red-700"
|
|
@click="handleRemove"
|
|
>
|
|
<Check class="mr-1 h-4 w-4" />
|
|
Ya
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</div>
|
|
</template>
|