Add Primayan Medicare report frontend and navigation
This commit is contained in:
@@ -16,9 +16,10 @@ class NavigationSeeder extends Seeder
|
||||
public function run()
|
||||
{
|
||||
$menuItems = [
|
||||
// DOCTORS & HOSPITALS
|
||||
// Dashboard
|
||||
[
|
||||
'title' => 'Dashboard',
|
||||
'urutan' => 1,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'Dashboard',
|
||||
@@ -31,6 +32,7 @@ class NavigationSeeder extends Seeder
|
||||
// DOCTORS & HOSPITALS
|
||||
[
|
||||
'title' => 'DOCTORS & HOSPITALS',
|
||||
'urutan' => 2,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'Doctors',
|
||||
@@ -48,6 +50,7 @@ class NavigationSeeder extends Seeder
|
||||
// PHARMACY & DELIVERY MANAGEMENT
|
||||
[
|
||||
'title' => 'PHARMACY & DELIVERY MANAGEMENT',
|
||||
'urutan' => 3,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'Drug',
|
||||
@@ -70,6 +73,7 @@ class NavigationSeeder extends Seeder
|
||||
// STATION BENEFIT & MEMBERSHIP
|
||||
[
|
||||
'title' => 'STATION BENEFIT & MEMBERSHIP',
|
||||
'urutan' => 4,
|
||||
'openWhen' => ['/corporates', '/formularium', '/diagnosis', '/hospitals'],
|
||||
'children' => [
|
||||
[
|
||||
@@ -77,7 +81,6 @@ class NavigationSeeder extends Seeder
|
||||
'path' => '/corporates',
|
||||
'permission' => 'corporate-list',
|
||||
],
|
||||
// ['title' => 'Corporate Create', 'path' => '/corporates/create'],
|
||||
[
|
||||
'title' => 'Formularium',
|
||||
'path' => '/master/formularium-template-v2',
|
||||
@@ -96,28 +99,33 @@ class NavigationSeeder extends Seeder
|
||||
],
|
||||
'permission' => null
|
||||
],
|
||||
// CLAIM REQUEST
|
||||
// MASTER
|
||||
[
|
||||
'title' => 'CLAIM REQUEST',
|
||||
'path' => '/claim-requests',
|
||||
'title' => 'MASTER',
|
||||
'urutan' => 5,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'CLAIM REQUEST',
|
||||
'path' => '/claim-requests',
|
||||
'permission' => 'claim-request-list'
|
||||
'title' => 'Diagnosis',
|
||||
'path' => '/master/diagnosis',
|
||||
'permission' => 'diagnosis-list'
|
||||
],
|
||||
],
|
||||
'permission' => null
|
||||
],
|
||||
// CLAIM MANAGEMENT
|
||||
// CUSTOMER SERVICES
|
||||
[
|
||||
'title' => 'CLAIM MANAGEMENT',
|
||||
'path' => '/claims',
|
||||
'title' => 'CUSTOMER SERVICES',
|
||||
'urutan' => 6,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'CLAIM MANAGEMENT',
|
||||
'path' => '/claims',
|
||||
'permission' => 'claim-management-list'
|
||||
'title' => 'Request',
|
||||
'path' => '/custormer-service/request',
|
||||
'permission' => 'request-log-list'
|
||||
],
|
||||
[
|
||||
'title' => 'Final LOG',
|
||||
'path' => '/custormer-service/final-log',
|
||||
'permission' => 'final-log-list'
|
||||
],
|
||||
],
|
||||
'permission' => null
|
||||
@@ -125,13 +133,13 @@ class NavigationSeeder extends Seeder
|
||||
// CASE MANAGEMENT
|
||||
[
|
||||
'title' => 'CASE MANAGEMENT',
|
||||
'urutan' => 7,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'Daily Monitoring',
|
||||
'path' => '/case_management/daily_monitoring',
|
||||
'permission' => 'daily-monitoring-list'
|
||||
],
|
||||
// ['title' => 'Laboratorium Result', 'path' => '/case_management/laboratorium_result'],
|
||||
[
|
||||
'title' => 'Inpatient Monitoring',
|
||||
'path' => '/case_management/inpatient_monitoring',
|
||||
@@ -145,9 +153,56 @@ class NavigationSeeder extends Seeder
|
||||
],
|
||||
'permission' => null
|
||||
],
|
||||
// Invoice
|
||||
// CLAIM REQUEST
|
||||
[
|
||||
'title' => 'CLAIM REQUEST',
|
||||
'urutan' => 8,
|
||||
'path' => '/claim-requests',
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'CLAIM REQUEST',
|
||||
'path' => '/claim-requests',
|
||||
'permission' => 'claim-request-list'
|
||||
],
|
||||
],
|
||||
'permission' => null
|
||||
],
|
||||
// CLAIM MANAGEMENT
|
||||
[
|
||||
'title' => 'CLAIM MANAGEMENT',
|
||||
'urutan' => 9,
|
||||
'path' => '/claims',
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'CLAIM MANAGEMENT',
|
||||
'path' => '/claims',
|
||||
'permission' => 'claim-management-list'
|
||||
],
|
||||
],
|
||||
'permission' => null
|
||||
],
|
||||
// USER MANAGEMENT
|
||||
[
|
||||
'title' => 'USER MANAGEMENT',
|
||||
'urutan' => 10,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'User Role',
|
||||
'path' => '/user-role',
|
||||
'permission' => 'user-role-list'
|
||||
],
|
||||
[
|
||||
'title' => 'User Access',
|
||||
'path' => '/user-access',
|
||||
'permission' => 'user-access-list'
|
||||
],
|
||||
],
|
||||
'permission' => null
|
||||
],
|
||||
// INVOICE
|
||||
[
|
||||
'title' => 'INVOICE',
|
||||
'urutan' => 11,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'Invoice',
|
||||
@@ -157,79 +212,78 @@ class NavigationSeeder extends Seeder
|
||||
],
|
||||
'permission' => null
|
||||
],
|
||||
// CUSTOMER SERVICES
|
||||
[
|
||||
'title' => 'CUSTOMER SERVICES',
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'Request',
|
||||
'path' => '/custormer-service/request',
|
||||
'permission' => 'request-log-list'
|
||||
],
|
||||
// ['title' => 'Membership', 'path' => '/cs-membership'],
|
||||
[
|
||||
'title' => 'Final LOG',
|
||||
'path' => '/custormer-service/final-log',
|
||||
'permission' => 'final-log-list'
|
||||
],
|
||||
],
|
||||
'permission' => null
|
||||
],
|
||||
// REPORT
|
||||
[
|
||||
'title' => 'REPORT',
|
||||
'urutan' => 12,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'Files Provider',
|
||||
'path' => 'report/files-provider',
|
||||
'permission' => 'report-files-provider-list'
|
||||
'permission' => 'report-files-provider-list',
|
||||
'urutan' => 1,
|
||||
],
|
||||
[
|
||||
'title' => 'Letter of Guarantee',
|
||||
'path' => '/report/logs',
|
||||
'permission' => 'report-log-list'
|
||||
'permission' => 'report-log-list',
|
||||
'urutan' => 2,
|
||||
],
|
||||
[
|
||||
'title' => 'Appointment',
|
||||
'path' => '/report/appointments',
|
||||
'permission' => 'report-appointment-list'
|
||||
'permission' => 'report-appointment-list',
|
||||
'urutan' => 3,
|
||||
],
|
||||
[
|
||||
'title' => 'Live Chat',
|
||||
'path' => '/report/live-chat',
|
||||
'permission' => 'report-livechat-list'
|
||||
'permission' => 'report-livechat-list',
|
||||
'urutan' => 4,
|
||||
],
|
||||
[
|
||||
'title' => 'Linksehat Payment',
|
||||
'path' => '/report/linksehat-payments',
|
||||
'permission' => 'report-livechat-payment'
|
||||
'permission' => 'report-livechat-payment',
|
||||
'urutan' => 5,
|
||||
],
|
||||
[
|
||||
'title' => 'Prescription',
|
||||
'path' => '/report/prescription',
|
||||
'permission' => 'report-prescription'
|
||||
'permission' => 'report-prescription',
|
||||
'urutan' => 6,
|
||||
],
|
||||
[
|
||||
'title' => 'Doctor Rating',
|
||||
'path' => '/report/doctor-rating',
|
||||
'permission' => 'report-doctor-rating'
|
||||
'permission' => 'report-doctor-rating',
|
||||
'urutan' => 7,
|
||||
],
|
||||
[
|
||||
'title' => 'Doctor Online',
|
||||
'path' => '/report/doctor-online',
|
||||
'permission' => 'report-doctor-online'
|
||||
'permission' => 'report-doctor-online',
|
||||
'urutan' => 8,
|
||||
],
|
||||
[
|
||||
'title' => 'Katalog Dokter',
|
||||
'path' => '/report/katalog-dokter',
|
||||
'permission' => 'report-katalog-dokter'
|
||||
]
|
||||
'permission' => 'report-katalog-dokter',
|
||||
'urutan' => 9,
|
||||
],
|
||||
[
|
||||
'title' => 'Primayan Medicare',
|
||||
'path' => '/report/primayan-medicare',
|
||||
'permission' => 'report-primayan-medicare',
|
||||
'urutan' => 10,
|
||||
],
|
||||
],
|
||||
'permission' => null
|
||||
],
|
||||
// MASTER
|
||||
[
|
||||
'title' => 'MASTER',
|
||||
'urutan' => 11,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'Diagnosis',
|
||||
@@ -242,6 +296,7 @@ class NavigationSeeder extends Seeder
|
||||
// USER MANAGEMENT
|
||||
[
|
||||
'title' => 'USER MANAGEMENT',
|
||||
'urutan' => 9,
|
||||
'children' => [
|
||||
[
|
||||
'title' => 'User Role',
|
||||
@@ -259,12 +314,14 @@ class NavigationSeeder extends Seeder
|
||||
// LINKING TOOLS
|
||||
[
|
||||
'title' => 'LINKING TOOLS',
|
||||
'urutan' => 13,
|
||||
'path' => '/linking',
|
||||
'permission' => 'linkking-list'
|
||||
],
|
||||
// E-PRESCRIPTION
|
||||
[
|
||||
'title' => 'E-PRESCRIPTION',
|
||||
'urutan' => 14,
|
||||
'path' => '/e-prescription/live-chat',
|
||||
'permission' => 'prescription-list'
|
||||
],
|
||||
@@ -370,7 +427,8 @@ class NavigationSeeder extends Seeder
|
||||
'title' => $menuItemData['title'],
|
||||
'path' => $menuItemData['path'] ?? null,
|
||||
'icon' => $menuItemData['icon'] ?? null,
|
||||
'permission' => $menuItemData['permission'] ?? null
|
||||
'permission' => $menuItemData['permission'] ?? null,
|
||||
'urutan' => $menuItemData['urutan'] ?? null
|
||||
]);
|
||||
|
||||
if (isset($menuItemData['children'])) {
|
||||
@@ -384,7 +442,8 @@ class NavigationSeeder extends Seeder
|
||||
'path' => $childData['path'] ?? null,
|
||||
'icon' => $childData['icon'] ?? null,
|
||||
'parent_id' => $menuItem->id,
|
||||
'permission' => $childData['permission'] ?? null
|
||||
'permission' => $childData['permission'] ?? null,
|
||||
'urutan' => $childData['urutan'] ?? null
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ class PermissionTableSeeder extends Seeder
|
||||
'report-livechat-list',
|
||||
'report-livechat-payment',
|
||||
'report-doctor-rating',
|
||||
'report-primayan-medicare',
|
||||
'report-doctor-online',
|
||||
'report-prescription',
|
||||
'user-role-list',
|
||||
|
||||
@@ -106,6 +106,7 @@ const navConfig = [
|
||||
{ title: 'Linksehat Payment', path: '/report/linksehat-payments' },
|
||||
// { title: 'Prescription', path: '/report/prescription' },
|
||||
{ title: 'Doctor Rating', path: '/report/doctor-rating' },
|
||||
{ title: 'Primayan Medicare', path: '/report/primayan-medicare' },
|
||||
|
||||
],
|
||||
},
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Container } from '@mui/material';
|
||||
import HeaderBreadcrumbs from '../../../components/HeaderBreadcrumbs';
|
||||
import Page from '../../../components/Page';
|
||||
import useSettings from '../../../hooks/useSettings';
|
||||
import List from './List';
|
||||
|
||||
export default function PrimayanMedicare() {
|
||||
const { themeStretch } = useSettings();
|
||||
|
||||
const pageTitle = 'Primayan Medicare';
|
||||
return (
|
||||
<Page title={pageTitle}>
|
||||
<Container maxWidth={themeStretch ? false : 'xl'}>
|
||||
<HeaderBreadcrumbs
|
||||
heading={pageTitle}
|
||||
links={[
|
||||
{
|
||||
name: 'Report',
|
||||
href: '/report',
|
||||
},
|
||||
{
|
||||
name: 'Primayan Medicare',
|
||||
href: '/report/primayan-medicare',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<List />
|
||||
</Container>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
402
frontend/dashboard/src/pages/Report/PrimayanMedicare/List.tsx
Normal file
402
frontend/dashboard/src/pages/Report/PrimayanMedicare/List.tsx
Normal file
@@ -0,0 +1,402 @@
|
||||
import {
|
||||
Card,
|
||||
Grid,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableContainer,
|
||||
TableRow,
|
||||
TextField,
|
||||
Stack,
|
||||
Chip,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
Select,
|
||||
MenuItem,
|
||||
Menu,
|
||||
} from '@mui/material';
|
||||
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import React, { ChangeEvent, useEffect, useRef, useState } from 'react';
|
||||
import axios from '../../../utils/axios';
|
||||
import { LaravelPaginatedData } from '../../../@types/paginated-data';
|
||||
import BasePagination from '../../../components/BasePagination';
|
||||
import { fNumber } from '@/utils/formatNumber';
|
||||
import { fDateOnly } from '@/utils/formatTime';
|
||||
import { DesktopDatePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
||||
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import UploadIcon from '@mui/icons-material/Upload';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const statusColors: Record<string, 'default' | 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning'> = {
|
||||
draft: 'default',
|
||||
requested: 'info',
|
||||
received: 'primary',
|
||||
approved: 'success',
|
||||
postpone: 'warning',
|
||||
paid: 'success',
|
||||
declined: 'error',
|
||||
};
|
||||
|
||||
export default function List() {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [providers, setProviders] = useState<any[]>([]);
|
||||
|
||||
function Filter() {
|
||||
const searchInput = useRef<HTMLInputElement>(null);
|
||||
const [searchText, setSearchText] = useState('');
|
||||
const [exportLoading, setExportLoading] = useState(false);
|
||||
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||
const exportMenuOpen = Boolean(anchorEl);
|
||||
|
||||
const handleExportClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
const handleExportClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const handleExport = (exportType: string) => {
|
||||
const parameters = Object.fromEntries([...searchParams.entries()]);
|
||||
setExportLoading(true);
|
||||
axios
|
||||
.get('/primayan-medicare/export', {
|
||||
params: { ...parameters, export_type: exportType },
|
||||
})
|
||||
.then((response) => {
|
||||
const link = document.createElement('a');
|
||||
link.href = response.data.data.file_url;
|
||||
link.setAttribute('download', response.data.data.file_name);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
handleExportClose();
|
||||
setExportLoading(false);
|
||||
})
|
||||
.catch(() => {
|
||||
setExportLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
const handleSearchChange = (event: any) => {
|
||||
setSearchText(event.target.value ?? '');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setSearchText(searchParams.get('search') ?? '');
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<form style={{ width: '100%' }}>
|
||||
<Grid container spacing={2} sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Grid item md={2}>
|
||||
<TextField
|
||||
id="search-input"
|
||||
ref={searchInput}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
onChange={handleSearchChange}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
const filter = Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['search', searchText],
|
||||
['page', '1'],
|
||||
]);
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}
|
||||
}}
|
||||
label="Search"
|
||||
value={searchText}
|
||||
InputProps={{
|
||||
placeholder: 'Nama, Member ID',
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid item md={2}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel>Status</InputLabel>
|
||||
<Select
|
||||
value={searchParams.get('status') ?? 'all'}
|
||||
label="Status"
|
||||
onChange={(el) => {
|
||||
const filter = Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['status', el.target.value],
|
||||
['page', '1'],
|
||||
]);
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}}
|
||||
>
|
||||
<MenuItem value={'all'}>Semua</MenuItem>
|
||||
<MenuItem value={'draft'}>Draft</MenuItem>
|
||||
<MenuItem value={'requested'}>Requested</MenuItem>
|
||||
<MenuItem value={'received'}>Received</MenuItem>
|
||||
<MenuItem value={'approved'}>Approved</MenuItem>
|
||||
<MenuItem value={'postpone'}>Postpone</MenuItem>
|
||||
<MenuItem value={'paid'}>Paid</MenuItem>
|
||||
<MenuItem value={'declined'}>Declined</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
|
||||
<Grid item md={2}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel>Provider</InputLabel>
|
||||
<Select
|
||||
value={searchParams.get('provider_id') ?? 'all'}
|
||||
label="Provider"
|
||||
onChange={(el) => {
|
||||
const filter = Object.fromEntries([
|
||||
...searchParams.entries(),
|
||||
['provider_id', el.target.value],
|
||||
['page', '1'],
|
||||
]);
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}}
|
||||
>
|
||||
<MenuItem value={'all'}>Semua</MenuItem>
|
||||
{providers.map((provider) => (
|
||||
<MenuItem key={provider.id} value={provider.id}>
|
||||
{provider.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
|
||||
<Grid item md={2}>
|
||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||
<DesktopDatePicker
|
||||
value={searchParams.get('start_date') || null}
|
||||
inputFormat="dd/MM/yyyy"
|
||||
onChange={(value) => {
|
||||
try {
|
||||
if (value && !!Date.parse(value)) {
|
||||
const date = fDateOnly(value);
|
||||
let entries = [...searchParams.entries(), ['start_date', date ?? '']];
|
||||
if (!searchParams.get('end_date')) {
|
||||
entries = [...entries, ['end_date', date ?? '']];
|
||||
}
|
||||
const filter = Object.fromEntries([...entries, ['page', '1']]);
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}
|
||||
} catch (e) {}
|
||||
}}
|
||||
renderInput={(params) => <TextField {...params} fullWidth label="Start Date" />}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
</Grid>
|
||||
|
||||
<Grid item md={2}>
|
||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||
<DesktopDatePicker
|
||||
value={searchParams.get('end_date') || null}
|
||||
inputFormat="dd/MM/yyyy"
|
||||
onChange={(value) => {
|
||||
try {
|
||||
if (value && !!Date.parse(value)) {
|
||||
const date = fDateOnly(value);
|
||||
let entries = [...searchParams.entries(), ['end_date', date ?? '']];
|
||||
if (!searchParams.get('start_date')) {
|
||||
entries = [...entries, ['start_date', date ?? '']];
|
||||
}
|
||||
const filter = Object.fromEntries([...entries, ['page', '1']]);
|
||||
setSearchParams(filter);
|
||||
loadDataTableData(filter);
|
||||
}
|
||||
} catch (e) {}
|
||||
}}
|
||||
renderInput={(params) => <TextField {...params} fullWidth label="End Date" />}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
</Grid>
|
||||
|
||||
<Grid item md={1}>
|
||||
<LoadingButton
|
||||
variant="outlined"
|
||||
startIcon={<UploadIcon />}
|
||||
sx={{ p: 1.8 }}
|
||||
onClick={handleExportClick}
|
||||
loading={exportLoading}
|
||||
>
|
||||
Export
|
||||
</LoadingButton>
|
||||
<Menu
|
||||
id="export-menu"
|
||||
anchorEl={anchorEl}
|
||||
open={exportMenuOpen}
|
||||
onClose={handleExportClose}
|
||||
MenuListProps={{
|
||||
'aria-labelledby': 'export-button',
|
||||
}}
|
||||
>
|
||||
<MenuItem onClick={() => handleExport('list')}>Download List Excel</MenuItem>
|
||||
<MenuItem onClick={() => handleExport('summary')}>Download Summary Excel</MenuItem>
|
||||
</Menu>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
function FilterForm() {
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
sx={{ p: 2, justifyContent: 'space-between', alignItems: 'center' }}
|
||||
>
|
||||
<Grid item xs={12} md={12} lg={12}>
|
||||
<Filter />
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
function Row(props: { row: any }) {
|
||||
const { row } = props;
|
||||
|
||||
const serviceCodeMap: Record<string, string> = {
|
||||
'OP': 'Outpatient',
|
||||
'IP': 'Inpatient',
|
||||
'DE': 'Dental',
|
||||
'MA': 'Maternal',
|
||||
'GL': 'Optical',
|
||||
'MCU': 'Medical Check Up',
|
||||
'MEDIVAC': 'Medical Emergency Evacuation',
|
||||
};
|
||||
|
||||
const serviceName = serviceCodeMap[row.service_code] || row.service_code || '-';
|
||||
|
||||
return (
|
||||
<TableRow>
|
||||
<TableCell align="left">
|
||||
{(row.claim_code || row.request_code) && row.log_code
|
||||
? `${row.claim_code ?? row.request_code} / ${row.log_code}`
|
||||
: row.claim_code ?? row.request_code ?? row.log_code ?? '-'}
|
||||
</TableCell>
|
||||
<TableCell align="left">{row.member_name ?? '-'}</TableCell>
|
||||
<TableCell align="left">{row.member_number ?? '-'}</TableCell>
|
||||
<TableCell align="left">{serviceName}</TableCell>
|
||||
<TableCell align="left">{row.provider_name ?? '-'}</TableCell>
|
||||
<TableCell align="left">{row.request_date ?? '-'}</TableCell>
|
||||
<TableCell align="right">{fNumber(parseInt(row.amount_incurred ?? 0))}</TableCell>
|
||||
<TableCell align="right">{fNumber(parseInt(row.amount_approved ?? 0))}</TableCell>
|
||||
<TableCell align="right">{fNumber(parseInt(row.excess_paid ?? 0))}</TableCell>
|
||||
<TableCell align="center">
|
||||
<Chip
|
||||
label={row.status ?? '-'}
|
||||
color={statusColors[row.status] ?? 'default'}
|
||||
size="small"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
|
||||
const headStyle = {
|
||||
fontWeight: 'bold',
|
||||
};
|
||||
|
||||
const [dataTableIsLoading, setDataTableLoading] = useState(true);
|
||||
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>({
|
||||
current_page: 1,
|
||||
data: [],
|
||||
path: '',
|
||||
first_page_url: '',
|
||||
last_page: 1,
|
||||
last_page_url: '',
|
||||
next_page_url: '',
|
||||
prev_page_url: '',
|
||||
per_page: 10,
|
||||
from: 0,
|
||||
to: 0,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
||||
setDataTableLoading(true);
|
||||
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||
try {
|
||||
const response = await axios.get('/primayan-medicare', {
|
||||
params: filter,
|
||||
});
|
||||
setDataTableData(response.data.data.results);
|
||||
setProviders(response.data.data.providers);
|
||||
} catch (error) {
|
||||
console.error('Failed to load Primayan Medicare data:', error);
|
||||
}
|
||||
setDataTableLoading(false);
|
||||
};
|
||||
|
||||
const handlePageChange = (event: ChangeEvent, value: number) => {
|
||||
const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]);
|
||||
loadDataTableData(filter);
|
||||
setSearchParams(filter);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadDataTableData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Card sx={{ marginTop: '30px' }}>
|
||||
<FilterForm />
|
||||
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell style={headStyle} align="left">Code Claim / Code LOG</TableCell>
|
||||
<TableCell style={headStyle} align="left">Nama Member</TableCell>
|
||||
<TableCell style={headStyle} align="left">Member ID</TableCell>
|
||||
<TableCell style={headStyle} align="left">Service</TableCell>
|
||||
<TableCell style={headStyle} align="left">Provider</TableCell>
|
||||
<TableCell style={headStyle} align="left">Tanggal Request</TableCell>
|
||||
<TableCell style={headStyle} align="right">Amount Incurred</TableCell>
|
||||
<TableCell style={headStyle} align="right">Amount Approved</TableCell>
|
||||
<TableCell style={headStyle} align="right">Excess Paid</TableCell>
|
||||
<TableCell style={headStyle} align="center">Status</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
{dataTableIsLoading ? (
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell colSpan={10} align="center">
|
||||
Loading
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
) : dataTableData.data.length === 0 ? (
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell colSpan={10} align="center">
|
||||
No Data
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
) : (
|
||||
<TableBody>
|
||||
{dataTableData.data.map((row, index) => (
|
||||
<Row key={row.id ?? index} row={row} />
|
||||
))}
|
||||
</TableBody>
|
||||
)}
|
||||
</Table>
|
||||
</TableContainer>
|
||||
|
||||
<BasePagination paginationData={dataTableData} onPageChange={handlePageChange} />
|
||||
</Card>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -471,6 +471,10 @@ export default function Router() {
|
||||
path: 'report/linksehat-payments',
|
||||
element: <LinksehatPayment />,
|
||||
},
|
||||
{
|
||||
path: 'report/primayan-medicare',
|
||||
element: <PrimayanMedicare />,
|
||||
},
|
||||
|
||||
{
|
||||
path: 'report/phr',
|
||||
@@ -770,6 +774,8 @@ const EPrescriptionShow = Loadable(lazy(() => import('../pages/EPrescription/Liv
|
||||
|
||||
const LinksehatPayment = Loadable(lazy(() => import('../pages/Report/LinksehatPayments/Index')));
|
||||
|
||||
const PrimayanMedicare = Loadable(lazy(() => import('../pages/Report/PrimayanMedicare/Index')));
|
||||
|
||||
const RiwayatMedisPeserta = Loadable(lazy(() => import('../pages/Report/RiwayatMedisPeserta/Index')));
|
||||
const RujukanPasien = Loadable(lazy(() => import('../pages/Report/Rujukan/Index')));
|
||||
const Prescription = Loadable(lazy(() => import('../pages/Report/Prescription/Index')));
|
||||
|
||||
Reference in New Issue
Block a user