[WIP] Claim Encounters

This commit is contained in:
R
2023-03-24 14:41:02 +07:00
parent 229908e492
commit 7b9a341ccd
23 changed files with 1099 additions and 37 deletions

View File

@@ -21,19 +21,19 @@ export default function DiagnosisHistory({ diagnosis }) {
<Paper variant="outlined" sx={{ background: '#f4f6f8', p: 2, marginTop: 2 }}>
<Stack direction="row" justifyContent="space-between" alignItems="center">
<Stack direction="row" alignItems="center" spacing={1}>
<Iconify icon="eva:bell-fill" />
<Iconify icon="eva:clock-outline" />
<Typography variant="body2" fontWeight={600}>
Riwayat Diagnosa
</Typography>
</Stack>
<Typography
{/* <Typography
variant="body2"
onClick={() => {
setOpenDialogRequestDocument(true);
}}
>
View All
</Typography>
</Typography> */}
</Stack>
<Paper sx={{ background: 'white', marginTop: 2 }}>

View File

@@ -0,0 +1,73 @@
import MuiDialog from '@/components/MuiDialog';
import axios from '@/utils/axios';
import { Button, Checkbox, Typography } from '@mui/material';
import { Paper } from '@mui/material';
import { Stack } from '@mui/material';
import { enqueueSnackbar } from 'notistack';
import { useState } from 'react';
import FormHistoryPerawatan from './FormHistoryPerawatan';
type DialogHistoryPerawatanType = {
openDialog: boolean;
setOpenDialog: void;
onSubmit?: void;
claim: any; // TODO create ClaimType
encounter?: any;
}
export default function DialogHistoryPerawatan({ openDialog, setOpenDialog, onSubmit, claim, encounter } : DialogHistoryPerawatanType) {
const isEdit = encounter?.id != null
// const benefits = member?.current_plan?.benefits ?? [];
// const [selectedBenefits, setSelectedBenefits] = useState([]);
// const toggleBenefit = (benefit) => {
// if (selectedBenefits.includes(benefit)) {
// console.log('removing', benefit)
// setSelectedBenefits(selectedBenefits.filter((throughBenefit) => benefit.id != throughBenefit.id))
// } else {
// console.log('adding', benefit)
// setSelectedBenefits([...selectedBenefits, benefit])
// }
// }
const handleSubmit = (data) => {
if (!isEdit) {
axios.post(`claims/${claim.id}/encounters`, data)
.then((res) => {
enqueueSnackbar(res.data.message, {variant: 'success'})
setOpenDialog(false);
})
.catch((err) => {
enqueueSnackbar(err.message, {variant: 'error'})
})
} else {
axios.post(`claims/${claim.id}/encounters/${data.id}/update`, data)
.then((res) => {
enqueueSnackbar(res.data.message, {variant: 'success'})
setOpenDialog(false);
})
.catch((err) => {
enqueueSnackbar(err.message, {variant: 'error'})
})
}
};
const getContent = () => (
<Stack spacing={1} marginTop={2}>
<FormHistoryPerawatan claim={claim} onSubmit={handleSubmit} encounter={encounter}></FormHistoryPerawatan>
</Stack>
);
return (
<MuiDialog
title={{ name: !isEdit ? 'Tambah History Perawatan' : 'Edit History Perawatan' }}
openDialog={openDialog}
setOpenDialog={setOpenDialog}
content={getContent()}
maxWidth="xl"
/>
);
}

View File

@@ -0,0 +1,352 @@
import * as Yup from 'yup';
import { IcdType } from '@/@types/diagnosis';
import { OrganizationType, PractitionerType } from '@/@types/doctor';
import AutocompleteDiagnosisControlled from '@/components/autocomplete/AutocompleteDiagnosisControlled';
import { LoadingButton } from '@mui/lab';
import { Paper, Stack, TextField } from '@mui/material';
import { Controller, useForm } from 'react-hook-form';
import React, { useEffect, useMemo, useState } from 'react';
import { yupResolver } from '@hookform/resolvers/yup';
import { enqueueSnackbar } from 'notistack';
import axios from '@/utils/axios';
import { FormProvider, RHFDatepicker, RHFTextField, RHFSelect } from '@/components/hook-form';
import AutocompleteDoctor from '@/components/autocomplete/AutocompleteDoctor';
import AutocompleteHealthcare from '@/components/autocomplete/AutocompleteHealthcare';
import { Typography } from '@mui/material';
import Iconify from '@/components/Iconify';
import { Divider } from '@mui/material';
type FormHistoryPerawatanProps = {
claim: any;
onSubmit: void;
encounter?: any; // TODO EncounterType
};
export default function FormHistoryPerawatan({
claim,
onSubmit,
encounter,
}: FormHistoryPerawatanProps) {
const isEdit = encounter?.id != null;
// --------------------------------------------------------------
// Diagnosis
const [primaryDiagnosis, setPrimaryDiagnosis] = useState(null);
const [secondaryDiagnosis, setSecondaryDiagnosis] = useState(null);
const [loadingDiagnosis, setLoadingDiagnosis] = useState(false);
const [primaryDiagnosisOptions, setPrimaryDiagnosisOptions] = useState([]);
const [secondaryDiagnosisOptions, setSecondaryDiagnosisOptions] = useState([]);
const [doctorOptions, setDoctorOptions] = useState([]);
const [healthcareOptions, setHealthcareOptions] = useState([]);
const ClaimDetailSchema = Yup.object().shape({
primary_diagnosis: Yup.object().required('Diagnosis Utama Wajib dipilih'),
// secondary_diagnosis: Yup.object().required('Diagnosis Utama Wajib dipilih'),
doctor: Yup.object().required('Dokter Harus dipilih'),
healthcare: Yup.object().required('Healthcare Harus dipilih'),
});
interface FormValuesProps extends Partial<any> {
service_code: String;
primary_diagnosis: IcdType;
secondary_diagnosis: IcdType;
doctor: PractitionerType;
healthcare: OrganizationType;
secondary_diagnoses: IcdType[];
}
const defaultValues = useMemo(
() => ({
service_code: 'OP',
tanggal_masuk: null,
tanggal_keluar: null,
primary_diagnosis: null,
doctor: null,
healthcare: null,
no_medrec: '',
bed: '',
duration: '',
secondary_diagnoses: [],
}),
[claim]
);
const methods = useForm<FormValuesProps>({
resolver: yupResolver(ClaimDetailSchema),
defaultValues,
});
const {
reset,
watch,
control,
setValue,
getValues,
setError,
handleSubmit,
formState: { isSubmitting },
} = methods;
const values = watch();
const handleSaveDiagnosis = () => {
setLoadingDiagnosis(true);
axios
.post(`claims/${claim.id}/update-diagnosis`, {
primary: [getValues('primary_diagnosis')?.id],
secondary: [getValues('secondary_diagnosis')?.id],
})
.then((res) => {
enqueueSnackbar(res.data.message, { variant: 'success' });
})
.catch((err) => {
setLoadingDiagnosis(false);
enqueueSnackbar(err.response?.data?.message ?? err?.message, { variant: 'error' });
})
.then(() => {
setLoadingDiagnosis(false);
});
};
useEffect(() => {
if (claim) {
// 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);
// }
}
}, [claim]);
useEffect(() => {
if (encounter?.id) {
// Primary Diagnosis
if (encounter.primary_diagnosis && encounter.primary_diagnosis?.diagnosis) {
setPrimaryDiagnosisOptions([encounter.primary_diagnosis.diagnosis]);
setValue('primary_diagnosis', encounter.primary_diagnosis.diagnosis);
}
// Sondary Diagnoses
if (encounter.secondary_diagnoses && encounter.secondary_diagnoses.length) {
encounter.secondary_diagnoses.map();
setPrimaryDiagnosisOptions([encounter.primary_diagnosis.diagnosis]);
setValue('primary_diagnosis', encounter.primary_diagnosis.diagnosis);
}
if (encounter.primary_doctor) {
// TODO Clear Up Data to used by autocomplete
setDoctorOptions([encounter.primary_doctor]);
setValue('doctor', encounter.primary_doctor);
}
if (encounter.healthcare) {
// TODO Clear Up Data to used by autocomplete
setDoctorOptions([encounter.healthcare]);
setValue('healthcare', encounter.healthcare);
}
setValue('service_code', encounter.class);
setValue('tanggal_masuk', encounter.start);
setValue('tanggal_keluar', encounter.end);
setValue('medical_record_number', encounter.medical_record_number);
setValue('number_of_bed', encounter.number_of_bed);
setValue('duration_day', encounter.duration_day);
setValue('secondary_diagnoses', encounter.secondary_diagnosis);
setValue('id', encounter.id);
}
}, [encounter]);
function handleAddSecondaryDiagnosis() {
setValue('secondary_diagnoses', [...getValues('secondary_diagnoses'), null]);
}
function handleRemoveSecondaryDiagnosis(diagnosis) {
// TODO Fix Bug
const newDiagnoses = getValues('secondary_diagnoses').filter((val) => {
return diagnosis !== val;
});
setValue('secondary_diagnoses', newDiagnoses);
}
const services = [
{
code: 'OP',
name: 'Rawat Jalan',
},
{
code: 'IP',
name: 'Rawat Inap',
},
];
const submitting = () => {
onSubmit(getValues());
};
return (
<FormProvider methods={methods} onSubmit={handleSubmit(submitting)}>
<Stack spacing={2}>
<Stack spacing={2} sx={{ background: 'white', p: 2 }}>
<RHFSelect name="service_code" label="Layanan" placeholder="Layanan">
{/* <option value="" /> */}
{services.map((option, index) => (
<option key={index} value={option.code}>
{option.name}
</option>
))}
</RHFSelect>
<RHFDatepicker
name="tanggal_masuk"
placeholder="DD/MM/YYYY"
label="Tanggal Masuk"
></RHFDatepicker>
<RHFDatepicker
name="tanggal_keluar"
placeholder="DD/MM/YYYY"
label="Tanggal Keluar"
></RHFDatepicker>
<Controller
name="healthcare"
control={control}
render={({ field: { onChange, value } }) => (
<AutocompleteHealthcare
onChange={onChange}
currentOptions={healthcareOptions}
currentValue={value}
textLabel="Tempat Dirawat"
placeholder="Ketik nama fasilitas kesehatan"
/>
)}
/>
<Controller
name="doctor"
control={control}
render={({ field: { onChange, value } }) => (
<AutocompleteDoctor
onChange={onChange}
currentOptions={doctorOptions}
currentValue={value}
textLabel="Dokter yang merawat"
placeholder="Ketik nama dokter"
/>
)}
/>
<RHFTextField
name="medical_record_number"
placeholder='"No. Rekam Medis" di fasilitas kesehatan'
label="No. Rekam Medis"
></RHFTextField>
<RHFTextField name="number_of_bed" label="Jumlah Tempat Tidur"></RHFTextField>
<RHFTextField name="duration_day" label="Lama Perawatan (hari)"></RHFTextField>
</Stack>
<Paper variant="outlined" sx={{ background: 'white', p: 2 }}>
<Stack spacing={2}>
{/* {JSON.stringify(getValues('primary_diagnosis'))} */}
<Controller
name="primary_diagnosis"
control={control}
render={({ field: { onChange, value } }) => (
<AutocompleteDiagnosisControlled
onChange={onChange}
currentOptions={primaryDiagnosisOptions}
currentValue={value}
textLabel="Diagnosis Utama (ICD-X)"
/>
)}
/>
{/* SECONDARY DIAGNOSES */}
<Stack direction="row" justifyContent="end">
<Typography
onClick={() => {
handleAddSecondaryDiagnosis();
}}
>
+ Secondary Diagnosis
</Typography>
</Stack>
{getValues('secondary_diagnoses') &&
getValues('secondary_diagnoses').map(function (diagnosis, index) {
return (
<React.Fragment key={index}>
{/* <Stack direction="row" sx={{ width: '100%'}}> */}
<Stack
direction="row"
justifyContent="space-between"
alignItems="center"
divider={<Divider orientation="horizontal" flexItem />}
>
<Typography>
<strong>#{index + 1}</strong>
</Typography>
<Iconify
icon="eva-trash-outline"
color="red"
onClick={() => {
handleRemoveSecondaryDiagnosis(diagnosis);
}}
></Iconify>
</Stack>
<Controller
name={`secondary_diagnoses[${index}]`}
control={control}
sx={{ width: '100%' }}
render={({ field: { onChange, value } }) => (
<AutocompleteDiagnosisControlled
onChange={onChange}
currentOptions={[diagnosis]}
currentValue={value}
textLabel="Diagnosis Tambahan (ICD-X)"
/>
)}
/>
{/* </Stack> */}
</React.Fragment>
);
})}
</Stack>
</Paper>
{(claim?.status == 'requested' || claim?.status == 'received') && (
<LoadingButton
variant="contained"
sx={{ marginTop: 2 }}
loading={loadingDiagnosis}
onClick={() => {
submitting();
}}
>
Simpan Detail
</LoadingButton>
)}
</Stack>
</FormProvider>
);
}