-
Notifications
You must be signed in to change notification settings - Fork 477
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
Issues/8607/review missed #9259
Closed
Sancharisingh
wants to merge
16
commits into
ohcnetwork:develop
from
Sancharisingh:issues/8607/review-missed
+199
−115
Closed
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
cb3f18d
Adds support for review missed logic #8607
Sancharisingh b47daad
Merge branch 'ohcnetwork:develop' into issues/8607/review-missed
Sancharisingh 4972598
Merge branch 'ohcnetwork:develop' into issues/8607/review-missed
Sancharisingh 7d0a6c2
Update package.json
Sancharisingh 7bc58ae
Update ManagePatients.tsx
Sancharisingh b0d6b44
Update package-lock.json
Sancharisingh 47b4c4a
Update package.json
Sancharisingh 3e10890
Update package.json
Sancharisingh fb0039d
Update package-lock.json
Sancharisingh fd158a9
Remove old comment code.
Sancharisingh 289e4e6
Merge branch 'develop' into issues/8607/review-missed
Sancharisingh 0a450f2
Remove comment code and add shadcn/ui badge.
Sancharisingh ad568f9
Add files via upload
Sancharisingh e4bb04b
Added a success variant and updated the purple variant as suggested.
Sancharisingh b77f123
Added purple and success as suggested, remove destructive.
Sancharisingh c6e8d75
Usage for review status
Sancharisingh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,40 @@ | ||
import dayjs from "dayjs"; | ||
import { Link, navigate } from "raviger"; | ||
import { ReactNode, useCallback, useEffect, useState } from "react"; | ||
import { ReactNode, useEffect, useState } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
|
||
import Chip from "@/CAREUI/display/Chip"; | ||
import CountBlock from "@/CAREUI/display/Count"; | ||
import FilterBadge from "@/CAREUI/display/FilterBadge"; | ||
import RecordMeta from "@/CAREUI/display/RecordMeta"; | ||
import CareIcon from "@/CAREUI/icons/CareIcon"; | ||
import { AdvancedFilterButton } from "@/CAREUI/interactive/FiltersSlideover"; | ||
|
||
import { Badge } from "@/components/ui/badge"; | ||
|
||
import { Avatar } from "@/components/Common/Avatar"; | ||
import ButtonV2 from "@/components/Common/ButtonV2"; | ||
import { ExportMenu } from "@/components/Common/Export"; | ||
import Loading from "@/components/Common/Loading"; | ||
import Page from "@/components/Common/Page"; | ||
import SearchByMultipleFields from "@/components/Common/SearchByMultipleFields"; | ||
import SortDropdownMenu from "@/components/Common/SortDropdown"; | ||
import Tabs from "@/components/Common/Tabs"; | ||
import { ICD11DiagnosisModel } from "@/components/Diagnosis/types"; | ||
import { getDiagnosesByIds } from "@/components/Diagnosis/utils"; | ||
import FacilitiesSelectDialogue from "@/components/ExternalResult/FacilitiesSelectDialogue"; | ||
import DoctorVideoSlideover from "@/components/Facility/DoctorVideoSlideover"; | ||
import { FacilityModel, PatientCategory } from "@/components/Facility/models"; | ||
import { PhoneNumberValidator } from "@/components/Form/FieldValidators"; | ||
import PhoneNumberFormField from "@/components/Form/FormFields/PhoneNumberFormField"; | ||
import { FieldChangeEvent } from "@/components/Form/FormFields/Utils"; | ||
import SearchInput from "@/components/Form/SearchInput"; | ||
import { | ||
DIAGNOSES_FILTER_LABELS, | ||
DiagnosesFilterKey, | ||
FILTER_BY_DIAGNOSES_KEYS, | ||
} from "@/components/Patient/DiagnosesFilter"; | ||
import PatientFilter from "@/components/Patient/PatientFilter"; | ||
import { isPatientMandatoryDataFilled } from "@/components/Patient/Utils"; | ||
|
||
import useAuthUser from "@/hooks/useAuthUser"; | ||
import useFilters from "@/hooks/useFilters"; | ||
|
@@ -27,36 +51,17 @@ import { | |
} from "@/common/constants"; | ||
import { parseOptionId } from "@/common/utils"; | ||
|
||
import { triggerGoal } from "@/Integrations/Plausible"; | ||
import * as Notification from "@/Utils/Notifications"; | ||
import routes from "@/Utils/request/api"; | ||
|
||
import Chip from "../../CAREUI/display/Chip"; | ||
import CountBlock from "../../CAREUI/display/Count"; | ||
import FilterBadge from "../../CAREUI/display/FilterBadge"; | ||
import RecordMeta from "../../CAREUI/display/RecordMeta"; | ||
import CareIcon from "../../CAREUI/icons/CareIcon"; | ||
import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover"; | ||
import { triggerGoal } from "../../Integrations/Plausible"; | ||
import * as Notification from "../../Utils/Notifications"; | ||
import request from "../../Utils/request/request"; | ||
import useQuery from "../../Utils/request/useQuery"; | ||
import request from "@/Utils/request/request"; | ||
import useQuery from "@/Utils/request/useQuery"; | ||
import { | ||
formatPatientAge, | ||
humanizeStrings, | ||
isAntenatal, | ||
parsePhoneNumber, | ||
} from "../../Utils/utils"; | ||
import { ICD11DiagnosisModel } from "../Diagnosis/types"; | ||
import { getDiagnosesByIds } from "../Diagnosis/utils"; | ||
import FacilitiesSelectDialogue from "../ExternalResult/FacilitiesSelectDialogue"; | ||
import DoctorVideoSlideover from "../Facility/DoctorVideoSlideover"; | ||
import { FacilityModel, PatientCategory } from "../Facility/models"; | ||
import { | ||
DIAGNOSES_FILTER_LABELS, | ||
DiagnosesFilterKey, | ||
FILTER_BY_DIAGNOSES_KEYS, | ||
} from "./DiagnosesFilter"; | ||
import PatientFilter from "./PatientFilter"; | ||
import { isPatientMandatoryDataFilled } from "./Utils"; | ||
} from "@/Utils/utils"; | ||
|
||
interface TabPanelProps { | ||
children?: ReactNode; | ||
|
@@ -90,7 +95,6 @@ export const PatientManager = () => { | |
Pagination, | ||
FilterBadges, | ||
resultsPerPage, | ||
clearSearch, | ||
} = useFilters({ | ||
limit: 12, | ||
cacheBlacklist: [ | ||
|
@@ -107,6 +111,30 @@ export const PatientManager = () => { | |
const [diagnoses, setDiagnoses] = useState<ICD11DiagnosisModel[]>([]); | ||
const [showDialog, setShowDialog] = useState<"create" | "list-discharged">(); | ||
const [showDoctors, setShowDoctors] = useState(false); | ||
const [phoneNumber, _setPhoneNumber] = useState(""); | ||
const [emergencyPhoneNumber, _setEmergencyPhoneNumber] = useState(""); | ||
|
||
const setPhoneNumber = (value: string) => { | ||
_setPhoneNumber(value); | ||
const error = PhoneNumberValidator()(value); | ||
if (!error) { | ||
updateQuery({ phone_number: value }); | ||
} | ||
if ((value === "+91" || value === "") && qParams.phone_number) { | ||
updateQuery({ phone_number: null }); | ||
} | ||
}; | ||
|
||
const setEmergencyPhoneNumber = (value: string) => { | ||
_setEmergencyPhoneNumber(value); | ||
const error = PhoneNumberValidator()(value); | ||
if (!error) { | ||
updateQuery({ emergency_phone_number: value }); | ||
} | ||
if ((value === "+91" || value === "") && qParams.emergency_phone_number) { | ||
updateQuery({ emergency_phone_number: null }); | ||
} | ||
}; | ||
|
||
const tabValue = | ||
qParams.last_consultation__new_discharge_reason || | ||
|
@@ -293,6 +321,14 @@ export const PatientManager = () => { | |
|
||
const { loading: isLoading, data } = useQuery(routes.patientList, { | ||
query: params, | ||
onResponse: () => { | ||
if (!params.phone_number) { | ||
_setPhoneNumber("+91"); | ||
} | ||
if (!params.emergency_phone_number) { | ||
_setEmergencyPhoneNumber("+91"); | ||
} | ||
}, | ||
}); | ||
|
||
const getTheCategoryFromId = () => { | ||
|
@@ -596,15 +632,26 @@ export const PatientManager = () => { | |
)} | ||
{patient.review_time && | ||
!patient.last_consultation?.discharge_date && | ||
Number(patient.last_consultation?.review_interval) > 0 && | ||
dayjs().isAfter(patient.review_time) && ( | ||
<Chip | ||
size="small" | ||
variant="danger" | ||
startIcon="l-clock" | ||
text="Review Missed" | ||
/> | ||
Number(patient.last_consultation?.review_interval) > 0 && ( | ||
<Badge | ||
variant={ | ||
dayjs().isAfter(patient.review_time) | ||
? "purple" | ||
: "success" | ||
} | ||
className="flex items-center gap-1" | ||
> | ||
<i className="icon-class l-clock"></i> | ||
{dayjs().isAfter(patient.review_time) | ||
? `Review Missed ${Math.abs( | ||
dayjs().diff(dayjs(patient.review_time), "days"), | ||
)} days ago` | ||
: `Review Due in ${Math.abs( | ||
dayjs(patient.review_time).diff(dayjs(), "days"), | ||
)} days`} | ||
</Badge> | ||
)} | ||
|
||
{patient.last_consultation?.is_readmission && ( | ||
<Chip | ||
size="small" | ||
|
@@ -745,74 +792,22 @@ export const PatientManager = () => { | |
); | ||
} | ||
|
||
const queryField = <T,>(name: string, defaultValue?: T) => { | ||
return { | ||
name, | ||
value: qParams[name] || defaultValue, | ||
onChange: (e: FieldChangeEvent<T>) => updateQuery({ [e.name]: e.value }), | ||
}; | ||
}; | ||
|
||
const onlyAccessibleFacility = | ||
permittedFacilities?.count === 1 ? permittedFacilities.results[0] : null; | ||
|
||
const searchOptions = [ | ||
{ | ||
key: "phone_number", | ||
label: "Phone Number", | ||
type: "phone" as const, | ||
placeholder: "Search_by_phone_number", | ||
value: qParams.phone_number || "", | ||
shortcutKey: "p", | ||
}, | ||
{ | ||
key: "name", | ||
label: "Name", | ||
type: "text" as const, | ||
placeholder: "search_by_patient_name", | ||
value: qParams.name || "", | ||
shortcutKey: "n", | ||
}, | ||
{ | ||
key: "patient_no", | ||
label: "IP/OP No", | ||
type: "text" as const, | ||
placeholder: "search_by_patient_no", | ||
value: qParams.patient_no || "", | ||
shortcutKey: "u", | ||
}, | ||
{ | ||
key: "emergency_contact_number", | ||
label: "Emergency Contact Phone Number", | ||
type: "phone" as const, | ||
placeholder: "search_by_emergency_phone_number", | ||
value: qParams.emergency_phone_number || "", | ||
shortcutKey: "e", | ||
}, | ||
]; | ||
|
||
const handleSearch = useCallback( | ||
(key: string, value: string) => { | ||
const updatedQuery = { | ||
phone_number: | ||
key === "phone_number" | ||
? value.length >= 13 || value === "" | ||
? value | ||
: undefined | ||
: undefined, | ||
name: key === "name" ? value : undefined, | ||
patient_no: key === "patient_no" ? value : undefined, | ||
emergency_phone_number: | ||
key === "emergency_contact_number" | ||
? value.length >= 13 || value === "" | ||
? value | ||
: undefined | ||
: undefined, | ||
}; | ||
|
||
updateQuery(updatedQuery); | ||
}, | ||
[updateQuery], | ||
); | ||
|
||
return ( | ||
<Page | ||
title={t("patients")} | ||
hideBack={true} | ||
breadcrumbs={false} | ||
className="px-4 md:px-6" | ||
options={ | ||
<div className="flex w-full flex-col items-center justify-between lg:flex-row"> | ||
<div className="mb-2 flex w-full flex-col items-center lg:mb-0 lg:w-fit lg:flex-row lg:gap-5"> | ||
|
@@ -991,23 +986,59 @@ export const PatientManager = () => { | |
}} | ||
/> | ||
|
||
<div className="mt-4 gap-4 lg:gap-16 flex flex-col lg:flex-row lg:items-center"> | ||
<div id="total-patientcount"> | ||
<CountBlock | ||
text={t("total_patients")} | ||
count={data?.count || 0} | ||
loading={isLoading} | ||
icon="d-patient" | ||
/> | ||
<div className="manualGrid my-4 mb-[-12px] mt-5 grid-cols-1 gap-3 px-2 sm:grid-cols-4 md:px-0"> | ||
<div className="mt-2 flex h-full flex-col gap-3 xl:flex-row"> | ||
<div className="flex-1" id="total-patientcount"> | ||
<CountBlock | ||
text="Total Patients" | ||
count={data?.count || 0} | ||
loading={isLoading} | ||
icon="l-user-injured" | ||
className="pb-12" | ||
/> | ||
</div> | ||
</div> | ||
<div className="col-span-3 w-full"> | ||
<div className="mt-2"> | ||
<div className="mb-4 mt-1 md:flex md:gap-4"> | ||
<SearchInput | ||
label="Search by Patient" | ||
placeholder="Enter patient name" | ||
{...queryField("name")} | ||
className="w-full grow" | ||
/> | ||
<SearchInput | ||
label="Search by IP/OP Number" | ||
placeholder="Enter IP/OP Number" | ||
secondary | ||
{...queryField("patient_no")} | ||
className="w-full grow" | ||
/> | ||
</div> | ||
<div className="mb-4 md:flex md:gap-4"> | ||
<PhoneNumberFormField | ||
label="Search by Primary Number" | ||
{...queryField("phone_number", "+91")} | ||
value={phoneNumber} | ||
onChange={(e) => setPhoneNumber(e.value)} | ||
types={["mobile", "landline"]} | ||
className="w-full grow" | ||
error={((phoneNumber || "+91") === "+91" && "") || undefined} | ||
/> | ||
<PhoneNumberFormField | ||
label="Search by Emergency Number" | ||
{...queryField("emergency_phone_number", "+91")} | ||
value={emergencyPhoneNumber} | ||
onChange={(e) => setEmergencyPhoneNumber(e.value)} | ||
types={["mobile", "landline"]} | ||
className="w-full" | ||
error={ | ||
((emergencyPhoneNumber || "+91") === "+91" && "") || undefined | ||
} | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<SearchByMultipleFields | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Merge error here; SearchByMultipleFields should be included instead of the individual search fields. |
||
id="patient-search" | ||
options={searchOptions} | ||
onSearch={handleSearch} | ||
clearSearch={clearSearch} | ||
className="w-full" | ||
/> | ||
</div> | ||
<div className="col-span-3 flex flex-wrap"> | ||
<FilterBadges | ||
|
@@ -1125,10 +1156,7 @@ export const PatientManager = () => { | |
/> | ||
</div> | ||
<div> | ||
<PatientFilter | ||
{...advancedFilter} | ||
key={JSON.stringify(advancedFilter.filter)} | ||
/> | ||
<PatientFilter {...advancedFilter} key={window.location.search} /> | ||
<TabPanel value={tabValue} index={0}> | ||
<div className="mb-4">{managePatients}</div> | ||
</TabPanel> | ||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge error; Part of SearchByMultipleFields, and as such should be included.