Skip to content

Commit

Permalink
Merge branch 'enhanced-asset-header' of https://github.com/manmeetnag…
Browse files Browse the repository at this point in the history
…ii/care_fe into enhanced-asset-header
  • Loading branch information
manmeetnagii committed Dec 17, 2024
2 parents f601b89 + 1832378 commit 4d9be38
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 230 deletions.
275 changes: 209 additions & 66 deletions src/components/Common/DateInputV2.tsx

Large diffs are not rendered by default.

38 changes: 14 additions & 24 deletions src/components/Common/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ import { useTranslation } from "react-i18next";
import CareIcon, { IconName } from "@/CAREUI/icons/CareIcon";
import SlideOver from "@/CAREUI/interactive/SlideOver";

import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { TooltipComponent, TooltipProvider } from "@/components/ui/tooltip";

import {
ShrinkedSidebarItem,
Expand Down Expand Up @@ -243,24 +238,19 @@ const ToggleShrink = ({ shrinked, toggle }: ToggleShrinkProps) => {
const { t } = useTranslation();
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<button
className={`flex h-6 w-6 cursor-pointer items-center justify-center rounded focus:outline-none focus:ring-2 focus:ring-indigo-500 ${shrinked ? "bg-gray-200" : "bg-gray-100"} text-gray-600 hover:bg-primary-200 hover:text-primary-800 ${
shrinked ? "mx-auto" : "mr-4"
} transition-all ease-in-out`}
onClick={toggle}
>
<CareIcon
icon={shrinked ? "l-arrow-bar-right" : "l-layout-sidebar-alt"}
className="text-lg transition"
/>
</button>
</TooltipTrigger>
<TooltipContent>
<p>{shrinked ? t("expand_sidebar") : t("collapse_sidebar")}</p>
</TooltipContent>
</Tooltip>
<TooltipComponent
content={shrinked ? t("expand_sidebar") : t("collapse_sidebar")}
>
<button
className={`flex h-6 w-6 cursor-pointer items-center justify-center rounded focus:outline-none focus:ring-2 focus:ring-indigo-500 ${shrinked ? "bg-gray-200" : "bg-gray-100"} text-gray-600 hover:bg-primary-200 hover:text-primary-800 ${shrinked ? "mx-auto" : "mr-4"} transition-all ease-in-out`}
onClick={toggle}
>
<CareIcon
icon={shrinked ? "l-arrow-bar-right" : "l-layout-sidebar-alt"}
className="text-lg transition"
/>
</button>
</TooltipComponent>
</TooltipProvider>
);
};
202 changes: 95 additions & 107 deletions src/components/Facility/DischargedPatientsList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Link, navigate } from "raviger";
import { useEffect, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";

import CountBlock from "@/CAREUI/display/Count";
Expand All @@ -11,13 +11,11 @@ import PaginatedList from "@/CAREUI/misc/PaginatedList";

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 { getDiagnosesByIds } from "@/components/Diagnosis/utils";
import { ICD11DiagnosisModel } from "@/components/Facility/models";
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,
Expand Down Expand Up @@ -52,16 +50,79 @@ const DischargedPatientsList = ({
pathParams: { id: facility_external_id },
});

const { qParams, updateQuery, advancedFilter, FilterBadges, updatePage } =
useFilters({
limit: 12,
cacheBlacklist: [
"name",
"patient_no",
"phone_number",
"emergency_phone_number",
],
});
const {
qParams,
updateQuery,
advancedFilter,
FilterBadges,
updatePage,
clearSearch,
} = useFilters({
limit: 12,
cacheBlacklist: [
"name",
"patient_no",
"phone_number",
"emergency_phone_number",
],
});

const searchOptions = [
{
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: "phone_number",
label: "Phone Number",
type: "phone" as const,
placeholder: "Search_by_phone_number",
value: qParams.phone_number || "",
shortcutKey: "p",
},
{
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 isValidPhoneNumber = (val: string) =>
val.length >= 13 || val === "";

const updatedQuery = {
phone_number:
key === "phone_number" && isValidPhoneNumber(value)
? value
: undefined,
name: key === "name" ? value : undefined,
patient_no: key === "patient_no" ? value : undefined,
emergency_phone_number:
key === "emergency_contact_number" && isValidPhoneNumber(value)
? value
: undefined,
};
updateQuery(updatedQuery);
},
[updateQuery],
);

useEffect(() => {
if (!qParams.phone_number && phone_number.length >= 13) {
Expand Down Expand Up @@ -200,56 +261,11 @@ const DischargedPatientsList = ({
});
};

const queryField = <T,>(name: string, defaultValue?: T) => {
return {
name,
value: qParams[name] || defaultValue,
onChange: (e: FieldChangeEvent<T>) => updateQuery({ [e.name]: e.value }),
className: "grow w-full mb-2",
};
};
const [diagnoses, setDiagnoses] = useState<ICD11DiagnosisModel[]>([]);
const [phone_number, setPhoneNumber] = useState("");
const [phoneNumberError, setPhoneNumberError] = useState("");
const [emergency_phone_number, setEmergencyPhoneNumber] = useState("");
const [emergencyPhoneNumberError, setEmergencyPhoneNumberError] =
useState("");
const [count, setCount] = useState(0);

const setPhoneNum = (phone_number: string) => {
setPhoneNumber(phone_number);
if (phone_number.length >= 13) {
setPhoneNumberError("");
updateQuery({ phone_number });
return;
}

if (phone_number === "+91" || phone_number === "") {
setPhoneNumberError("");
qParams.phone_number && updateQuery({ phone_number: null });
return;
}

setPhoneNumberError("Enter a valid number");
};

const setEmergencyPhoneNum = (emergency_phone_number: string) => {
setEmergencyPhoneNumber(emergency_phone_number);
if (emergency_phone_number.length >= 13) {
setEmergencyPhoneNumberError("");
updateQuery({ emergency_phone_number });
return;
}

if (emergency_phone_number === "+91" || emergency_phone_number === "") {
setEmergencyPhoneNumberError("");
qParams.emergency_phone_number &&
updateQuery({ emergency_phone_number: null });
return;
}

setEmergencyPhoneNumberError("Enter a valid number");
};
const [isLoading, setIsLoading] = useState(false);

return (
<Page
Expand Down Expand Up @@ -281,53 +297,22 @@ const DischargedPatientsList = ({
</>
}
>
<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">
<CountBlock
text="Discharged Patients"
count={count}
loading={facilityQuery.loading}
icon="d-patient"
className="pb-12"
/>
</div>
</div>
<div className="col-span-3 w-full">
<div className="col-span-2 mt-2">
<div className="mt-1 md:flex md:gap-4">
<SearchInput
label="Search by Patient"
placeholder="Enter patient name"
{...queryField("name")}
/>
<SearchInput
label="Search by IP/OP Number"
placeholder="Enter IP/OP Number"
secondary
{...queryField("patient_no")}
/>
</div>
<div className="md:flex md:gap-4">
<PhoneNumberFormField
label="Search by Primary Number"
{...queryField("phone_number", "+91")}
value={phone_number}
onChange={(e) => setPhoneNum(e.value)}
error={phoneNumberError}
types={["mobile", "landline"]}
/>
<PhoneNumberFormField
label="Search by Emergency Number"
{...queryField("emergency_phone_number", "+91")}
value={emergency_phone_number}
onChange={(e) => setEmergencyPhoneNum(e.value)}
error={emergencyPhoneNumberError}
types={["mobile", "landline"]}
/>
</div>
</div>
<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={count || 0}
loading={isLoading}
icon="d-patient"
/>
</div>
<SearchByMultipleFields
id="patient-search"
options={searchOptions}
onSearch={handleSearch}
clearSearch={clearSearch}
className="w-full"
/>
</div>
<div className="col-span-3 mt-6 flex flex-wrap">
<FilterBadges
Expand Down Expand Up @@ -440,7 +425,10 @@ const DischargedPatientsList = ({
route={routes.listFacilityDischargedPatients}
pathParams={{ facility_external_id }}
query={{ ordering: "-modified_date", ...qParams }}
queryCB={(query) => setCount(query.data?.count || 0)}
queryCB={(query) => {
setCount(query.data?.count || 0);
setIsLoading(query.loading);
}}
initialPage={qParams.page}
onPageChange={updatePage}
>
Expand Down
37 changes: 24 additions & 13 deletions src/components/Facility/FacilityCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { useTranslation } from "react-i18next";
import Chip from "@/CAREUI/display/Chip";
import CareIcon from "@/CAREUI/icons/CareIcon";

import { TooltipComponent, TooltipProvider } from "@/components/ui/tooltip";

import { Avatar } from "@/components/Common/Avatar";
import ButtonV2, { Cancel, Submit } from "@/components/Common/ButtonV2";
import DialogModal from "@/components/Common/Dialog";
Expand Down Expand Up @@ -98,19 +100,28 @@ export const FacilityCard = (props: {
>
{facility.name}
</Link>
<div
data-test-id="occupancy-badge"
className={`tooltip flex items-center gap-1 text-sm ${(facility.patient_count || 0) / (facility.bed_count || 0) > 0.85 ? "justify-center rounded-md border border-red-600 bg-red-500 p-1 font-bold text-white" : "text-secondary-700"}`}
>
<span className="tooltip-text tooltip-top">
{t("live_patients_total_beds")}
</span>{" "}
<CareIcon icon="l-bed" />
<dt data-test-id="occupancy-badge-text">
{t("occupancy")}: {facility.patient_count} /{" "}
{facility.bed_count}{" "}
</dt>
</div>
<TooltipProvider>
<TooltipComponent
content={t("live_patients_total_beds")}
>
<div
data-test-id="occupancy-badge"
className={`relative flex items-center gap-1 text-sm ${
(facility.patient_count || 0) /
(facility.bed_count || 0) >
0.85
? "justify-center rounded-md border border-red-600 bg-red-500 p-1 font-bold text-white"
: "text-secondary-700"
}`}
>
<CareIcon icon="l-bed" />
<dt data-test-id="occupancy-badge-text">
{t("occupancy")}: {facility.patient_count} /{" "}
{facility.bed_count}
</dt>
</div>
</TooltipComponent>
</TooltipProvider>
</div>
<ButtonV2
id="view-cns-button"
Expand Down
8 changes: 5 additions & 3 deletions src/components/Form/FormFields/AutocompleteMultiselect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,16 +171,18 @@ export const AutocompleteMutliSelect = <T, V>(
{!props.disabled && (
<ComboboxButton
ref={comboButtonRef}
className="absolute inset-y-0 right-0 flex items-center pr-2"
className="absolute inset-y-0 right-0 flex items-center justify-center pr-2"
>
<div className="absolute right-0 top-1 mr-2 flex items-center text-lg text-secondary-900">
<div
className={`relative flex items-center justify-center text-lg text-secondary-900 ${value.some((val: any) => val.option) ? "-top-5" : ""}`}
>
{props.isLoading ? (
<CareIcon icon="l-spinner" className="animate-spin" />
) : (
<CareIcon
id="dropdown-toggle"
icon="l-angle-down"
className="-mb-1.5"
className="text-lg"
/>
)}
</div>
Expand Down
5 changes: 4 additions & 1 deletion src/components/Form/FormFields/DateFormField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ const DateFormField = (props: Props) => {
return (
<FormField field={field}>
<DateInputV2
className={classNames(field.error && "border-red-500")}
className={classNames(
field.error && "border-red-500",
"mr-9 text-ellipsis",
)}
containerClassName={props.containerClassName}
id={field.id}
name={field.name}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Form/ModelCrudEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export default function ModelCrudEditor<TRes extends Identifier, TReq, TErr>(
onClick={() => handleDelete(props.item.id)}
className="w-full text-xl text-red-500 hover:text-red-700 disabled:grayscale md:w-auto"
>
<CareIcon icon="l-times-circle" />{" "}
<CareIcon icon="l-times-circle" />
<span className="text-sm md:hidden">{t("remove")}</span>
</button>
)}
Expand Down
Loading

0 comments on commit 4d9be38

Please sign in to comment.