From 75685a1558d0d73d11f41577808c54728c166a65 Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Mon, 12 Feb 2024 09:15:53 +0530
Subject: [PATCH 01/17] Fix bed check for log update button (#7202)

* Fix bed check for log update button

* Update username length in user creation test
---
 cypress/e2e/users_spec/user_creation.cy.ts |   2 +-
 src/Components/Patient/PatientInfoCard.tsx | 103 +++++++++------------
 2 files changed, 46 insertions(+), 59 deletions(-)

diff --git a/cypress/e2e/users_spec/user_creation.cy.ts b/cypress/e2e/users_spec/user_creation.cy.ts
index 72d2e7f15f4..b8e0dfe63eb 100644
--- a/cypress/e2e/users_spec/user_creation.cy.ts
+++ b/cypress/e2e/users_spec/user_creation.cy.ts
@@ -25,7 +25,7 @@ describe("User Creation", () => {
     }
     return result;
   };
-  const username = makeid(25);
+  const username = makeid(8);
   const alreadylinkedusersviews = [
     "devdoctor",
     "devstaff2",
diff --git a/src/Components/Patient/PatientInfoCard.tsx b/src/Components/Patient/PatientInfoCard.tsx
index c954438e6c2..67df8a2dd29 100644
--- a/src/Components/Patient/PatientInfoCard.tsx
+++ b/src/Components/Patient/PatientInfoCard.tsx
@@ -472,72 +472,59 @@ export default function PatientInfoCard(props: {
             </div>
           )}
           <div className="flex w-full flex-col gap-3 lg:w-auto 2xl:flex-row">
-            {[
-              [
-                `/facility/${patient.facility}/patient/${patient.id}/consultation/${consultation?.id}/daily-rounds`,
-                "Log Update",
-                "plus",
-                patient.is_active &&
-                  consultation?.id &&
-                  !consultation?.discharge_date,
-                [
-                  !(consultation?.facility !== patient.facility) &&
+            {patient.is_active &&
+              consultation?.id &&
+              !consultation?.discharge_date && (
+                <div className="h-10 min-h-[40px] w-full min-w-[170px] lg:w-auto">
+                  <ButtonV2
+                    variant={
+                      !(consultation?.facility !== patient.facility) &&
+                      !(consultation?.discharge_date ?? !patient.is_active) &&
+                      dayjs(consultation?.modified_date).isBefore(
+                        dayjs().subtract(1, "day")
+                      )
+                        ? "danger"
+                        : "primary"
+                    }
+                    href={
+                      consultation?.admitted && !consultation?.current_bed
+                        ? undefined
+                        : `/facility/${patient.facility}/patient/${patient.id}/consultation/${consultation?.id}/daily-rounds`
+                    }
+                    onClick={() => {
+                      if (
+                        consultation?.admitted &&
+                        !consultation?.current_bed
+                      ) {
+                        Notification.Error({
+                          msg: "Please assign a bed to the patient",
+                        });
+                        setOpen(true);
+                      }
+                    }}
+                    className="w-full"
+                  >
+                    <span className="flex w-full items-center justify-center gap-2">
+                      <CareIcon className="care-l-plus text-xl" />
+                      <p className="font-semibold">Log Update</p>
+                    </span>
+                  </ButtonV2>
+                  {!(consultation?.facility !== patient.facility) &&
                     !(consultation?.discharge_date ?? !patient.is_active) &&
                     dayjs(consultation?.modified_date).isBefore(
                       dayjs().subtract(1, "day")
-                    ),
-                  <div className="text-center">
-                    <CareIcon className="care-l-exclamation-triangle" /> No
-                    update filed in the last 24 hours
-                  </div>,
-                ],
-              ],
-            ].map(
-              (action: any, i) =>
-                action[3] && (
-                  <div
-                    className="h-10 min-h-[40px] w-full min-w-[170px] lg:w-auto"
-                    key={i}
-                  >
-                    <ButtonV2
-                      key={i}
-                      variant={action?.[4]?.[0] ? "danger" : "primary"}
-                      href={
-                        consultation?.admitted &&
-                        !consultation?.current_bed &&
-                        i === 1
-                          ? undefined
-                          : `${action[0]}`
-                      }
-                      onClick={() => {
-                        if (
-                          consultation?.admitted &&
-                          !consultation?.current_bed &&
-                          i === 1
-                        ) {
-                          Notification.Error({
-                            msg: "Please assign a bed to the patient",
-                          });
-                          setOpen(true);
-                        }
-                      }}
-                      className="w-full"
-                    >
-                      <span className="flex w-full items-center justify-center gap-2">
-                        <CareIcon className={`care-l-${action[2]} text-xl`} />
-                        <p className="font-semibold">{action[1]}</p>
-                      </span>
-                    </ButtonV2>
-                    {action?.[4]?.[0] && (
+                    ) && (
                       <>
                         <p className="mt-0.5 text-xs text-red-500">
-                          {action[4][1]}
+                          <div className="text-center">
+                            <CareIcon className="care-l-exclamation-triangle" />{" "}
+                            No update filed in the last 24 hours
+                          </div>
                         </p>
                       </>
                     )}
-                  </div>
-                )
-            )}
+                </div>
+              )}
             <DropdownMenu
               id="show-more"
               itemClassName="min-w-0 sm:min-w-[225px]"

From fc8e976c12a560e7fc37b80d1a242e733818d894 Mon Sep 17 00:00:00 2001
From: Aakash Singh <mail@singhaakash.dev>
Date: Mon, 12 Feb 2024 10:01:58 +0530
Subject: [PATCH 02/17] Update username validation on useradd (#7134)

* update username validation on useradd

* update username length
---
 src/Common/validation.tsx        |  2 +-
 src/Components/Users/UserAdd.tsx | 30 ++++++++++++++++++------------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/src/Common/validation.tsx b/src/Common/validation.tsx
index 54ad399c6e2..ef60a40bd79 100644
--- a/src/Common/validation.tsx
+++ b/src/Common/validation.tsx
@@ -43,7 +43,7 @@ export const validateName = (name: string) => {
 };
 
 export const validateUsername = (username: string) => {
-  const pattern = /^[\w.@+-]+[^.@+_-]$/;
+  const pattern = /^(?!.*[._-]{2})[a-z0-9](?:[a-z0-9._-]{2,14}[a-z0-9])$/s;
   return pattern.test(username);
 };
 
diff --git a/src/Components/Users/UserAdd.tsx b/src/Components/Users/UserAdd.tsx
index b3fc9b830f8..3f7fcb9d56a 100644
--- a/src/Components/Users/UserAdd.tsx
+++ b/src/Components/Users/UserAdd.tsx
@@ -211,11 +211,7 @@ export const UserAdd = (props: UserProps) => {
 
   useEffect(() => {
     setUsernameExists(userExistsEnums.idle);
-    if (
-      usernameInput.length > 1 &&
-      !(state.form.username?.length < 2) &&
-      /[^.@+_-]/.test(state.form.username[state.form.username?.length - 1])
-    ) {
+    if (validateUsername(usernameInput)) {
       const timeout = setTimeout(() => {
         check_username(usernameInput);
       }, 500);
@@ -403,7 +399,7 @@ export const UserAdd = (props: UserProps) => {
             invalidForm = true;
           } else if (!validateUsername(state.form[field])) {
             errors[field] =
-              "Please enter letters, digits and @ . + - _ only and username should not end with @, ., +, - or _";
+              "Please enter a 4-16 characters long username with lowercase letters, digits and . _ - only and it should not start or end with . _ -";
             invalidForm = true;
           } else if (usernameExists !== userExistsEnums.available) {
             errors[field] = "This username already exists";
@@ -757,16 +753,26 @@ export const UserAdd = (props: UserProps) => {
                   </div>
                   <div>
                     {validateRule(
-                      state.form.username?.length >= 2,
-                      "Username should be atleast 2 characters long"
+                      usernameInput.length >= 4 && usernameInput.length <= 16,
+                      "Username should be 4-16 characters long"
                     )}
                   </div>
                   <div>
                     {validateRule(
-                      /[^.@+_-]/.test(
-                        state.form.username[state.form.username?.length - 1]
-                      ),
-                      "Username can't end with ^ . @ + _ -"
+                      /^[a-z0-9._-]*$/.test(usernameInput),
+                      "Username can only contain lowercase letters, numbers, and . _ -"
+                    )}
+                  </div>
+                  <div>
+                    {validateRule(
+                      /^[a-z0-9].*[a-z0-9]$/i.test(usernameInput),
+                      "Username must start and end with a letter or number"
+                    )}
+                  </div>
+                  <div>
+                    {validateRule(
+                      !/(?:[._-]{2,})/.test(usernameInput),
+                      "Username can't contain consecutive special characters . _ -"
                     )}
                   </div>
                 </div>

From fcc276aa70f9abb42fd7d21bb3e5da1437a77eb4 Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Mon, 12 Feb 2024 11:42:33 +0530
Subject: [PATCH 03/17] Fix update log filters on page change (#7204)

* Fix update log filters on page change

* Clear unnecessary refetch
---
 .../Facility/Consultations/DailyRoundsList.tsx       | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/Components/Facility/Consultations/DailyRoundsList.tsx b/src/Components/Facility/Consultations/DailyRoundsList.tsx
index 828a41c8c24..d438ee098c7 100644
--- a/src/Components/Facility/Consultations/DailyRoundsList.tsx
+++ b/src/Components/Facility/Consultations/DailyRoundsList.tsx
@@ -11,6 +11,8 @@ import DailyRoundsFilter from "./DailyRoundsFilter";
 import { ConsultationModel } from "../models";
 import { useSlugs } from "../../../Common/hooks/useSlug";
 import { TimelineNode } from "../../../CAREUI/display/Timeline";
+import { useState } from "react";
+import { QueryParams } from "../../../Utils/request/types";
 
 interface Props {
   consultation: ConsultationModel;
@@ -19,6 +21,7 @@ interface Props {
 export default function DailyRoundsList({ consultation }: Props) {
   const [consultationId] = useSlugs("consultation");
   const { t } = useTranslation();
+  const [query, setQuery] = useState<QueryParams>();
 
   const consultationUrl = `/facility/${consultation.facility}/patient/${consultation.patient}/consultation/${consultation.id}`;
 
@@ -26,12 +29,17 @@ export default function DailyRoundsList({ consultation }: Props) {
     <PaginatedList
       route={routes.getDailyReports}
       pathParams={{ consultationId }}
+      query={query}
     >
-      {({ refetch }) => (
+      {() => (
         <>
           <div className="flex flex-1 justify-between">
             <PageTitle title="Update Log" hideBack breadcrumbs={false} />
-            <DailyRoundsFilter onApply={(query) => refetch({ query })} />
+            <DailyRoundsFilter
+              onApply={(query) => {
+                setQuery(query);
+              }}
+            />
           </div>
 
           <div className="-mt-2 flex w-full flex-col gap-4">

From 2a7c2615103529f28c702b1afcfacdfe7d51e875 Mon Sep 17 00:00:00 2001
From: Pranshu Aggarwal <70687348+Pranshu1902@users.noreply.github.com>
Date: Mon, 12 Feb 2024 12:22:34 +0530
Subject: [PATCH 04/17] Show Asset Downtime on assets lists page (#6952)

* Show Asset Downtime on assets lists page

* fetch downtime from asset api

* update icon

* update to new api variable
---
 src/Components/Assets/AssetTypes.tsx | 1 +
 src/Components/Assets/AssetsList.tsx | 7 +++++++
 2 files changed, 8 insertions(+)

diff --git a/src/Components/Assets/AssetTypes.tsx b/src/Components/Assets/AssetTypes.tsx
index dc70d246e0b..6186f3c4ee9 100644
--- a/src/Components/Assets/AssetTypes.tsx
+++ b/src/Components/Assets/AssetTypes.tsx
@@ -99,6 +99,7 @@ export interface AssetData {
   manufacturer: string;
   warranty_amc_end_of_validity: string;
   resolved_middleware?: ResolvedMiddleware;
+  latest_status: string;
   last_service: AssetService;
   meta?: {
     [key: string]: any;
diff --git a/src/Components/Assets/AssetsList.tsx b/src/Components/Assets/AssetsList.tsx
index bc0abbd4c2a..946618fd970 100644
--- a/src/Components/Assets/AssetsList.tsx
+++ b/src/Components/Assets/AssetsList.tsx
@@ -240,6 +240,13 @@ const AssetsList = () => {
                   <Chip variant="danger" startIcon="l-cog" text="Not Working" />
                 )}
                 {warrantyAmcValidityChip(asset.warranty_amc_end_of_validity)}
+                {asset?.latest_status === "Down" && (
+                  <Chip
+                    variant="danger"
+                    startIcon="l-link-broken"
+                    text={asset?.latest_status}
+                  />
+                )}{" "}
               </div>
             </div>
           </Link>

From d63ef9f4a8fe77ac6933c1741b72fc8c5c397a5b Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Mon, 12 Feb 2024 16:31:37 +0530
Subject: [PATCH 05/17] Add min_encounter_date validation (#7207)

* Add min_encounter_date validation

* Add check for minimum encounter date in ConsultationForm
---
 public/config.json                           |  3 ++-
 src/Common/hooks/useConfig.ts                |  5 +++++
 src/Components/Facility/ConsultationForm.tsx | 16 ++++++++++++++--
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/public/config.json b/public/config.json
index 69d898af544..d02bd135cfe 100644
--- a/public/config.json
+++ b/public/config.json
@@ -22,5 +22,6 @@
     "sample_format_asset_import": "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key=11JaEhNHdyCHth4YQs_44YaRlP77Rrqe81VSEfg1glko&exportFormat=xlsx",
     "sample_format_external_result_import": "/External-Results-Template.csv",
     "enable_abdm": true,
-    "enable_hcx": false
+    "enable_hcx": false,
+    "min_encounter_date": "2020-01-01"
 }
diff --git a/src/Common/hooks/useConfig.ts b/src/Common/hooks/useConfig.ts
index 79addd71c8b..4e1cb806e3f 100644
--- a/src/Common/hooks/useConfig.ts
+++ b/src/Common/hooks/useConfig.ts
@@ -69,6 +69,11 @@ export interface IConfig {
    */
   wartime_shifting: boolean;
   jwt_token_refresh_interval?: number;
+
+  /*
+   * Minimum date for a possible consultation encounter.
+   */
+  min_encounter_date: string;
 }
 
 const useConfig = () => {
diff --git a/src/Components/Facility/ConsultationForm.tsx b/src/Components/Facility/ConsultationForm.tsx
index d7bc5f67a70..344e24c7c31 100644
--- a/src/Components/Facility/ConsultationForm.tsx
+++ b/src/Components/Facility/ConsultationForm.tsx
@@ -263,6 +263,8 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => {
   const [bedStatusVisible, bedStatusRef] = useVisibility(-300);
   const [disabledFields, setDisabledFields] = useState<string[]>([]);
 
+  const { min_encounter_date } = useConfig();
+
   const sections = {
     "Consultation Details": {
       iconClass: "care-l-medkit",
@@ -504,8 +506,13 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => {
             errors[field] = "Field is required";
             invalidForm = true;
           }
-          if (dayjs(state.form.encounter_date).isBefore(dayjs("2000-01-01"))) {
-            errors[field] = "Admission date cannot be before 01/01/2000";
+          if (
+            min_encounter_date &&
+            dayjs(state.form.encounter_date).isBefore(dayjs(min_encounter_date))
+          ) {
+            errors[
+              field
+            ] = `Admission date cannot be before ${min_encounter_date}`;
             invalidForm = true;
           }
           return;
@@ -1238,6 +1245,11 @@ export const ConsultationForm = ({ facilityId, patientId, id }: Props) => {
                         "YYYY-MM-DDTHH:mm"
                       )}
                       max={dayjs().format("YYYY-MM-DDTHH:mm")}
+                      min={
+                        min_encounter_date
+                          ? dayjs(min_encounter_date).format("YYYY-MM-DDTHH:mm")
+                          : undefined
+                      }
                     />
                   </div>
 

From 000138b0cf322a1f8eb5887253081769e38c787b Mon Sep 17 00:00:00 2001
From: konavivekramakrishna <konavivekramakrishna@gmail.com>
Date: Wed, 14 Feb 2024 10:15:30 +0530
Subject: [PATCH 06/17] Add Search Box to Resource (#7199)

* add search for resource

* fix styling
---
 src/Components/Resource/BadgesList.tsx        |  1 +
 src/Components/Resource/Commons.tsx           |  2 +
 src/Components/Resource/ListView.tsx          | 81 ++++++++++++-------
 src/Components/Resource/ResourceBoard.tsx     |  3 +-
 src/Components/Resource/ResourceBoardView.tsx | 17 +++-
 src/Locale/en/Resource.json                   |  3 +-
 6 files changed, 70 insertions(+), 37 deletions(-)

diff --git a/src/Components/Resource/BadgesList.tsx b/src/Components/Resource/BadgesList.tsx
index 4ab4f3cc8e4..9fa1859fdd4 100644
--- a/src/Components/Resource/BadgesList.tsx
+++ b/src/Components/Resource/BadgesList.tsx
@@ -31,6 +31,7 @@ export default function BadgesList(props: any) {
           getDescShiftingFilterOrder(appliedFilters.ordering)
         ),
         badge("Status", "status"),
+        badge("Title", "title"),
         boolean("Emergency", "emergency", {
           trueValue: "yes",
           falseValue: "no",
diff --git a/src/Components/Resource/Commons.tsx b/src/Components/Resource/Commons.tsx
index 0162f34d02c..9ba522f763b 100644
--- a/src/Components/Resource/Commons.tsx
+++ b/src/Components/Resource/Commons.tsx
@@ -12,6 +12,7 @@ export const initialFilterData = {
   modified_date_after: null,
   offset: 0,
   ordering: null,
+  title: "",
 };
 
 export const formatFilter = (params: any) => {
@@ -35,5 +36,6 @@ export const formatFilter = (params: any) => {
     modified_date_before: filter.modified_date_before || undefined,
     modified_date_after: filter.modified_date_after || undefined,
     ordering: filter.ordering || undefined,
+    title: filter.title || undefined,
   };
 };
diff --git a/src/Components/Resource/ListView.tsx b/src/Components/Resource/ListView.tsx
index 5eb5a93fb8f..05b2ce2f4bb 100644
--- a/src/Components/Resource/ListView.tsx
+++ b/src/Components/Resource/ListView.tsx
@@ -14,13 +14,21 @@ import CareIcon from "../../CAREUI/icons/CareIcon";
 import dayjs from "../../Utils/dayjs";
 import useQuery from "../../Utils/request/useQuery";
 import routes from "../../Redux/api";
+import Page from "../Common/components/Page";
+import SearchInput from "../Form/SearchInput";
 
 const Loading = lazy(() => import("../Common/Loading"));
-const PageTitle = lazy(() => import("../Common/PageTitle"));
 
 export default function ListView() {
-  const { qParams, Pagination, FilterBadges, advancedFilter, resultsPerPage } =
-    useFilters({});
+  const {
+    qParams,
+    Pagination,
+    FilterBadges,
+    advancedFilter,
+    resultsPerPage,
+    updateQuery,
+  } = useFilters({ cacheBlacklist: ["title"] });
+
   const { t } = useTranslation();
 
   const onBoardViewBtnClick = () =>
@@ -148,33 +156,42 @@ export default function ListView() {
   };
 
   return (
-    <div className="flex h-screen flex-col px-2 pb-2">
-      <div className="px-4 md:flex md:items-center md:justify-between">
-        <PageTitle
-          title="Resource"
-          hideBack
-          componentRight={
-            <ExportButton
-              action={() =>
-                downloadResourceRequests({ ...appliedFilters, csv: 1 })
-              }
-              filenamePrefix="resource_requests"
-            />
-          }
-          breadcrumbs={false}
+    <Page
+      title="Resource"
+      hideBack
+      componentRight={
+        <ExportButton
+          action={() => downloadResourceRequests({ ...appliedFilters, csv: 1 })}
+          filenamePrefix="resource_requests"
         />
+      }
+      breadcrumbs={false}
+      options={
+        <>
+          <div className="md:px-4">
+            <SearchInput
+              name="title"
+              value={qParams.title}
+              onChange={(e) => updateQuery({ [e.name]: e.value })}
+              placeholder={t("search_resource")}
+            />
+          </div>
+          <div className="w-32">
+            {/* dummy div to align space as per board view */}
+          </div>
+          <div className="flex w-full flex-col gap-2 lg:w-fit lg:flex-row lg:gap-4">
+            <ButtonV2 className="py-[11px]" onClick={onBoardViewBtnClick}>
+              <CareIcon className="care-l-list-ul rotate-90" />
+              {t("board_view")}
+            </ButtonV2>
 
-        <div className="w-32" />
-        <div className="flex w-full flex-col gap-2 lg:w-fit lg:flex-row lg:gap-4">
-          <ButtonV2 className="py-[11px]" onClick={onBoardViewBtnClick}>
-            <CareIcon className="care-l-list-ul rotate-90" />
-            {t("board_view")}
-          </ButtonV2>
-
-          <AdvancedFilterButton onClick={() => advancedFilter.setShow(true)} />
-        </div>
-      </div>
-
+            <AdvancedFilterButton
+              onClick={() => advancedFilter.setShow(true)}
+            />
+          </div>
+        </>
+      }
+    >
       <BadgesList {...{ appliedFilters, FilterBadges }} />
 
       <div className="px-1">
@@ -188,14 +205,16 @@ export default function ListView() {
                 onClick={() => refetch()}
               >
                 <i className="fa fa-refresh mr-1" aria-hidden="true"></i>
-                Refresh List
+                {t("refresh_list")}
               </button>
             </div>
 
             <div className="mb-5 flex flex-wrap md:-mx-4">
               {data?.results && showResourceCardList(data?.results)}
             </div>
-            <Pagination totalCount={data?.count || 0} />
+            <div>
+              <Pagination totalCount={data?.count || 0} />
+            </div>
           </div>
         )}
       </div>
@@ -204,6 +223,6 @@ export default function ListView() {
         showResourceStatus={true}
         key={window.location.search}
       />
-    </div>
+    </Page>
   );
 }
diff --git a/src/Components/Resource/ResourceBoard.tsx b/src/Components/Resource/ResourceBoard.tsx
index d57c7a0d36f..0f16391b9ab 100644
--- a/src/Components/Resource/ResourceBoard.tsx
+++ b/src/Components/Resource/ResourceBoard.tsx
@@ -171,6 +171,7 @@ export default function ResourceBoard({
     setIsLoading((loading) => reduceLoading("BOARD", loading));
   }, [
     board,
+    filterProp.title,
     filterProp.facility,
     filterProp.origin_facility,
     filterProp.approving_facility,
@@ -231,7 +232,7 @@ export default function ResourceBoard({
     <div
       ref={drop}
       className={classNames(
-        "mr-2 h-full w-full shrink-0 overflow-y-auto rounded-md bg-gray-200 pb-4 @lg:w-1/2 @3xl:w-1/3 @7xl:w-1/4",
+        "e mr-2 h-full w-full  shrink-0 overflow-y-auto rounded-md bg-gray-200 pb-4 @lg:w-1/2 @3xl:w-1/3 @7xl:w-1/4",
         isOver && "cursor-move"
       )}
     >
diff --git a/src/Components/Resource/ResourceBoardView.tsx b/src/Components/Resource/ResourceBoardView.tsx
index 17fb70c662f..558cd77c1f0 100644
--- a/src/Components/Resource/ResourceBoardView.tsx
+++ b/src/Components/Resource/ResourceBoardView.tsx
@@ -14,6 +14,7 @@ import ButtonV2 from "../Common/components/ButtonV2";
 import { useTranslation } from "react-i18next";
 import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover";
 import CareIcon from "../../CAREUI/icons/CareIcon";
+import SearchInput from "../Form/SearchInput";
 
 const Loading = lazy(() => import("../Common/Loading"));
 const PageTitle = lazy(() => import("../Common/PageTitle"));
@@ -24,7 +25,10 @@ const COMPLETED = ["COMPLETED", "REJECTED"];
 const ACTIVE = resourceStatusOptions.filter((o) => !COMPLETED.includes(o));
 
 export default function BoardView() {
-  const { qParams, FilterBadges, advancedFilter } = useFilters({ limit: -1 });
+  const { qParams, FilterBadges, advancedFilter, updateQuery } = useFilters({
+    limit: -1,
+    cacheBlacklist: ["title"],
+  });
   const [boardFilter, setBoardFilter] = useState(ACTIVE);
   // eslint-disable-next-line
   const [isLoading, setIsLoading] = useState(false);
@@ -37,7 +41,7 @@ export default function BoardView() {
   };
 
   return (
-    <div className="flex h-screen flex-col px-2 pb-2">
+    <div className="max-h[95vh] flex min-h-full max-w-[100vw] flex-col px-2 pb-2">
       <div className="flex w-full flex-col items-center justify-between lg:flex-row">
         <div className="w-1/3 lg:w-1/4">
           <PageTitle
@@ -56,8 +60,13 @@ export default function BoardView() {
           />
         </div>
 
-        <div className="flex w-full flex-col items-center justify-between gap-2 pt-2 lg:flex-row lg:gap-4">
-          <div></div>
+        <div className="flex w-full flex-col items-center justify-between gap-2 pt-2 xl:flex-row">
+          <SearchInput
+            name="title"
+            value={qParams.title}
+            onChange={(e) => updateQuery({ [e.name]: e.value })}
+            placeholder={t("search_resource")}
+          />
           <SwitchTabs
             tab1="Active"
             tab2="Completed"
diff --git a/src/Locale/en/Resource.json b/src/Locale/en/Resource.json
index 68ed195f8e4..cc36bdb5d40 100644
--- a/src/Locale/en/Resource.json
+++ b/src/Locale/en/Resource.json
@@ -7,5 +7,6 @@
   "request_title_placeholder": "Type your title here",
   "required_quantity": "Required Quantity",
   "request_description": "Description of Request",
-  "request_description_placeholder": "Type your description here"
+  "request_description_placeholder": "Type your description here",
+  "search_resource": "Search Resource"
 }

From 847a5deb70ce5b2607483ce16ff1a68d139acba2 Mon Sep 17 00:00:00 2001
From: Abhiuday Gupta <77210185+aeswibon@users.noreply.github.com>
Date: Wed, 14 Feb 2024 10:16:14 +0530
Subject: [PATCH 07/17] fix: hide the diagonses card if it's empty (#7196)

* fix(consultation): fixes #7187 hide diagnoses card if empty

* fix(consultation): resolved suggestion

* Update src/Components/Facility/ConsultationDetails/index.tsx

---------

Co-authored-by: Rithvik Nishad <rithvikn2001@gmail.com>
---
 .../Facility/ConsultationDetails/index.tsx         | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx
index 071e7bfc1af..808a2c90de9 100644
--- a/src/Components/Facility/ConsultationDetails/index.tsx
+++ b/src/Components/Facility/ConsultationDetails/index.tsx
@@ -401,13 +401,15 @@ export const ConsultationDetails = (props: any) => {
             </div>
           </div>
         </div>
-        <div className="col-span-1 mt-2 overflow-hidden rounded-lg bg-white shadow">
-          <div className="px-4 py-2">
-            <DiagnosesListAccordion
-              diagnoses={consultationData.diagnoses ?? []}
-            />
+        {!!consultationData.diagnoses?.length && (
+          <div className="col-span-1 mt-2 overflow-hidden rounded-lg bg-white shadow">
+            <div className="px-4 py-2">
+              <DiagnosesListAccordion
+                diagnoses={consultationData.diagnoses ?? []}
+              />
+            </div>
           </div>
-        </div>
+        )}
         <div className="mt-4 w-full border-b-2 border-gray-200">
           <div className="overflow-x-auto sm:flex sm:items-baseline">
             <div className="mt-4 sm:mt-0">

From 77fa4de78c1dc00a8256b007af258a7a356d9b5e Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Wed, 14 Feb 2024 10:16:41 +0530
Subject: [PATCH 08/17] Add facility name to ReportTable component (#7190)

* Add facility name to ReportTable component

* Refactor ReportTable component to remove facilityName prop
---
 .../Facility/Investigations/Reports/ReportTable.tsx  | 12 ++++++++++--
 .../Facility/Investigations/Reports/types.ts         |  5 ++++-
 .../Facility/Investigations/Reports/utils.tsx        | 10 +++++++---
 src/Components/Patient/PatientInfoCard.tsx           |  2 +-
 4 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/src/Components/Facility/Investigations/Reports/ReportTable.tsx b/src/Components/Facility/Investigations/Reports/ReportTable.tsx
index 1f20ec94180..c15eec4e33b 100644
--- a/src/Components/Facility/Investigations/Reports/ReportTable.tsx
+++ b/src/Components/Facility/Investigations/Reports/ReportTable.tsx
@@ -124,9 +124,17 @@ const ReportTable: FC<ReportTableProps> = ({
                   <th
                     scope="col"
                     key={session.session_external_id}
-                    className="bg-[#4B5563] px-6 py-3 text-center text-xs font-semibold uppercase  tracking-wider text-[#F9FAFB]"
+                    className="bg-[#4B5563] px-6 py-3 text-center text-xs  font-semibold tracking-wider text-[#F9FAFB]"
                   >
-                    {formatDateTime(session.session_created_date)}
+                    <div className="flex flex-col items-center justify-center gap-1">
+                      {formatDateTime(session.session_created_date)}
+                      <a
+                        className="max-w-fit font-semibold text-white hover:underline"
+                        href={`/facility/${session.facility_id}/`}
+                      >
+                        {session.facility_name}
+                      </a>
+                    </div>
                   </th>
                 ))}
                 <th
diff --git a/src/Components/Facility/Investigations/Reports/types.ts b/src/Components/Facility/Investigations/Reports/types.ts
index 8c48fe30864..7bb88428896 100644
--- a/src/Components/Facility/Investigations/Reports/types.ts
+++ b/src/Components/Facility/Investigations/Reports/types.ts
@@ -1,8 +1,10 @@
 import { InvestigationValueType } from "..";
+import { ConsultationModel } from "../../models";
 
 export interface Investigation {
   id: string;
   group_object: any;
+  consultation_object: ConsultationModel;
   investigation_object: {
     external_id: string;
     name: string;
@@ -16,12 +18,13 @@ export interface Investigation {
   session_object: {
     session_external_id: string;
     session_created_date: string;
+    facility_name: string;
+    facility_id: string;
   };
   value: number | null;
   notes: any;
   investigation: number;
   group: any;
-  consultation: number;
   session: number;
 }
 
diff --git a/src/Components/Facility/Investigations/Reports/utils.tsx b/src/Components/Facility/Investigations/Reports/utils.tsx
index e57f3c42c53..7228f3f47d2 100644
--- a/src/Components/Facility/Investigations/Reports/utils.tsx
+++ b/src/Components/Facility/Investigations/Reports/utils.tsx
@@ -3,7 +3,13 @@ import { InvestigationResponse } from "./types";
 
 export const transformData = _.memoize((data: InvestigationResponse) => {
   const sessions = _.chain(data)
-    .map((value) => value.session_object)
+    .map((value) => {
+      return {
+        ...value.session_object,
+        facility_name: value.consultation_object?.facility_name,
+        facility_id: value.consultation_object?.facility,
+      };
+    })
     .uniqBy("session_external_id")
     .orderBy("session_created_date", "desc")
     .value();
@@ -28,7 +34,6 @@ export const transformData = _.memoize((data: InvestigationResponse) => {
       }
     });
     const {
-      consultation,
       group,
       group_object,
       id,
@@ -40,7 +45,6 @@ export const transformData = _.memoize((data: InvestigationResponse) => {
     } = value[0];
 
     return {
-      consultation,
       group,
       group_object,
       id,
diff --git a/src/Components/Patient/PatientInfoCard.tsx b/src/Components/Patient/PatientInfoCard.tsx
index 67df8a2dd29..25683e1a461 100644
--- a/src/Components/Patient/PatientInfoCard.tsx
+++ b/src/Components/Patient/PatientInfoCard.tsx
@@ -411,7 +411,7 @@ export default function PatientInfoCard(props: {
                             Principal Diagnosis:
                           </div>
                           <div className="flex gap-2 text-sm">
-                            {principal_diagnosis.diagnosis_object.label}{" "}
+                            {principal_diagnosis.diagnosis_object?.label ?? "-"}{" "}
                             <span className="flex items-center rounded border border-primary-500 pl-1 pr-2 text-xs font-medium text-primary-500">
                               <CareIcon icon="l-check" className="text-base" />
                               <p className="capitalize">

From 7956c90dd4862a50071b610bc85f15e2c7cbe34a Mon Sep 17 00:00:00 2001
From: Shyam Prakash <106866225+shyamprakash123@users.noreply.github.com>
Date: Wed, 14 Feb 2024 10:17:25 +0530
Subject: [PATCH 09/17] Hide Asset Type (#7180)

* update

* Revert "update"

This reverts commit 137539925bfd73e9163e39eb5a90760bf6b24c69.

* hideAssetType

* update

* Revert "update"

This reverts commit 137539925bfd73e9163e39eb5a90760bf6b24c69.

---------

Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com>
---
 cypress/e2e/assets_spec/asset_homepage.cy.ts  |   2 -
 cypress/e2e/assets_spec/assets_creation.cy.ts |   4 -
 cypress/e2e/sample_test_spec/filter.cy.ts     |   7 --
 cypress/pageobject/Asset/AssetCreation.ts     |  15 ---
 cypress/pageobject/Asset/AssetFilters.ts      |   9 --
 src/Components/Assets/AssetFilter.tsx         |  16 ---
 src/Components/Assets/AssetManage.tsx         |   5 -
 src/Components/Assets/AssetsList.tsx          |   7 --
 src/Components/Facility/AssetCreate.tsx       | 101 +++++-------------
 9 files changed, 28 insertions(+), 138 deletions(-)

diff --git a/cypress/e2e/assets_spec/asset_homepage.cy.ts b/cypress/e2e/assets_spec/asset_homepage.cy.ts
index 388f19424a4..5710df08e83 100644
--- a/cypress/e2e/assets_spec/asset_homepage.cy.ts
+++ b/cypress/e2e/assets_spec/asset_homepage.cy.ts
@@ -63,7 +63,6 @@ describe("Asset Tab", () => {
   it("Filter Asset", () => {
     assetFilters.filterAssets(
       "Dummy Facility 40",
-      "INTERNAL",
       "ACTIVE",
       "ONVIF Camera",
       "Camera Loc"
@@ -71,7 +70,6 @@ describe("Asset Tab", () => {
     assetFilters.clickadvancefilter();
     assetFilters.clickslideoverbackbutton(); // to verify the back button doesn't clear applied filters
     assetFilters.assertFacilityText("Dummy Facility 40");
-    assetFilters.assertAssetTypeText("INTERNAL");
     assetFilters.assertAssetClassText("ONVIF");
     assetFilters.assertStatusText("ACTIVE");
     assetFilters.assertLocationText("Camera Loc");
diff --git a/cypress/e2e/assets_spec/assets_creation.cy.ts b/cypress/e2e/assets_spec/assets_creation.cy.ts
index 63f8bee50c8..f8edc2bb172 100644
--- a/cypress/e2e/assets_spec/assets_creation.cy.ts
+++ b/cypress/e2e/assets_spec/assets_creation.cy.ts
@@ -29,7 +29,6 @@ describe("Asset", () => {
     assetPage.clickCreateAsset();
 
     assetPage.verifyEmptyAssetNameError();
-    assetPage.verifyEmptyAssetTypeError();
     assetPage.verifyEmptyLocationError();
     assetPage.verifyEmptyStatusError();
     assetPage.verifyEmptyPhoneError();
@@ -41,7 +40,6 @@ describe("Asset", () => {
     assetPage.createAsset();
     assetPage.selectFacility("Dummy Facility 40");
     assetPage.selectLocation("Camera Loc");
-    assetPage.selectAssetType("Internal");
     assetPage.selectAssetClass("ONVIF Camera");
 
     const qr_id_1 = uuidv4();
@@ -68,7 +66,6 @@ describe("Asset", () => {
     const qr_id_2 = uuidv4();
 
     assetPage.selectLocation("Camera Loc");
-    assetPage.selectAssetType("Internal");
     assetPage.selectAssetClass("ONVIF Camera");
     assetPage.enterAssetDetails(
       "New Test Asset 2",
@@ -141,7 +138,6 @@ describe("Asset", () => {
     assetPage.createAsset();
     assetPage.selectFacility("Dummy Facility 40");
     assetPage.selectLocation("Camera Loc");
-    assetPage.selectAssetType("Internal");
     assetPage.selectAssetClass("HL7 Vitals Monitor");
 
     const qr_id_1 = uuidv4();
diff --git a/cypress/e2e/sample_test_spec/filter.cy.ts b/cypress/e2e/sample_test_spec/filter.cy.ts
index a015d1ba7c5..df934c641bb 100644
--- a/cypress/e2e/sample_test_spec/filter.cy.ts
+++ b/cypress/e2e/sample_test_spec/filter.cy.ts
@@ -20,13 +20,6 @@ describe("Sample Filter", () => {
       .click();
   });
 
-  it("Filter by Asset Type", () => {
-    cy.get("#result").click();
-    cy.get("li[role='option']")
-      .contains(/^POSITIVE$/)
-      .click();
-  });
-
   it("Filter by sample type", () => {
     cy.get("#sample_type").click();
     cy.get("li[role='option']")
diff --git a/cypress/pageobject/Asset/AssetCreation.ts b/cypress/pageobject/Asset/AssetCreation.ts
index 6932b5ed15e..8f611e97d92 100644
--- a/cypress/pageobject/Asset/AssetCreation.ts
+++ b/cypress/pageobject/Asset/AssetCreation.ts
@@ -24,14 +24,6 @@ export class AssetPage {
       });
   }
 
-  selectAssetType(assetType: string) {
-    cy.get("[data-testid=asset-type-input] button")
-      .click()
-      .then(() => {
-        cy.get("[role='option']").contains(assetType).click();
-      });
-  }
-
   selectAssetClass(assetClass: string) {
     cy.get("[data-testid=asset-class-input] button")
       .click()
@@ -205,13 +197,6 @@ export class AssetPage {
     );
   }
 
-  verifyEmptyAssetTypeError() {
-    cy.get("[data-testid=asset-type-input] span").should(
-      "contain",
-      "Select an asset type"
-    );
-  }
-
   verifyEmptyStatusError() {
     cy.get("[data-testid=asset-working-status-input] span").should(
       "contain",
diff --git a/cypress/pageobject/Asset/AssetFilters.ts b/cypress/pageobject/Asset/AssetFilters.ts
index 5ded59f4f63..33363f2d161 100644
--- a/cypress/pageobject/Asset/AssetFilters.ts
+++ b/cypress/pageobject/Asset/AssetFilters.ts
@@ -1,7 +1,6 @@
 export class AssetFilters {
   filterAssets(
     facilityName: string,
-    assetType: string,
     assetStatus: string,
     assetClass: string,
     assetLocation: string
@@ -13,11 +12,6 @@ export class AssetFilters {
       .then(() => {
         cy.get("[role='option']").contains(facilityName).click();
       });
-    cy.get("#asset-type")
-      .click()
-      .then(() => {
-        cy.get("[role='option']").contains(assetType).click();
-      });
     cy.get("#asset-status")
       .click()
       .then(() => {
@@ -65,9 +59,6 @@ export class AssetFilters {
   assertFacilityText(text) {
     cy.get("[data-testid=Facility]").should("contain", text);
   }
-  assertAssetTypeText(text) {
-    cy.get("[data-testid='Asset Type']").should("contain", text);
-  }
   assertAssetClassText(text) {
     cy.get("[data-testid='Asset Class']").should("contain", text);
   }
diff --git a/src/Components/Assets/AssetFilter.tsx b/src/Components/Assets/AssetFilter.tsx
index 3edde4ab0cd..1fca1475269 100644
--- a/src/Components/Assets/AssetFilter.tsx
+++ b/src/Components/Assets/AssetFilter.tsx
@@ -21,9 +21,6 @@ const getDate = (value: any) =>
 function AssetFilter(props: any) {
   const { filter, onChange, closeFilter, removeFilters } = props;
   const [facility, setFacility] = useState<FacilityModel | null>(null);
-  const [asset_type, setAssetType] = useState<string>(
-    filter.asset_type ? filter.asset_type : ""
-  );
   const [asset_status, setAssetStatus] = useState<string>(filter.status || "");
   const [asset_class, setAssetClass] = useState<string>(
     filter.asset_class || ""
@@ -61,7 +58,6 @@ function AssetFilter(props: any) {
   const applyFilter = () => {
     const data = {
       facility: facilityId,
-      asset_type: asset_type ?? "",
       asset_class: asset_class ?? "",
       status: asset_status ?? "",
       location: locationId ?? "",
@@ -125,18 +121,6 @@ function AssetFilter(props: any) {
         </div>
       )}
 
-      <SelectFormField
-        label="Asset Type"
-        errorClassName="hidden"
-        id="asset-type"
-        name="asset_type"
-        options={["EXTERNAL", "INTERNAL"]}
-        optionLabel={(o) => o}
-        optionValue={(o) => o}
-        value={asset_type}
-        onChange={({ value }) => setAssetType(value)}
-      />
-
       <SelectFormField
         id="asset-status"
         name="asset_status"
diff --git a/src/Components/Assets/AssetManage.tsx b/src/Components/Assets/AssetManage.tsx
index 4f65bc6a569..0da432eccb6 100644
--- a/src/Components/Assets/AssetManage.tsx
+++ b/src/Components/Assets/AssetManage.tsx
@@ -365,11 +365,6 @@ const AssetManage = (props: AssetManageProps) => {
                   {asset?.description}
                 </div>
                 <div className="flex flex-wrap gap-2">
-                  {asset?.asset_type === "INTERNAL" ? (
-                    <Chip text="Internal" startIcon="l-building" />
-                  ) : (
-                    <Chip text="External" startIcon="l-globe" />
-                  )}
                   {asset?.status === "ACTIVE" ? (
                     <Chip text="Active" startIcon="l-check" />
                   ) : (
diff --git a/src/Components/Assets/AssetsList.tsx b/src/Components/Assets/AssetsList.tsx
index 946618fd970..f210bf04535 100644
--- a/src/Components/Assets/AssetsList.tsx
+++ b/src/Components/Assets/AssetsList.tsx
@@ -45,7 +45,6 @@ const AssetsList = () => {
   const [isScannerActive, setIsScannerActive] = useState(false);
   const [totalCount, setTotalCount] = useState(0);
   const [facility, setFacility] = useState<FacilityModel>();
-  const [asset_type, setAssetType] = useState<string>();
   const [status, setStatus] = useState<string>();
   const [asset_class, setAssetClass] = useState<string>();
   const [importAssetModalOpen, setImportAssetModalOpen] = useState(false);
@@ -60,7 +59,6 @@ const AssetsList = () => {
     offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage,
     search_text: qParams.search || "",
     facility: qParams.facility || "",
-    asset_type: qParams.asset_type || "",
     asset_class: qParams.asset_class || "",
     location: qParams.facility ? qParams.location || "" : "",
     status: qParams.status || "",
@@ -91,10 +89,6 @@ const AssetsList = () => {
     prefetch: !!qParams.facility,
   });
 
-  useEffect(() => {
-    setAssetType(qParams.asset_type);
-  }, [qParams.asset_type]);
-
   useEffect(() => {
     setStatus(qParams.status);
   }, [qParams.status]);
@@ -387,7 +381,6 @@ const AssetsList = () => {
                 qParams.facility && facilityObject?.name
               ),
               badge("Name/Serial No./QR ID", "search"),
-              value("Asset Type", "asset_type", asset_type ?? ""),
               value("Asset Class", "asset_class", asset_class ?? ""),
               value("Status", "status", status?.replace(/_/g, " ") ?? ""),
               value(
diff --git a/src/Components/Facility/AssetCreate.tsx b/src/Components/Facility/AssetCreate.tsx
index 784174cd2f7..0c422d1f646 100644
--- a/src/Components/Facility/AssetCreate.tsx
+++ b/src/Components/Facility/AssetCreate.tsx
@@ -40,7 +40,6 @@ const Loading = lazy(() => import("../Common/Loading"));
 
 const formErrorKeys = [
   "name",
-  "asset_type",
   "asset_class",
   "description",
   "is_working",
@@ -103,12 +102,10 @@ const AssetCreate = (props: AssetProps) => {
   const { goBack } = useAppHistory();
   const { facilityId, assetId } = props;
 
-  let assetTypeInitial: AssetType;
   let assetClassInitial: AssetClass;
 
   const [state, dispatch] = useReducer(asset_create_reducer, initialState);
   const [name, setName] = useState("");
-  const [asset_type, setAssetType] = useState<AssetType>();
   const [asset_class, setAssetClass] = useState<AssetClass>();
   const [not_working_reason, setNotWorkingReason] = useState("");
   const [description, setDescription] = useState("");
@@ -177,7 +174,6 @@ const AssetCreate = (props: AssetProps) => {
       setName(asset.name);
       setDescription(asset.description);
       setLocation(asset.location_object.id!);
-      setAssetType(asset.asset_type);
       setAssetClass(asset.asset_class);
       setIsWorking(String(asset.is_working));
       setNotWorkingReason(asset.not_working_reason);
@@ -219,12 +215,6 @@ const AssetCreate = (props: AssetProps) => {
             invalidForm = true;
           }
           return;
-        case "asset_type":
-          if (!asset_type || asset_type == "NONE") {
-            errors[field] = "Select an asset type";
-            invalidForm = true;
-          }
-          return;
         case "support_phone": {
           if (!support_phone) {
             errors[field] = "Field is required";
@@ -282,7 +272,6 @@ const AssetCreate = (props: AssetProps) => {
     setName("");
     setDescription("");
     setLocation("");
-    setAssetType(assetTypeInitial);
     setAssetClass(assetClassInitial);
     setIsWorking(undefined);
     setNotWorkingReason("");
@@ -307,7 +296,7 @@ const AssetCreate = (props: AssetProps) => {
       setIsLoading(true);
       const data: any = {
         name: name,
-        asset_type: asset_type,
+        asset_type: AssetType.INTERNAL,
         asset_class: asset_class || "",
         description: description,
         is_working: is_working,
@@ -547,68 +536,34 @@ const AssetCreate = (props: AssetProps) => {
                         errors={state.errors.location}
                       />
                     </div>
-                    {/* Asset Type */}
-                    <div className="col-span-6 flex flex-col gap-x-12 transition-all lg:flex-row xl:gap-x-16">
-                      <div
-                        ref={fieldRef["asset_type"]}
-                        className="flex-1"
-                        data-testid="asset-type-input"
-                      >
-                        <SelectFormField
-                          label={t("asset_type")}
-                          name="asset_type"
-                          required
-                          options={[
-                            {
-                              title: "Internal",
-                              description:
-                                "Asset is inside the facility premises.",
-                              value: AssetType.INTERNAL,
-                            },
-                            {
-                              title: "External",
-                              description:
-                                "Asset is outside the facility premises.",
-                              value: AssetType.EXTERNAL,
-                            },
-                          ]}
-                          value={asset_type}
-                          optionLabel={({ title }) => title}
-                          optionDescription={({ description }) => description}
-                          optionValue={({ value }) => value}
-                          onChange={({ value }) => setAssetType(value)}
-                          error={state.errors.asset_type}
-                        />
-                      </div>
 
-                      {/* Asset Class */}
-                      <div
-                        ref={fieldRef["asset_class"]}
-                        className="flex-1"
-                        data-testid="asset-class-input"
-                      >
-                        <SelectFormField
-                          disabled={!!(props.assetId && asset_class)}
-                          name="asset_class"
-                          label={t("asset_class")}
-                          value={asset_class}
-                          options={[
-                            { title: "ONVIF Camera", value: AssetClass.ONVIF },
-                            {
-                              title: "HL7 Vitals Monitor",
-                              value: AssetClass.HL7MONITOR,
-                            },
-                            {
-                              title: "Ventilator",
-                              value: AssetClass.VENTILATOR,
-                            },
-                          ]}
-                          optionLabel={({ title }) => title}
-                          optionValue={({ value }) => value}
-                          onChange={({ value }) => setAssetClass(value)}
-                          error={state.errors.asset_class}
-                        />
-                      </div>
+                    {/* Asset Class */}
+                    <div
+                      ref={fieldRef["asset_class"]}
+                      className="col-span-6"
+                      data-testid="asset-class-input"
+                    >
+                      <SelectFormField
+                        disabled={!!(props.assetId && asset_class)}
+                        name="asset_class"
+                        label={t("asset_class")}
+                        value={asset_class}
+                        options={[
+                          { title: "ONVIF Camera", value: AssetClass.ONVIF },
+                          {
+                            title: "HL7 Vitals Monitor",
+                            value: AssetClass.HL7MONITOR,
+                          },
+                          {
+                            title: "Ventilator",
+                            value: AssetClass.VENTILATOR,
+                          },
+                        ]}
+                        optionLabel={({ title }) => title}
+                        optionValue={({ value }) => value}
+                        onChange={({ value }) => setAssetClass(value)}
+                        error={state.errors.asset_class}
+                      />
                     </div>
                     {/* Description */}
                     <div

From ba0b192222ce4721b8444c91ee1753bcf0f46fc9 Mon Sep 17 00:00:00 2001
From: Shyam Prakash <106866225+shyamprakash123@users.noreply.github.com>
Date: Wed, 14 Feb 2024 10:17:54 +0530
Subject: [PATCH 10/17] Increase the Add button height in skills slideover.
 (#7163)

* Fixed btn height

* updated height, width, font-size according to the requested changes.

* update

* Revert "update"

This reverts commit 137539925bfd73e9163e39eb5a90760bf6b24c69.
---
 src/Components/Users/ManageUsers.tsx     | 2 +-
 src/Components/Users/SkillsSlideOver.tsx | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Components/Users/ManageUsers.tsx b/src/Components/Users/ManageUsers.tsx
index 6f5de125600..15f4ba4ed81 100644
--- a/src/Components/Users/ManageUsers.tsx
+++ b/src/Components/Users/ManageUsers.tsx
@@ -671,7 +671,7 @@ function UserFacilities(props: { user: any }) {
         <ButtonV2
           id="link-facility"
           disabled={!facility}
-          className="mt-1"
+          className="mt-1 h-[45px] w-[74px] text-base"
           onClick={() => addFacility(username, facility)}
         >
           Add
diff --git a/src/Components/Users/SkillsSlideOver.tsx b/src/Components/Users/SkillsSlideOver.tsx
index 63353479f0d..616dbb6404d 100644
--- a/src/Components/Users/SkillsSlideOver.tsx
+++ b/src/Components/Users/SkillsSlideOver.tsx
@@ -125,7 +125,7 @@ export default ({ show, setShow, username }: IProps) => {
                   id="add-skill-button"
                   disabled={!authorizeForAddSkill}
                   onClick={() => addSkill(username, selectedSkill)}
-                  className="w-6rem"
+                  className="mt-1 h-[45px] w-[74px] text-base"
                 >
                   {t("add")}
                 </ButtonV2>

From bba3b5c7d2172ff01cc481d8f75d18df6403f12d Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Wed, 14 Feb 2024 10:18:25 +0530
Subject: [PATCH 11/17] Set Form Drafts to expire after 24 hours (#7125)

---
 src/Utils/AutoSave.tsx | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/Utils/AutoSave.tsx b/src/Utils/AutoSave.tsx
index 5cdf118650f..0c929f371e5 100644
--- a/src/Utils/AutoSave.tsx
+++ b/src/Utils/AutoSave.tsx
@@ -104,6 +104,23 @@ export function DraftSection(props: {
     };
   }, []);
 
+  // Remove drafts older than 24 hours
+  useEffect(() => {
+    const keys = Object.keys(localStorage);
+    const now = Date.now();
+    keys.forEach((key) => {
+      if (key.startsWith("form_draft_")) {
+        const savedDrafts = localStorage.getItem(key);
+        const drafts = savedDrafts ? JSON.parse(savedDrafts) : [];
+        const newDrafts = drafts.filter(
+          (draft: Draft) => now - draft.timestamp < 24 * 60 * 60 * 1000
+        );
+        localStorage.setItem(key, JSON.stringify(newDrafts));
+        if (newDrafts.length === 0) localStorage.removeItem(key);
+      }
+    });
+  }, []);
+
   return (
     <>
       {drafts && (

From 2cc66f08e2f49d9dadf21fd038e724e9bfadbd5d Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Wed, 14 Feb 2024 12:51:53 +0530
Subject: [PATCH 12/17] Update Uptime endpoint for AssetUptime (#7210)

* Track uptime for Locations

* Refactor Uptime component to accept route and params

* Remove unused import in api.tsx
---
 src/Components/Assets/AssetManage.tsx |  7 ++++-
 src/Components/Assets/AssetTypes.tsx  | 11 ++-----
 src/Components/Common/Uptime.tsx      | 41 ++++++++++++++-------------
 src/Redux/api.tsx                     | 25 +++++++---------
 4 files changed, 41 insertions(+), 43 deletions(-)

diff --git a/src/Components/Assets/AssetManage.tsx b/src/Components/Assets/AssetManage.tsx
index 0da432eccb6..77bb88da3a8 100644
--- a/src/Components/Assets/AssetManage.tsx
+++ b/src/Components/Assets/AssetManage.tsx
@@ -498,7 +498,12 @@ const AssetManage = (props: AssetManageProps) => {
       </div>
       {asset?.id &&
         asset?.asset_class &&
-        asset?.asset_class != AssetClass.NONE && <Uptime assetId={asset?.id} />}
+        asset?.asset_class != AssetClass.NONE && (
+          <Uptime
+            route={routes.listAssetAvailability}
+            params={{ external_id: asset.id }}
+          />
+        )}
       <div className="mb-4 mt-8 text-xl font-semibold">Service History</div>
       <div
         className="min-w-full overflow-hidden overflow-x-auto align-middle shadow sm:rounded-lg"
diff --git a/src/Components/Assets/AssetTypes.tsx b/src/Components/Assets/AssetTypes.tsx
index 6186f3c4ee9..39fff240efb 100644
--- a/src/Components/Assets/AssetTypes.tsx
+++ b/src/Components/Assets/AssetTypes.tsx
@@ -113,16 +113,11 @@ export interface AssetsResponse {
   results: AssetData[];
 }
 
-export interface AssetUptimeRecord {
-  id: string;
-  asset: {
-    id: string;
-    name: string;
-  };
+export interface AvailabilityRecord {
+  linked_id: string;
+  linked_model: string;
   status: string;
   timestamp: string;
-  created_date: string;
-  modified_date: string;
 }
 
 export interface AssetTransaction {
diff --git a/src/Components/Common/Uptime.tsx b/src/Components/Common/Uptime.tsx
index e3c7dd7a439..e7272e2e1f4 100644
--- a/src/Components/Common/Uptime.tsx
+++ b/src/Components/Common/Uptime.tsx
@@ -1,10 +1,10 @@
 import { Popover } from "@headlessui/react";
 import { useEffect, useRef, useState } from "react";
-import { AssetStatus, AssetUptimeRecord } from "../Assets/AssetTypes";
+import { AssetStatus, AvailabilityRecord } from "../Assets/AssetTypes";
 import { classNames } from "../../Utils/utils";
 import dayjs from "../../Utils/dayjs";
 import useQuery from "../../Utils/request/useQuery.js";
-import routes from "../../Redux/api.js";
+import { PaginatedResponse, QueryRoute } from "../../Utils/request/types";
 
 const STATUS_COLORS = {
   Operational: "bg-green-500",
@@ -37,7 +37,7 @@ function UptimeInfo({
   records,
   date,
 }: {
-  records: AssetUptimeRecord[];
+  records: AvailabilityRecord[];
   date: string;
 }) {
   const incidents =
@@ -66,7 +66,7 @@ function UptimeInfo({
                     let endTimestamp;
                     let ongoing = false;
 
-                    if (prevIncident?.id) {
+                    if (prevIncident?.linked_id) {
                       endTimestamp = dayjs(prevIncident.timestamp);
                     } else if (dayjs(incident.timestamp).isSame(now, "day")) {
                       endTimestamp = dayjs();
@@ -141,7 +141,7 @@ function UptimeInfoPopover({
   date,
   numDays,
 }: {
-  records: AssetUptimeRecord[];
+  records: AvailabilityRecord[];
   day: number;
   date: string;
   numDays: number;
@@ -165,12 +165,17 @@ function UptimeInfoPopover({
   );
 }
 
-export default function Uptime(props: { assetId: string }) {
+export default function Uptime(
+  props: Readonly<{
+    route: QueryRoute<PaginatedResponse<AvailabilityRecord>>;
+    params?: Record<string, string | number>;
+  }>
+) {
   const [summary, setSummary] = useState<{
-    [key: number]: AssetUptimeRecord[];
+    [key: number]: AvailabilityRecord[];
   }>([]);
-  const { data, loading } = useQuery(routes.listAssetAvailability, {
-    query: { external_id: props.assetId },
+  const { data, loading } = useQuery(props.route, {
+    pathParams: props.params,
     onResponse: ({ data }) => setUptimeRecord(data?.results.reverse() ?? []),
   });
   const availabilityData = data?.results ?? [];
@@ -186,8 +191,8 @@ export default function Uptime(props: { assetId: string }) {
     setNumDays(Math.min(newNumDays, 100));
   };
 
-  const setUptimeRecord = (records: AssetUptimeRecord[]): void => {
-    const recordsByDayBefore: { [key: number]: AssetUptimeRecord[] } = {};
+  const setUptimeRecord = (records: AvailabilityRecord[]): void => {
+    const recordsByDayBefore: { [key: number]: AvailabilityRecord[] } = {};
 
     records.forEach((record) => {
       const timestamp = dayjs(record.timestamp).startOf("day");
@@ -207,10 +212,8 @@ export default function Uptime(props: { assetId: string }) {
         recordsByDayBefore[i] = [];
         if (statusToCarryOver) {
           recordsByDayBefore[i].push({
-            id: "",
-            asset: { id: "", name: "" },
-            created_date: "",
-            modified_date: "",
+            linked_id: "",
+            linked_model: "",
             status: statusToCarryOver,
             timestamp: dayjs()
               .subtract(i, "days")
@@ -225,10 +228,8 @@ export default function Uptime(props: { assetId: string }) {
           ).length === 0
         ) {
           recordsByDayBefore[i].unshift({
-            id: "",
-            asset: { id: "", name: "" },
-            created_date: "",
-            modified_date: "",
+            linked_id: "",
+            linked_model: "",
             status: statusToCarryOver,
             timestamp: dayjs()
               .subtract(i, "days")
@@ -284,7 +285,7 @@ export default function Uptime(props: { assetId: string }) {
       const statusColors: (typeof STATUS_COLORS)[keyof typeof STATUS_COLORS][] =
         [];
       let dayUptimeScore = 0;
-      const recordsInPeriodCache: { [key: number]: AssetUptimeRecord[] } = {};
+      const recordsInPeriodCache: { [key: number]: AvailabilityRecord[] } = {};
       for (let i = 0; i < 3; i++) {
         const start = i * 8;
         const end = (i + 1) * 8;
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index eed17ad3b4b..40c842adc07 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -27,7 +27,7 @@ import {
   AssetService,
   AssetServiceUpdate,
   AssetTransaction,
-  AssetUptimeRecord,
+  AvailabilityRecord,
   PatientAssetBed,
 } from "../Components/Assets/AssetTypes";
 import {
@@ -371,6 +371,11 @@ const routes = {
     path: "/api/v1/facility/{facility_external_id}/asset_location/{external_id}/",
     method: "PATCH",
   },
+  getFacilityAssetLocationAvailability: {
+    path: "/api/v1/facility/{facility_external_id}/asset_location/{external_id}/availability/",
+    method: "GET",
+    TRes: Type<PaginatedResponse<AvailabilityRecord>>(),
+  },
 
   // Asset bed
   listAssetBeds: {
@@ -1116,6 +1121,11 @@ const routes = {
     TRes: Type<AssetData>(),
     TBody: Type<Partial<AssetData>>(),
   },
+  listAssetAvailability: {
+    path: "/api/v1/asset/{external_id}/availability/",
+    method: "GET",
+    TRes: Type<PaginatedResponse<AvailabilityRecord>>(),
+  },
 
   // Asset transaction endpoints
 
@@ -1290,19 +1300,6 @@ const routes = {
     },
   },
 
-  // Asset Availability endpoints
-
-  listAssetAvailability: {
-    path: "/api/v1/asset_availability/",
-    method: "GET",
-    TRes: Type<PaginatedResponse<AssetUptimeRecord>>(),
-  },
-  getAssetAvailability: {
-    path: "/api/v1/asset_availability/{id}",
-    method: "GET",
-    TRes: Type<AssetUptimeRecord>(),
-  },
-
   // Prescription endpoints
 
   listPrescriptions: {

From 5e0727d88f2801c059d051a80d9ed25f124f6606 Mon Sep 17 00:00:00 2001
From: Kshitij Verma <101321276+kshitijv256@users.noreply.github.com>
Date: Wed, 14 Feb 2024 12:54:23 +0530
Subject: [PATCH 13/17] Added support for multi-line text input for Doctor
 Notes (#6977)

* Changed TextFormField to TextAreaFormField

* made doctor notes input size dynamic

* fixed max height of textareafield

* made max height variable

* replaced ids with ref

* removed id prop

* added required comments

* added required comments

* lineheight computed dynamically
---
 .../ConsultationDoctorNotes/index.tsx         |  8 +--
 .../Facility/PatientNotesSlideover.tsx        |  7 +--
 .../AutoExpandingTextInputFormField.tsx       | 30 +++++++++++
 .../Form/FormFields/TextAreaFormField.tsx     | 53 +++++++++++--------
 4 files changed, 71 insertions(+), 27 deletions(-)
 create mode 100644 src/Components/Form/FormFields/AutoExpandingTextInputFormField.tsx

diff --git a/src/Components/Facility/ConsultationDoctorNotes/index.tsx b/src/Components/Facility/ConsultationDoctorNotes/index.tsx
index 8e39ee04e4e..c17ee3fb2db 100644
--- a/src/Components/Facility/ConsultationDoctorNotes/index.tsx
+++ b/src/Components/Facility/ConsultationDoctorNotes/index.tsx
@@ -1,7 +1,6 @@
 import { useState } from "react";
 import * as Notification from "../../../Utils/Notifications.js";
 import Page from "../../Common/components/Page";
-import TextFormField from "../../Form/FormFields/TextFormField";
 import ButtonV2 from "../../Common/components/ButtonV2";
 import CareIcon from "../../../CAREUI/icons/CareIcon";
 import { NonReadOnlyUsers } from "../../../Utils/AuthorizeFor";
@@ -13,6 +12,7 @@ import request from "../../../Utils/request/request.js";
 import useQuery from "../../../Utils/request/useQuery.js";
 import useKeyboardShortcut from "use-keyboard-shortcut";
 import { isAppleDevice } from "../../../Utils/utils.js";
+import AutoExpandingTextInputFormField from "../../Form/FormFields/AutoExpandingTextInputFormField.js";
 
 interface ConsultationDoctorNotesProps {
   patientId: string;
@@ -120,12 +120,14 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
         />
 
         <div className="relative mx-4 flex items-center">
-          <TextFormField
+          <AutoExpandingTextInputFormField
+            id="doctor_consultation_notes"
+            maxHeight={160}
+            rows={1}
             name="note"
             value={noteField}
             onChange={(e) => setNoteField(e.value)}
             className="grow"
-            type="text"
             errorClassName="hidden"
             placeholder="Type your Note"
             disabled={!patientActive}
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index 5ecf30cfcdf..2e231576eb2 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -3,7 +3,6 @@ import * as Notification from "../../Utils/Notifications.js";
 import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
 import CareIcon from "../../CAREUI/icons/CareIcon";
 import { classNames, isAppleDevice } from "../../Utils/utils";
-import TextFormField from "../Form/FormFields/TextFormField";
 import ButtonV2 from "../Common/components/ButtonV2";
 import { make as Link } from "../Common/components/Link.bs";
 import { useMessageListener } from "../../Common/hooks/useMessageListener";
@@ -12,6 +11,7 @@ import request from "../../Utils/request/request";
 import routes from "../../Redux/api";
 import { PatientNoteStateType } from "./models";
 import useKeyboardShortcut from "use-keyboard-shortcut";
+import AutoExpandingTextInputFormField from "../Form/FormFields/AutoExpandingTextInputFormField.js";
 
 interface PatientNotesProps {
   patientId: string;
@@ -169,13 +169,14 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
             setReload={setReload}
           />
           <div className="relative mx-4 flex items-center">
-            <TextFormField
+            <AutoExpandingTextInputFormField
               id="doctor_notes_textarea"
+              maxHeight={160}
+              rows={1}
               name="note"
               value={noteField}
               onChange={(e) => setNoteField(e.value)}
               className="grow"
-              type="text"
               errorClassName="hidden"
               placeholder="Type your Note"
               disabled={!patientActive}
diff --git a/src/Components/Form/FormFields/AutoExpandingTextInputFormField.tsx b/src/Components/Form/FormFields/AutoExpandingTextInputFormField.tsx
new file mode 100644
index 00000000000..22707f133bc
--- /dev/null
+++ b/src/Components/Form/FormFields/AutoExpandingTextInputFormField.tsx
@@ -0,0 +1,30 @@
+import React, { useEffect, useRef } from "react";
+import TextAreaFormField, { TextAreaFormFieldProps } from "./TextAreaFormField";
+
+type AutoExpandingTextInputFormFieldProps = TextAreaFormFieldProps & {
+  maxHeight?: number;
+};
+
+const AutoExpandingTextInputFormField = (
+  props: AutoExpandingTextInputFormFieldProps
+) => {
+  const myref = useRef<HTMLTextAreaElement>(null);
+  useEffect(() => {
+    if (myref.current == null) return;
+    const text = myref.current.textContent?.split("\n");
+    const len = text?.length || 1;
+    // 46 is height of the textarea when there is only 1 line
+    // getting line height from window
+    const lineHeight =
+      window.getComputedStyle(myref.current).lineHeight.slice(0, -2) || "20";
+    // added 26 for padding (20+26 = 46)
+    const height =
+      Math.min(len * parseInt(lineHeight), (props.maxHeight || 160) - 26) + 26;
+    // 160 is the max height of the textarea if not specified
+    myref.current.style.cssText = "height:" + height + "px";
+  });
+
+  return <TextAreaFormField ref={myref} {...props} className="w-full" />;
+};
+
+export default AutoExpandingTextInputFormField;
diff --git a/src/Components/Form/FormFields/TextAreaFormField.tsx b/src/Components/Form/FormFields/TextAreaFormField.tsx
index 23a7d025938..5c23bfec764 100644
--- a/src/Components/Form/FormFields/TextAreaFormField.tsx
+++ b/src/Components/Form/FormFields/TextAreaFormField.tsx
@@ -1,33 +1,44 @@
+import { forwardRef } from "react";
 import FormField from "./FormField";
 import { FormFieldBaseProps, useFormFieldPropsResolver } from "./Utils";
 
-type TextAreaFormFieldProps = FormFieldBaseProps<string> & {
+export type TextAreaFormFieldProps = FormFieldBaseProps<string> & {
   placeholder?: string;
   value?: string | number;
   rows?: number;
   // prefixIcon?: React.ReactNode;
   // suffixIcon?: React.ReactNode;
+  onFocus?: (event: React.FocusEvent<HTMLTextAreaElement>) => void;
+  onBlur?: (event: React.FocusEvent<HTMLTextAreaElement>) => void;
 };
 
-const TextAreaFormField = ({ rows = 3, ...props }: TextAreaFormFieldProps) => {
-  const field = useFormFieldPropsResolver(props as any);
-  return (
-    <FormField field={field}>
-      <textarea
-        id={field.id}
-        disabled={field.disabled}
-        name={field.name}
-        value={field.value}
-        required={field.required}
-        onChange={(e) => field.handleChange(e.target.value)}
-        placeholder={props.placeholder}
-        rows={rows}
-        className={`cui-input-base resize-none ${
-          field.error && "border-danger-500"
-        }`}
-      />
-    </FormField>
-  );
-};
+const TextAreaFormField = forwardRef(
+  (
+    { rows = 3, ...props }: TextAreaFormFieldProps,
+    ref?: React.Ref<HTMLTextAreaElement>
+  ) => {
+    const field = useFormFieldPropsResolver(props as any);
+    return (
+      <FormField field={field}>
+        <textarea
+          id={field.id}
+          ref={ref}
+          disabled={field.disabled}
+          name={field.name}
+          value={field.value}
+          required={field.required}
+          onChange={(e) => field.handleChange(e.target.value)}
+          placeholder={props.placeholder}
+          rows={rows}
+          className={`cui-input-base resize-none ${
+            field.error && "border-danger-500"
+          }`}
+          onFocus={props.onFocus}
+          onBlur={props.onBlur}
+        />
+      </FormField>
+    );
+  }
+);
 
 export default TextAreaFormField;

From 3d0e6f2f5baba3462a22e6e654412bcf11cdc0c5 Mon Sep 17 00:00:00 2001
From: Ashesh <3626859+Ashesh3@users.noreply.github.com>
Date: Wed, 14 Feb 2024 12:56:54 +0530
Subject: [PATCH 14/17] Add edit option for doctor notes (#6919)

* Add edit option for doctor notes

* use edited_date

* Update PatientNoteCard component and models

* disableEdit for inactive patient

* Make editing more intuitive

* Refactor PatientNoteCard component buttons
---
 .../ConsultationDoctorNotes/index.tsx         |   4 +-
 src/Components/Facility/DoctorNote.tsx        |  12 +-
 .../Facility/PatientConsultationNotesList.tsx |  16 +-
 src/Components/Facility/PatientNoteCard.tsx   | 262 ++++++++++++++++--
 src/Components/Facility/PatientNotesList.tsx  |   4 +-
 .../Facility/PatientNotesSlideover.tsx        |   5 +-
 src/Components/Facility/models.tsx            |  12 +
 .../Form/FormFields/TextFormField.tsx         |   2 +
 src/Redux/api.tsx                             |  11 +
 9 files changed, 290 insertions(+), 38 deletions(-)

diff --git a/src/Components/Facility/ConsultationDoctorNotes/index.tsx b/src/Components/Facility/ConsultationDoctorNotes/index.tsx
index c17ee3fb2db..cf0f78a39bb 100644
--- a/src/Components/Facility/ConsultationDoctorNotes/index.tsx
+++ b/src/Components/Facility/ConsultationDoctorNotes/index.tsx
@@ -34,6 +34,8 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
     notes: [],
     cPage: 1,
     totalPages: 1,
+    facilityId: facilityId,
+    patientId: patientId,
   };
   const [state, setState] = useState(initialData);
 
@@ -113,8 +115,6 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
         <PatientConsultationNotesList
           state={state}
           setState={setState}
-          patientId={patientId}
-          facilityId={facilityId}
           reload={reload}
           setReload={setReload}
         />
diff --git a/src/Components/Facility/DoctorNote.tsx b/src/Components/Facility/DoctorNote.tsx
index 85703a1e3d8..1fe28ba38d0 100644
--- a/src/Components/Facility/DoctorNote.tsx
+++ b/src/Components/Facility/DoctorNote.tsx
@@ -5,11 +5,13 @@ import { PatientNoteStateType } from "./models";
 
 interface DoctorNoteProps {
   state: PatientNoteStateType;
+  setReload: any;
   handleNext: () => void;
+  disableEdit?: boolean;
 }
 
 const DoctorNote = (props: DoctorNoteProps) => {
-  const { state, handleNext } = props;
+  const { state, handleNext, setReload, disableEdit } = props;
   return (
     <div
       className="m-2 flex h-[390px] grow flex-col-reverse overflow-auto bg-white"
@@ -30,7 +32,13 @@ const DoctorNote = (props: DoctorNoteProps) => {
           scrollableTarget="patient-notes-list"
         >
           {state.notes.map((note: any) => (
-            <PatientNoteCard note={note} key={note.id} />
+            <PatientNoteCard
+              state={state}
+              note={note}
+              key={note.id}
+              setReload={setReload}
+              disableEdit={disableEdit}
+            />
           ))}
         </InfiniteScroll>
       ) : (
diff --git a/src/Components/Facility/PatientConsultationNotesList.tsx b/src/Components/Facility/PatientConsultationNotesList.tsx
index f38de51110b..2b9df8c3902 100644
--- a/src/Components/Facility/PatientConsultationNotesList.tsx
+++ b/src/Components/Facility/PatientConsultationNotesList.tsx
@@ -10,16 +10,15 @@ import request from "../../Utils/request/request";
 interface PatientNotesProps {
   state: PatientNoteStateType;
   setState: any;
-  patientId: string;
-  facilityId: string;
   reload?: boolean;
   setReload?: any;
+  disableEdit?: boolean;
 }
 
 const pageSize = RESULTS_PER_PAGE_LIMIT;
 
 const PatientConsultationNotesList = (props: PatientNotesProps) => {
-  const { state, setState, reload, setReload } = props;
+  const { state, setState, reload, setReload, disableEdit } = props;
   const consultationId = useSlug("consultation") ?? "";
 
   const [isLoading, setIsLoading] = useState(true);
@@ -28,7 +27,7 @@ const PatientConsultationNotesList = (props: PatientNotesProps) => {
     setIsLoading(true);
     const { data }: any = await request(routes.getPatientNotes, {
       pathParams: {
-        patientId: props.patientId,
+        patientId: props.state.patientId,
       },
       query: {
         consultation: consultationId,
@@ -81,7 +80,14 @@ const PatientConsultationNotesList = (props: PatientNotesProps) => {
     );
   }
 
-  return <DoctorNote state={state} handleNext={handleNext} />;
+  return (
+    <DoctorNote
+      state={state}
+      handleNext={handleNext}
+      setReload={setReload}
+      disableEdit={disableEdit}
+    />
+  );
 };
 
 export default PatientConsultationNotesList;
diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index 2f07702504a..671c1744acf 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -1,36 +1,246 @@
 import { relativeDate, formatDateTime, classNames } from "../../Utils/utils";
 import { USER_TYPES_MAP } from "../../Common/constants";
-import { PatientNotesModel } from "./models";
+import {
+  PatientNoteStateType,
+  PatientNotesEditModel,
+  PatientNotesModel,
+} from "./models";
+import ButtonV2 from "../Common/components/ButtonV2";
+import CareIcon from "../../CAREUI/icons/CareIcon";
+import { useState } from "react";
+import { Error, Success } from "../../Utils/Notifications";
+import request from "../../Utils/request/request";
+import routes from "../../Redux/api";
+import DialogModal from "../Common/Dialog";
+import { t } from "i18next";
+import dayjs from "dayjs";
+import Spinner from "../Common/Spinner";
+import useAuthUser from "../../Common/hooks/useAuthUser";
+
+const PatientNoteCard = ({
+  state,
+  note,
+  setReload,
+  disableEdit,
+}: {
+  state: PatientNoteStateType;
+  note: PatientNotesModel;
+  setReload: any;
+  disableEdit?: boolean;
+}) => {
+  const [isEditing, setIsEditing] = useState(false);
+  const [noteField, setNoteField] = useState(note.note);
+  const [showEditHistory, setShowEditHistory] = useState(false);
+  const [editHistory, setEditHistory] = useState<PatientNotesEditModel[]>([]);
+  const authUser = useAuthUser();
+
+  const fetchEditHistory = async () => {
+    const { res, data } = await request(routes.getPatientNoteEditHistory, {
+      pathParams: { patientId: state.patientId, noteId: note.id },
+    });
+    if (res?.status === 200) {
+      setEditHistory(data?.results ?? []);
+    }
+  };
+
+  const onUpdateNote = async () => {
+    if (noteField === note.note) {
+      setIsEditing(false);
+      return;
+    }
+    const payload = {
+      note: noteField,
+    };
+    if (!/\S+/.test(noteField)) {
+      Error({
+        msg: "Note Should Contain At Least 1 Character",
+      });
+      return;
+    }
+
+    const { res } = await request(routes.updatePatientNote, {
+      pathParams: { patientId: state.patientId, noteId: note.id },
+      body: payload,
+    });
+    if (res?.status === 200) {
+      Success({ msg: "Note updated successfully" });
+      setIsEditing(false);
+      setReload(true);
+    }
+  };
 
-const PatientNoteCard = ({ note }: { note: PatientNotesModel }) => {
   return (
-    <div
-      className={classNames(
-        "mt-4 flex w-full flex-col rounded-lg border border-gray-300 bg-white p-3 text-gray-800",
-        note.user_type === "RemoteSpecialist" && "border-primary-400"
-      )}
-    >
-      <div className="flex">
-        <span className="text-sm font-semibold text-gray-700">
-          {note.created_by_object?.first_name || "Unknown"}{" "}
-          {note.created_by_object?.last_name}
-        </span>
-        {note.user_type && (
-          <span className="pl-2 text-sm text-gray-700">
-            {`(${USER_TYPES_MAP[note.user_type]})`}
-          </span>
+    <>
+      {" "}
+      <div
+        className={classNames(
+          "mt-4 flex w-full flex-col rounded-lg border border-gray-300 bg-white p-3 text-gray-800",
+          note.user_type === "RemoteSpecialist" && "border-primary-400"
         )}
-      </div>
-      <span className="whitespace-pre-wrap break-words">{note.note}</span>
-      <div className="mt-3 text-end text-xs text-gray-500">
-        <div className="tooltip inline">
-          <span className="tooltip-text tooltip-left">
-            {formatDateTime(note.created_date)}
-          </span>
-          {relativeDate(note.created_date)}
+      >
+        <div className="flex justify-between">
+          <div>
+            <div>
+              <span className="text-sm font-semibold text-gray-700">
+                {note.created_by_object?.first_name || "Unknown"}{" "}
+                {note.created_by_object?.last_name}
+              </span>
+              {note.user_type && (
+                <span className="pl-2 text-sm text-gray-700">
+                  {`(${USER_TYPES_MAP[note.user_type]})`}
+                </span>
+              )}
+            </div>
+            <div className="text-xs text-gray-600">
+              <div className="tooltip inline">
+                <span className="tooltip-text tooltip-bottom">
+                  {formatDateTime(note.created_date)}
+                </span>
+                Created {relativeDate(note.created_date, true)}
+              </div>
+            </div>
+            {
+              // If last edited date is same as created date, then it is not edited
+              !dayjs(note.last_edited_date).isSame(
+                note.created_date,
+                "second"
+              ) && (
+                <div className="flex">
+                  <div
+                    className="cursor-pointer text-xs text-gray-600"
+                    onClick={() => {
+                      fetchEditHistory();
+                      setShowEditHistory(true);
+                    }}
+                  >
+                    <div className="tooltip inline">
+                      <span className="tooltip-text tooltip-bottom">
+                        {formatDateTime(note.last_edited_date)}
+                      </span>
+                      Edited {relativeDate(note.last_edited_date, true)}
+                    </div>
+                    <CareIcon
+                      icon="l-history"
+                      className="ml-1 h-4 w-4 pt-[3px] text-primary-600"
+                    />
+                  </div>
+                </div>
+              )
+            }
+          </div>
+
+          {!disableEdit &&
+            note.created_by_object.id === authUser.id &&
+            !isEditing && (
+              <ButtonV2
+                ghost
+                onClick={() => {
+                  setIsEditing(true);
+                }}
+              >
+                <CareIcon icon="l-pen" className="h-5 w-5" />
+              </ButtonV2>
+            )}
         </div>
+        {
+          <div className="mt-2">
+            {isEditing ? (
+              <div className="flex flex-col">
+                <textarea
+                  rows={2}
+                  className="h-20 w-full resize-none rounded-lg border border-gray-300 p-2"
+                  value={noteField}
+                  onChange={(e) => setNoteField(e.target.value)}
+                ></textarea>
+                <div className="mt-2 flex justify-end gap-2">
+                  <ButtonV2
+                    className="py-1"
+                    variant="secondary"
+                    border
+                    onClick={() => {
+                      setIsEditing(false);
+                      setNoteField(note.note);
+                    }}
+                    id="cancel-update-note-button"
+                  >
+                    <CareIcon icon="l-times-circle" className="h-5 w-5" />
+                    Cancel
+                  </ButtonV2>
+                  <ButtonV2
+                    className="py-1"
+                    onClick={onUpdateNote}
+                    id="update-note-button"
+                  >
+                    <CareIcon icon="l-check" className="h-5 w-5 text-white" />
+                    Update Note
+                  </ButtonV2>
+                </div>
+              </div>
+            ) : (
+              <div className="text-sm text-gray-700">{noteField}</div>
+            )}
+          </div>
+        }
       </div>
-    </div>
+      {showEditHistory && (
+        <DialogModal
+          show={showEditHistory}
+          onClose={() => setShowEditHistory(false)}
+          title={t("edit_history")}
+        >
+          <div>
+            <div className="mb-4">
+              <p className="text-md mt-1 text-gray-500">
+                Edit History for note
+                <strong> {note.id}</strong>
+              </p>
+            </div>
+            <div className="h-96 overflow-scroll">
+              {editHistory.length === 0 && (
+                <div className="flex h-full items-center justify-center">
+                  <Spinner />
+                </div>
+              )}
+              {editHistory?.map((edit, index) => {
+                const isLast = index === editHistory.length - 1;
+                return (
+                  <div
+                    key={index}
+                    className="my-2 flex flex-col justify-between rounded-lg border border-gray-300 p-4 py-2 transition-colors duration-200 hover:bg-gray-100"
+                  >
+                    <div className="flex">
+                      <div className="grow">
+                        <p className="text-sm font-medium text-gray-500">
+                          {isLast ? "Created" : "Edited"} On
+                        </p>
+                        <p className="text-sm text-gray-900">
+                          {formatDateTime(edit.edited_date)}
+                        </p>
+                      </div>
+                    </div>
+                    <div className="mt-2 grow">
+                      <p className="text-sm font-medium text-gray-500">Note</p>
+                      <p className="text-sm text-gray-900">{edit.note}</p>
+                    </div>
+                  </div>
+                );
+              })}
+            </div>
+            <div className="flex justify-end">
+              <ButtonV2
+                id="view-history-back-button"
+                variant="secondary"
+                onClick={() => {
+                  setShowEditHistory(false);
+                }}
+              >
+                {t("close")}
+              </ButtonV2>
+            </div>
+          </div>
+        </DialogModal>
+      )}
+    </>
   );
 };
 
diff --git a/src/Components/Facility/PatientNotesList.tsx b/src/Components/Facility/PatientNotesList.tsx
index 96f9dcad871..a36762072b9 100644
--- a/src/Components/Facility/PatientNotesList.tsx
+++ b/src/Components/Facility/PatientNotesList.tsx
@@ -74,7 +74,9 @@ const PatientNotesList = (props: PatientNotesProps) => {
     );
   }
 
-  return <DoctorNote state={state} handleNext={handleNext} />;
+  return (
+    <DoctorNote state={state} handleNext={handleNext} setReload={setReload} />
+  );
 };
 
 export default PatientNotesList;
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index 2e231576eb2..8943d7fe21a 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -30,6 +30,8 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
     notes: [],
     cPage: 1,
     totalPages: 1,
+    patientId: props.patientId,
+    facilityId: props.facilityId,
   };
   const [state, setState] = useState(initialData);
 
@@ -163,10 +165,9 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
           <PatientConsultationNotesList
             state={state}
             setState={setState}
-            facilityId={facilityId}
-            patientId={patientId}
             reload={reload}
             setReload={setReload}
+            disableEdit={!patientActive}
           />
           <div className="relative mx-4 flex items-center">
             <AutoExpandingTextInputFormField
diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx
index de035f9ffea..e3913f072cd 100644
--- a/src/Components/Facility/models.tsx
+++ b/src/Components/Facility/models.tsx
@@ -490,16 +490,28 @@ export interface BaseUserModel {
   last_login: string;
 }
 
+export interface PatientNotesEditModel {
+  id: string;
+  edited_by: BaseUserModel;
+  edited_date: string;
+  note: string;
+}
+
 export interface PatientNotesModel {
+  id: string;
   note: string;
   facility: BaseFacilityModel;
   created_by_object: BaseUserModel;
   user_type?: UserRole | "RemoteSpecialist";
   created_date: string;
+  last_edited_by?: BaseUserModel;
+  last_edited_date?: string;
 }
 
 export interface PatientNoteStateType {
   notes: PatientNotesModel[];
+  patientId: string;
+  facilityId: string;
   cPage: number;
   totalPages: number;
 }
diff --git a/src/Components/Form/FormFields/TextFormField.tsx b/src/Components/Form/FormFields/TextFormField.tsx
index 4e89e7e0ff2..773dddc034b 100644
--- a/src/Components/Form/FormFields/TextFormField.tsx
+++ b/src/Components/Form/FormFields/TextFormField.tsx
@@ -21,6 +21,7 @@ export type TextFormFieldProps = FormFieldBaseProps<string> & {
   leadingPadding?: string | undefined;
   min?: string | number;
   max?: string | number;
+  onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
   onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
   onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
 };
@@ -62,6 +63,7 @@ const TextFormField = forwardRef((props: TextFormFieldProps, ref) => {
       onFocus={props.onFocus}
       onBlur={props.onBlur}
       onChange={(e) => field.handleChange(e.target.value)}
+      onKeyDown={props.onKeyDown}
     />
   );
 
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index 40c842adc07..4893bfbd33f 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -50,6 +50,7 @@ import {
   WardModel,
   LocationModel,
   PatientNotesModel,
+  PatientNotesEditModel,
   BedModel,
   MinimumQuantityItemResponse,
   InventorySummaryResponse,
@@ -677,6 +678,16 @@ const routes = {
     method: "POST",
     TRes: Type<PatientNotesModel>(),
   },
+  updatePatientNote: {
+    path: "/api/v1/patient/{patientId}/notes/{noteId}/",
+    method: "PUT",
+    TRes: Type<PatientNotesModel>(),
+  },
+  getPatientNoteEditHistory: {
+    path: "/api/v1/patient/{patientId}/notes/{noteId}/edits/",
+    method: "GET",
+    TRes: Type<PaginatedResponse<PatientNotesEditModel>>(),
+  },
   sampleTestList: {
     path: "/api/v1/patient/{patientId}/test_sample/",
   },

From d36c0f24a60e09adaee68bc74b0ebc04dda6967f Mon Sep 17 00:00:00 2001
From: konavivekramakrishna <konavivekramakrishna@gmail.com>
Date: Wed, 14 Feb 2024 13:48:40 +0530
Subject: [PATCH 15/17] Replace useDispatch in Patient Files
 (src/Components/Patient/) (#7078)

* replaced useDispatch in patientHome

* replace usedispatch in patientfiler and managepatinet

* add patientfilter

* replace useDispatch in dailyroundslistdetials

* replaced useDispatch in sampleDetails

* replace useDispatch in sampleFilters

* replace useDispatch in samplePreview

* sampleTestCard

* replace useDispatch in sampleTest

* replace useDispatch in sampleViewAdmin

* replace useDispatch in shiftCreate

* fix

* fix

* revert managePatients and patientFilter useDispatch

* replace useDispatch in managePatients

* fix

* fix

* replace useDispatch in PatientFilter

* fix prefetch

* minor fix

* add trailing slashes to api's

* fix based on review

* Update package-lock.json

* Update package-lock.json

* replace reload

* implement paginated list

* fix types

* rm Timeline from paginatedList

* Update button styling in CommentsSection component

* Fix API paths in Redux file

* Update  API paths

* remove unused actions

* fix eslint

* fix daily rounds and filters

* fix sample view admin

* fix shifting

* fix based on review

* minor fix

* fix lint

---------

Co-authored-by: rithviknishad <mail@rithviknishad.dev>
Co-authored-by: Mohammed Nihal <57055998+nihal467@users.noreply.github.com>
---
 src/CAREUI/display/Timeline.tsx               |   2 +-
 src/CAREUI/misc/PaginatedList.tsx             |  29 +-
 .../Consultations/DailyRoundsList.tsx         |  95 ++--
 .../Patient/DailyRoundListDetails.tsx         |  78 ++--
 src/Components/Patient/ManagePatients.tsx     | 229 +++-------
 src/Components/Patient/PatientHome.tsx        | 422 ++++++------------
 src/Components/Patient/SampleDetails.tsx      |  91 ++--
 src/Components/Patient/SampleFilters.tsx      |  32 +-
 src/Components/Patient/SamplePreview.tsx      |  41 +-
 src/Components/Patient/SampleTest.tsx         |  61 ++-
 src/Components/Patient/SampleTestCard.tsx     |  33 +-
 src/Components/Patient/SampleViewAdmin.tsx    | 133 +++---
 src/Components/Patient/ShiftCreate.tsx        |  76 ++--
 src/Redux/actions.tsx                         |  63 +--
 src/Redux/api.tsx                             |  39 +-
 15 files changed, 540 insertions(+), 884 deletions(-)

diff --git a/src/CAREUI/display/Timeline.tsx b/src/CAREUI/display/Timeline.tsx
index 276c437056c..49ace78bd88 100644
--- a/src/CAREUI/display/Timeline.tsx
+++ b/src/CAREUI/display/Timeline.tsx
@@ -14,7 +14,7 @@ export interface TimelineEvent<TType = string> {
 }
 
 interface TimelineProps {
-  className: string;
+  className?: string;
   children: React.ReactNode | React.ReactNode[];
   name: string;
 }
diff --git a/src/CAREUI/misc/PaginatedList.tsx b/src/CAREUI/misc/PaginatedList.tsx
index 1487d69e4fa..363e657f253 100644
--- a/src/CAREUI/misc/PaginatedList.tsx
+++ b/src/CAREUI/misc/PaginatedList.tsx
@@ -7,7 +7,6 @@ import ButtonV2, {
 import CareIcon from "../icons/CareIcon";
 import { classNames } from "../../Utils/utils";
 import Pagination from "../../Components/Common/Pagination";
-import Timeline from "../display/Timeline";
 
 const DEFAULT_PER_PAGE_LIMIT = 14;
 
@@ -135,21 +134,19 @@ const Items = <TItem extends object>(props: ItemsProps<TItem>) => {
   }
 
   return (
-    <Timeline className="rounded-lg bg-white p-2 shadow" name="log update">
-      <ul className={props.className}>
-        {loading && props.shimmer
-          ? Array.from({ length: props.shimmerCount ?? 8 }).map((_, i) => (
-              <li key={i} className="w-full">
-                {props.shimmer}
-              </li>
-            ))
-          : items.map((item, index, items) => (
-              <li key={index} className="w-full">
-                {props.children(item, items)}
-              </li>
-            ))}
-      </ul>
-    </Timeline>
+    <ul className={props.className}>
+      {loading && props.shimmer
+        ? Array.from({ length: props.shimmerCount ?? 8 }).map((_, i) => (
+            <li key={i} className="w-full">
+              {props.shimmer}
+            </li>
+          ))
+        : items.map((item, index, items) => (
+            <li key={index} className="w-full">
+              {props.children(item, items)}
+            </li>
+          ))}
+    </ul>
   );
 };
 
diff --git a/src/Components/Facility/Consultations/DailyRoundsList.tsx b/src/Components/Facility/Consultations/DailyRoundsList.tsx
index d438ee098c7..0d569eade41 100644
--- a/src/Components/Facility/Consultations/DailyRoundsList.tsx
+++ b/src/Components/Facility/Consultations/DailyRoundsList.tsx
@@ -10,7 +10,8 @@ import PageTitle from "../../Common/PageTitle";
 import DailyRoundsFilter from "./DailyRoundsFilter";
 import { ConsultationModel } from "../models";
 import { useSlugs } from "../../../Common/hooks/useSlug";
-import { TimelineNode } from "../../../CAREUI/display/Timeline";
+
+import Timeline, { TimelineNode } from "../../../CAREUI/display/Timeline";
 import { useState } from "react";
 import { QueryParams } from "../../../Utils/request/types";
 
@@ -52,69 +53,71 @@ export default function DailyRoundsList({ consultation }: Props) {
               <PaginatedList.WhenLoading>
                 <LoadingLogUpdateCard />
               </PaginatedList.WhenLoading>
-              <PaginatedList.Items<DailyRoundsModel> className="flex grow flex-col gap-3">
-                {(item, items) => {
-                  if (item.rounds_type === "AUTOMATED") {
+              <Timeline name="log update">
+                <PaginatedList.Items<DailyRoundsModel> className="flex grow flex-col gap-3 rounded-lg bg-white p-2 shadow">
+                  {(item, items) => {
+                    if (item.rounds_type === "AUTOMATED") {
+                      return (
+                        <TimelineNode
+                          event={{
+                            type: "created",
+                            timestamp: item.taken_at?.toString() ?? "",
+                            by: {
+                              user_type: "",
+                              first_name: "Virtual",
+                              last_name: "Assistant",
+                              username: "",
+                              id: "",
+                              email: "",
+                              last_login: "",
+                            },
+                            icon: "l-robot",
+                          }}
+                          isLast={items.indexOf(item) == items.length - 1}
+                        >
+                          <VirtualNursingAssistantLogUpdateCard
+                            round={item}
+                            previousRound={items[items.indexOf(item) + 1]}
+                          />
+                        </TimelineNode>
+                      );
+                    }
+
+                    const itemUrl = ["NORMAL", "TELEMEDICINE"].includes(
+                      item.rounds_type as string
+                    )
+                      ? `${consultationUrl}/daily-rounds/${item.id}`
+                      : `${consultationUrl}/daily_rounds/${item.id}`;
+
                     return (
                       <TimelineNode
                         event={{
                           type: "created",
                           timestamp: item.taken_at?.toString() ?? "",
                           by: {
-                            user_type: "",
-                            first_name: "Virtual",
-                            last_name: "Assistant",
+                            user_type: item.created_by?.user_type ?? "",
+                            first_name: item.created_by?.first_name ?? "",
+                            last_name: item.created_by?.last_name ?? "",
                             username: "",
                             id: "",
                             email: "",
                             last_login: "",
                           },
-                          icon: "l-robot",
+                          icon: "l-user-nurse",
                         }}
                         isLast={items.indexOf(item) == items.length - 1}
                       >
-                        <VirtualNursingAssistantLogUpdateCard
+                        <DefaultLogUpdateCard
                           round={item}
-                          previousRound={items[items.indexOf(item) + 1]}
+                          consultationData={consultation}
+                          onViewDetails={() => navigate(itemUrl)}
+                          onUpdateLog={() => navigate(`${itemUrl}/update`)}
                         />
                       </TimelineNode>
                     );
-                  }
-
-                  const itemUrl = ["NORMAL", "TELEMEDICINE"].includes(
-                    item.rounds_type
-                  )
-                    ? `${consultationUrl}/daily-rounds/${item.id}`
-                    : `${consultationUrl}/daily_rounds/${item.id}`;
-
-                  return (
-                    <TimelineNode
-                      event={{
-                        type: "created",
-                        timestamp: item.taken_at?.toString() ?? "",
-                        by: {
-                          user_type: item.created_by?.user_type ?? "",
-                          first_name: item.created_by?.first_name ?? "",
-                          last_name: item.created_by?.last_name ?? "",
-                          username: "",
-                          id: "",
-                          email: "",
-                          last_login: "",
-                        },
-                        icon: "l-user-nurse",
-                      }}
-                      isLast={items.indexOf(item) == items.length - 1}
-                    >
-                      <DefaultLogUpdateCard
-                        round={item}
-                        consultationData={consultation}
-                        onViewDetails={() => navigate(itemUrl)}
-                        onUpdateLog={() => navigate(`${itemUrl}/update`)}
-                      />
-                    </TimelineNode>
-                  );
-                }}
-              </PaginatedList.Items>
+                  }}
+                </PaginatedList.Items>
+              </Timeline>
               <div className="flex w-full items-center justify-center">
                 <PaginatedList.Paginator hideIfSinglePage />
               </div>
diff --git a/src/Components/Patient/DailyRoundListDetails.tsx b/src/Components/Patient/DailyRoundListDetails.tsx
index 8f313c0a51d..02ad9aa47fa 100644
--- a/src/Components/Patient/DailyRoundListDetails.tsx
+++ b/src/Components/Patient/DailyRoundListDetails.tsx
@@ -1,75 +1,53 @@
-import { lazy, useCallback, useState } from "react";
-import { useDispatch } from "react-redux";
+import { lazy, useState } from "react";
 import {
   CONSCIOUSNESS_LEVEL,
   CURRENT_HEALTH_CHANGE,
   SYMPTOM_CHOICES,
 } from "../../Common/constants";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import { getConsultationDailyRoundsDetails } from "../../Redux/actions";
 import { DailyRoundsModel } from "./models";
 import Page from "../Common/components/Page";
 import ButtonV2 from "../Common/components/ButtonV2";
 import { formatDateTime } from "../../Utils/utils";
+import useQuery from "../../Utils/request/useQuery";
+import routes from "../../Redux/api";
 const Loading = lazy(() => import("../Common/Loading"));
 const symptomChoices = [...SYMPTOM_CHOICES];
 const currentHealthChoices = [...CURRENT_HEALTH_CHANGE];
 
 export const DailyRoundListDetails = (props: any) => {
   const { facilityId, patientId, consultationId, id } = props;
-  const dispatch: any = useDispatch();
   const [dailyRoundListDetailsData, setDailyRoundListDetails] =
     useState<DailyRoundsModel>({});
-  const [isLoading, setIsLoading] = useState(false);
 
-  const fetchpatient = useCallback(
-    async (status: statusType) => {
-      setIsLoading(true);
-      const res = await dispatch(
-        getConsultationDailyRoundsDetails({ consultationId, id })
-      );
-      if (!status.aborted) {
-        if (res && res.data) {
-          const currentHealth = currentHealthChoices.find(
-            (i) => i.text === res.data.current_health
-          );
+  const { loading: isLoading } = useQuery(routes.getDailyReport, {
+    pathParams: { consultationId, id },
+    onResponse: ({ res, data }) => {
+      if (res && data) {
+        const currentHealth = currentHealthChoices.find(
+          (i) => i.text === data.current_health
+        );
 
-          const data: DailyRoundsModel = {
-            ...res.data,
-            temperature: Number(res.data.temperature)
-              ? res.data.temperature
-              : "",
-            additional_symptoms_text: "",
-            medication_given:
-              Object.keys(res.data.medication_given).length === 0
-                ? []
-                : res.data.medication_given,
-            current_health: currentHealth
-              ? currentHealth.desc
-              : res.data.current_health,
-          };
-          if (res.data.additional_symptoms?.length) {
-            const symptoms = res.data.additional_symptoms.map(
-              (symptom: number) => {
-                const option = symptomChoices.find((i) => i.id === symptom);
-                return option ? option.text.toLowerCase() : symptom;
-              }
-            );
-            data.additional_symptoms_text = symptoms.join(", ");
-          }
-          setDailyRoundListDetails(data);
+        const tdata: DailyRoundsModel = {
+          ...data,
+          temperature: Number(data.temperature) ? data.temperature : "",
+          additional_symptoms_text: "",
+          medication_given: data.medication_given ?? [],
+
+          current_health: currentHealth
+            ? currentHealth.desc
+            : data.current_health,
+        };
+        if (data.additional_symptoms?.length) {
+          const symptoms = data.additional_symptoms.map((symptom: number) => {
+            const option = symptomChoices.find((i) => i.id === symptom);
+            return option ? option.text.toLowerCase() : symptom;
+          });
+          tdata.additional_symptoms_text = symptoms.join(", ");
         }
-        setIsLoading(false);
+        setDailyRoundListDetails(tdata);
       }
     },
-    [consultationId, dispatch, id]
-  );
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchpatient(status);
-    },
-    [dispatch, fetchpatient]
-  );
+  });
 
   if (isLoading) {
     return <Loading />;
diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx
index ce8475e4c66..5e8afaf2d5c 100644
--- a/src/Components/Patient/ManagePatients.tsx
+++ b/src/Components/Patient/ManagePatients.tsx
@@ -11,19 +11,9 @@ import {
 } from "../../Common/constants";
 import { FacilityModel, PatientCategory } from "../Facility/models";
 import { Link, navigate } from "raviger";
-import { ReactNode, lazy, useCallback, useEffect, useState } from "react";
-import {
-  getAllPatient,
-  getAnyFacility,
-  getDistrict,
-  getFacilityAssetLocation,
-  getLocalBody,
-} from "../../Redux/actions";
-import {
-  statusType,
-  useAbortableEffect,
-  parseOptionId,
-} from "../../Common/utils";
+import { ReactNode, lazy, useEffect, useState } from "react";
+import { getAllPatient } from "../../Redux/actions";
+import { parseOptionId } from "../../Common/utils";
 
 import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover";
 import ButtonV2 from "../Common/components/ButtonV2";
@@ -42,7 +32,6 @@ import SearchInput from "../Form/SearchInput";
 import SortDropdownMenu from "../Common/SortDropdown";
 import SwitchTabs from "../Common/components/SwitchTabs";
 import { formatAge, parsePhoneNumber } from "../../Utils/utils.js";
-import { useDispatch } from "react-redux";
 import useFilters from "../../Common/hooks/useFilters";
 import { useTranslation } from "react-i18next";
 import Page from "../Common/components/Page.js";
@@ -93,10 +82,6 @@ const PatientCategoryDisplayText: Record<PatientCategory, string> = {
 
 export const PatientManager = () => {
   const { t } = useTranslation();
-  const dispatch: any = useDispatch();
-  const [data, setData] = useState<any[]>();
-  const [isLoading, setIsLoading] = useState(false);
-  const [totalCount, setTotalCount] = useState(0);
   const {
     qParams,
     updateQuery,
@@ -121,10 +106,6 @@ export const PatientManager = () => {
   const [showDialog, setShowDialog] = useState(false);
   const [showDoctors, setShowDoctors] = useState(false);
   const [showDoctorConnect, setShowDoctorConnect] = useState(false);
-  const [districtName, setDistrictName] = useState("");
-  const [localbodyName, setLocalbodyName] = useState("");
-  const [facilityBadgeName, setFacilityBadge] = useState("");
-  const [locationBadgeName, setLocationBadge] = useState("");
   const [phone_number, setPhoneNumber] = useState("");
   const [phoneNumberError, setPhoneNumberError] = useState("");
   const [emergency_phone_number, setEmergencyPhoneNumber] = useState("");
@@ -367,73 +348,17 @@ export const PatientManager = () => {
     return cleanedData;
   };
 
-  useEffect(() => {
-    setIsLoading(true);
-    if (!params.phone_number) {
-      setPhoneNumber("+91");
-    }
-    if (!params.emergency_phone_number) {
-      setEmergencyPhoneNumber("+91");
-    }
-    dispatch(getAllPatient(params, "listPatients")).then((res: any) => {
-      if (res && res.data) {
-        setData(res.data.results);
-        setTotalCount(res.data.count);
-        setIsLoading(false);
+  const { loading: isLoading, data } = useQuery(routes.patientList, {
+    query: params,
+    onResponse: () => {
+      if (!params.phone_number) {
+        setPhoneNumber("+91");
       }
-    });
-  }, [
-    dispatch,
-    qParams.last_consultation_medico_legal_case,
-    qParams.last_consultation_encounter_date_before,
-    qParams.last_consultation_encounter_date_after,
-    qParams.last_consultation_discharge_date_before,
-    qParams.last_consultation_discharge_date_after,
-    qParams.age_max,
-    qParams.age_min,
-    qParams.last_consultation_admitted_bed_type_list,
-    qParams.last_consultation__new_discharge_reason,
-    qParams.last_consultation_current_bed__location,
-    qParams.facility,
-    qParams.facility_type,
-    qParams.district,
-    qParams.category,
-    qParams.gender,
-    qParams.ordering,
-    qParams.created_date_before,
-    qParams.created_date_after,
-    qParams.modified_date_before,
-    qParams.modified_date_after,
-    qParams.is_active,
-    qParams.disease_status,
-    qParams.name,
-    qParams.patient_no,
-    qParams.page,
-    qParams.phone_number,
-    qParams.emergency_phone_number,
-    qParams.srf_id,
-    qParams.covin_id,
-    qParams.number_of_doses,
-    qParams.lsgBody,
-    qParams.is_kasp,
-    qParams.is_declared_positive,
-    qParams.date_declared_positive_before,
-    qParams.date_declared_positive_after,
-    qParams.date_of_result_before,
-    qParams.date_of_result_after,
-    qParams.last_consultation_symptoms_onset_date_before,
-    qParams.last_consultation_symptoms_onset_date_after,
-    qParams.last_vaccinated_date_before,
-    qParams.last_vaccinated_date_after,
-    qParams.last_consultation_is_telemedicine,
-    qParams.is_antenatal,
-    qParams.ventilator_interface,
-    qParams.diagnoses,
-    qParams.diagnoses_confirmed,
-    qParams.diagnoses_provisional,
-    qParams.diagnoses_unconfirmed,
-    qParams.diagnoses_differential,
-  ]);
+      if (!params.emergency_phone_number) {
+        setEmergencyPhoneNumber("+91");
+      }
+    },
+  });
 
   const getTheCategoryFromId = () => {
     let category_name;
@@ -448,80 +373,35 @@ export const PatientManager = () => {
     }
   };
 
-  const fetchDistrictName = useCallback(
-    async (status: statusType) => {
-      const res =
-        Number(qParams.district) &&
-        (await dispatch(getDistrict(qParams.district)));
-      if (!status.aborted) {
-        setDistrictName(res?.data?.name);
-      }
-    },
-    [dispatch, qParams.district]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchDistrictName(status);
-    },
-    [fetchDistrictName]
-  );
-
-  const fetchLocalbodyName = useCallback(
-    async (status: statusType) => {
-      const res =
-        Number(qParams.lsgBody) &&
-        (await dispatch(getLocalBody({ id: qParams.lsgBody })));
-      if (!status.aborted) {
-        setLocalbodyName(res?.data?.name);
-      }
-    },
-    [dispatch, qParams.lsgBody]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchLocalbodyName(status);
+  const { data: districtData } = useQuery(routes.getDistrict, {
+    pathParams: {
+      id: qParams.district,
     },
-    [fetchLocalbodyName]
-  );
-
-  const fetchFacilityBadgeName = useCallback(
-    async (status: statusType) => {
-      const res =
-        qParams.facility && (await dispatch(getAnyFacility(qParams.facility)));
+    prefetch: !!Number(qParams.district),
+  });
 
-      if (!status.aborted) {
-        setFacilityBadge(res?.data?.name);
-      }
+  const { data: LocalBodyData } = useQuery(routes.getLocalBody, {
+    pathParams: {
+      id: qParams.lsgBody,
     },
-    [dispatch, qParams.facility]
-  );
-
-  const fetchLocationBadgeName = useCallback(
-    async (status: statusType) => {
-      const res =
-        qParams.last_consultation_current_bed__location &&
-        (await dispatch(
-          getFacilityAssetLocation(
-            qParams.facility,
-            qParams.last_consultation_current_bed__location
-          )
-        ));
-
-      if (!status.aborted) {
-        setLocationBadge(res?.data?.name);
-      }
-    },
-    [dispatch, qParams.last_consultation_current_bed__location]
-  );
+    prefetch: !!Number(qParams.lsgBody),
+  });
 
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchFacilityBadgeName(status);
-      fetchLocationBadgeName(status);
+  const { data: facilityData } = useQuery(routes.getAnyFacility, {
+    pathParams: {
+      id: qParams.facility,
     },
-    [fetchFacilityBadgeName, fetchLocationBadgeName]
+    prefetch: !!qParams.facility,
+  });
+  const { data: facilityAssetLocationData } = useQuery(
+    routes.getFacilityAssetLocation,
+    {
+      pathParams: {
+        facility_external_id: qParams.facility,
+        external_id: qParams.last_consultation_current_bed__location,
+      },
+      prefetch: !!qParams.last_consultation_current_bed__location,
+    }
   );
 
   const { data: permittedFacilities } = useQuery(
@@ -564,8 +444,8 @@ export const PatientManager = () => {
   };
 
   let patientList: ReactNode[] = [];
-  if (data && data.length) {
-    patientList = data.map((patient: any) => {
+  if (data?.count) {
+    patientList = data.results.map((patient: any) => {
       let patientUrl = "";
       if (
         patient.last_consultation &&
@@ -814,16 +694,16 @@ export const PatientManager = () => {
         <Loading />
       </div>
     );
-  } else if (data?.length) {
+  } else if (data?.count) {
     managePatients = (
       <>
         <div className="mt-4 grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
           {patientList}
         </div>
-        <Pagination totalCount={totalCount} />
+        <Pagination totalCount={data?.count} />
       </>
     );
-  } else if (data && data.length === 0) {
+  } else if (data && data.count === 0) {
     managePatients = (
       <div className="col-span-3 w-full rounded-lg bg-white p-2 py-8 pt-4 text-center">
         <p className="text-2xl font-bold text-gray-600">No Patients Found</p>
@@ -967,7 +847,7 @@ export const PatientManager = () => {
           <div className="flex-1">
             <CountBlock
               text="Total Patients"
-              count={totalCount}
+              count={data?.count || 0}
               loading={isLoading}
               icon="l-user-injured"
               className="pb-12"
@@ -1038,14 +918,25 @@ export const PatientManager = () => {
               "Is Medico-Legal Case",
               "last_consultation_medico_legal_case"
             ),
-            value("Facility", "facility", facilityBadgeName),
+            value(
+              "Facility",
+              "facility",
+              qParams.facility ? facilityData?.name || "" : ""
+            ),
             value(
               "Location",
               "last_consultation_current_bed__location",
-              locationBadgeName
+              qParams.last_consultation_current_bed__location
+                ? facilityAssetLocationData?.name ||
+                    qParams.last_consultation_current_bed__locations
+                : ""
             ),
             badge("Facility Type", "facility_type"),
-            value("District", "district", districtName),
+            value(
+              "District",
+              "district",
+              qParams.district ? districtData?.name || "" : ""
+            ),
             ordering(),
             value("Category", "category", getTheCategoryFromId()),
             badge("Disease Status", "disease_status"),
@@ -1067,7 +958,11 @@ export const PatientManager = () => {
             },
             ...range("Age", "age"),
             badge("SRF ID", "srf_id"),
-            { name: "LSG Body", value: localbodyName, paramKey: "lsgBody" },
+            {
+              name: "LSG Body",
+              value: qParams.lsgBody ? LocalBodyData?.name || "" : "",
+              paramKey: "lsgBody",
+            },
             ...FILTER_BY_DIAGNOSES_KEYS.map((key) =>
               value(
                 DIAGNOSES_FILTER_LABELS[key],
diff --git a/src/Components/Patient/PatientHome.tsx b/src/Components/Patient/PatientHome.tsx
index 9b719ba31dd..22dc86117f4 100644
--- a/src/Components/Patient/PatientHome.tsx
+++ b/src/Components/Patient/PatientHome.tsx
@@ -1,23 +1,13 @@
 import { navigate } from "raviger";
-import { lazy, useCallback, useEffect, useState } from "react";
-import { useDispatch } from "react-redux";
+import { lazy, useEffect, useState } from "react";
+
 import {
   DISCHARGE_REASONS,
   GENDER_TYPES,
   SAMPLE_TEST_STATUS,
 } from "../../Common/constants";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import {
-  getConsultationList,
-  listShiftRequests,
-  getPatient,
-  getSampleTestList,
-  patchSample,
-  patchPatient,
-  completeTransfer,
-} from "../../Redux/actions";
+
 import * as Notification from "../../Utils/Notifications";
-import Pagination from "../Common/Pagination";
 import { ConsultationCard } from "../Facility/ConsultationCard";
 import { ConsultationModel } from "../Facility/models";
 import { PatientModel, SampleTestModel } from "./models";
@@ -44,35 +34,18 @@ import useAuthUser from "../../Common/hooks/useAuthUser";
 import useQuery from "../../Utils/request/useQuery";
 import routes from "../../Redux/api";
 import { InsuranceDetialsCard } from "./InsuranceDetailsCard";
+import request from "../../Utils/request/request";
+import PaginatedList from "../../CAREUI/misc/PaginatedList";
 
 const Loading = lazy(() => import("../Common/Loading"));
 
 export const PatientHome = (props: any) => {
   const { facilityId, id } = props;
-  const dispatch: any = useDispatch();
   const [showShifts, setShowShifts] = useState(false);
   const [isShiftClicked, setIsShiftClicked] = useState(false);
-  const [isShiftDataLoaded, setIsShiftDataLoaded] = useState(false);
   const [patientData, setPatientData] = useState<PatientModel>({});
-  const [consultationListData, setConsultationListData] = useState<
-    Array<ConsultationModel>
-  >([]);
-  const [sampleListData, setSampleListData] = useState<Array<SampleTestModel>>(
-    []
-  );
-  const [activeShiftingData, setActiveShiftingData] = useState<Array<any>>([]);
   const [assignedVolunteerObject, setAssignedVolunteerObject] =
     useState<any>(null);
-  const [isLoading, setIsLoading] = useState(false);
-  const [totalConsultationCount, setTotalConsultationCount] = useState(0);
-  const [currentConsultationPage, setCurrentConsultationPage] = useState(1);
-  const [consultationOffset, setConsultationOffset] = useState(0);
-  const [totalSampleListCount, setTotalSampleListCount] = useState(0);
-  const [currentSampleListPage, setCurrentSampleListPage] = useState(1);
-  const [sampleListOffset, setSampleListOffset] = useState(0);
-  const [isConsultationLoading, setIsConsultationLoading] = useState(false);
-  const [isSampleLoading, setIsSampleLoading] = useState(false);
-  const [sampleFlag, callSampleList] = useState(false);
   const authUser = useAuthUser();
   const { t } = useTranslation();
   const [selectedStatus, setSelectedStatus] = useState<{
@@ -94,13 +67,16 @@ export const PatientHome = (props: any) => {
     setAssignedVolunteerObject(patientData.assigned_to_object);
   }, [patientData.assigned_to_object]);
 
-  const handleTransferComplete = (shift: any) => {
+  const handleTransferComplete = async (shift: any) => {
     setModalFor({ ...modalFor, loading: true });
-    dispatch(completeTransfer({ externalId: modalFor })).then(() => {
-      navigate(
-        `/facility/${shift.assigned_facility}/patient/${shift.patient}/consultation`
-      );
+    await request(routes.completeTransfer, {
+      pathParams: {
+        id: modalFor.externalId ?? "",
+      },
     });
+    navigate(
+      `/facility/${shift.assigned_facility}/patient/${shift.patient}/consultation`
+    );
   };
 
   const { data: insuranceDetials } = useQuery(routes.listHCXPolicies, {
@@ -110,52 +86,28 @@ export const PatientHome = (props: any) => {
     },
   });
 
-  const handleAssignedVolunteer = () => {
-    dispatch(
-      patchPatient(
-        {
-          assigned_to: assignedVolunteerObject
-            ? assignedVolunteerObject.id
-            : null,
-        },
-        { id: patientData.id }
-      )
-    ).then((response: any) => {
-      if ((response || {}).status === 200) {
-        const dummyPatientData = Object.assign({}, patientData);
-        dummyPatientData["assigned_to"] = assignedVolunteerObject;
-        setPatientData(dummyPatientData);
-        if (assignedVolunteerObject)
-          Notification.Success({
-            msg: "Volunteer assigned successfully.",
-          });
-        else
-          Notification.Success({
-            msg: "Volunteer unassigned successfully.",
-          });
-        document.location.reload();
-      }
-    });
-    setOpenAssignVolunteerDialog(false);
-    if (errors["assignedVolunteer"]) delete errors["assignedVolunteer"];
-  };
-
-  const handlePatientTransfer = (value: boolean) => {
+  const handlePatientTransfer = async (value: boolean) => {
     const dummyPatientData = Object.assign({}, patientData);
     dummyPatientData["allow_transfer"] = value;
 
-    dispatch(
-      patchPatient({ allow_transfer: value }, { id: patientData.id })
-    ).then((response: any) => {
-      if ((response || {}).status === 200) {
-        const dummyPatientData = Object.assign({}, patientData);
-        dummyPatientData["allow_transfer"] = value;
-        setPatientData(dummyPatientData);
+    await request(routes.patchPatient, {
+      pathParams: {
+        id: patientData.id as string,
+      },
 
-        Notification.Success({
-          msg: "Transfer status updated.",
-        });
-      }
+      body: { allow_transfer: value },
+
+      onResponse: ({ res }) => {
+        if ((res || {}).status === 200) {
+          const dummyPatientData = Object.assign({}, patientData);
+          dummyPatientData["allow_transfer"] = value;
+          setPatientData(dummyPatientData);
+
+          Notification.Success({
+            msg: "Transfer status updated.",
+          });
+        }
+      },
     });
   };
 
@@ -163,122 +115,58 @@ export const PatientHome = (props: any) => {
     setAssignedVolunteerObject(volunteer.value);
   };
 
-  const limit = 5;
-
-  const fetchpatient = useCallback(
-    async (status: statusType) => {
-      setIsLoading(true);
-      const patientRes = await dispatch(getPatient({ id }));
-      if (!status.aborted) {
-        if (patientRes && patientRes.data) {
-          setPatientData(patientRes.data);
-        }
-        setIsLoading(false);
-      }
+  const { loading: isLoading, refetch } = useQuery(routes.getPatient, {
+    pathParams: {
+      id,
     },
-    [dispatch, id]
-  );
-
-  const fetchConsultation = useCallback(
-    async (status: statusType) => {
-      setIsConsultationLoading(true);
-      const consultationRes = await dispatch(
-        getConsultationList({ patient: id, limit, offset: consultationOffset })
-      );
-      if (!status.aborted) {
-        if (
-          consultationRes &&
-          consultationRes.data &&
-          consultationRes.data.results
-        ) {
-          setConsultationListData(consultationRes.data.results);
-          setTotalConsultationCount(consultationRes.data.count);
-        }
-        setIsConsultationLoading(false);
-      }
-    },
-    [dispatch, id, consultationOffset]
-  );
-
-  const fetchSampleTest = useCallback(
-    async (status: statusType) => {
-      setIsSampleLoading(true);
-      const sampleRes = await dispatch(
-        getSampleTestList(
-          { limit, offset: sampleListOffset },
-          { patientId: id }
-        )
-      );
-      if (!status.aborted) {
-        if (sampleRes && sampleRes.data && sampleRes.data.results) {
-          setSampleListData(sampleRes.data.results);
-          setTotalSampleListCount(sampleRes.data.count);
-        }
-        setIsSampleLoading(false);
+    onResponse: ({ res, data }) => {
+      if (res?.ok && data) {
+        setPatientData(data);
       }
-    },
-    [dispatch, id, sampleListOffset]
-  );
-
-  const fetchActiveShiftingData = useCallback(
-    async (status: statusType) => {
-      const shiftingRes = isShiftClicked
-        ? await dispatch(listShiftRequests({ patient: id }, "shift-list-call"))
-        : activeShiftingData;
-      setIsShiftDataLoaded(isShiftClicked);
-      if (!status.aborted) {
-        if (shiftingRes && shiftingRes.data && shiftingRes.data.results) {
-          const activeShiftingRes: any[] = shiftingRes.data.results;
-          setActiveShiftingData(activeShiftingRes);
-        }
-      }
-    },
-    [dispatch, id, isShiftClicked]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchpatient(status);
       triggerGoal("Patient Profile Viewed", {
         facilityId: facilityId,
         userId: authUser.id,
       });
     },
-    [dispatch, fetchpatient]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchConsultation(status);
-    },
-    [dispatch, fetchConsultation]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchSampleTest(status);
-    },
-    [dispatch, fetchSampleTest, sampleFlag]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchActiveShiftingData(status);
-    },
-    [dispatch, fetchActiveShiftingData]
-  );
+  });
 
-  const handleConsultationPagination = (page: number, limit: number) => {
-    const offset = (page - 1) * limit;
-    setCurrentConsultationPage(page);
-    setConsultationOffset(offset);
+  const handleAssignedVolunteer = async () => {
+    const { res, data } = await request(routes.patchPatient, {
+      pathParams: {
+        id: patientData.id as string,
+      },
+      body: {
+        assigned_to: assignedVolunteerObject
+          ? assignedVolunteerObject.id
+          : null,
+      },
+    });
+    if (res?.ok && data) {
+      setPatientData(data);
+      if (assignedVolunteerObject) {
+        Notification.Success({
+          msg: "Volunteer assigned successfully.",
+        });
+      } else {
+        Notification.Success({
+          msg: "Volunteer unassigned successfully.",
+        });
+      }
+      refetch();
+    }
+    setOpenAssignVolunteerDialog(false);
+    if (errors["assignedVolunteer"]) delete errors["assignedVolunteer"];
   };
 
-  const handleSampleListPagination = (page: number, limit: number) => {
-    const offset = (page - 1) * limit;
-    setCurrentSampleListPage(page);
-    setSampleListOffset(offset);
-  };
+  const { loading: isShiftDataLoading, data: activeShiftingData } = useQuery(
+    routes.listShiftRequests,
+    {
+      query: {
+        patient: id,
+      },
+      prefetch: isShiftClicked,
+    }
+  );
 
   const confirmApproval = (status: number, sample: any) => {
     setSelectedStatus({ status, sample });
@@ -289,20 +177,25 @@ export const PatientHome = (props: any) => {
     const { status, sample } = selectedStatus;
     const sampleData = {
       id: sample.id,
-      status,
+      status: status.toString(),
       consultation: sample.consultation,
     };
     const statusName = SAMPLE_TEST_STATUS.find((i) => i.id === status)?.desc;
 
-    const res = await dispatch(patchSample(sampleData, { id: sample.id }));
-    if (res && (res.status === 201 || res.status === 200)) {
-      Notification.Success({
-        msg: `Request ${statusName}`,
-      });
-      callSampleList(!sampleFlag);
-    }
-
-    setShowAlertMessage(false);
+    await request(routes.patchSample, {
+      body: sampleData,
+      pathParams: {
+        id: sample.id,
+      },
+      onResponse: ({ res }) => {
+        if (res?.ok) {
+          Notification.Success({
+            msg: `Request ${statusName}`,
+          });
+        }
+        setShowAlertMessage(false);
+      },
+    });
   };
 
   if (isLoading) {
@@ -334,57 +227,7 @@ export const PatientHome = (props: any) => {
       ));
   }
 
-  let consultationList, sampleList;
-
-  if (isConsultationLoading) {
-    consultationList = <CircularProgress />;
-  } else if (consultationListData.length === 0) {
-    consultationList = (
-      <div>
-        <hr />
-        <div className="flex items-center justify-center border-2 border-solid border-gray-200 p-4 text-xl font-bold text-gray-500">
-          No Data Found
-        </div>
-      </div>
-    );
-  } else if (consultationListData.length > 0) {
-    consultationList = consultationListData.map((itemData, idx) => (
-      <ConsultationCard
-        itemData={itemData}
-        key={idx}
-        isLastConsultation={itemData.id === patientData.last_consultation?.id}
-      />
-    ));
-  }
-
-  if (isSampleLoading) {
-    sampleList = <CircularProgress />;
-  } else if (sampleListData.length === 0) {
-    sampleList = (
-      <div>
-        <hr />
-        <div className="flex items-center justify-center border-2 border-solid border-gray-200 p-4 text-xl font-bold text-gray-500">
-          No Data Found
-        </div>
-      </div>
-    );
-  } else if (sampleListData.length > 0) {
-    sampleList = (
-      <div className="lg:gap-4">
-        {sampleListData.map((itemData, idx) => (
-          <SampleTestCard
-            itemData={itemData}
-            key={idx}
-            handleApproval={confirmApproval}
-            facilityId={facilityId}
-            patientId={id}
-          />
-        ))}
-      </div>
-    );
-  }
-
-  const isPatientInactive = (patientData: PatientModel, facilityId: number) => {
+  const isPatientInactive = (patientData: PatientModel, facilityId: string) => {
     return (
       !patientData.is_active ||
       !(patientData?.last_consultation?.facility === facilityId)
@@ -798,8 +641,7 @@ export const PatientHome = (props: any) => {
                     id="patient-allow-transfer"
                     className="mt-4 w-full"
                     disabled={
-                      !consultationListData ||
-                      !consultationListData.length ||
+                      !patientData.last_consultation?.id ||
                       !patientData.is_active
                     }
                     onClick={() =>
@@ -835,14 +677,14 @@ export const PatientHome = (props: any) => {
           <div
             className={
               showShifts
-                ? activeShiftingData.length
+                ? activeShiftingData?.count || 0
                   ? "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3"
                   : ""
                 : "hidden"
             }
           >
-            {activeShiftingData.length ? (
-              activeShiftingData.map((shift: any) => (
+            {activeShiftingData?.count ? (
+              activeShiftingData.results.map((shift: any) => (
                 <div key={`shift_${shift.id}`} className="mx-2 ">
                   <div className="h-full overflow-hidden rounded-lg bg-white shadow">
                     <div
@@ -988,7 +830,7 @@ export const PatientHome = (props: any) => {
               ))
             ) : (
               <div className=" text-center text-gray-500">
-                {isShiftDataLoaded ? "No Shifting Records!" : "Loading..."}
+                {isShiftDataLoading ? "Loading..." : "No Shifting Records!"}
               </div>
             )}
           </div>
@@ -1511,34 +1353,66 @@ export const PatientHome = (props: any) => {
         <h2 className="ml-0 mt-9 text-2xl font-semibold leading-tight">
           Consultation History
         </h2>
-        {consultationList}
-        {!isConsultationLoading && totalConsultationCount > limit && (
-          <div className="mt-4 flex w-full justify-center">
-            <Pagination
-              cPage={currentConsultationPage}
-              defaultPerPage={limit}
-              data={{ totalCount: totalConsultationCount }}
-              onChange={handleConsultationPagination}
-            />
-          </div>
-        )}
+
+        <PaginatedList
+          route={routes.getConsultationList}
+          query={{ patient: id }}
+          perPage={5}
+        >
+          {(_) => (
+            <div>
+              <PaginatedList.WhenLoading>
+                <CircularProgress />
+              </PaginatedList.WhenLoading>
+              <PaginatedList.Items<ConsultationModel>>
+                {(item) => (
+                  <ConsultationCard
+                    itemData={item}
+                    isLastConsultation={
+                      item.id == patientData.last_consultation?.id
+                    }
+                  />
+                )}
+              </PaginatedList.Items>
+              <div className="flex w-full items-center justify-center">
+                <PaginatedList.Paginator hideIfSinglePage />
+              </div>
+            </div>
+          )}
+        </PaginatedList>
       </div>
 
       <div>
         <h2 className="my-4 ml-0 text-2xl font-semibold leading-tight">
           Sample Test History
         </h2>
-        {sampleList}
-        {!isSampleLoading && totalSampleListCount > limit && (
-          <div className="mt-4 flex w-full justify-center">
-            <Pagination
-              cPage={currentSampleListPage}
-              defaultPerPage={limit}
-              data={{ totalCount: totalSampleListCount }}
-              onChange={handleSampleListPagination}
-            />
-          </div>
-        )}
+        <PaginatedList
+          route={routes.sampleTestList}
+          pathParams={{ patientId: id }}
+          perPage={5}
+        >
+          {(_, query) => (
+            <div>
+              <PaginatedList.WhenLoading>
+                <CircularProgress />
+              </PaginatedList.WhenLoading>
+              <PaginatedList.Items<SampleTestModel>>
+                {(item) => (
+                  <SampleTestCard
+                    refetch={query.refetch}
+                    itemData={item}
+                    handleApproval={confirmApproval}
+                    facilityId={facilityId}
+                    patientId={id}
+                  />
+                )}
+              </PaginatedList.Items>
+              <div className="flex w-full items-center justify-center">
+                <PaginatedList.Paginator hideIfSinglePage />
+              </div>
+            </div>
+          )}
+        </PaginatedList>
       </div>
     </Page>
   );
diff --git a/src/Components/Patient/SampleDetails.tsx b/src/Components/Patient/SampleDetails.tsx
index 9b08395a233..bcaf170cc4f 100644
--- a/src/Components/Patient/SampleDetails.tsx
+++ b/src/Components/Patient/SampleDetails.tsx
@@ -1,7 +1,6 @@
-import { FlowModel, SampleTestModel } from "./models";
+import { FlowModel } from "./models";
 import { GENDER_TYPES, TEST_TYPE_CHOICES } from "../../Common/constants";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import { lazy, useCallback, useState } from "react";
+import { lazy } from "react";
 
 import ButtonV2 from "../Common/components/ButtonV2";
 import Card from "../../CAREUI/display/Card";
@@ -9,41 +8,29 @@ import { FileUpload } from "./FileUpload";
 import Page from "../Common/components/Page";
 import _ from "lodash-es";
 import { formatAge, formatDateTime } from "../../Utils/utils";
-import { getTestSample } from "../../Redux/actions";
 
 import { navigate } from "raviger";
-import { useDispatch } from "react-redux";
 import { DetailRoute } from "../../Routers/types";
+import useQuery from "../../Utils/request/useQuery";
+import routes from "../../Redux/api";
 
 const Loading = lazy(() => import("../Common/Loading"));
 
 export const SampleDetails = ({ id }: DetailRoute) => {
-  const dispatch: any = useDispatch();
-  const [isLoading, setIsLoading] = useState(false);
-  const [sampleDetails, setSampleDetails] = useState<SampleTestModel>({});
-
-  const fetchData = useCallback(
-    async (status: statusType) => {
-      setIsLoading(true);
-      const res = await dispatch(getTestSample(id));
-      if (!status.aborted) {
-        if (res && res.data) {
-          setSampleDetails(res.data);
-        } else {
+  const { loading: isLoading, data: sampleDetails } = useQuery(
+    routes.getTestSample,
+    {
+      pathParams: {
+        id,
+      },
+      onResponse: ({ res, data }) => {
+        if (!(res?.ok && data)) {
           navigate("/not-found");
         }
-        setIsLoading(false);
-      }
-    },
-    [dispatch, id]
+      },
+    }
   );
 
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchData(status);
-    },
-    [dispatch, fetchData, id]
-  );
   const yesOrNoBadge = (param: any) =>
     param ? (
       <span className="badge badge-pill badge-warning">Yes</span>
@@ -287,7 +274,7 @@ export const SampleDetails = ({ id }: DetailRoute) => {
       title="Sample Test Details"
       backUrl="/sample"
       options={
-        sampleDetails.patient && (
+        sampleDetails?.patient && (
           <div className="flex justify-end">
             <ButtonV2
               href={`/patient/${sampleDetails.patient}/test_sample/${id}/icmr_sample`}
@@ -304,37 +291,37 @@ export const SampleDetails = ({ id }: DetailRoute) => {
             <span className="font-semibold capitalize leading-relaxed">
               Status:{" "}
             </span>
-            {sampleDetails.status}
+            {sampleDetails?.status}
           </div>
           <div>
             <span className="font-semibold capitalize leading-relaxed">
               Result:{" "}
             </span>
-            {sampleDetails.result}
+            {sampleDetails?.result}
           </div>
           <div>
             <span className="font-semibold leading-relaxed">Patient: </span>
-            {sampleDetails.patient_name}
+            {sampleDetails?.patient_name}
           </div>
-          {sampleDetails.facility_object && (
+          {sampleDetails?.facility_object && (
             <div>
               <span className="font-semibold leading-relaxed">Facility: </span>
-              {sampleDetails.facility_object.name}
+              {sampleDetails?.facility_object.name}
             </div>
           )}
           <div>
             <span className="font-semibold leading-relaxed">Tested on: </span>
-            {sampleDetails.date_of_result
+            {sampleDetails?.date_of_result
               ? formatDateTime(sampleDetails.date_of_result)
               : "-"}
           </div>
           <div>
             <span className="font-semibold leading-relaxed">Result on: </span>
-            {sampleDetails.date_of_result
+            {sampleDetails?.date_of_result
               ? formatDateTime(sampleDetails.date_of_result)
               : "-"}
           </div>
-          {sampleDetails.fast_track && (
+          {sampleDetails?.fast_track && (
             <div className="md:col-span-2">
               <span className="font-semibold leading-relaxed">
                 Fast track testing reason:{" "}
@@ -342,7 +329,7 @@ export const SampleDetails = ({ id }: DetailRoute) => {
               {sampleDetails.fast_track}
             </div>
           )}
-          {sampleDetails.doctor_name && (
+          {sampleDetails?.doctor_name && (
             <div className="capitalize md:col-span-2">
               <span className="font-semibold leading-relaxed">
                 Doctor&apos;s Name:{" "}
@@ -350,21 +337,21 @@ export const SampleDetails = ({ id }: DetailRoute) => {
               {_.startCase(_.camelCase(sampleDetails.doctor_name))}
             </div>
           )}
-          {sampleDetails.diagnosis && (
+          {sampleDetails?.diagnosis && (
             <div className="md:col-span-2">
               <span className="font-semibold leading-relaxed">Diagnosis: </span>
               {sampleDetails.diagnosis}
             </div>
           )}
-          {sampleDetails.diff_diagnosis && (
+          {sampleDetails?.diff_diagnosis && (
             <div className="md:col-span-2">
               <span className="font-semibold leading-relaxed">
                 Differential diagnosis:{" "}
               </span>
-              {sampleDetails.diff_diagnosis}
+              {sampleDetails?.diff_diagnosis}
             </div>
           )}
-          {sampleDetails.etiology_identified && (
+          {sampleDetails?.etiology_identified && (
             <div className="md:col-span-2">
               <span className="font-semibold leading-relaxed">
                 Etiology identified:{" "}
@@ -376,15 +363,15 @@ export const SampleDetails = ({ id }: DetailRoute) => {
             <span className="font-semibold leading-relaxed">
               Is Atypical presentation{" "}
             </span>
-            {yesOrNoBadge(sampleDetails.is_atypical_presentation)}
+            {yesOrNoBadge(sampleDetails?.is_atypical_presentation)}
           </div>
           <div>
             <span className="font-semibold leading-relaxed">
               Is unusual course{" "}
             </span>
-            {yesOrNoBadge(sampleDetails.is_unusual_course)}
+            {yesOrNoBadge(sampleDetails?.is_unusual_course)}
           </div>
-          {sampleDetails.atypical_presentation && (
+          {sampleDetails?.atypical_presentation && (
             <div className="md:col-span-2">
               <span className="font-semibold leading-relaxed">
                 Atypical presentation details:{" "}
@@ -396,27 +383,27 @@ export const SampleDetails = ({ id }: DetailRoute) => {
             <span className="font-semibold leading-relaxed">
               SARI - Severe Acute Respiratory illness{" "}
             </span>
-            {yesOrNoBadge(sampleDetails.has_sari)}
+            {yesOrNoBadge(sampleDetails?.has_sari)}
           </div>
           <div>
             <span className="font-semibold leading-relaxed">
               ARI - Acute Respiratory illness{" "}
             </span>
-            {yesOrNoBadge(sampleDetails.has_ari)}
+            {yesOrNoBadge(sampleDetails?.has_ari)}
           </div>
           <div>
             <span className="font-semibold leading-relaxed">
               Contact with confirmed carrier{" "}
             </span>
-            {yesOrNoBadge(sampleDetails.patient_has_confirmed_contact)}
+            {yesOrNoBadge(sampleDetails?.patient_has_confirmed_contact)}
           </div>
           <div>
             <span className="font-semibold leading-relaxed">
               Contact with suspected carrier{" "}
             </span>
-            {yesOrNoBadge(sampleDetails.patient_has_suspected_contact)}
+            {yesOrNoBadge(sampleDetails?.patient_has_suspected_contact)}
           </div>
-          {sampleDetails.patient_travel_history &&
+          {sampleDetails?.patient_travel_history &&
             sampleDetails.patient_travel_history.length !== 0 && (
               <div className="md:col-span-2">
                 <span className="font-semibold leading-relaxed">
@@ -425,7 +412,7 @@ export const SampleDetails = ({ id }: DetailRoute) => {
                 {sampleDetails.patient_travel_history.join(", ")}
               </div>
             )}
-          {sampleDetails.sample_type && (
+          {sampleDetails?.sample_type && (
             <div className="md:col-span-2">
               <span className="font-semibold capitalize leading-relaxed">
                 Sample Type:{" "}
@@ -438,12 +425,12 @@ export const SampleDetails = ({ id }: DetailRoute) => {
 
       <div>
         <h4 className="mt-8">Details of patient</h4>
-        {showPatientCard(sampleDetails.patient_object)}
+        {showPatientCard(sampleDetails?.patient_object)}
       </div>
 
       <div>
         <h4 className="mt-8">Sample Test History</h4>
-        {sampleDetails.flow &&
+        {sampleDetails?.flow &&
           sampleDetails.flow.map((flow: FlowModel) => renderFlow(flow))}
       </div>
 
diff --git a/src/Components/Patient/SampleFilters.tsx b/src/Components/Patient/SampleFilters.tsx
index 8bebd135e0b..2a72f54204f 100644
--- a/src/Components/Patient/SampleFilters.tsx
+++ b/src/Components/Patient/SampleFilters.tsx
@@ -1,4 +1,3 @@
-import { useState, useEffect } from "react";
 import {
   SAMPLE_TEST_STATUS,
   SAMPLE_TEST_RESULT,
@@ -6,14 +5,14 @@ import {
 } from "../../Common/constants";
 import { FacilitySelect } from "../Common/FacilitySelect";
 import { FacilityModel } from "../Facility/models";
-import { getAnyFacility } from "../../Redux/actions";
-import { useDispatch } from "react-redux";
 import useMergeState from "../../Common/hooks/useMergeState";
 import FiltersSlideover from "../../CAREUI/interactive/FiltersSlideover";
 import CircularProgress from "../Common/components/CircularProgress";
 import { FieldLabel } from "../Form/FormFields/FormField";
 import { SelectFormField } from "../Form/FormFields/SelectFormField";
 import { FieldChangeEvent } from "../Form/FormFields/Utils";
+import useQuery from "../../Utils/request/useQuery";
+import routes from "../../Redux/api";
 
 export default function UserFilter(props: any) {
   const { filter, onChange, closeFilter, removeFilters } = props;
@@ -26,9 +25,6 @@ export default function UserFilter(props: any) {
     sample_type: filter.sample_type || "",
   });
 
-  const [isFacilityLoading, setFacilityLoading] = useState(false);
-  const dispatch: any = useDispatch();
-
   const handleChange = ({ name, value }: FieldChangeEvent<unknown>) => {
     setFilterState({ ...filterState, [name]: value });
   };
@@ -44,21 +40,15 @@ export default function UserFilter(props: any) {
     onChange(data);
   };
 
-  useEffect(() => {
-    async function fetchData() {
-      if (filter.facility) {
-        setFacilityLoading(true);
-        const { data: facilityData } = await dispatch(
-          getAnyFacility(filter.facility, "facility")
-        );
-        setFilterState({ ...filterState, facility_ref: facilityData });
-        setFacilityLoading(false);
-      }
-    }
-    fetchData();
-  }, [dispatch]);
-
-  console.log(filterState.sample_type);
+  const { loading: isFacilityLoading } = useQuery(routes.getAnyFacility, {
+    pathParams: {
+      id: filter.facility,
+    },
+    prefetch: !!filter.facility,
+    onResponse: ({ data }) => {
+      setFilterState({ ...filterState, facility_ref: data });
+    },
+  });
 
   return (
     <FiltersSlideover
diff --git a/src/Components/Patient/SamplePreview.tsx b/src/Components/Patient/SamplePreview.tsx
index b2a325d5013..7648ad6647e 100644
--- a/src/Components/Patient/SamplePreview.tsx
+++ b/src/Components/Patient/SamplePreview.tsx
@@ -1,13 +1,11 @@
 import { classNames, formatDateTime } from "../../Utils/utils";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import { lazy, useCallback, useState } from "react";
+
+import { lazy } from "react";
 
 import ButtonV2 from "../Common/components/ButtonV2";
 import Page from "../Common/components/Page";
-import { SampleReportModel } from "./models";
-
-import { sampleReport } from "../../Redux/actions";
-import { useDispatch } from "react-redux";
+import useQuery from "../../Utils/request/useQuery";
+import routes from "../../Redux/api";
 
 const Loading = lazy(() => import("../Common/Loading"));
 
@@ -56,34 +54,19 @@ function SampleReportSection({ title, fields }: ISampleReportSectionProps) {
 }
 
 export default function SampleReport(props: ISamplePreviewProps) {
-  const dispatch: any = useDispatch();
   const { id, sampleId } = props;
-  const [isLoading, setIsLoading] = useState(false);
-  const [sampleData, setSampleData] = useState<SampleReportModel>({});
 
   let report: JSX.Element = <></>;
   let reportData: JSX.Element = <></>;
 
-  const fetchData = useCallback(
-    async (status: statusType) => {
-      setIsLoading(true);
-      const res: any = await dispatch(sampleReport(id, sampleId));
-
-      if (!status.aborted) {
-        if (res && res.data) {
-          setSampleData(res.data);
-        }
-      }
-      setIsLoading(false);
-    },
-    [dispatch, id]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchData(status);
-    },
-    [fetchData]
+  const { loading: isLoading, data: sampleData } = useQuery(
+    routes.sampleReport,
+    {
+      pathParams: {
+        id,
+        sampleId,
+      },
+    }
   );
 
   if (sampleData) {
diff --git a/src/Components/Patient/SampleTest.tsx b/src/Components/Patient/SampleTest.tsx
index 625e2104d0d..21a308fa393 100644
--- a/src/Components/Patient/SampleTest.tsx
+++ b/src/Components/Patient/SampleTest.tsx
@@ -1,9 +1,7 @@
 import { navigate } from "raviger";
 
-import { useReducer, useState, useEffect, lazy } from "react";
-import { useDispatch } from "react-redux";
+import { useReducer, useState, lazy } from "react";
 import { SAMPLE_TYPE_CHOICES, ICMR_CATEGORY } from "../../Common/constants";
-import { createSampleTest, getPatient } from "../../Redux/actions";
 import * as Notification from "../../Utils/Notifications.js";
 import { SampleTestModel } from "./models";
 import { Cancel, Submit } from "../Common/components/ButtonV2";
@@ -16,6 +14,9 @@ import CheckBoxFormField from "../Form/FormFields/CheckBoxFormField";
 import { FieldChangeEvent } from "../Form/FormFields/Utils";
 import Page from "../Common/components/Page";
 import { FacilitySelect } from "../Common/FacilitySelect";
+import request from "../../Utils/request/request";
+import routes from "../../Redux/api";
+import useQuery from "../../Utils/request/useQuery";
 const Loading = lazy(() => import("../Common/Loading"));
 
 const initForm: SampleTestModel = {
@@ -68,30 +69,18 @@ const sampleTestFormReducer = (state = initialState, action: any) => {
 
 export const SampleTest = ({ facilityId, patientId }: any) => {
   const { goBack } = useAppHistory();
-  const dispatchAction: any = useDispatch();
   const [state, dispatch] = useReducer(sampleTestFormReducer, initialState);
   const [isLoading, setIsLoading] = useState(false);
-  const [facilityName, setFacilityName] = useState("");
-  const [patientName, setPatientName] = useState("");
 
   const headerText = "Request Sample";
   const buttonText = "Confirm your request to send sample for testing";
 
-  useEffect(() => {
-    async function fetchPatientName() {
-      if (patientId) {
-        const res = await dispatchAction(getPatient({ id: patientId }));
-        if (res.data) {
-          setPatientName(res.data.name);
-          setFacilityName(res.data.facility_object.name);
-        }
-      } else {
-        setPatientName("");
-        setFacilityName("");
-      }
-    }
-    fetchPatientName();
-  }, [dispatchAction, patientId]);
+  const { data } = useQuery(routes.getPatient, {
+    pathParams: {
+      id: patientId,
+    },
+    prefetch: !!patientId,
+  });
 
   const validateForm = () => {
     const errors = { ...initError };
@@ -170,15 +159,23 @@ export const SampleTest = ({ facilityId, patientId }: any) => {
             ? state.form.sample_type_other
             : undefined,
       };
-      const res = await dispatchAction(createSampleTest(data, { patientId }));
-      setIsLoading(false);
-      if (res && res.data) {
-        dispatch({ type: "set_form", form: initForm });
-        Notification.Success({
-          msg: "Sample test created successfully",
-        });
-        navigate(`/facility/${facilityId}/patient/${patientId}`);
-      }
+
+      await request(routes.createSampleTest, {
+        pathParams: {
+          patientId,
+        },
+        body: data,
+        onResponse: ({ res, data }) => {
+          setIsLoading(false);
+          if (res?.ok && data) {
+            dispatch({ type: "set_form", form: initForm });
+            Notification.Success({
+              msg: "Sample test created successfully",
+            });
+            navigate(`/facility/${facilityId}/patient/${patientId}`);
+          }
+        },
+      });
     }
   };
 
@@ -201,8 +198,8 @@ export const SampleTest = ({ facilityId, patientId }: any) => {
     <Page
       title={headerText}
       crumbsReplacements={{
-        [facilityId]: { name: facilityName },
-        [patientId]: { name: patientName },
+        [facilityId]: { name: data?.facility_object?.name || "" },
+        [patientId]: { name: data?.name || "" },
       }}
       backUrl={`/facility/${facilityId}/patient/${patientId}`}
     >
diff --git a/src/Components/Patient/SampleTestCard.tsx b/src/Components/Patient/SampleTestCard.tsx
index 1ae1ff8671b..f2cc928bf50 100644
--- a/src/Components/Patient/SampleTestCard.tsx
+++ b/src/Components/Patient/SampleTestCard.tsx
@@ -1,9 +1,7 @@
 import { navigate } from "raviger";
 import { useState } from "react";
 import { SampleTestModel } from "./models";
-import { useDispatch } from "react-redux";
 import { SAMPLE_TEST_STATUS } from "../../Common/constants";
-import { patchSample } from "../../Redux/actions";
 import * as Notification from "../../Utils/Notifications";
 import UpdateStatusDialog from "./UpdateStatusDialog";
 import _ from "lodash-es";
@@ -11,17 +9,19 @@ import { formatDateTime } from "../../Utils/utils";
 import ButtonV2 from "../Common/components/ButtonV2";
 import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
 import RelativeDateUserMention from "../Common/RelativeDateUserMention";
+import request from "../../Utils/request/request";
+import routes from "../../Redux/api";
 
 interface SampleDetailsProps {
   facilityId: number;
   patientId: number;
   itemData: SampleTestModel;
+  refetch: () => void;
   handleApproval: (status: number, sample: SampleTestModel) => void;
 }
 
 export const SampleTestCard = (props: SampleDetailsProps) => {
-  const { itemData, handleApproval, facilityId, patientId } = props;
-  const dispatch: any = useDispatch();
+  const { itemData, handleApproval, facilityId, patientId, refetch } = props;
 
   const [statusDialog, setStatusDialog] = useState<{
     show: boolean;
@@ -43,15 +43,21 @@ export const SampleTestCard = (props: SampleDetailsProps) => {
       sampleData.date_of_result = new Date().toISOString();
     }
     const statusName = SAMPLE_TEST_STATUS.find((i) => i.id === status)?.desc;
-
-    const res = await dispatch(patchSample(sampleData, { id: sample.id }));
-    if (res && (res.status === 201 || res.status === 200)) {
-      window.location.reload();
-      Notification.Success({
-        msg: `Success - ${statusName}`,
-      });
-    }
-    dismissUpdateStatus();
+    await request(routes.patchSample, {
+      pathParams: {
+        id: sample.id!,
+      },
+      body: sampleData,
+      onResponse: ({ res }) => {
+        if (res?.ok) {
+          refetch();
+          Notification.Success({
+            msg: `Success - ${statusName}`,
+          });
+        }
+        dismissUpdateStatus();
+      },
+    });
   };
 
   const showUpdateStatus = (sample: SampleTestModel) => {
@@ -78,6 +84,7 @@ export const SampleTestCard = (props: SampleDetailsProps) => {
           : "bg-white hover:border-primary-500"
       } mt-4 block cursor-pointer rounded-lg border bg-white p-4 text-black shadow`}
     >
+      <div>test card this</div>
       <div
         onClick={(_e) =>
           navigate(
diff --git a/src/Components/Patient/SampleViewAdmin.tsx b/src/Components/Patient/SampleViewAdmin.tsx
index 5aca767e480..122f82aa7e2 100644
--- a/src/Components/Patient/SampleViewAdmin.tsx
+++ b/src/Components/Patient/SampleViewAdmin.tsx
@@ -1,20 +1,13 @@
 import SampleFilter from "./SampleFilters";
 import { navigate } from "raviger";
-import { useCallback, useState, useEffect, lazy } from "react";
-import { useDispatch } from "react-redux";
+import { useState, lazy } from "react";
 import {
   SAMPLE_TEST_STATUS,
   SAMPLE_TEST_RESULT,
   SAMPLE_FLOW_RULES,
   SAMPLE_TYPE_CHOICES,
 } from "../../Common/constants";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import {
-  getTestList,
-  patchSample,
-  downloadSampleTests,
-  getAnyFacility,
-} from "../../Redux/actions";
+import { downloadSampleTests } from "../../Redux/actions";
 import * as Notification from "../../Utils/Notifications";
 import { SampleTestModel } from "./models";
 import UpdateStatusDialog from "./UpdateStatusDialog";
@@ -26,6 +19,9 @@ import CountBlock from "../../CAREUI/display/Count";
 import CareIcon from "../../CAREUI/icons/CareIcon";
 import { AdvancedFilterButton } from "../../CAREUI/interactive/FiltersSlideover";
 import Page from "../Common/components/Page";
+import useQuery from "../../Utils/request/useQuery";
+import routes from "../../Redux/api";
+import request from "../../Utils/request/request";
 
 const Loading = lazy(() => import("../Common/Loading"));
 
@@ -41,70 +37,35 @@ export default function SampleViewAdmin() {
     limit: 10,
     cacheBlacklist: ["patient_name", "district_name"],
   });
-  const dispatch: any = useDispatch();
-  const initialData: any[] = [];
   let manageSamples: any = null;
-  const [sample, setSample] = useState<Array<SampleTestModel>>(initialData);
-  const [isLoading, setIsLoading] = useState(false);
-  const [totalCount, setTotalCount] = useState(0);
-  const [fetchFlag, callFetchData] = useState(false);
-  const [facilityName, setFacilityName] = useState("");
   const [statusDialog, setStatusDialog] = useState<{
     show: boolean;
     sample: SampleTestModel;
   }>({ show: false, sample: {} });
 
-  useEffect(() => {
-    async function fetchData() {
-      if (!qParams.facility) return setFacilityName("");
-      const res = await dispatch(getAnyFacility(qParams.facility));
-      setFacilityName(res?.data?.name);
-    }
-
-    fetchData();
-  }, [dispatch, qParams.facility]);
-
-  const fetchData = useCallback(
-    async (status: statusType) => {
-      setIsLoading(true);
-      const res = await dispatch(
-        getTestList({
-          limit: resultsPerPage,
-          offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage,
-          patient_name: qParams.patient_name || undefined,
-          district_name: qParams.district_name || undefined,
-          status: qParams.status || undefined,
-          result: qParams.result || undefined,
-          facility: qParams.facility || "",
-          sample_type: qParams.sample_type || undefined,
-        })
-      );
-      if (!status.aborted) {
-        if (res && res.data) {
-          setSample(res.data.results);
-          setTotalCount(res.data.count);
-        }
-        setIsLoading(false);
-      }
+  const { data: facilityData } = useQuery(routes.getAnyFacility, {
+    pathParams: {
+      id: qParams.facility,
     },
-    [
-      dispatch,
-      qParams.page,
-      qParams.patient_name,
-      qParams.district_name,
-      qParams.status,
-      qParams.result,
-      qParams.facility,
-      qParams.sample_type,
-    ]
-  );
+    prefetch: !!qParams.facility,
+  });
 
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchData(status);
+  const {
+    loading: isLoading,
+    data: sampeleData,
+    refetch,
+  } = useQuery(routes.getTestSampleList, {
+    query: {
+      limit: resultsPerPage,
+      offset: (qParams.page ? qParams.page - 1 : 0) * resultsPerPage,
+      patient_name: qParams.patient_name || undefined,
+      district_name: qParams.district_name || undefined,
+      status: qParams.status || undefined,
+      result: qParams.result || undefined,
+      facility: qParams.facility || undefined,
+      sample_type: qParams.sample_type || undefined,
     },
-    [fetchData, fetchFlag]
-  );
+  });
 
   const handleApproval = async (
     sample: SampleTestModel,
@@ -121,14 +82,22 @@ export default function SampleViewAdmin() {
       sampleData.date_of_result = new Date().toISOString();
     }
     const statusName = SAMPLE_TEST_STATUS.find((i) => i.id === status)?.desc;
-    const res = await dispatch(patchSample(sampleData, { id: sample.id }));
-    if (res && (res.status === 201 || res.status === 200)) {
-      Notification.Success({
-        msg: `Success - ${statusName}`,
-      });
-      callFetchData(!fetchFlag);
-    }
-    dismissUpdateStatus();
+
+    await request(routes.patchSample, {
+      pathParams: {
+        id: sample.id || 0,
+      },
+      body: sampleData,
+      onResponse: ({ res }) => {
+        if (res?.ok) {
+          Notification.Success({
+            msg: `Success - ${statusName}`,
+          });
+          refetch();
+        }
+        dismissUpdateStatus();
+      },
+    });
   };
 
   const showUpdateStatus = (sample: SampleTestModel) => {
@@ -163,8 +132,8 @@ export default function SampleViewAdmin() {
       .join("\n");
 
   let sampleList: any[] = [];
-  if (sample && sample.length) {
-    sampleList = sample.map((item) => {
+  if (sampeleData?.count) {
+    sampleList = sampeleData.results.map((item) => {
       const status = String(item.status) as keyof typeof SAMPLE_FLOW_RULES;
       const statusText = SAMPLE_TEST_STATUS.find(
         (i) => i.text === status
@@ -303,20 +272,20 @@ export default function SampleViewAdmin() {
     });
   }
 
-  if (isLoading || !sample) {
+  if (isLoading || !sampeleData) {
     manageSamples = (
       <div className="flex w-full justify-center">
         <Loading />
       </div>
     );
-  } else if (sample && sample.length) {
+  } else if (sampeleData?.count) {
     manageSamples = (
       <>
         {sampleList}
-        <Pagination totalCount={totalCount} />
+        <Pagination totalCount={sampeleData?.count} />
       </>
     );
-  } else if (sample && sample.length === 0) {
+  } else if (sampeleData?.count === 0) {
     manageSamples = (
       <div className="w-full rounded-lg bg-white p-3">
         <div className="mt-4 flex w-full  justify-center text-2xl font-bold text-gray-600">
@@ -351,7 +320,7 @@ export default function SampleViewAdmin() {
           <div className="w-full">
             <CountBlock
               text="Total Samples Taken"
-              count={totalCount}
+              count={sampeleData?.count || 0}
               loading={isLoading}
               icon="l-thermometer"
               className="flex-1"
@@ -401,7 +370,11 @@ export default function SampleViewAdmin() {
                 (type) => type.id === qParams.sample_type
               )?.text || ""
             ),
-            value("Facility", "facility", facilityName),
+            value(
+              "Facility",
+              "facility",
+              qParams.facility ? facilityData?.name || "" : ""
+            ),
           ]}
         />
       </div>
diff --git a/src/Components/Patient/ShiftCreate.tsx b/src/Components/Patient/ShiftCreate.tsx
index fb15039a2ea..0323ddb7c4b 100644
--- a/src/Components/Patient/ShiftCreate.tsx
+++ b/src/Components/Patient/ShiftCreate.tsx
@@ -7,8 +7,7 @@ import {
   SHIFTING_VEHICLE_CHOICES,
 } from "../../Common/constants";
 import { Cancel, Submit } from "../Common/components/ButtonV2";
-import { createShift, getPatient } from "../../Redux/actions";
-import { lazy, useEffect, useReducer, useState } from "react";
+import { lazy, useReducer, useState } from "react";
 
 import { FacilitySelect } from "../Common/FacilitySelect";
 import { FieldChangeEvent } from "../Form/FormFields/Utils";
@@ -22,28 +21,27 @@ import { parsePhoneNumber } from "../../Utils/utils.js";
 import { phonePreg } from "../../Common/validation";
 import useAppHistory from "../../Common/hooks/useAppHistory";
 import useConfig from "../../Common/hooks/useConfig";
-import { useDispatch } from "react-redux";
 import { useTranslation } from "react-i18next";
 import Page from "../Common/components/Page.js";
 import Card from "../../CAREUI/display/Card.js";
 import CheckBoxFormField from "../Form/FormFields/CheckBoxFormField.js";
 import { SelectFormField } from "../Form/FormFields/SelectFormField.js";
 import { PhoneNumberValidator } from "../Form/FieldValidators.js";
+import useQuery from "../../Utils/request/useQuery.js";
+import routes from "../../Redux/api.js";
+import request from "../../Utils/request/request.js";
 
 const Loading = lazy(() => import("../Common/Loading"));
 
 interface patientShiftProps {
-  facilityId: number;
-  patientId: number;
+  facilityId: string;
+  patientId: string;
 }
 
 export const ShiftCreate = (props: patientShiftProps) => {
   const { goBack } = useAppHistory();
   const { facilityId, patientId } = props;
-  const dispatchAction: any = useDispatch();
   const [isLoading, setIsLoading] = useState(false);
-  const [facilityName, setFacilityName] = useState("");
-  const [patientName, setPatientName] = useState("");
   const [patientCategory, setPatientCategory] = useState<any>();
   const { t } = useTranslation();
   const { wartime_shifting } = useConfig();
@@ -109,27 +107,22 @@ export const ShiftCreate = (props: patientShiftProps) => {
     errors: { ...initError },
   };
 
-  useEffect(() => {
-    async function fetchPatientName() {
-      if (patientId) {
-        const res = await dispatchAction(getPatient({ id: patientId }));
-        if (res.data) {
-          const patient_category =
-            res.data.last_consultation?.last_daily_round?.patient_category ??
-            res.data.last_consultation?.category;
-          setPatientCategory(
-            PATIENT_CATEGORIES.find((c) => c.text === patient_category)?.id
-          );
-          setPatientName(res.data.name);
-          setFacilityName(res.data.facility_object.name);
-        }
-      } else {
-        setPatientName("");
-        setFacilityName("");
+  const { data: patientData } = useQuery(routes.getPatient, {
+    pathParams: {
+      id: patientId,
+    },
+    prefetch: !!patientId,
+    onResponse: ({ data }) => {
+      if (data) {
+        const patient_category =
+          data.last_consultation?.last_daily_round?.patient_category ??
+          data.last_consultation?.category;
+        setPatientCategory(
+          PATIENT_CATEGORIES.find((c) => c.text === patient_category)?.id
+        );
       }
-    }
-    fetchPatientName();
-  }, [dispatchAction, patientId]);
+    },
+  });
 
   const shiftFormReducer = (state = initialState, action: any) => {
     switch (action.type) {
@@ -242,17 +235,22 @@ export const ShiftCreate = (props: patientShiftProps) => {
         ambulance_number: state.form.ambulance_number,
       };
 
-      const res = await dispatchAction(createShift(data));
-      setIsLoading(false);
+      await request(routes.createShift, {
+        body: data,
 
-      if (res && res.data && (res.status == 201 || res.status == 200)) {
-        await dispatch({ type: "set_form", form: initForm });
-        Notification.Success({
-          msg: "Shift request created successfully",
-        });
+        onResponse: ({ res, data }) => {
+          setIsLoading(false);
 
-        navigate(`/shifting/${res.data.id}`);
-      }
+          if (res?.ok && data) {
+            dispatch({ type: "set_form", form: initForm });
+            Notification.Success({
+              msg: "Shift request created successfully",
+            });
+
+            navigate(`/shifting/${data.id}`);
+          }
+        },
+      });
     }
   };
 
@@ -271,8 +269,8 @@ export const ShiftCreate = (props: patientShiftProps) => {
     <Page
       title={"Create Shift Request"}
       crumbsReplacements={{
-        [facilityId]: { name: facilityName },
-        [patientId]: { name: patientName },
+        [facilityId]: { name: patientData?.facility_object?.name || "" },
+        [patientId]: { name: patientData?.name || "" },
       }}
       backUrl={`/facility/${facilityId}/patient/${patientId}`}
     >
diff --git a/src/Redux/actions.tsx b/src/Redux/actions.tsx
index 280abbce5cc..cfe298bda82 100644
--- a/src/Redux/actions.tsx
+++ b/src/Redux/actions.tsx
@@ -20,31 +20,9 @@ export const getFacilityUsers = (id: string, params?: object) => {
   );
 };
 
-export const getFacilityAssetLocation = (
-  facility_external_id: string,
-  external_id: string
-) =>
-  fireRequest(
-    "getFacilityAssetLocation",
-    [],
-    {},
-    { facility_external_id, external_id }
-  );
-
 // asset bed
 export const listAssetBeds = (params: object, altKey?: string) =>
   fireRequest("listAssetBeds", [], params, {}, altKey);
-export const createAssetBed = (
-  params: object,
-  asset_id: string,
-  bed_id: string
-) =>
-  fireRequest(
-    "createAssetBed",
-    [],
-    { ...params, asset: asset_id, bed: bed_id },
-    {}
-  );
 
 export const partialUpdateAssetBed = (params: object, asset_id: string) =>
   fireRequest(
@@ -99,6 +77,11 @@ export const getPatient = (pathParam: object) => {
 export const updatePatient = (params: object, pathParam: object) => {
   return fireRequest("updatePatient", [], params, pathParam);
 };
+
+export const transferPatient = (params: object, pathParam: object) => {
+  return fireRequest("transferPatient", [], params, pathParam);
+};
+
 export const patchPatient = (params: object, pathParam: object) => {
   return fireRequest("patchPatient", [], params, pathParam);
 };
@@ -114,9 +97,6 @@ export const getDistrictByState = (pathParam: object) => {
 export const getDistrictByName = (params: object) => {
   return fireRequest("getDistrictByName", [], params, null);
 };
-export const getDistrict = (id: number, key?: string) => {
-  return fireRequest("getDistrict", [], {}, { id: id }, key);
-};
 
 export const getLocalbodyByDistrict = (pathParam: object) => {
   return fireRequest("getLocalbodyByDistrict", [], {}, pathParam);
@@ -126,30 +106,7 @@ export const getWardByLocalBody = (pathParam: object) => {
   return fireRequest("getWardByLocalBody", [], {}, pathParam);
 };
 
-// Local Body
-export const getLocalBody = (pathParam: object) => {
-  return fireRequest("getLocalBody", [], {}, pathParam);
-};
-
 // Sample Test
-export const getSampleTestList = (params: object, pathParam: object) => {
-  return fireRequest("sampleTestList", [], params, pathParam);
-};
-export const createSampleTest = (params: object, pathParam: object) => {
-  return fireRequest("createSampleTest", [], params, pathParam);
-};
-export const sampleReport = (id: string, sampleId: string) => {
-  return fireRequest("sampleReport", [], {}, { id, sampleId });
-};
-export const getTestList = (params: object) => {
-  return fireRequest("getTestSampleList", [], params);
-};
-export const getTestSample = (id: string) => {
-  return fireRequest("getTestSample", [id], {});
-};
-export const patchSample = (params: object, pathParam: object) => {
-  return fireRequest("patchSample", [], params, pathParam);
-};
 export const downloadSampleTests = (params: object) => {
   return fireRequest("getTestSampleList", [], { ...params, csv: 1 });
 };
@@ -173,9 +130,6 @@ export const getConsultationDailyRoundsDetails = (pathParam: object) => {
 export const createConsultation = (params: object) => {
   return fireRequest("createConsultation", [], params);
 };
-export const getConsultationList = (params: object) => {
-  return fireRequest("getConsultationList", [], params);
-};
 export const getConsultation = (id: string) => {
   return fireRequest("getConsultation", [], {}, { id: id });
 };
@@ -204,17 +158,10 @@ export const dischargePatient = (params: object, pathParams: object) => {
 };
 
 //Shift
-export const createShift = (params: object) => {
-  return fireRequest("createShift", [], params);
-};
-
 export const listShiftRequests = (params: object, key: string) => {
   return fireRequest("listShiftRequests", [], params, null, key);
 };
 
-export const completeTransfer = (pathParams: object) => {
-  return fireRequest("completeTransfer", [], {}, pathParams);
-};
 export const downloadShiftRequests = (params: object) => {
   return fireRequest("downloadShiftRequests", [], params);
 };
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index 4893bfbd33f..8b2a3ae08c2 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -74,7 +74,12 @@ import {
   UserModel,
 } from "../Components/Users/models";
 import { Prescription } from "../Components/Medicine/models";
-import { DailyRoundsModel, PatientModel } from "../Components/Patient/models";
+import {
+  DailyRoundsModel,
+  PatientModel,
+  SampleReportModel,
+  SampleTestModel,
+} from "../Components/Patient/models";
 import { PaginatedResponse } from "../Utils/request/types";
 import {
   NotificationData,
@@ -505,6 +510,8 @@ const routes = {
   },
   getConsultationList: {
     path: "/api/v1/consultation/",
+    method: "GET",
+    TRes: Type<PaginatedResponse<ConsultationModel>>(),
   },
   createConsultation: {
     path: "/api/v1/consultation/",
@@ -549,6 +556,8 @@ const routes = {
 
   getDailyReport: {
     path: "/api/v1/consultation/{consultationId}/daily_rounds/{id}/",
+    method: "GET",
+    TRes: Type<DailyRoundsModel>(),
   },
   dailyRoundsAnalyse: {
     path: "/api/v1/consultation/{consultationId}/daily_rounds/analyse/",
@@ -644,6 +653,8 @@ const routes = {
   },
   patientList: {
     path: "/api/v1/patient/",
+    method: "GET",
+    TRes: Type<PaginatedResponse<PatientModel>>(),
   },
   addPatient: {
     path: "/api/v1/patient/",
@@ -651,7 +662,7 @@ const routes = {
   },
   getPatient: {
     path: "/api/v1/patient/{id}/",
-    TBody: Type<PatientModel>(),
+    method: "GET",
     TRes: Type<PatientModel>(),
   },
   updatePatient: {
@@ -661,6 +672,8 @@ const routes = {
   patchPatient: {
     path: "/api/v1/patient/{id}/",
     method: "PATCH",
+    TBody: Type<Partial<PatientModel>>(),
+    TRes: Type<PatientModel>(),
   },
   transferPatient: {
     path: "/api/v1/patient/{id}/transfer/",
@@ -690,13 +703,19 @@ const routes = {
   },
   sampleTestList: {
     path: "/api/v1/patient/{patientId}/test_sample/",
+    method: "GET",
+    TRes: Type<PaginatedResponse<SampleTestModel>>(),
   },
   createSampleTest: {
     path: "/api/v1/patient/{patientId}/test_sample/",
     method: "POST",
+    TRes: Type<PatientModel>(),
+    TBody: Type<SampleTestModel>(),
   },
   sampleReport: {
-    path: "/api/v1/patient/{id}/test_sample/{sampleId}/icmr_sample",
+    path: "/api/v1/patient/{id}/test_sample/{sampleId}/icmr_sample/",
+    method: "GET",
+    TRes: Type<SampleReportModel>(),
   },
 
   // External Results
@@ -803,13 +822,19 @@ const routes = {
   // Sample Test
   getTestSampleList: {
     path: "/api/v1/test_sample/",
+    method: "GET",
+    TRes: Type<PaginatedResponse<SampleTestModel>>(),
   },
   getTestSample: {
-    path: "/api/v1/test_sample",
+    path: "/api/v1/test_sample/{id}/",
+    method: "GET",
+    TRes: Type<SampleTestModel>(),
   },
   patchSample: {
     path: "/api/v1/test_sample/{id}/",
     method: "PATCH",
+    TBody: Type<SampleTestModel>(),
+    TRes: Type<PatientModel>(),
   },
 
   //inventory
@@ -905,15 +930,17 @@ const routes = {
   createShift: {
     path: "/api/v1/shift/",
     method: "POST",
+    TBody: Type<Partial<IShift>>(),
+    TRes: Type<PatientModel>(),
   },
   updateShift: {
-    path: "/api/v1/shift/{id}",
+    path: "/api/v1/shift/{id}/",
     method: "PUT",
     TBody: Type<IShift>(),
     TRes: Type<IShift>(),
   },
   deleteShiftRecord: {
-    path: "/api/v1/shift/{id}",
+    path: "/api/v1/shift/{id}/",
     method: "DELETE",
     TRes: Type<{ detail: string }>(),
   },

From d56b9e56e490873e7960bd62592da84600004430 Mon Sep 17 00:00:00 2001
From: Rithvik Nishad <mail@rithviknishad.dev>
Date: Thu, 15 Feb 2024 19:39:00 +0530
Subject: [PATCH 16/17] fixes #7217; Allows "MESSAGE" type push notifications
 to show notification (#7221)

---
 src/service-worker.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/service-worker.ts b/src/service-worker.ts
index 0b1c40288f5..76501ea21f1 100644
--- a/src/service-worker.ts
+++ b/src/service-worker.ts
@@ -105,7 +105,7 @@ self.addEventListener("push", async function (event) {
   if (event.data) {
     const data = JSON.parse(event.data.text());
 
-    if (["MESSAGE", "PUSH_MESSAGE"].includes(data?.type)) {
+    if (["PUSH_MESSAGE"].includes(data?.type)) {
       self.clients.matchAll().then((clients) => {
         clients[0].postMessage(data);
       });

From dacc7f8b56e45a73e5a166ffeb06d92f8950704e Mon Sep 17 00:00:00 2001
From: Khavin Shankar <khavinshankar@gmail.com>
Date: Thu, 15 Feb 2024 22:00:56 +0530
Subject: [PATCH 17/17] Minor ui spacing fix (#7147)

---
 src/Components/Patient/ManagePatients.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx
index 5e8afaf2d5c..534a3e876a1 100644
--- a/src/Components/Patient/ManagePatients.tsx
+++ b/src/Components/Patient/ManagePatients.tsx
@@ -747,7 +747,7 @@ export const PatientManager = () => {
               </p>
             </ButtonV2>
           </div>
-          <div className="flex w-full flex-col justify-end gap-2 lg:w-fit lg:flex-row lg:gap-3">
+          <div className="flex w-full flex-col items-center justify-end gap-2 lg:ml-3 lg:w-fit lg:flex-row lg:gap-3">
             <SwitchTabs
               tab1="Live"
               tab2="Discharged"