320 lines
10 KiB
TypeScript
320 lines
10 KiB
TypeScript
// @mui
|
|
import {
|
|
Box,
|
|
Button,
|
|
Card,
|
|
Collapse,
|
|
IconButton,
|
|
MenuItem,
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableRow,
|
|
TextField,
|
|
Typography,
|
|
Stack,
|
|
Menu,
|
|
ButtonGroup,
|
|
Tooltip,
|
|
TableHead,
|
|
} from '@mui/material';
|
|
import FindInPageOutlinedIcon from '@mui/icons-material/FindInPageOutlined';
|
|
import AssessmentIcon from '@mui/icons-material/Assessment';
|
|
// hooks
|
|
import React, { ChangeEvent, useEffect, useRef, useState } from 'react';
|
|
import { Link, Navigate, useNavigate, useSearchParams } from 'react-router-dom';
|
|
// 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 { Chip } from '@mui/material';
|
|
import Iconify from '@/components/Iconify';
|
|
import { enqueueSnackbar } from 'notistack';
|
|
import { fDate } from '../../utils/formatTime';
|
|
import { Claims } from '@/@types/claims';
|
|
import Label from '@/components/Label';
|
|
import { capitalizeFirstLetter } from '@/utils/formatString';
|
|
import TableMoreMenu from '@/components/table/TableMoreMenu';
|
|
import Edit from '@mui/icons-material/Edit';
|
|
import { Download } from '@mui/icons-material';
|
|
|
|
export default function List() {
|
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
const [importResult, setImportResult] = useState(null);
|
|
const navigate = useNavigate();
|
|
|
|
function SearchInput(props: any) {
|
|
// SEARCH
|
|
const searchInput = useRef<HTMLInputElement>(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
|
|
};
|
|
|
|
const handleGetData = (type :string) => {
|
|
axios.get(`claims/1/data-claim`)
|
|
.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();
|
|
})
|
|
}
|
|
|
|
useEffect(() => {
|
|
// Trigger First Search
|
|
setSearchText(searchParams.get('search') ?? '');
|
|
}, []);
|
|
|
|
return (
|
|
<form onSubmit={handleSearchSubmit} style={{ width: '100%' }}>
|
|
<Stack direction={'row'} spacing={2} sx={{ mb: 2 }}>
|
|
<TextField
|
|
id="search-input"
|
|
ref={searchInput}
|
|
label="Search"
|
|
variant="outlined"
|
|
fullWidth
|
|
onChange={handleSearchChange}
|
|
value={searchText}
|
|
placeholder='Search Code or Member ID...'
|
|
/>
|
|
<Button
|
|
variant="contained"
|
|
startIcon={<Download />}
|
|
sx={{ p: 1.8 }}
|
|
onClick={handleGetData}
|
|
>
|
|
Export
|
|
</Button>
|
|
</Stack>
|
|
</form>
|
|
);
|
|
}
|
|
|
|
function ImportForm(props: any) {
|
|
// IMPORT
|
|
// Create Button Menu
|
|
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
|
|
|
return (
|
|
<div>
|
|
<Stack direction={'row'} spacing={2} sx={{ p: 2 }}>
|
|
<SearchInput onSearch={applyFilter} />
|
|
{/* <Button
|
|
variant="outlined"
|
|
startIcon={<AddIcon />}
|
|
sx={{ p: 1.8 }}
|
|
onClick={() => {
|
|
navigate('/claims/create');
|
|
}}
|
|
>
|
|
Create
|
|
</Button> */}
|
|
</Stack>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Dummy Default Data
|
|
const [dataTableIsLoading, setDataTableLoading] = useState(true);
|
|
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>(
|
|
LaravelPaginatedDataDefault
|
|
);
|
|
|
|
const loadDataTableData = async (appliedFilter: any | null = null) => {
|
|
setDataTableLoading(true);
|
|
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
|
const response = await axios.get('/claims', { 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);
|
|
};
|
|
|
|
useEffect(() => {
|
|
loadDataTableData();
|
|
}, []);
|
|
|
|
const headStyle = {
|
|
fontWeight: 'bold',
|
|
};
|
|
|
|
// Called on every row to map the data to the columns
|
|
function createData(data: Claims): Claims {
|
|
return {
|
|
...data,
|
|
};
|
|
}
|
|
|
|
{
|
|
/* ------------------ TABLE ROW ------------------ */
|
|
}
|
|
function Row(props: { row: ReturnType<typeof createData> }) {
|
|
const { row } = props;
|
|
const [open, setOpen] = React.useState(false);
|
|
|
|
return (
|
|
<React.Fragment>
|
|
<TableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
|
|
{/* <TableCell>
|
|
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
|
|
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
|
</IconButton>
|
|
</TableCell> */}
|
|
<TableCell align="left">{row.claim_request?.code}</TableCell>
|
|
{/* <TableCell align="left">{row.code}</TableCell> */}
|
|
<TableCell align="left">{row.member?.current_plan?.code}</TableCell>
|
|
<TableCell align="left">{row.member?.current_corporate?.payor_id}</TableCell>
|
|
<TableCell align="left">{row.member?.current_corporate?.code}</TableCell>
|
|
<TableCell align="left">{row.member?.current_corporate?.current_policy?.code}</TableCell>
|
|
<TableCell align="left">{row.member?.member_id}</TableCell>
|
|
<TableCell align="left">{row.benefit ? row.benefit?.description : '-'}</TableCell>
|
|
|
|
<TableCell align="center">
|
|
{row.status == 'draft' && (<Label color='secondary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
|
{row.status == 'requested' && (<Label color='primary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
|
{row.status == 'received' && (<Label color='secondary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
|
{row.status == 'approved' && (<Label color='success' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
|
{row.status == 'postpone' && (<Label color='secondary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
|
{row.status == 'paid' && (<Label color='secondary' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
|
{row.status == 'declined' && (<Label color='error' variant='ghost'>{capitalizeFirstLetter(row.status)}</Label>)}
|
|
</TableCell>
|
|
|
|
<TableMoreMenu actions={
|
|
<>
|
|
<MenuItem onClick={() =>navigate(`/claims/edit/${row.id}`) }>
|
|
<Edit />
|
|
Edit
|
|
</MenuItem>
|
|
<MenuItem onClick={() => setOpen(!open) }>
|
|
<FindInPageOutlinedIcon />
|
|
Detail
|
|
</MenuItem>
|
|
</>
|
|
} />
|
|
|
|
|
|
</TableRow>
|
|
{/* COLLAPSIBLE ROW */}
|
|
<TableRow>
|
|
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={99}>
|
|
<Collapse in={open} timeout="auto" unmountOnExit>
|
|
{/* <Box sx={{ borderBottom: 1 }}>
|
|
<Typography variant="body2" gutterBottom component="div">
|
|
Description : {row.description}
|
|
</Typography>
|
|
</Box> */}
|
|
</Collapse>
|
|
</TableCell>
|
|
</TableRow>
|
|
</React.Fragment>
|
|
);
|
|
}
|
|
{
|
|
/* ------------------ END TABLE ROW ------------------ */
|
|
}
|
|
|
|
function TableContent() {
|
|
return (
|
|
<Table aria-label="collapsible table">
|
|
{/* ------------------ TABLE HEADER ------------------ */}
|
|
<TableHead>
|
|
<TableRow>
|
|
{/* <TableCell style={headStyle} align="left" /> */}
|
|
<TableCell style={headStyle} align="left">
|
|
Code
|
|
</TableCell>
|
|
<TableCell style={headStyle} align="left">
|
|
Plan ID
|
|
</TableCell>
|
|
<TableCell style={headStyle} align="left">
|
|
Payor ID
|
|
</TableCell>
|
|
<TableCell style={headStyle} align="left">
|
|
Corporate ID
|
|
</TableCell>
|
|
<TableCell style={headStyle} align="left">
|
|
Policy Number
|
|
</TableCell>
|
|
<TableCell style={headStyle} align="left">
|
|
Member ID
|
|
</TableCell>
|
|
<TableCell style={headStyle} align="left">
|
|
Benefit Desc
|
|
</TableCell>
|
|
<TableCell style={headStyle} align="left">
|
|
Status
|
|
</TableCell>
|
|
<TableCell style={headStyle} align="left">
|
|
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableHead>
|
|
{/* ------------------ END TABLE HEADER ------------------ */}
|
|
|
|
{/* ------------------ TABLE ROW ------------------ */}
|
|
{dataTableIsLoading ? (
|
|
<TableBody>
|
|
<TableRow>
|
|
<TableCell colSpan={8} align="center">
|
|
Loading
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableBody>
|
|
) : dataTableData.data.length === 0 ? (
|
|
<TableBody>
|
|
<TableRow>
|
|
<TableCell colSpan={8} align="center">
|
|
No Data
|
|
</TableCell>
|
|
</TableRow>
|
|
</TableBody>
|
|
) : (
|
|
<TableBody>
|
|
{dataTableData.data.map((row) => (
|
|
<Row key={row.id} row={row} />
|
|
))}
|
|
</TableBody>
|
|
)}
|
|
{/* ------------------ END TABLE ROW ------------------ */}
|
|
</Table>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Card>
|
|
<ImportForm />
|
|
|
|
<DataTable
|
|
isLoading={dataTableIsLoading}
|
|
lastRequest={0}
|
|
data={dataTableData}
|
|
handlePageChange={handlePageChange}
|
|
TableContent={<TableContent />}
|
|
/>
|
|
</Card>
|
|
);
|
|
}
|