Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate page for patient consent records #7882

Merged
merged 15 commits into from
May 24, 2024
2 changes: 1 addition & 1 deletion src/Common/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1308,7 +1308,7 @@ export const CONSENT_PATIENT_CODE_STATUS_CHOICES = [
{ id: 1, text: "Do Not Hospitalise (DNH)" },
{ id: 2, text: "Do Not Resuscitate (DNR)" },
{ id: 3, text: "Comfort Care Only" },
{ id: 4, text: "Active treatment (Default)" },
{ id: 4, text: "Active treatment" },
];
export const OCCUPATION_TYPES = [
{
Expand Down
207 changes: 5 additions & 202 deletions src/Components/Facility/ConsultationForm.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import * as Notification from "../../Utils/Notifications.js";

import { BedModel, FacilityModel } from "./models";
import { BedModel, ConsentRecord, FacilityModel } from "./models";
import {
CONSULTATION_SUGGESTION,
DISCHARGE_REASONS,
ConsultationSuggestionValue,
PATIENT_CATEGORIES,
REVIEW_AT_CHOICES,
TELEMEDICINE_ACTIONS,
CONSENT_TYPE_CHOICES,
CONSENT_PATIENT_CODE_STATUS_CHOICES,
} from "../../Common/constants";
import { Cancel, Submit } from "../Common/components/ButtonV2";
import { DraftSection, useAutoSaveReducer } from "../../Utils/AutoSave";
Expand Down Expand Up @@ -59,8 +57,6 @@ import {
CreateDiagnosesBuilder,
EditDiagnosesBuilder,
} from "../Diagnosis/ConsultationDiagnosisBuilder/ConsultationDiagnosisBuilder.js";
import { FileUpload } from "../Patient/FileUpload.js";
import ConfirmDialog from "../Common/ConfirmDialog.js";
import request from "../../Utils/request/request.js";
import routes from "../../Redux/api.js";
import useQuery from "../../Utils/request/useQuery.js";
Expand All @@ -71,13 +67,6 @@ const PageTitle = lazy(() => import("../Common/PageTitle"));

type BooleanStrings = "true" | "false";

export type ConsentRecord = {
id: string;
type: (typeof CONSENT_TYPE_CHOICES)[number]["id"];
patient_code_status?: (typeof CONSENT_PATIENT_CODE_STATUS_CHOICES)[number]["id"];
deleted?: boolean;
};

type FormDetails = {
symptoms: number[];
other_symptoms: string;
Expand Down Expand Up @@ -125,6 +114,7 @@ type FormDetails = {
death_datetime: string;
death_confirmed_doctor: string;
InvestigationAdvice: InvestigationType[];
procedures: ProcedureType[];
consent_records: ConsentRecord[];
};

Expand Down Expand Up @@ -175,6 +165,7 @@ const initForm: FormDetails = {
death_datetime: "",
death_confirmed_doctor: "",
InvestigationAdvice: [],
procedures: [],
consent_records: [],
};

Expand Down Expand Up @@ -226,7 +217,6 @@ type ConsultationFormSection =
| "Consultation Details"
| "Diagnosis"
| "Treatment Plan"
| "Consent Records"
| "Bed Status";

type Props = {
Expand Down Expand Up @@ -259,14 +249,8 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => {
const [diagnosisVisible, diagnosisRef] = useVisibility(-300);
const [treatmentPlanVisible, treatmentPlanRef] = useVisibility(-300);
const [bedStatusVisible, bedStatusRef] = useVisibility(-300);
const [consentRecordsVisible, consentRecordsRef] = useVisibility(-300);

const [disabledFields, setDisabledFields] = useState<string[]>([]);
const [collapsedConsentRecords, setCollapsedConsentRecords] = useState<
number[]
>([]);
const [showDeleteConsent, setShowDeleteConsent] = useState<string | null>(
null,
);

const { min_encounter_date } = useConfig();

Expand All @@ -286,11 +270,6 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => {
visible: treatmentPlanVisible,
ref: treatmentPlanRef,
},
"Consent Records": {
iconClass: "l-file-alt",
visible: consentRecordsVisible,
ref: consentRecordsRef,
},
"Bed Status": {
iconClass: "l-bed",
visible: bedStatusVisible,
Expand All @@ -303,15 +282,13 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => {
if (consultationDetailsVisible) return "Consultation Details";
if (diagnosisVisible) return "Diagnosis";
if (treatmentPlanVisible) return "Treatment Plan";
if (consentRecordsVisible) return "Consent Records";
if (bedStatusVisible) return "Bed Status";
return prev;
});
}, [
consultationDetailsVisible,
diagnosisVisible,
treatmentPlanVisible,
consentRecordsVisible,
bedStatusVisible,
]);

Expand Down Expand Up @@ -769,7 +746,6 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => {
height: Number(state.form.height),
bed: bed && bed instanceof Array ? bed[0]?.id : bed?.id,
patient_no: state.form.patient_no || null,
consent_records: state.form.consent_records || [],
};

const { data: obj } = await request(
Expand Down Expand Up @@ -917,64 +893,6 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => {
};
};

const handleConsentTypeChange: FieldChangeEventHandler<number> = async (
event,
) => {
if (!id) return;
const consentRecords = [...state.form.consent_records];
if (
consentRecords
.filter((cr) => cr.deleted !== true)
.map((cr) => cr.type)
.includes(event.value)
) {
return;
} else {
const randomId = "consent-" + new Date().getTime().toString();
const newRecords = [
...consentRecords,
{ id: randomId, type: event.value },
];
await request(routes.partialUpdateConsultation, {
pathParams: { id },
body: { consent_records: newRecords },
});
dispatch({
type: "set_form",
form: { ...state.form, consent_records: newRecords },
});
}
};

const handleConsentPCSChange: FieldChangeEventHandler<number> = (event) => {
dispatch({
type: "set_form",
form: {
...state.form,
consent_records: state.form.consent_records.map((cr) =>
cr.type === 2 ? { ...cr, patient_code_status: event.value } : cr,
),
},
});
};

const handleDeleteConsent = async () => {
const consent_id = showDeleteConsent;
if (!consent_id || !id) return;
const newRecords = state.form.consent_records.map((cr) =>
cr.id === consent_id ? { ...cr, deleted: true } : cr,
);
await request(routes.partialUpdateConsultation, {
pathParams: { id },
body: { consent_records: newRecords },
});
dispatch({
type: "set_form",
form: { ...state.form, consent_records: newRecords },
});
setShowDeleteConsent(null);
};

return (
<div className="relative flex flex-col pb-2">
<PageTitle
Expand All @@ -994,10 +912,7 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => {
<div className="top-0 mt-5 flex grow-0 sm:mx-12">
<div className="fixed hidden h-full w-72 flex-col xl:flex">
{Object.keys(sections).map((sectionTitle) => {
if (
!isUpdate &&
["Bed Status", "Consent Records"].includes(sectionTitle)
) {
if (!isUpdate && ["Bed Status"].includes(sectionTitle)) {
return null;
}
const isCurrent = currentSection === sectionTitle;
Expand Down Expand Up @@ -1551,118 +1466,6 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => {
</>
)}
</div>
{id && (
<>
<div className="flex flex-col gap-4 pb-4">
{sectionTitle("Consent Records", true)}
</div>
<ConfirmDialog
show={showDeleteConsent !== null}
onClose={() => setShowDeleteConsent(null)}
onConfirm={handleDeleteConsent}
action="Delete"
variant="danger"
description={
"Are you sure you want to delete this consent record?"
}
title="Delete Consent"
className="w-auto"
/>
<SelectFormField
{...selectField("consent_type")}
onChange={handleConsentTypeChange}
label="Add Consent Type"
options={CONSENT_TYPE_CHOICES.filter(
(c) =>
!state.form.consent_records
.filter((r) => r.deleted !== true)
.map((record) => record.type)
.includes(c.id),
)}
/>
<div className="flex flex-col gap-4">
{state.form.consent_records
.filter((record) => record.deleted !== true)
.map((record, index) => (
<div
className="overflow-hidden rounded-xl border border-gray-300 bg-gray-100"
key={index}
>
<div className="flex items-center justify-between bg-gray-200 p-4">
<button
type="button"
className="font-bold"
onClick={() =>
setCollapsedConsentRecords((prev) =>
prev.includes(record.type)
? prev.filter((r) => r !== record.type)
: [...prev, record.type],
)
}
>
<CareIcon
icon={
collapsedConsentRecords.includes(
record.type,
)
? "l-arrow-down"
: "l-arrow-up"
}
className="mr-2"
/>
{
CONSENT_TYPE_CHOICES.find(
(c) => c.id === record.type,
)?.text
}
</button>
<button
className="text-red-400"
type="button"
onClick={() => {
setShowDeleteConsent(record.id);
}}
>
<CareIcon
icon="l-trash-alt"
className="h-4 w-4"
/>
</button>
</div>
<div
className={`${
collapsedConsentRecords.includes(record.type)
? "hidden"
: ""
}`}
>
<div className="px-4 pt-4">
{record.type === 2 && (
<SelectFormField
{...selectField("consent_type")}
onChange={handleConsentPCSChange}
label="Patient Code Status"
value={record.patient_code_status}
options={
CONSENT_PATIENT_CODE_STATUS_CHOICES
}
/>
)}
</div>
<FileUpload
changePageMetadata={false}
type="CONSENT_RECORD"
hideBack
unspecified
className="w-full"
consentId={record.id}
/>
</div>
</div>
))}
</div>
</>
)}
<div className="mt-6 flex flex-col justify-end gap-3 sm:flex-row">
<Cancel
onClick={() =>
Expand Down
10 changes: 9 additions & 1 deletion src/Components/Facility/models.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {
CONSENT_PATIENT_CODE_STATUS_CHOICES,
CONSENT_TYPE_CHOICES,
ConsultationSuggestionValue,
DISCHARGE_REASONS,
PATIENT_NOTES_THREADS,
Expand All @@ -12,7 +14,6 @@ import { ConsultationDiagnosis, CreateDiagnosis } from "../Diagnosis/types";
import { NormalPrescription, PRNPrescription } from "../Medicine/models";
import { AssignedToObjectModel, DailyRoundsModel } from "../Patient/models";
import { UserBareMinimum } from "../Users/models";
import { ConsentRecord } from "./ConsultationForm";

export interface LocalBodyModel {
id: number;
Expand Down Expand Up @@ -97,6 +98,13 @@ export interface OptionsType {

export type PatientCategory = "Comfort Care" | "Mild" | "Moderate" | "Critical";

export type ConsentRecord = {
id: string;
type: (typeof CONSENT_TYPE_CHOICES)[number]["id"];
patient_code_status?: (typeof CONSENT_PATIENT_CODE_STATUS_CHOICES)[number]["id"];
deleted?: boolean;
};

export interface ConsultationModel {
encounter_date: string;
icu_admission_date?: string;
Expand Down
5 changes: 3 additions & 2 deletions src/Components/Patient/FileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const header_content_type: URLS = {
};

// Array of image extensions
const ExtImage: string[] = [
export const ExtImage: string[] = [
"jpeg",
"jpg",
"png",
Expand Down Expand Up @@ -119,12 +119,13 @@ interface URLS {
[id: string]: string;
}

interface ModalDetails {
export interface ModalDetails {
name?: string;
id?: string;
reason?: string;
userArchived?: string;
archiveTime?: any;
associatedId?: string;
}

export interface StateInterface {
Expand Down