[WIP] Add Diagnosa

This commit is contained in:
R
2023-03-14 18:19:57 +07:00
parent c35442e652
commit e06447bf00
5 changed files with 332 additions and 101 deletions

View File

@@ -9,3 +9,6 @@ export type Icd = {
childs?: Icd[]; childs?: Icd[];
status: string; status: string;
}; };
export type IcdType = Icd

View File

@@ -1,14 +1,97 @@
import axios from "@/utils/axios"; import axios from "@/utils/axios";
import { Autocomplete, TextField, CircularProgress } from "@mui/material"; import { Autocomplete, TextField, CircularProgress } from "@mui/material";
import { useState } from "react"; import { useEffect, useMemo, useState } from "react";
import { IcdType } from "@/@types/diagnosis";
export default function AutocompleteDiagnosis({ onChange, textLabel, currentValue = null }) type autocompleteValueType = {
title: string,
value: string | number | null,
readonly: boolean
}
type autocompleteDiagnosisType = {
onChange: void,
textLabel: string,
currentValue: autocompleteValueType | null,
currentOptions: autocompleteValueType[]
}
type optionType = {
title: string,
value: string | number | null,
}
// import TextField from '@material-ui/core/TextField';
// import Autocomplete from '@material-ui/lab/Autocomplete';
// const ControlledAutocomplete = ({ options = [], renderInput, getOptionLabel, onChange: ignored, control, defaultValue, name, renderOption }) => {
// return (
// <Controller
// render={({ onChange, ...props }) => (
// <Autocomplete
// options={options}
// getOptionLabel={getOptionLabel}
// renderOption={renderOption}
// renderInput={renderInput}
// onChange={(e, data) => onChange(data)}
// {...props}
// />
// )}
// onChange={([, data]) => data}
// defaultValue={defaultValue}
// name={name}
// control={control}
// />
// );
// }
export default function AutocompleteDiagnosis({ onChange, textLabel, currentValue, currentOptions = [] }: autocompleteDiagnosisType)
{ {
const [options, setOptions] = useState([]) const [options, setOptions] = useState<autocompleteValueType>([])
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
// const [defaultValue, setDefaultValue] = useState(currentValue ?? {title: 'A00-CHOLERA', value: 1})
function icdsToOptions(icds: IcdType[]) : autocompleteValueType[] {
return icds.map(function(icd: IcdType) {
return {
title: icd.code + '-' + icd.name,
value: icd.id
}
})
}
useEffect(() => {
setOptions(icdsToOptions(currentOptions))
// setDefaultValue(currentValue)
}, [currentOptions])
const defaultValue = useMemo(
() => (currentValue)
, [currentValue]
)
// useEffect(() => {
// if (currentValue && currentValue.value) {
// onChange(currentValue)
// }
// console.log(currentValue)
// }, [currentValue])
const getOptions = (search: string) => {
axios.get('options?type=diagnosis&search='+search)
.then((res) => {
setOptions(icdsToOptions(res.data))
})
.then(() => {
setLoading(false);
})
}
// console.log('defaultValue', defaultValue)
return (<Autocomplete return (<Autocomplete
defaultValue={currentValue ?? null} defaultValue={defaultValue ?? {title: '', value: null}}
onChange={(event, value) => {onChange(value)}} onChange={(event, value) => {onChange(value)}}
isOptionEqualToValue={(option, value) => option.title === value.title} isOptionEqualToValue={(option, value) => option.title === value.title}
getOptionLabel={(option) => option.title} getOptionLabel={(option) => option.title}
@@ -20,18 +103,7 @@ export default function AutocompleteDiagnosis({ onChange, textLabel, currentValu
label={textLabel != null ? textLabel : "Diagnosa ICD-X"} label={textLabel != null ? textLabel : "Diagnosa ICD-X"}
onChange={(event) => { onChange={(event) => {
setLoading(true); setLoading(true);
axios.get('options?type=diagnosis&search='+event.target.value) getOptions(event.target.value)
.then((res) => {
setOptions(res.data.map(function(icd) {
return {
title: icd.code + '-' + icd.name,
value: icd.id
}
}))
})
.then(() => {
setLoading(false);
})
}} }}
InputProps={{ InputProps={{
...params.InputProps, ...params.InputProps,

View File

@@ -0,0 +1,80 @@
import axios from '@/utils/axios';
import { Autocomplete, TextField, CircularProgress } from '@mui/material';
import { useEffect, useMemo, useState } from 'react';
import { IcdType } from '@/@types/diagnosis';
import { Controller } from 'react-hook-form';
type autocompleteValueType = {
title: string;
value: string | number | null;
readonly: string;
};
type autocompleteDiagnosisType = {
onChange: any;
textLabel: string;
currentValue: any | null;
currentOptions: IcdType[];
};
export default function AutocompleteDiagnosisControlled({
onChange,
currentValue,
textLabel,
currentOptions = [],
}: autocompleteDiagnosisType) {
const [options, setOptions] = useState<IcdType>(currentOptions);
const [loading, setLoading] = useState(false);
function icdsToOptions(icds: IcdType[]): IcdType[] {
return icds.map(function (icd: IcdType) {
return icd;
// return {
// title: icd.code + '-' + icd.name,
// value: icd.id,
// readonly: false,
// };
});
}
// To Receive Options from Props
useEffect(() => {
setOptions(icdsToOptions(currentOptions));
}, [currentOptions]);
// useEffect(() => {
// console.log('setting Value', currentValue);
// setValue(currentValue || null);
// }, [currentValue]);
// const defaultValue = useMemo(() => currentValue, [currentValue]);
const getOptions = (search: string) => {
axios
.get('options?type=diagnosis&search=' + search)
.then((res) => {
setOptions(icdsToOptions(res.data));
})
.then(() => {
setLoading(false);
});
};
return (
<Autocomplete
options={options}
getOptionLabel={(option) => (`${option.code} - ${option.name}`)}
value={currentValue}
isOptionEqualToValue={(option, value) => option.id == value.id}
onChange={(event: any, newValue: any) => {
// setValue('primary_diagnosis_id', newValue?.id ?? null);
onChange(newValue);
}}
loading={loading}
renderInput={(params) => (
<TextField {...params} label={textLabel} variant="outlined" fullWidth onChange={(event) => {getOptions(event.target.value)}}/>
)}
/>
);
}

View File

@@ -66,7 +66,7 @@ const navConfig = [
// ], // ],
}, },
{ {
title: 'CASE MANAGEMENT', title: 'CLAIM MANAGEMENT',
path: '/claims', path: '/claims',
// children: [ // children: [
// { title: 'Request', path: '/case-request' }, // { title: 'Request', path: '/case-request' },

View File

@@ -39,6 +39,7 @@ import DiagnosisHistory from './components/DiagnosisHistory';
import ClaimItems from './components/ClaimItems'; import ClaimItems from './components/ClaimItems';
import DialogMemberBenefit from './components/DialogMemberBenefit'; import DialogMemberBenefit from './components/DialogMemberBenefit';
import AutocompleteDiagnosis from '@/components/autocomplete/AutocompleteDiagnosis'; import AutocompleteDiagnosis from '@/components/autocomplete/AutocompleteDiagnosis';
import AutocompleteDiagnosisControlled from '@/components/autocomplete/AutocompleteDiagnosisControlled';
export default function ClaimsCreateUpdate() { export default function ClaimsCreateUpdate() {
const { themeStretch } = useSettings(); const { themeStretch } = useSettings();
@@ -97,9 +98,17 @@ export default function ClaimsCreateUpdate() {
const [primaryDiagnosis, setPrimaryDiagnosis] = useState(null); const [primaryDiagnosis, setPrimaryDiagnosis] = useState(null);
const [secondaryDiagnosis, setSecondaryDiagnosis] = useState(null); const [secondaryDiagnosis, setSecondaryDiagnosis] = useState(null);
const [loadingDiagnosis, setLoadingDiagnosis] = useState(false); const [loadingDiagnosis, setLoadingDiagnosis] = useState(false);
const [primaryDiagnosisOptions, setPrimaryDiagnosisOptions] = useState([]);
const [secondaryDiagnosisOptions, setSecondaryDiagnosisOptions] = useState([]);
const handlePrimaryDiagnosisChange = ({ title, value }) => { const handlePrimaryDiagnosisChange = (diagnosisOption) => {
setPrimaryDiagnosis(value); console.log('handle', diagnosisOption);
if (diagnosisOption) {
const { title, value } = diagnosisOption;
setPrimaryDiagnosis(value);
} else {
setPrimaryDiagnosis(null);
}
}; };
const handleSecondaryDiagnosisChange = ({ title, value }) => { const handleSecondaryDiagnosisChange = ({ title, value }) => {
@@ -174,48 +183,84 @@ export default function ClaimsCreateUpdate() {
}); });
}; };
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Initial LOG // Initial LOG
const [loadingLog, setLoadingLog] = useState(false) const [loadingLog, setLoadingLog] = useState(false);
const handleDownloadLog = (claim_id) => { const handleDownloadLog = (claim_id) => {
setLoadingLog(true); setLoadingLog(true);
axios axios
.post(`generate-log/${claim_id}`, { .post(`generate-log/${claim_id}`, {
responseType: 'blob', responseType: 'blob',
}) })
.then((response) => { .then((response) => {
window.open(URL.createObjectURL(response.data)); window.open(URL.createObjectURL(response.data));
setLoadingLog(false); setLoadingLog(false);
setOpenDialog(false); setOpenDialog(false);
}) })
.catch((response) => { .catch((response) => {
enqueueSnackbar(response.message, { variant: 'error' }); enqueueSnackbar(response.message, { variant: 'error' });
setLoadingLog(false); setLoadingLog(false);
}); });
} };
// ------------------------------------------------- // -------------------------------------------------
// Final LOG // Final LOG
const [loadingFinalLog, setLoadingFinalLog] = useState(false) const [loadingFinalLog, setLoadingFinalLog] = useState(false);
const handleDownloadFinalLog = (claim_id) => { const handleDownloadFinalLog = (claim_id) => {
setLoadingFinalLog(true); setLoadingFinalLog(true);
axios axios
.get(`final-log/${claim_id}`, { .get(`final-log/${claim_id}`, {
responseType: 'blob', responseType: 'blob',
}) })
.then((response) => { .then((response) => {
window.open(URL.createObjectURL(response.data)); window.open(URL.createObjectURL(response.data));
setLoadingFinalLog(false); setLoadingFinalLog(false);
}) })
.catch((response) => { .catch((response) => {
enqueueSnackbar(response.message, { variant: 'error' }); enqueueSnackbar(response.message, { variant: 'error' });
setLoadingFinalLog(false); setLoadingFinalLog(false);
}); });
};
// ---------------------------------------------------
// Primary ICD
const NewCorporateSchema = Yup.object().shape({
primary_diagnosis_id: Yup.string().required('Name is required'),
});
interface FormValuesProps extends Partial<any> {
primary_diagnosis_id: number;
} }
const defaultValues = useMemo(
() => ({
primary_diagnosis: currentClaim?.primary_diagnosis[0]?.icd ?? null,
secondary_diagnosis: currentClaim?.secondary_diagnosis[0]?.icd ?? null
}),
[currentClaim]
);
const methods = useForm<FormValuesProps>({
resolver: yupResolver(NewCorporateSchema),
defaultValues,
});
const {
reset,
watch,
control,
setValue,
getValues,
setError,
handleSubmit,
formState: { isSubmitting },
} = methods;
const values = watch();
// ----------------------------------------------------------------
useEffect(() => { useEffect(() => {
axios.get('/claims/' + id).then(({ data }) => { axios.get('/claims/' + id).then(({ data }) => {
@@ -225,6 +270,30 @@ export default function ClaimsCreateUpdate() {
setCurrentClaim(claim); setCurrentClaim(claim);
setDocuments(allFiles); setDocuments(allFiles);
setClaimItems(claim.benefit_items); setClaimItems(claim.benefit_items);
// SET Default Primary Diagnosis
if (claim.primary_diagnosis.length && claim.primary_diagnosis[0].icd) {
setPrimaryDiagnosisOptions(
claim.primary_diagnosis.map((diagnosis) => {
if (diagnosis.icd) {
return diagnosis.icd;
}
})
);
setValue('primary_diagnosis', claim.primary_diagnosis[0].icd);
}
// SET Default Secondary Diagnosis
if (claim.secondary_diagnosis.length && claim.secondary_diagnosis[0].icd) {
setSecondaryDiagnosisOptions(
claim.secondary_diagnosis.map((diagnosis) => {
if (diagnosis.icd) {
return diagnosis.icd;
}
})
);
setValue('secondary_diagnosis', claim.secondary_diagnosis[0].icd)
}
}); });
}, [id]); }, [id]);
@@ -280,24 +349,22 @@ export default function ClaimsCreateUpdate() {
Re-Open Re-Open
</LoadingButton> </LoadingButton>
)} )}
</Stack> </Stack>
</Stack> </Stack>
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2, marginY: 2 }}> <Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2, marginY: 2 }}>
<Stack direction="row" justifyContent="space-between" alignItems="center"> <Stack direction="row" justifyContent="space-between" alignItems="center">
<Typography>Status : {currentClaim?.status}</Typography> <Typography>Status : {currentClaim?.status}</Typography>
{ currentClaim?.status == 'approved' && ( {currentClaim?.status == 'approved' && (
<LoadingButton <LoadingButton
loading={loadingFinalLog} loading={loadingFinalLog}
variant="contained" variant="contained"
onClick={() => { onClick={() => {
handleDownloadFinalLog(currentClaim.id); handleDownloadFinalLog(currentClaim.id);
}} }}
> >
Download Final LOG Download Final LOG
</LoadingButton> </LoadingButton>
)} )}
</Stack> </Stack>
</Paper> </Paper>
@@ -381,35 +448,46 @@ export default function ClaimsCreateUpdate() {
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2 }}> <Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2 }}>
<Paper variant="outlined" sx={{ background: 'white', p: 2 }}> <Paper variant="outlined" sx={{ background: 'white', p: 2 }}>
<Stack spacing={2}> <Stack spacing={2}>
<AutocompleteDiagnosis {/* {JSON.stringify(getValues('primary_diagnosis'))} */}
onChange={handlePrimaryDiagnosisChange} <Controller
textLabel="Diagnosa Utama (ICD-X)" name="primary_diagnosis"
currentValue={ control={control}
currentClaim?.primary_diagnosis ? currentClaim?.primary_diagnosis : null render={({ field: { onChange, value } }) => (
} <AutocompleteDiagnosisControlled
></AutocompleteDiagnosis> onChange={onChange}
<AutocompleteDiagnosis currentOptions={primaryDiagnosisOptions}
onChange={handleSecondaryDiagnosisChange} currentValue={value}
textLabel="Diagnosa Tambahan (ICD-X)" textLabel="Diagnosis Utama (ICD-X)"
currentValue={ />
currentClaim?.secondary_diagnosis ? currentClaim?.secondary_diagnosis : null )}
} />
></AutocompleteDiagnosis>
<Controller
name="secondary_diagnosis"
control={control}
render={({ field: { onChange, value } }) => (
<AutocompleteDiagnosisControlled
onChange={onChange}
currentOptions={secondaryDiagnosisOptions}
currentValue={value}
textLabel="Diagnosis Tambahan (ICD-X)"
/>
)}
/>
</Stack> </Stack>
</Paper> </Paper>
{(currentClaim?.status == 'requested' || currentClaim?.status == 'received') && ( {(currentClaim?.status == 'requested' || currentClaim?.status == 'received') && (
<LoadingButton
<LoadingButton variant="contained"
variant="contained" sx={{ marginTop: 2 }}
sx={{ marginTop: 2 }} loading={loadingDiagnosis}
loading={loadingDiagnosis} onClick={() => {
onClick={() => { handleSaveDiagnosis();
handleSaveDiagnosis(); }}
}} >
> Simpan Diagnosa
Simpan Claim Item </LoadingButton>
</LoadingButton>
)} )}
</Paper> </Paper>
@@ -426,20 +504,18 @@ Simpan Claim Item
</Stack> </Stack>
<ClaimItems items={claimItems} setItems={setClaimItems}></ClaimItems> <ClaimItems items={claimItems} setItems={setClaimItems}></ClaimItems>
<Stack alignItems={'flex-end'}> <Stack alignItems={'flex-end'}>
{(currentClaim?.status == 'requested' || currentClaim?.status == 'received') && (
{(currentClaim?.status == 'requested' || currentClaim?.status == 'received') && ( <LoadingButton
variant="contained"
<LoadingButton sx={{ marginTop: 2 }}
variant="contained" loading={loadingClaimItems}
sx={{ marginTop: 2 }} onClick={() => {
loading={loadingClaimItems} handleSaveClaimItems();
onClick={() => { }}
handleSaveClaimItems(); >
}} Simpan Claim Item
> </LoadingButton>
Simpan Claim Item )}
</LoadingButton>
)}
</Stack> </Stack>
<DialogMemberBenefit <DialogMemberBenefit