diff --git a/database/seeders/NavigationSeeder.php b/database/seeders/NavigationSeeder.php index 5a208800..19809bd1 100755 --- a/database/seeders/NavigationSeeder.php +++ b/database/seeders/NavigationSeeder.php @@ -137,6 +137,11 @@ class NavigationSeeder extends Seeder 'path' => '/case_management/inpatient_monitoring', 'permission' => 'final-log-list' ], + [ + 'title' => 'Approval Inpatient', + 'path' => '/case_management/approval_inpatient_monitoring', + 'permission' => 'approval-log-list' + ], ], 'permission' => null ], diff --git a/database/seeders/PermissionTableSeeder.php b/database/seeders/PermissionTableSeeder.php index 0013f925..70578c48 100755 --- a/database/seeders/PermissionTableSeeder.php +++ b/database/seeders/PermissionTableSeeder.php @@ -76,6 +76,7 @@ class PermissionTableSeeder extends Seeder 'user-access-list', 'report-katalog-dokter', 'invoice-payment-list', + 'approval-inpatient-monitoring', ] ], ####################### CLIENT PORTAL ######################### diff --git a/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx b/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx index dee7accc..5add5536 100755 --- a/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx +++ b/frontend/dashboard/src/layouts/dashboard/navbar/NavConfig.tsx @@ -85,6 +85,7 @@ const navConfig = [ { title: 'Daily Monitoring', path: '/case_management/daily_monitoring' }, // { title: 'Laboratorium Result', path: '/case_management/laboratorium_result' }, { title: 'Inpatient Monitoring', path: '/case_management/inpatient_monitoring' }, + { title: 'Approval Monitoring', path: '/case_management/inpatient_monitoring' }, ], }, { diff --git a/frontend/dashboard/src/pages/CaseManagement/ApprovalMonitoring/Index.tsx b/frontend/dashboard/src/pages/CaseManagement/ApprovalMonitoring/Index.tsx new file mode 100755 index 00000000..a0f1083d --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/ApprovalMonitoring/Index.tsx @@ -0,0 +1,30 @@ +import { Card, Stack } from "@mui/material"; +import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs"; +import Page from "../../../components/Page"; +import List from "./List"; + + + +export default function Claims() { + + const pageTitle = 'Approval Monitoring'; + return ( + + + + + {/* */} + + {/* */} + + ); +} diff --git a/frontend/dashboard/src/pages/CaseManagement/ApprovalMonitoring/List.tsx b/frontend/dashboard/src/pages/CaseManagement/ApprovalMonitoring/List.tsx new file mode 100755 index 00000000..864145af --- /dev/null +++ b/frontend/dashboard/src/pages/CaseManagement/ApprovalMonitoring/List.tsx @@ -0,0 +1,636 @@ +// @mui +import { + Box, + Button, + Card, + Collapse, + IconButton, + MenuItem, + Table, + TableBody, + TableCell, + TableRow, + TextField, + Typography, + Stack, + Menu, + ButtonGroup, + FormControl, + Select, + Link, + Chip, + TableHead, + InputLabel, + Grid, +} from '@mui/material'; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; +import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; +import AddIcon from '@mui/icons-material/Add'; +import UploadIcon from '@mui/icons-material/Upload'; +import CancelIcon from '@mui/icons-material/Cancel'; + +import FindInPageOutlinedIcon from '@mui/icons-material/FindInPageOutlined'; +import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; +// hooks +import React, { ChangeEvent, useEffect, useRef, useState } from 'react'; +import { Navigate, useNavigate, useSearchParams } from 'react-router-dom'; +import useSettings from '@/hooks/useSettings'; +// components +import axios from '../../../utils/axios'; +import { LaravelPaginatedData, LaravelPaginatedDataDefault } from '../../../@types/paginated-data'; +import DataTable from '../../../components/LaravelTable'; +import { fCurrency } from '../../../utils/formatNumber'; +import EditRoundedIcon from '@mui/icons-material/EditRounded'; +import { LoadingButton } from '@mui/lab'; +import { enqueueSnackbar } from 'notistack'; +import { Divider } from '@mui/material'; +import Iconify from '@/components/Iconify'; +import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim'; +import { fDateTimesecond } from '@/utils/formatTime'; +import { capitalizeFirstLetter } from '@/utils/formatString'; +import Label from '@/components/Label'; +import TableMoreMenu from '@/components/table/TableMoreMenu'; +import { Import } from '@/@types/claims'; + +import { FinalLogType } from '../../CustomerService/FinalLog/Model/Types'; +import DialogDeleteFinalLOG from '@/pages/CustomerService/FinalLog/Components/DialogDeleteFinalLOG'; +import { Delete } from '@mui/icons-material'; +import useAuth from '@/hooks/useAuth'; +// import LoadingButton from '@/theme/overrides/LoadingButton'; + +export default function List() { + const { themeColorPresets } = useSettings(); + const [searchParams, setSearchParams] = useSearchParams(); + const [importResult, setImportResult] = useState(null); + const { user } = useAuth(); + + const navigate = useNavigate() + + const fileOptions = { + kondisi: 'Dokumen Billing', + diagnosa: 'Dokumen Diagnosa', + result: 'Dokumen Penduk Medis', + none: 'Belum ada Dokumen' + }; + + function SearchInput(props: any) { + // SEARCH + const searchInput = useRef(null); + const [searchText, setSearchText] = useState(''); + + const handleSearchChange = (event: any) => { + const newSearchText = event.target.value ?? ''; + setSearchText(newSearchText); + }; + + const handleSearchSubmit = (event: any) => { + event.preventDefault(); + props.onSearch({ search: searchText }); // Trigger to Parent + }; + + useEffect(() => { + // Trigger First Search + setSearchText(searchParams.get('search') ?? ''); + }, []); + + return ( +
+ + + ); + } + + function ImportForm(props: any) { + // IMPORT + // Create Button Menu + const [anchorEl, setAnchorEl] = React.useState(null); + const createMenu = Boolean(anchorEl); + const importForm = useRef(null); + const [currentImportFileName, setCurrentImportFileName] = useState(null); + const [importLoading, setImportLoading] = useState(false); + + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + const handleImportButton = () => { + if (importForm?.current) { + handleClose(); + importForm.current ? importForm.current.click() : console.log('No File selected'); + } else { + alert('No file selected'); + } + }; + + const handleCancelImportButton = () => { + importForm.current.value = ''; + importForm.current.dispatchEvent(new Event('change', { bubbles: true })); + }; + + const handleImportChange = (event: any) => { + if (event.target.files[0]) { + setCurrentImportFileName(event.target.files[0].name); + } else { + setCurrentImportFileName(null); + } + }; + + const handleUpload = () => { + if (importForm.current?.files.length) { + const formData = new FormData(); + formData.append('file', importForm.current?.files[0]); + + setImportLoading(true); + axios + .post(`claim-requests/import`, formData) + .then((response) => { + handleCancelImportButton(); + loadDataTableData(); + setImportResult(response.data); + // alert('Succesfully read '+ response.data.total_successed_row + ' with ' + response.data.total_failed_row + ' failed rows'); + setImportLoading(false); + }) + .catch((response) => { + enqueueSnackbar( + 'Looks like something went wrong. Please check your data and try again. ' + + response.message, + { variant: 'error' } + ); + setImportLoading(false); + }); + } else { + enqueueSnackbar('No File Selected', { variant: 'warning' }); + } + }; + + const handleGetTemplate = (type :string) => { + axios.get('corporates/import-document-example/' + type) + .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(); + handleClose(); + }) + } + + const handleGetData = (type :string) => { + axios.get(`corporates/${corporate_id}/data-plan-benefit`) + .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(); + handleClose(); + }) + } + + return ( +
+ + {!currentImportFileName && ( + + + + + + + File + + + + + + + + Import + {handleGetTemplate('claim-request')}}>Download Template + {handleGetData('data-plan-benefit')}}>Download Claim Request + + {/* */} + + )} + + {currentImportFileName && ( + + + + + + + } + sx={{ p: 1.8 }} + onClick={handleUpload} + loading={importLoading} + > + Upload + + + )} + {importResult && ( + + + Last Import Result Report :{' '} + + {importResult.result_file?.name ?? '-'} + + + + )} +
+ ); + } + + // Dummy Default Data + const [dataTableIsLoading, setDataTableLoading] = useState(true); + const [dataTableData, setDataTableData] = useState( + LaravelPaginatedDataDefault + ); + + const loadDataTableData = async (appliedFilter: any | null = null) => { + setDataTableLoading(true); + const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]); + const response = await axios.get('/customer-service/request?final_log=1&service_code=IP', { params: filter }); + // console.log(response.data); + setDataTableLoading(false); + + setDataTableData(response.data); + }; + + const applyFilter = async (searchFilter: { search: string }) => { + await loadDataTableData(searchFilter); + setSearchParams(searchFilter); + }; + + const handlePageChange = (event: ChangeEvent, value: number): void => { + const filter = Object.fromEntries([...searchParams.entries(), ['page', value]]); + loadDataTableData(filter); + setSearchParams(filter); + }; + + // Handel Delete Final LOG + const [idFinalLog, setidFinalLog] = useState(); + const [openDialogDeleteFinalLog, setDialogDeleteFinalLog] = useState(false) + + useEffect(() => { + loadDataTableData(); + }, []); + + const headStyle = { + fontWeight: 'bold', + }; + + // Called on every row to map the data to the columns + function createData(data: FinalLogType) { + return { + ...data, + }; + } + + { + /* ------------------ TABLE ROW ------------------ */ + } + function Row(props: { row: ReturnType }) { + const { row } = props; + const [open, setOpen] = React.useState(false); + const [loadingApprove, setLoadingApprove] = React.useState(false); + return ( + + *': { borderBottom: 'unset' } }}> + {/* + setOpen(!open)}> + {open ? : } + + */ } + {/* + { + // handleShowClaim(row); + // }} + > + {row.id} + + */} + {row.code} + {row.provider} + {row.member_name} + + {row.service_name} + {row.payment_type_name} + + {row.files_by_type?.final_log_diagnosis?.length > 0 && ( + <> + +
+ + )} + + {row.files_by_type?.final_log_kondisi?.length > 0 && ( + <> + +
+ + )} + + {row.files_by_type?.final_log_result?.length > 0 && ( + + )} +
+ + { row.status_final_log == "requested" ? + () : + row.status_final_log == "declined" ? + () + : + () + } + + + + {/* navigate(`/claim-requests/edit/${row.id}`)}> + + Edit + */} + navigate ('/custormer-service/final-log/detail/'+row.id+'/'+user.id)}> + + Detail + + { + setidFinalLog(row.id) + setDialogDeleteFinalLog(true) + }} + > + + Delete + + + } /> + + {/* + + { + handleShowClaim(row); + }} + > + + + */} +
+ {/* COLLAPSIBLE ROW */} + + + + + } + spacing={1} + sx={{ marginY: 2 }} + > + + Berkas Hasil Penunjang + {/* {row.files_by_type?.claim_kondisi && + row.files_by_type?.claim_kondisi.map((file, index) => ( + + -{' '} + + {file.name} + + + ))} */} + + {row.files_by_type?.claim_kondisi && ( + <> + - Kondisi + {row.files_by_type?.claim_kondisi.map((file, index) => ( + + + + {file.name} + + + ))} + + )} + + {row.files_by_type?.claim_diagnosis && ( + <> + - Diagnosa + {row.files_by_type?.claim_diagnosis.map((file, index) => ( + + + + {file.name} + + + ))} + + )} + + {row.files_by_type?.claim_result && ( + <> + - Hasil + {row.files_by_type?.claim_result.map((file, index) => ( + + + + {file.name} + + + ))} + + )} + {(!row.files_by_type?.claim_result && !row.files_by_type?.claim_diagnosis && !row.files_by_type?.claim_kondisi)&& Tidak ada berkas} + + + + + + +
+ ); + } + { + /* ------------------ END TABLE ROW ------------------ */ + } + + function TableContent() { + return ( + + {/* ------------------ TABLE HEADER ------------------ */} + + + {/* */} + {/* + ID Request LOG + */} + + Code + + + Provider + + + Name + + + Date of Admission + + + Service Type + + + Claim Method + + + File Upload + + + Status + + + + + {/* ------------------ END TABLE HEADER ------------------ */} + + {/* ------------------ TABLE ROW ------------------ */} + {dataTableIsLoading ? ( + + + + Loading + + + + ) : dataTableData.data.length === 0 ? ( + + + + No Data + + + + ) : ( + + {dataTableData.data.map((row) => ( + + ))} + + )} + {/* ------------------ END TABLE ROW ------------------ */} +
+ ); + } + return ( + + + + + + + } + /> + + + {/* Dialog Delete */} + + + + ); +} diff --git a/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx b/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx index fb45bb08..88724ef4 100755 --- a/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx +++ b/frontend/dashboard/src/pages/CustomerService/FinalLog/Detail.tsx @@ -117,7 +117,7 @@ export default function Detail() { }); } - const { id } = useParams(); + const { id, approval } = useParams(); useEffect(() => { axios @@ -474,14 +474,46 @@ export default function Detail() { > Simpan */} - + + {approval ? ( + <> + + {/* GRUP TOMBOL DI KANAN */} + + + + + + + ) : ( + <> {/* TOMBOL SIMPAN DI KIRI */} Simpan @@ -489,19 +521,36 @@ export default function Detail() { {/* Ini adalah spacer untuk mendorong tombol berikutnya ke kanan */} - {/* GRUP TOMBOL DI KANAN */} - - - - - + {/* GRUP TOMBOL DI KANAN */} + + + + + + + )} + diff --git a/frontend/dashboard/src/routes/index.tsx b/frontend/dashboard/src/routes/index.tsx index a44879f0..9082b104 100755 --- a/frontend/dashboard/src/routes/index.tsx +++ b/frontend/dashboard/src/routes/index.tsx @@ -269,6 +269,10 @@ export default function Router() { path: 'inpatient_monitoring', // Inpatient Monitoring element: }, + { + path: 'approval_inpatient_monitoring', // Approval Monitoring + element: + }, ] }, { @@ -555,6 +559,10 @@ export default function Router() { { path: 'custormer-service/final-log/detail/:id', element: , + }, + { + path: 'custormer-service/final-log/detail/:id/:approval', + element: , }, { path: 'e-prescription/live-chat', @@ -714,6 +722,7 @@ const DetailLabResultForm = Loadable(lazy(() => import('../pages/CaseManage const DetailLabResultList = Loadable(lazy(() => import('../pages/CaseManagement/LaboratoriumResult/Components/DetailLabResultList'))) // Inpatient Monitoring const InpatientMonitoring = Loadable(lazy(() => import('../pages/CaseManagement/InpatientMonitoring/Index'))) +const ApprovalMonitoring = Loadable(lazy(() => import('../pages/CaseManagement/ApprovalMonitoring/Index'))) /**