diff --git a/src/Components/Common/FacilitySelect.tsx b/src/Components/Common/FacilitySelect.tsx index ac098cc2127..2b820b40d6a 100644 --- a/src/Components/Common/FacilitySelect.tsx +++ b/src/Components/Common/FacilitySelect.tsx @@ -9,7 +9,9 @@ interface FacilitySelectProps { exclude_user?: string; errors?: string | undefined; className?: string; + required?: boolean; searchAll?: boolean; + disabled?: boolean; multiple?: boolean; facilityType?: number; district?: string; @@ -25,10 +27,12 @@ export const FacilitySelect = (props: FacilitySelectProps) => { const { name, exclude_user, + required, multiple, selected, setSelected, searchAll, + disabled = false, showAll = true, showNOptions = 10, className = "", @@ -69,8 +73,10 @@ export const FacilitySelect = (props: FacilitySelectProps) => { return ( void; consultationData: ConsultationModel; + referred_to?: FacilityModel | null; afterSubmit?: () => void; new_discharge_reason?: number | null; - discharge_notes?: string; discharge_date?: string; death_datetime?: string; } @@ -53,7 +53,7 @@ const DischargeModal = ({ consultationData, afterSubmit, new_discharge_reason = null, - discharge_notes = "", + referred_to = null, discharge_date = dayjs().format("YYYY-MM-DDTHH:mm"), death_datetime = dayjs().format("YYYY-MM-DDTHH:mm"), }: IProps) => { @@ -62,18 +62,40 @@ const DischargeModal = ({ const [preDischargeForm, setPreDischargeForm] = useState({ new_discharge_reason, - discharge_notes, + discharge_notes: referred_to + ? "Patient Shifted to another facility." + : "", discharge_date, death_datetime, death_confirmed_doctor: undefined, - referred_to_external: null, + referred_to_external: !referred_to?.id ? referred_to?.name : null, + referred_to: referred_to?.id ? referred_to.id : null, }); const [latestClaim, setLatestClaim] = useState(); const [isCreateClaimLoading, setIsCreateClaimLoading] = useState(false); const [isSendingDischargeApi, setIsSendingDischargeApi] = useState(false); - const [facility, setFacility] = useState(); + const [facility, setFacility] = useState(referred_to); const [errors, setErrors] = useState({}); + useEffect(() => { + setPreDischargeForm((prev) => ({ + ...prev, + new_discharge_reason, + discharge_notes: referred_to + ? "Patient Shifted to another facility." + : "", + discharge_date, + death_datetime, + referred_to_external: !referred_to?.id ? referred_to?.name : null, + referred_to: referred_to?.id ? referred_to.id : null, + })); + + setFacility(referred_to); + }, [referred_to, new_discharge_reason, discharge_date, death_datetime]); + + const discharge_reason = + new_discharge_reason ?? preDischargeForm.new_discharge_reason; + const fetchLatestClaim = useCallback(async () => { const res = await dispatch( HCXActions.claims.list({ @@ -111,7 +133,7 @@ const DischargeModal = ({ const handlePatientDischarge = async (value: boolean) => { setIsSendingDischargeApi(true); - if (!preDischargeForm.new_discharge_reason) { + if (!new_discharge_reason && !discharge_reason) { setErrors({ ...errors, new_discharge_reason: "Please select a reason for discharge", @@ -121,8 +143,7 @@ const DischargeModal = ({ } if ( - preDischargeForm.new_discharge_reason == - DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id + discharge_reason == DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id ) { const newErrors: Record = {}; @@ -143,6 +164,7 @@ const DischargeModal = ({ const dischargeDetails = { ...preDischargeForm, discharge: value, + referred_to: referred_to?.id ?? preDischargeForm.referred_to, discharge_date: dayjs(preDischargeForm.discharge_date).toISOString(), }; @@ -157,6 +179,7 @@ const DischargeModal = ({ { ...preDischargeForm, discharge: value, + new_discharge_reason: discharge_reason, discharge_date: dayjs(preDischargeForm.discharge_date).toISOString(), }, { id: consultationData.id }, @@ -174,7 +197,7 @@ const DischargeModal = ({ }; const handleFacilitySelect = (selected?: FacilityModel) => { - setFacility(selected); + setFacility(selected ?? null); setPreDischargeForm((prev) => ({ ...prev, referred_to: selected?.id ?? null, @@ -203,7 +226,7 @@ const DischargeModal = ({ label="Reason" name="discharge_reason" id="discharge_reason" - value={preDischargeForm.new_discharge_reason} + value={discharge_reason} disabled={!!new_discharge_reason} options={DISCHARGE_REASONS} optionValue={({ id }) => id} @@ -216,36 +239,35 @@ const DischargeModal = ({ } error={errors?.new_discharge_reason} /> - {preDischargeForm.new_discharge_reason === + {discharge_reason === DISCHARGE_REASONS.find((i) => i.text == "Referred")?.id && ( - <> -
- Referred to - - handleFacilitySelect(selected as FacilityModel | undefined) - } - selected={facility ?? null} - showAll - freeText - multiple={false} - errors={errors?.referred_to} - className="mb-4" - /> -
- +
+ Referred to + + handleFacilitySelect(selected as FacilityModel | undefined) + } + disabled={!!referred_to} + selected={facility ?? null} + showAll + freeText + multiple={false} + errors={errors?.referred_to} + className="mb-4" + /> +
)} i.text == "Expired")?.id } label={ { "3": "Cause of death", "1": "Discharged Advice", - }[preDischargeForm.new_discharge_reason ?? 0] ?? "Notes" + }[discharge_reason ?? 0] ?? "Notes" } name="discharge_notes" value={preDischargeForm.discharge_notes} @@ -259,13 +281,13 @@ const DischargeModal = ({ /> i.text == "Expired")?.id ? "death_datetime" : "discharge_date" } label={ - preDischargeForm.new_discharge_reason === + discharge_reason === DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id ? "Date of Death" : "Date and Time of Discharge" @@ -273,7 +295,7 @@ const DischargeModal = ({ type="datetime-local" value={ preDischargeForm[ - preDischargeForm.new_discharge_reason === + discharge_reason === DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id ? "death_datetime" : "discharge_date" @@ -293,14 +315,14 @@ const DischargeModal = ({ )} max={dayjs().format("YYYY-MM-DDTHH:mm")} error={ - preDischargeForm.new_discharge_reason === + discharge_reason === DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id ? errors?.death_datetime : errors?.discharge_date } /> - {preDischargeForm.new_discharge_reason === + {discharge_reason === DISCHARGE_REASONS.find((i) => i.text == "Recovered")?.id && ( <>
@@ -313,7 +335,7 @@ const DischargeModal = ({
)} - {preDischargeForm.new_discharge_reason === + {discharge_reason === DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id && ( { { )} {error && ( -
{error}
+
+ {error} +
)} diff --git a/src/Components/Shifting/ShiftDetailsUpdate.tsx b/src/Components/Shifting/ShiftDetailsUpdate.tsx index d327e402889..35e77066ef4 100644 --- a/src/Components/Shifting/ShiftDetailsUpdate.tsx +++ b/src/Components/Shifting/ShiftDetailsUpdate.tsx @@ -8,6 +8,7 @@ import { SHIFTING_CHOICES_PEACETIME, SHIFTING_CHOICES_WARTIME, SHIFTING_VEHICLE_CHOICES, + USER_TYPES, } from "../../Common/constants"; import { Cancel, Submit } from "../Common/components/ButtonV2"; @@ -39,6 +40,7 @@ import routes from "../../Redux/api.js"; import { IShift } from "./models.js"; import request from "../../Utils/request/request.js"; import { PatientModel } from "../Patient/models.js"; +import useAuthUser from "../../Common/hooks/useAuthUser.js"; const Loading = lazy(() => import("../Common/Loading")); @@ -48,6 +50,7 @@ interface patientShiftProps { export const ShiftDetailsUpdate = (props: patientShiftProps) => { const { goBack } = useAppHistory(); + const { user_type, home_facility } = useAuthUser(); const { kasp_full_string, kasp_enabled, wartime_shifting } = useConfig(); @@ -60,6 +63,7 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { {} as ConsultationModel, ); const [showDischargeModal, setShowDischargeModal] = useState(false); + const [dischargeReason, setDischargeReason] = useState(); const { t } = useTranslation(); const initForm: any = { @@ -91,27 +95,6 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { errors: { ...initError }, }; - let requiredFields: any = { - reason: { - errorText: t("please_enter_a_reason_for_the_shift"), - }, - }; - - if (wartime_shifting) { - requiredFields = { - ...requiredFields, - shifting_approving_facility_object: { - errorText: t("shifting_approving_facility_can_not_be_empty"), - }, - assigned_facility_type: { - errorText: t("please_select_facility_type"), - }, - preferred_vehicle_choice: { - errorText: t("please_select_preferred_vehicle_type"), - }, - }; - } - const shiftFormReducer = (state = initialState, action: any) => { switch (action.type) { case "set_form": { @@ -133,6 +116,45 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { const [state, dispatch] = useReducer(shiftFormReducer, initialState); + let requiredFields: any = { + assigned_facility_object: { + condition: [ + "DESTINATION APPROVED", + "PATIENT TO BE PICKED UP", + "TRANSFER IN PROGRESS", + "COMPLETED", + ].includes(state.form.status), + errorText: t("please_select_a_facility"), + }, + status: { + errorText: t("please_select_status"), + }, + patient_category: { + errorText: t("please_select_patient_category"), + }, + reason: { + errorText: t("please_enter_a_reason_for_the_shift"), + }, + }; + + if (wartime_shifting) { + requiredFields = { + ...requiredFields, + shifting_approving_facility_object: { + errorText: t("shifting_approving_facility_can_not_be_empty"), + }, + assigned_facility_type: { + errorText: t("please_select_facility_type"), + }, + preferred_vehicle_choice: { + errorText: t("please_select_preferred_vehicle_type"), + }, + breathlessness_level: { + errorText: t("please_select_breathlessness_level"), + }, + }; + } + const { loading: assignedUserLoading } = useQuery(routes.userList, { query: { id: state.form.assigned_to }, prefetch: state.form.assigned_to ? true : false, @@ -145,9 +167,16 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { const errors = { ...initError }; let isInvalidForm = false; Object.keys(requiredFields).forEach((field) => { - if (!state.form[field] || !/\S+/.test(state.form[field])) { + if ( + (!state.form[field] || !/\S+/.test(state.form[field])) && + ("condition" in requiredFields[field] + ? requiredFields[field].condition + : true) + ) { errors[field] = requiredFields[field].errorText; isInvalidForm = true; + } else { + errors[field] = ""; } }); @@ -188,6 +217,16 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { if (validForm) { if (!discharged && state.form.status === "PATIENT EXPIRED") { + setDischargeReason( + DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id, + ); + setShowDischargeModal(true); + return; + } + if (!discharged && state.form.status === "COMPLETED") { + setDischargeReason( + DISCHARGE_REASONS.find((i) => i.text == "Referred")?.id, + ); setShowDischargeModal(true); return; } @@ -282,9 +321,8 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { show={showDischargeModal} onClose={() => setShowDischargeModal(false)} consultationData={consultationData} - new_discharge_reason={ - DISCHARGE_REASONS.find((i) => i.text == "Expired")?.id - } + referred_to={state.form.assigned_facility_object} + new_discharge_reason={dischargeReason} afterSubmit={() => { handleSubmit(true); }} @@ -303,6 +341,13 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { value={state.form.status} optionLabel={(option) => option.text} optionValue={(option) => option.text} + optionDisabled={(option) => + // disable all options except `Destination Approved` for non-admin destination facility users + home_facility === state.form.assigned_facility_object?.id && + USER_TYPES.findIndex((type) => user_type === type) < + USER_TYPES.findIndex((type) => type === "DistrictAdmin") && + !["DESTINATION APPROVED"].includes(option.text) + } optionSelectedLabel={(option) => option.text} onChange={handleFormFieldChange} className="w-full bg-white md:col-span-1 md:leading-5" @@ -341,16 +386,31 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { )}
- {t("what_facility_assign_the_patient_to")} + + {t("what_facility_assign_the_patient_to")} + setFacility(obj, "assigned_facility_object") } - errors={state.errors.assigned_facility} + errors={state.errors.assigned_facility_object} />
@@ -402,6 +462,7 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { onChange={handleFormFieldChange} label="Patient Category" className="md:col-span-2" + error={state.errors.patient_category} /> {wartime_shifting && ( diff --git a/src/Locale/en/Shifting.json b/src/Locale/en/Shifting.json index 0fc177281d5..e1bc1916d89 100644 --- a/src/Locale/en/Shifting.json +++ b/src/Locale/en/Shifting.json @@ -76,6 +76,10 @@ "please_enter_a_reason_for_the_shift": "Please enter a reason for the shift.", "please_select_preferred_vehicle_type": "Please select Preferred Vehicle Type", "please_select_facility_type": "Please select Facility Type", + "please_select_breathlessness_level": "Please select Breathlessness Level", + "please_select_a_facility": "Please select a facility", + "please_select_status": "Please select Status", + "please_select_patient_category": "Please select Patient Category", "shifting_approving_facility_can_not_be_empty": "Shifting approving facility can not be empty.", "redirected_to_create_consultation": "Note: You will be redirected to create consultation form. Please complete the form to finish the transfer process", "mark_this_transfer_as_complete_question": "Are you sure you want to mark this transfer as complete? The Origin facility will no longer have access to this patient",