Files

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>