Update Show Claim Request
This commit is contained in:
@@ -0,0 +1,296 @@
|
|||||||
|
// @mui
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Box,
|
||||||
|
Stepper,
|
||||||
|
Step,
|
||||||
|
StepLabel,
|
||||||
|
Card,
|
||||||
|
Typography,
|
||||||
|
Divider,
|
||||||
|
Stack,
|
||||||
|
CircularProgress,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { Add } from '@mui/icons-material';
|
||||||
|
// components
|
||||||
|
import MuiDialog from '../../components/MuiDialog';
|
||||||
|
// theme
|
||||||
|
import palette from '../../theme/palette';
|
||||||
|
// React
|
||||||
|
import { ReactElement, useEffect, useState } from 'react';
|
||||||
|
import { fDate } from '@/utils/formatTime';
|
||||||
|
import { addMinutes, format } from 'date-fns';
|
||||||
|
import { LoadingButton } from '@mui/lab';
|
||||||
|
|
||||||
|
type DataContent = {
|
||||||
|
claim: object;
|
||||||
|
isLoading: boolean;
|
||||||
|
handleDownloadLog: void;
|
||||||
|
};
|
||||||
|
|
||||||
|
type MuiDialogProps = {
|
||||||
|
title?: {
|
||||||
|
name?: string;
|
||||||
|
icon?: string;
|
||||||
|
};
|
||||||
|
openDialog: boolean;
|
||||||
|
setOpenDialog: Function;
|
||||||
|
content?: ReactElement;
|
||||||
|
data?: DataContent[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const steps = ['Review', 'Approval', 'Disbursement'];
|
||||||
|
|
||||||
|
const DialogDetailClaim = ({ title, openDialog, setOpenDialog, data }: MuiDialogProps) => {
|
||||||
|
const claim = data.claim ?? null;
|
||||||
|
|
||||||
|
// ---------------------------------------------
|
||||||
|
// Step
|
||||||
|
const [currentStep, setCurrentStep] = useState(0);
|
||||||
|
useEffect(
|
||||||
|
function () {
|
||||||
|
if (claim?.status == 'requested') {
|
||||||
|
setCurrentStep(0);
|
||||||
|
}
|
||||||
|
if (claim?.status == 'approved') {
|
||||||
|
setCurrentStep(1);
|
||||||
|
}
|
||||||
|
if (claim?.status == 'closed') {
|
||||||
|
setCurrentStep(2);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[data]
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------
|
||||||
|
// Download LOG
|
||||||
|
const [loadingDownloadLog, setLoadingDownloadLog] = useState(false)
|
||||||
|
const handleDownloadLog = async (claimRequest) => {
|
||||||
|
setLoadingDownloadLog(true)
|
||||||
|
await data.handleDownloadLog(claimRequest).then(() => {
|
||||||
|
setLoadingDownloadLog(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getContent = () => (
|
||||||
|
<>
|
||||||
|
{data.isLoading && (
|
||||||
|
<Stack alignItems="center" justifyContent="space-between" sx={{ p: 4 }}>
|
||||||
|
<CircularProgress />
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!data.isLoading && (
|
||||||
|
<>
|
||||||
|
<Stack
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="space-between"
|
||||||
|
direction="row"
|
||||||
|
sx={{ marginTop: 1 }}
|
||||||
|
>
|
||||||
|
<Typography variant="subtitle1" sx={{ height: 'max-content' }}>
|
||||||
|
Claim Request
|
||||||
|
</Typography>
|
||||||
|
<Stack>
|
||||||
|
<Typography variant="caption">Submission date</Typography>
|
||||||
|
{/* {JSON.stringify(data)} */}
|
||||||
|
<Typography variant="caption">{claim && fDate(claim.created_at)}</Typography>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
<Box sx={{ width: '100%', marginTop: 2 }}>
|
||||||
|
<Stepper alternativeLabel activeStep={currentStep ?? 0}>
|
||||||
|
{steps.map((label) => (
|
||||||
|
<Step key={label}>
|
||||||
|
<StepLabel>{label}</StepLabel>
|
||||||
|
</Step>
|
||||||
|
))}
|
||||||
|
</Stepper>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{ claim.status == 'approved' && (
|
||||||
|
<Stack sx={{ marginTop: 4}}>
|
||||||
|
<LoadingButton loading={loadingDownloadLog}
|
||||||
|
variant="contained"
|
||||||
|
startIcon={<Add />}
|
||||||
|
fullWidth
|
||||||
|
// sx={{ typography: 'subtitle2', borderColor: '#F5F5F5' }}
|
||||||
|
onClick={() => {handleDownloadLog(claim)}}
|
||||||
|
>
|
||||||
|
Upload Invoice
|
||||||
|
</LoadingButton>
|
||||||
|
</Stack>)}
|
||||||
|
|
||||||
|
<Stack marginTop={2}>
|
||||||
|
<Typography variant="subtitle1" paddingY={2}>
|
||||||
|
{fDate(claim.created_at)}
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Stack direction="row" spacing={2}>
|
||||||
|
<Divider orientation="vertical" flexItem sx={{ borderStyle: 'dashed' }} />
|
||||||
|
<Stack spacing={2} sx={{ flex: 1, maxWidth: '100%' }}>
|
||||||
|
|
||||||
|
{/* Download LOG */}
|
||||||
|
{claim.status == 'approved' && (
|
||||||
|
<Card sx={{ paddingY: 2, paddingX: 3 }}>
|
||||||
|
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||||
|
<Typography variant="body1">
|
||||||
|
{format(
|
||||||
|
addMinutes(
|
||||||
|
new Date(claim.created_at),
|
||||||
|
15 //Math.floor(Math.random() * (20 - 15 + 1)) + 15
|
||||||
|
),
|
||||||
|
'HH:mm'
|
||||||
|
)}{' '}
|
||||||
|
WIB</Typography>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
backgroundColor: palette.light.warning.lighter,
|
||||||
|
color: palette.light.warning.dark,
|
||||||
|
borderColor: palette.light.warning.dark,
|
||||||
|
border: '1px solid',
|
||||||
|
borderRadius: '6px',
|
||||||
|
padding: 1,
|
||||||
|
}}
|
||||||
|
variant="caption"
|
||||||
|
>
|
||||||
|
Approved
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Divider sx={{ marginY: 2 }} />
|
||||||
|
<Stack>
|
||||||
|
<LoadingButton loading={loadingDownloadLog}
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<Add />}
|
||||||
|
fullWidth
|
||||||
|
// sx={{ typography: 'subtitle2', borderColor: '#F5F5F5' }}
|
||||||
|
onClick={() => {handleDownloadLog(claim)}}
|
||||||
|
>
|
||||||
|
Download Guarantee Letter
|
||||||
|
</LoadingButton>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
|
{/* Item 1 */}
|
||||||
|
{claim.status == 'requested' && (
|
||||||
|
<Card sx={{ paddingY: 2, paddingX: 3 }}>
|
||||||
|
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||||
|
<Typography variant="body1">09:10 WIB</Typography>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
backgroundColor: palette.light.warning.lighter,
|
||||||
|
color: palette.light.warning.dark,
|
||||||
|
borderColor: palette.light.warning.dark,
|
||||||
|
border: '1px solid',
|
||||||
|
borderRadius: '6px',
|
||||||
|
padding: 1,
|
||||||
|
}}
|
||||||
|
variant="caption"
|
||||||
|
>
|
||||||
|
Approval
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Divider sx={{ marginY: 2 }} />
|
||||||
|
<Stack>
|
||||||
|
<Typography variant="subtitle2" color="#404040">
|
||||||
|
Details : mohon melengkapi kekurangan dokumen
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="caption"
|
||||||
|
color="#757575"
|
||||||
|
sx={{ marginTop: 2, marginBottom: 1 }}
|
||||||
|
>
|
||||||
|
Lab pemeriksaan darah
|
||||||
|
</Typography>
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<Add />}
|
||||||
|
fullWidth
|
||||||
|
sx={{ typography: 'subtitle2', borderColor: '#F5F5F5' }}
|
||||||
|
>
|
||||||
|
Hasil Pemeriksaan Laboratorium
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Item 2 */}
|
||||||
|
<Card sx={{ flex: 1, maxWidth: '100%', paddingY: 2, paddingX: 3 }}>
|
||||||
|
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||||
|
{/* // TODO sementara tanggal random */}
|
||||||
|
<Typography variant="body1">
|
||||||
|
{format(
|
||||||
|
addMinutes(
|
||||||
|
new Date(claim.created_at),
|
||||||
|
10// Math.floor(Math.random() * (15 - 5 + 1)) + 5
|
||||||
|
),
|
||||||
|
'HH:mm'
|
||||||
|
)}{' '}
|
||||||
|
WIB
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
backgroundColor: palette.light.warning.lighter,
|
||||||
|
color: palette.light.warning.dark,
|
||||||
|
borderColor: palette.light.warning.dark,
|
||||||
|
border: '1px solid',
|
||||||
|
borderRadius: '6px',
|
||||||
|
padding: 1,
|
||||||
|
}}
|
||||||
|
variant="caption"
|
||||||
|
>
|
||||||
|
Approval
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Divider sx={{ marginY: 2 }} />
|
||||||
|
<Stack>
|
||||||
|
<Typography variant="subtitle2" color="#404040">
|
||||||
|
Details : Penilaian Dokter
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
{/* Item 3 */}
|
||||||
|
<Card sx={{ flex: 1, maxWidth: '100%', paddingY: 2, paddingX: 3 }}>
|
||||||
|
<Stack direction="row" justifyContent="space-between" alignItems="center">
|
||||||
|
<Typography variant="body1">{fDate(claim.created_at, 'HH:mm')} WIB</Typography>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
backgroundColor: '#F5F5F5',
|
||||||
|
color: '#757575',
|
||||||
|
borderColor: '#757575',
|
||||||
|
border: '1px solid',
|
||||||
|
borderRadius: '6px',
|
||||||
|
padding: 1,
|
||||||
|
}}
|
||||||
|
variant="caption"
|
||||||
|
>
|
||||||
|
Review
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Divider sx={{ marginY: 2 }} />
|
||||||
|
<Stack>
|
||||||
|
<Typography variant="subtitle2" color="#404040">
|
||||||
|
Details : Klaim Diajukan
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MuiDialog
|
||||||
|
title={title}
|
||||||
|
openDialog={openDialog}
|
||||||
|
setOpenDialog={setOpenDialog}
|
||||||
|
content={getContent()}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DialogDetailClaim;
|
||||||
@@ -40,6 +40,7 @@ import { useSearchParams } from 'react-router-dom';
|
|||||||
import { fSplit } from '@/utils/formatNumber';
|
import { fSplit } from '@/utils/formatNumber';
|
||||||
import { Chip } from '@mui/material';
|
import { Chip } from '@mui/material';
|
||||||
import { enqueueSnackbar } from 'notistack';
|
import { enqueueSnackbar } from 'notistack';
|
||||||
|
import DialogDetailClaim from '@/components/dialogs/DialogDetailClaim';
|
||||||
|
|
||||||
/* ---------------------------------- types --------------------------------- */
|
/* ---------------------------------- types --------------------------------- */
|
||||||
type PaginationTableProps = {
|
type PaginationTableProps = {
|
||||||
@@ -310,10 +311,11 @@ export default function TableList(props: any) {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
// Download LOG
|
// Download LOG
|
||||||
function handleDownloadLog(claimRequest) {
|
async function handleDownloadLog(claimRequest) {
|
||||||
axios.get(`claim-requests/${claimRequest.id}/log`, {
|
return axios
|
||||||
responseType: 'blob'
|
.get(`claim-requests/${claimRequest.id}/log`, {
|
||||||
})
|
responseType: 'blob',
|
||||||
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
window.open(URL.createObjectURL(response.data));
|
window.open(URL.createObjectURL(response.data));
|
||||||
// setLoadingLog(false);
|
// setLoadingLog(false);
|
||||||
@@ -323,9 +325,24 @@ export default function TableList(props: any) {
|
|||||||
// setLoadingLog(false);
|
// setLoadingLog(false);
|
||||||
// })
|
// })
|
||||||
.catch((response) => {
|
.catch((response) => {
|
||||||
enqueueSnackbar(response.message, {variant: 'error'})
|
enqueueSnackbar(response.message, { variant: 'error' });
|
||||||
// setLoadingLog(false);
|
// setLoadingLog(false);
|
||||||
})
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------
|
||||||
|
// Dialog Detail Claim
|
||||||
|
const [openDialogDetailClaim, setOpenDialogDetailClaim] = useState(false);
|
||||||
|
const [loadingClaimDetail, setLoadingClaimDetail] = useState(true);
|
||||||
|
const [currentClaim, setCurrentClaim] = useState(null);
|
||||||
|
|
||||||
|
function handleShowClaim(claimRequest) {
|
||||||
|
setLoadingClaimDetail(true);
|
||||||
|
setOpenDialogDetailClaim(true);
|
||||||
|
setTimeout(function () {
|
||||||
|
setCurrentClaim(claimRequest);
|
||||||
|
setLoadingClaimDetail(false);
|
||||||
|
}, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -379,7 +396,11 @@ export default function TableList(props: any) {
|
|||||||
>
|
>
|
||||||
{statusOptions &&
|
{statusOptions &&
|
||||||
statusOptions.map((option, index) => (
|
statusOptions.map((option, index) => (
|
||||||
<MenuItem value={option} sx={{ textTransform: 'capitalize' }} key={index}>
|
<MenuItem
|
||||||
|
value={option}
|
||||||
|
sx={{ textTransform: 'capitalize' }}
|
||||||
|
key={index}
|
||||||
|
>
|
||||||
{option}
|
{option}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
@@ -427,7 +448,9 @@ export default function TableList(props: any) {
|
|||||||
color: palette.dark.success.darker,
|
color: palette.dark.success.darker,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onClick={() => {handleDownloadLog(row)}}
|
onClick={() => {
|
||||||
|
handleDownloadLog(row);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Download LOG
|
Download LOG
|
||||||
</Button>
|
</Button>
|
||||||
@@ -451,6 +474,16 @@ export default function TableList(props: any) {
|
|||||||
sx={{ textTransform: 'capitalize' }}
|
sx={{ textTransform: 'capitalize' }}
|
||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
<TableCell align="right">
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
handleShowClaim(row);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Iconify icon="eva:eye-fill" />
|
||||||
|
</IconButton>
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
@@ -475,6 +508,13 @@ export default function TableList(props: any) {
|
|||||||
</Grid>
|
</Grid>
|
||||||
{/* End Field 2 */}
|
{/* End Field 2 */}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
<DialogDetailClaim
|
||||||
|
openDialog={openDialogDetailClaim}
|
||||||
|
setOpenDialog={setOpenDialogDetailClaim}
|
||||||
|
title={{ name: 'Claim Request Detail' }}
|
||||||
|
data={{ claim: currentClaim, isLoading: loadingClaimDetail, handleDownloadLog }}
|
||||||
|
></DialogDetailClaim>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { format, getTime, formatDistanceToNow } from 'date-fns';
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
export function fDate(date: Date | string | number) {
|
export function fDate(date: Date | string | number, dateFormat = 'dd MMMM yyyy' ) {
|
||||||
return format(new Date(date), 'dd MMMM yyyy');
|
return format(new Date(date), dateFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fDateTime(date: Date | string | number) {
|
export function fDateTime(date: Date | string | number) {
|
||||||
|
|||||||
Reference in New Issue
Block a user