445 lines
15 KiB
TypeScript
445 lines
15 KiB
TypeScript
import * as Yup from 'yup';
|
|
import { useSnackbar } from 'notistack';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { yupResolver } from '@hookform/resolvers/yup';
|
|
import { Controller, useForm } from 'react-hook-form';
|
|
import React, { useRef, useEffect, useMemo, useState } from 'react';
|
|
import axios from '../../utils/axios';
|
|
import { FormProvider, RHFTextField } from '../../components/hook-form';
|
|
|
|
import { makeFormData } from '@/utils/jsonToFormData';
|
|
import {
|
|
Autocomplete,
|
|
Button,
|
|
Grid,
|
|
Stack,
|
|
Table,
|
|
TableBody,
|
|
TableCell,
|
|
TableRow,
|
|
TextField,
|
|
Typography,
|
|
useTheme,
|
|
List,
|
|
ListItem,
|
|
IconButton,
|
|
ListItemAvatar,
|
|
Avatar,
|
|
ListItemText,
|
|
Card,
|
|
InputAdornment,
|
|
Divider,
|
|
ButtonBase,
|
|
Box,
|
|
} from '@mui/material';
|
|
import Iconify from '../../components/Iconify';
|
|
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
|
|
import { LoadingButton } from '@mui/lab';
|
|
import { fCurrency } from '../../utils/formatNumber';
|
|
import MemberSelectDialog from '../../components/dialogs/MemberSelectDialog';
|
|
import { Add, DeleteOutline } from '@mui/icons-material';
|
|
import { ClaimRequest, Files } from '@/@types/claims';
|
|
import { fDateTimesecond } from '@/utils/formatTime';
|
|
|
|
interface FormValuesProps extends Partial<ClaimRequest> {
|
|
taxes: boolean;
|
|
inStock: boolean;
|
|
}
|
|
|
|
type Props = {
|
|
isEdit: boolean;
|
|
currentClaim?: ClaimRequest;
|
|
};
|
|
|
|
export default function ClaimForm({ isEdit, currentClaim }: Props) {
|
|
const navigate = useNavigate();
|
|
|
|
const { enqueueSnackbar } = useSnackbar();
|
|
|
|
const EditClaimSchema = Yup.object().shape({
|
|
organization_id: Yup.string().required('Code Provider is required'),
|
|
});
|
|
|
|
const defaultValues = useMemo(
|
|
() => ({
|
|
id: currentClaim?.id || '-',
|
|
code: currentClaim?.code || '-',
|
|
member_name: currentClaim?.member?.name || '-',
|
|
date: currentClaim?.submission_date ? fDateTimesecond(currentClaim?.submission_date) : '-',
|
|
claim_method: currentClaim?.payment_type || '-',
|
|
service_type: currentClaim?.service_code || '-',
|
|
organization_id: currentClaim?.organization?.code || '-',
|
|
}),
|
|
[currentClaim]
|
|
);
|
|
|
|
useEffect(() => {
|
|
if (isEdit && currentClaim) {
|
|
reset(defaultValues);
|
|
}
|
|
if (!isEdit) {
|
|
reset(defaultValues);
|
|
}
|
|
// setFileKondisis(currentClaim?.files_by_type?.claim_diagnosis);
|
|
// setFileDiagnosas(currentClaim?.files_by_type?.claim_diagnosis);
|
|
setFileHasilPenunjangCurrent(currentClaim?.files_by_type?.claim_result);
|
|
}, [isEdit, currentClaim]);
|
|
|
|
|
|
const methods = useForm<FormValuesProps>({
|
|
resolver: yupResolver(EditClaimSchema),
|
|
defaultValues,
|
|
});
|
|
|
|
const {
|
|
reset,
|
|
watch,
|
|
control,
|
|
setValue,
|
|
getValues,
|
|
setError,
|
|
handleSubmit,
|
|
formState: { isSubmitting },
|
|
} = methods;
|
|
|
|
const values = watch();
|
|
|
|
const [isCheckingLimit, setIsCheckingLimit] = useState(false);
|
|
const [isEligible, setIsEligible] = useState(false);
|
|
const [memberBenefits, setMemberBenefits] = useState([]);
|
|
const [diagnosisOption, setDiagnosisOption] = useState([]);
|
|
const [isMemberDialogOpen, setIsMemberDialogOpen] = useState(false);
|
|
const [member, setMember] = useState({})
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// Files Result Kondisi
|
|
const fileKondisiInput = useRef<HTMLInputElement>(null);
|
|
const [fileKondisis, setFileKondisis] = useState<Files>([]);
|
|
|
|
const handleKondisiInputChange = (event) => {
|
|
if (event.target.files[0]) {
|
|
setFileKondisis([...fileKondisis, ...event.target.files]);
|
|
} else {
|
|
console.log('NO FILE');
|
|
}
|
|
};
|
|
const removeKondisiFiles = (filesState, index) => {
|
|
setFileKondisis(
|
|
filesState.filter((file, fileIndex) => {
|
|
return fileIndex != index;
|
|
})
|
|
);
|
|
};
|
|
|
|
// Files Result Diagnosa
|
|
const fileDiagnosaInput = useRef<HTMLInputElement>(null);
|
|
const [fileDiagnosas, setFileDiagnosas] = useState([]);
|
|
|
|
const handleDiagnosaInputChange = (event) => {
|
|
if (event.target.files[0]) {
|
|
setFileDiagnosas([...fileDiagnosas, ...event.target.files]);
|
|
} else {
|
|
console.log('NO FILE');
|
|
}
|
|
};
|
|
const removeDiagnosaFiles = (filesState, index) => {
|
|
setFileDiagnosas(
|
|
filesState.filter((file, fileIndex) => {
|
|
return fileIndex != index;
|
|
})
|
|
);
|
|
};
|
|
|
|
// Files Result Hasil Penunjang
|
|
const fileHasilPenunjangInput = useRef<HTMLInputElement>(null);
|
|
const [fileHasilPenunjangs, setFileHasilPenunjangs] = useState([]);
|
|
const [fileHasilPenunjangsCurrent, setFileHasilPenunjangCurrent] = useState([]);
|
|
|
|
const handleResultInputChange = (event) => {
|
|
if (event.target.files[0]) {
|
|
setFileHasilPenunjangs([...fileHasilPenunjangs, ...event.target.files]);
|
|
} else {
|
|
console.log('NO FILE');
|
|
}
|
|
};
|
|
const removeFiles = (filesState, index) => {
|
|
setFileHasilPenunjangs(
|
|
filesState.filter((file, fileIndex) => {
|
|
return fileIndex != index;
|
|
})
|
|
);
|
|
};
|
|
|
|
|
|
const onSubmit = async (data: FormValuesProps) => {
|
|
try {
|
|
// const formData = new FormData();
|
|
// formData.append('result_files', fileHasilPenunjangs);
|
|
// formData.append('diagnosa_files', fileDiagnosaInput);
|
|
// formData.append('kondisi_files', fileKondisiInput);
|
|
// formData.append('provider_code', data.organization_id);
|
|
// formData.append('_method', 'PUT');
|
|
const formData = makeFormData({
|
|
result_files: fileHasilPenunjangs,
|
|
diagnosa_files: fileDiagnosas,
|
|
kondisi_files: fileKondisis,
|
|
provider_code: data.organization_id,
|
|
_method: 'PUT'
|
|
});
|
|
|
|
const response = await axios.post(`/claim-requests/${data.id}`, formData);
|
|
|
|
reset();
|
|
enqueueSnackbar('Claim Request Updated Successfully!', { variant: 'success' });
|
|
navigate('/claim-requests');
|
|
} catch (error: any) {
|
|
if (error && error.response.status === 422) {
|
|
for (const [key, value] of Object.entries(error.response.data.errors)) {
|
|
// setError(key, { message: value[0] });
|
|
enqueueSnackbar('Failed Processing Request', { variant: 'error' });
|
|
}
|
|
} else {
|
|
enqueueSnackbar(error.message ?? 'Failed Processing Request', { variant: 'error' });
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
return (
|
|
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
|
<Card sx={{paddingX:2, paddingY:2}}>
|
|
<Grid container spacing={2}>
|
|
<Grid item xs={5}>
|
|
<Typography variant="subtitle1">Code*</Typography>
|
|
</Grid>
|
|
<Grid item xs={7}>
|
|
<Typography variant="subtitle1">Name*</Typography>
|
|
</Grid>
|
|
<Grid item xs={5}>
|
|
<RHFTextField name="code" label="Code" disabled/>
|
|
</Grid>
|
|
<Grid item xs={7}>
|
|
<RHFTextField name="member_name" label="Name" disabled/>
|
|
</Grid>
|
|
{/* <input type="hidden" name="id"/> */}
|
|
|
|
|
|
<Grid item xs={12}></Grid>
|
|
|
|
<Grid item xs={3}>
|
|
<Typography variant="subtitle1">Date of Submission*</Typography>
|
|
</Grid>
|
|
<Grid item xs={3}>
|
|
<Typography variant="subtitle1">Claim Method*</Typography>
|
|
</Grid>
|
|
<Grid item xs={3}>
|
|
<Typography variant="subtitle1">Service Type*</Typography>
|
|
</Grid>
|
|
<Grid item xs={3}>
|
|
<Typography variant="subtitle1">Code Provider*</Typography>
|
|
</Grid>
|
|
|
|
|
|
<Grid item xs={3}>
|
|
<RHFTextField InputProps={{endAdornment: (
|
|
<InputAdornment position="end">
|
|
<CalendarTodayIcon />
|
|
</InputAdornment>
|
|
), }}
|
|
name="date" label="Date of Submission" disabled/>
|
|
</Grid>
|
|
<Grid item xs={3}>
|
|
<RHFTextField name="claim_method" label="Claim Method" disabled/>
|
|
</Grid>
|
|
<Grid item xs={3}>
|
|
<RHFTextField name="service_type" label="Service Type*" disabled/>
|
|
</Grid>
|
|
<Grid item xs={3}>
|
|
<RHFTextField name="organization_id" label="Code Provider*"/>
|
|
</Grid>
|
|
|
|
|
|
{/* -------------------------------Upload Dokumen Kondisi------------------------------- */}
|
|
<React.Fragment>
|
|
<Grid item xs={12}>
|
|
<Typography variant='h6'> Condition Document</Typography>
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
{fileKondisis &&
|
|
fileKondisis.map((file, index) => (
|
|
<Stack sx={{marginTop: 2}} direction="row" justifyContent={'space-between'} key={index}>
|
|
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
|
|
<Iconify
|
|
icon="eva:trash-2-outline"
|
|
color={'darkred'}
|
|
onClick={() => {
|
|
removeKondisiFiles(fileKondisis, index);
|
|
}}
|
|
></Iconify>
|
|
</Stack>
|
|
))}
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
bgcolor: '#919EAB52',
|
|
borderRadius: '8px',
|
|
width: '100%', height: '60px'}} onClick={() => fileKondisiInput.current?.click()}>
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
placeItems: 'center',
|
|
gap: 1,
|
|
placeContent: 'center',
|
|
}}
|
|
>
|
|
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
|
<Typography variant="body1" fontWeight="bold">
|
|
Add File
|
|
</Typography>
|
|
</Box>
|
|
<input
|
|
type="file"
|
|
id="file"
|
|
ref={fileKondisiInput}
|
|
style={{ display: 'none' }}
|
|
multiple
|
|
onChange={handleKondisiInputChange}
|
|
accept="application/pdf"
|
|
/>
|
|
</ButtonBase>
|
|
</Grid>
|
|
</React.Fragment>
|
|
{/* -------------------------------Upload Dokumen Diagnosa------------------------------- */}
|
|
<React.Fragment>
|
|
<Grid item xs={12}>
|
|
<Typography variant='h6'> Diagnosis Document</Typography>
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
{fileDiagnosas &&
|
|
fileDiagnosas.map((file, index) => (
|
|
<Stack sx={{marginTop: 2}} direction="row" justifyContent={'space-between'} key={index}>
|
|
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
|
|
<Iconify
|
|
icon="eva:trash-2-outline"
|
|
color={'darkred'}
|
|
onClick={() => {
|
|
removeDiagnosaFiles(fileDiagnosas, index);
|
|
}}
|
|
></Iconify>
|
|
</Stack>
|
|
))}
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
bgcolor: '#919EAB52',
|
|
borderRadius: '8px',
|
|
width: '100%', height: '60px'}} onClick={() => fileDiagnosaInput.current?.click()}>
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
placeItems: 'center',
|
|
gap: 1,
|
|
placeContent: 'center',
|
|
}}
|
|
>
|
|
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
|
<Typography variant="body1" fontWeight="bold">
|
|
Add Result
|
|
</Typography>
|
|
</Box>
|
|
<input
|
|
type="file"
|
|
id="file"
|
|
ref={fileDiagnosaInput}
|
|
style={{ display: 'none' }}
|
|
multiple
|
|
onChange={handleDiagnosaInputChange}
|
|
accept="application/pdf"
|
|
/>
|
|
</ButtonBase>
|
|
</Grid>
|
|
</React.Fragment>
|
|
{/* -------------------------------Upload Result Hasil Penunjang------------------------------- */}
|
|
<React.Fragment>
|
|
<Grid item xs={12}>
|
|
<Typography variant='h6'> Supporting Result Document</Typography>
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
{fileHasilPenunjangs &&
|
|
fileHasilPenunjangs.map((file, index) => (
|
|
<Stack sx={{marginTop: 2}} direction="row" justifyContent={'space-between'} key={index}>
|
|
<Typography sx={{ color: "text.secondary" }}>{file.name}</Typography>
|
|
<Iconify
|
|
icon="eva:trash-2-outline"
|
|
color={'darkred'}
|
|
onClick={() => {
|
|
removeFiles(fileHasilPenunjangs, index);
|
|
}}
|
|
></Iconify>
|
|
</Stack>
|
|
))}
|
|
</Grid>
|
|
<Grid item xs={12}>
|
|
<ButtonBase sx={{ p: 4, border: '2px dashed #F9FAFB',
|
|
bgcolor: '#919EAB52',
|
|
borderRadius: '8px',
|
|
width: '100%', height: '60px'}} onClick={() => fileHasilPenunjangInput.current?.click()}>
|
|
<Box
|
|
sx={{
|
|
display: 'flex',
|
|
placeItems: 'center',
|
|
gap: 1,
|
|
placeContent: 'center',
|
|
}}
|
|
>
|
|
<Iconify icon="icon-park-outline:upload-one" fontSize="3em" />
|
|
<Typography variant="body1" fontWeight="bold">
|
|
Add Result
|
|
</Typography>
|
|
</Box>
|
|
<input
|
|
type="file"
|
|
id="file"
|
|
ref={fileHasilPenunjangInput}
|
|
style={{ display: 'none' }}
|
|
multiple
|
|
onChange={handleResultInputChange}
|
|
accept="application/pdf"
|
|
/>
|
|
</ButtonBase>
|
|
</Grid>
|
|
</React.Fragment>
|
|
|
|
</Grid>
|
|
</Card>
|
|
<Grid container marginTop={3}>
|
|
<Grid item xs={12} md={12} >
|
|
<Stack direction="row" alignItems="center" justifyContent="flex-end">
|
|
<Button
|
|
sx={{
|
|
margin: 1
|
|
}}
|
|
type="submit"
|
|
variant="contained"
|
|
size="large"
|
|
color='inherit'
|
|
onClick={() => navigate(`/claim-requests`)}
|
|
>
|
|
Cancel
|
|
</Button>
|
|
<LoadingButton
|
|
type="submit"
|
|
variant="contained"
|
|
size="large"
|
|
loading={isSubmitting}
|
|
>
|
|
Update
|
|
</LoadingButton>
|
|
</Stack>
|
|
</Grid>
|
|
</Grid>
|
|
</FormProvider>
|
|
);
|
|
}
|