Add Primayan Medicare report frontend and navigation
This commit is contained in:
@@ -16,9 +16,10 @@ class NavigationSeeder extends Seeder
|
|||||||
public function run()
|
public function run()
|
||||||
{
|
{
|
||||||
$menuItems = [
|
$menuItems = [
|
||||||
// DOCTORS & HOSPITALS
|
// Dashboard
|
||||||
[
|
[
|
||||||
'title' => 'Dashboard',
|
'title' => 'Dashboard',
|
||||||
|
'urutan' => 1,
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
'title' => 'Dashboard',
|
'title' => 'Dashboard',
|
||||||
@@ -31,6 +32,7 @@ class NavigationSeeder extends Seeder
|
|||||||
// DOCTORS & HOSPITALS
|
// DOCTORS & HOSPITALS
|
||||||
[
|
[
|
||||||
'title' => 'DOCTORS & HOSPITALS',
|
'title' => 'DOCTORS & HOSPITALS',
|
||||||
|
'urutan' => 2,
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
'title' => 'Doctors',
|
'title' => 'Doctors',
|
||||||
@@ -48,6 +50,7 @@ class NavigationSeeder extends Seeder
|
|||||||
// PHARMACY & DELIVERY MANAGEMENT
|
// PHARMACY & DELIVERY MANAGEMENT
|
||||||
[
|
[
|
||||||
'title' => 'PHARMACY & DELIVERY MANAGEMENT',
|
'title' => 'PHARMACY & DELIVERY MANAGEMENT',
|
||||||
|
'urutan' => 3,
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
'title' => 'Drug',
|
'title' => 'Drug',
|
||||||
@@ -70,6 +73,7 @@ class NavigationSeeder extends Seeder
|
|||||||
// STATION BENEFIT & MEMBERSHIP
|
// STATION BENEFIT & MEMBERSHIP
|
||||||
[
|
[
|
||||||
'title' => 'STATION BENEFIT & MEMBERSHIP',
|
'title' => 'STATION BENEFIT & MEMBERSHIP',
|
||||||
|
'urutan' => 4,
|
||||||
'openWhen' => ['/corporates', '/formularium', '/diagnosis', '/hospitals'],
|
'openWhen' => ['/corporates', '/formularium', '/diagnosis', '/hospitals'],
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
@@ -77,7 +81,6 @@ class NavigationSeeder extends Seeder
|
|||||||
'path' => '/corporates',
|
'path' => '/corporates',
|
||||||
'permission' => 'corporate-list',
|
'permission' => 'corporate-list',
|
||||||
],
|
],
|
||||||
// ['title' => 'Corporate Create', 'path' => '/corporates/create'],
|
|
||||||
[
|
[
|
||||||
'title' => 'Formularium',
|
'title' => 'Formularium',
|
||||||
'path' => '/master/formularium-template-v2',
|
'path' => '/master/formularium-template-v2',
|
||||||
@@ -96,28 +99,33 @@ class NavigationSeeder extends Seeder
|
|||||||
],
|
],
|
||||||
'permission' => null
|
'permission' => null
|
||||||
],
|
],
|
||||||
// CLAIM REQUEST
|
// MASTER
|
||||||
[
|
[
|
||||||
'title' => 'CLAIM REQUEST',
|
'title' => 'MASTER',
|
||||||
'path' => '/claim-requests',
|
'urutan' => 5,
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
'title' => 'CLAIM REQUEST',
|
'title' => 'Diagnosis',
|
||||||
'path' => '/claim-requests',
|
'path' => '/master/diagnosis',
|
||||||
'permission' => 'claim-request-list'
|
'permission' => 'diagnosis-list'
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'permission' => null
|
'permission' => null
|
||||||
],
|
],
|
||||||
// CLAIM MANAGEMENT
|
// CUSTOMER SERVICES
|
||||||
[
|
[
|
||||||
'title' => 'CLAIM MANAGEMENT',
|
'title' => 'CUSTOMER SERVICES',
|
||||||
'path' => '/claims',
|
'urutan' => 6,
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
'title' => 'CLAIM MANAGEMENT',
|
'title' => 'Request',
|
||||||
'path' => '/claims',
|
'path' => '/custormer-service/request',
|
||||||
'permission' => 'claim-management-list'
|
'permission' => 'request-log-list'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'title' => 'Final LOG',
|
||||||
|
'path' => '/custormer-service/final-log',
|
||||||
|
'permission' => 'final-log-list'
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'permission' => null
|
'permission' => null
|
||||||
@@ -125,13 +133,13 @@ class NavigationSeeder extends Seeder
|
|||||||
// CASE MANAGEMENT
|
// CASE MANAGEMENT
|
||||||
[
|
[
|
||||||
'title' => 'CASE MANAGEMENT',
|
'title' => 'CASE MANAGEMENT',
|
||||||
|
'urutan' => 7,
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
'title' => 'Daily Monitoring',
|
'title' => 'Daily Monitoring',
|
||||||
'path' => '/case_management/daily_monitoring',
|
'path' => '/case_management/daily_monitoring',
|
||||||
'permission' => 'daily-monitoring-list'
|
'permission' => 'daily-monitoring-list'
|
||||||
],
|
],
|
||||||
// ['title' => 'Laboratorium Result', 'path' => '/case_management/laboratorium_result'],
|
|
||||||
[
|
[
|
||||||
'title' => 'Inpatient Monitoring',
|
'title' => 'Inpatient Monitoring',
|
||||||
'path' => '/case_management/inpatient_monitoring',
|
'path' => '/case_management/inpatient_monitoring',
|
||||||
@@ -145,9 +153,56 @@ class NavigationSeeder extends Seeder
|
|||||||
],
|
],
|
||||||
'permission' => null
|
'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',
|
'title' => 'INVOICE',
|
||||||
|
'urutan' => 11,
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
'title' => 'Invoice',
|
'title' => 'Invoice',
|
||||||
@@ -157,79 +212,78 @@ class NavigationSeeder extends Seeder
|
|||||||
],
|
],
|
||||||
'permission' => null
|
'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
|
// REPORT
|
||||||
[
|
[
|
||||||
'title' => 'REPORT',
|
'title' => 'REPORT',
|
||||||
|
'urutan' => 12,
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
'title' => 'Files Provider',
|
'title' => 'Files Provider',
|
||||||
'path' => 'report/files-provider',
|
'path' => 'report/files-provider',
|
||||||
'permission' => 'report-files-provider-list'
|
'permission' => 'report-files-provider-list',
|
||||||
|
'urutan' => 1,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'title' => 'Letter of Guarantee',
|
'title' => 'Letter of Guarantee',
|
||||||
'path' => '/report/logs',
|
'path' => '/report/logs',
|
||||||
'permission' => 'report-log-list'
|
'permission' => 'report-log-list',
|
||||||
|
'urutan' => 2,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'title' => 'Appointment',
|
'title' => 'Appointment',
|
||||||
'path' => '/report/appointments',
|
'path' => '/report/appointments',
|
||||||
'permission' => 'report-appointment-list'
|
'permission' => 'report-appointment-list',
|
||||||
|
'urutan' => 3,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'title' => 'Live Chat',
|
'title' => 'Live Chat',
|
||||||
'path' => '/report/live-chat',
|
'path' => '/report/live-chat',
|
||||||
'permission' => 'report-livechat-list'
|
'permission' => 'report-livechat-list',
|
||||||
|
'urutan' => 4,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'title' => 'Linksehat Payment',
|
'title' => 'Linksehat Payment',
|
||||||
'path' => '/report/linksehat-payments',
|
'path' => '/report/linksehat-payments',
|
||||||
'permission' => 'report-livechat-payment'
|
'permission' => 'report-livechat-payment',
|
||||||
|
'urutan' => 5,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'title' => 'Prescription',
|
'title' => 'Prescription',
|
||||||
'path' => '/report/prescription',
|
'path' => '/report/prescription',
|
||||||
'permission' => 'report-prescription'
|
'permission' => 'report-prescription',
|
||||||
|
'urutan' => 6,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'title' => 'Doctor Rating',
|
'title' => 'Doctor Rating',
|
||||||
'path' => '/report/doctor-rating',
|
'path' => '/report/doctor-rating',
|
||||||
'permission' => 'report-doctor-rating'
|
'permission' => 'report-doctor-rating',
|
||||||
|
'urutan' => 7,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'title' => 'Doctor Online',
|
'title' => 'Doctor Online',
|
||||||
'path' => '/report/doctor-online',
|
'path' => '/report/doctor-online',
|
||||||
'permission' => 'report-doctor-online'
|
'permission' => 'report-doctor-online',
|
||||||
|
'urutan' => 8,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'title' => 'Katalog Dokter',
|
'title' => 'Katalog Dokter',
|
||||||
'path' => '/report/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
|
'permission' => null
|
||||||
],
|
],
|
||||||
// MASTER
|
// MASTER
|
||||||
[
|
[
|
||||||
'title' => 'MASTER',
|
'title' => 'MASTER',
|
||||||
|
'urutan' => 11,
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
'title' => 'Diagnosis',
|
'title' => 'Diagnosis',
|
||||||
@@ -242,6 +296,7 @@ class NavigationSeeder extends Seeder
|
|||||||
// USER MANAGEMENT
|
// USER MANAGEMENT
|
||||||
[
|
[
|
||||||
'title' => 'USER MANAGEMENT',
|
'title' => 'USER MANAGEMENT',
|
||||||
|
'urutan' => 9,
|
||||||
'children' => [
|
'children' => [
|
||||||
[
|
[
|
||||||
'title' => 'User Role',
|
'title' => 'User Role',
|
||||||
@@ -259,12 +314,14 @@ class NavigationSeeder extends Seeder
|
|||||||
// LINKING TOOLS
|
// LINKING TOOLS
|
||||||
[
|
[
|
||||||
'title' => 'LINKING TOOLS',
|
'title' => 'LINKING TOOLS',
|
||||||
|
'urutan' => 13,
|
||||||
'path' => '/linking',
|
'path' => '/linking',
|
||||||
'permission' => 'linkking-list'
|
'permission' => 'linkking-list'
|
||||||
],
|
],
|
||||||
// E-PRESCRIPTION
|
// E-PRESCRIPTION
|
||||||
[
|
[
|
||||||
'title' => 'E-PRESCRIPTION',
|
'title' => 'E-PRESCRIPTION',
|
||||||
|
'urutan' => 14,
|
||||||
'path' => '/e-prescription/live-chat',
|
'path' => '/e-prescription/live-chat',
|
||||||
'permission' => 'prescription-list'
|
'permission' => 'prescription-list'
|
||||||
],
|
],
|
||||||
@@ -370,7 +427,8 @@ class NavigationSeeder extends Seeder
|
|||||||
'title' => $menuItemData['title'],
|
'title' => $menuItemData['title'],
|
||||||
'path' => $menuItemData['path'] ?? null,
|
'path' => $menuItemData['path'] ?? null,
|
||||||
'icon' => $menuItemData['icon'] ?? null,
|
'icon' => $menuItemData['icon'] ?? null,
|
||||||
'permission' => $menuItemData['permission'] ?? null
|
'permission' => $menuItemData['permission'] ?? null,
|
||||||
|
'urutan' => $menuItemData['urutan'] ?? null
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (isset($menuItemData['children'])) {
|
if (isset($menuItemData['children'])) {
|
||||||
@@ -384,7 +442,8 @@ class NavigationSeeder extends Seeder
|
|||||||
'path' => $childData['path'] ?? null,
|
'path' => $childData['path'] ?? null,
|
||||||
'icon' => $childData['icon'] ?? null,
|
'icon' => $childData['icon'] ?? null,
|
||||||
'parent_id' => $menuItem->id,
|
'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-list',
|
||||||
'report-livechat-payment',
|
'report-livechat-payment',
|
||||||
'report-doctor-rating',
|
'report-doctor-rating',
|
||||||
|
'report-primayan-medicare',
|
||||||
'report-doctor-online',
|
'report-doctor-online',
|
||||||
'report-prescription',
|
'report-prescription',
|
||||||
'user-role-list',
|
'user-role-list',
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ const navConfig = [
|
|||||||
{ title: 'Linksehat Payment', path: '/report/linksehat-payments' },
|
{ title: 'Linksehat Payment', path: '/report/linksehat-payments' },
|
||||||
// { title: 'Prescription', path: '/report/prescription' },
|
// { title: 'Prescription', path: '/report/prescription' },
|
||||||
{ title: 'Doctor Rating', path: '/report/doctor-rating' },
|
{ 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',
|
path: 'report/linksehat-payments',
|
||||||
element: <LinksehatPayment />,
|
element: <LinksehatPayment />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'report/primayan-medicare',
|
||||||
|
element: <PrimayanMedicare />,
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: 'report/phr',
|
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 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 RiwayatMedisPeserta = Loadable(lazy(() => import('../pages/Report/RiwayatMedisPeserta/Index')));
|
||||||
const RujukanPasien = Loadable(lazy(() => import('../pages/Report/Rujukan/Index')));
|
const RujukanPasien = Loadable(lazy(() => import('../pages/Report/Rujukan/Index')));
|
||||||
const Prescription = Loadable(lazy(() => import('../pages/Report/Prescription/Index')));
|
const Prescription = Loadable(lazy(() => import('../pages/Report/Prescription/Index')));
|
||||||
|
|||||||
Reference in New Issue
Block a user