From 53568617d35fe49060c69c75393af7f482161aa1 Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Fri, 7 Jul 2023 11:26:55 +0530
Subject: [PATCH 01/17] feat: add patient notes pop-up on consultation page

---
 package-lock.json                             |  33 +++++
 package.json                                  |   1 +
 .../Facility/ConsultationDetails.tsx          |   3 +
 src/Components/Facility/PatientNoteCard.tsx   |  39 ++++++
 src/Components/Facility/PatientNotesList.tsx  | 125 ++++++++++++++++++
 .../Facility/PatientNotesSlideover.tsx        | 117 ++++++++++++++++
 6 files changed, 318 insertions(+)
 create mode 100644 src/Components/Facility/PatientNoteCard.tsx
 create mode 100644 src/Components/Facility/PatientNotesList.tsx
 create mode 100644 src/Components/Facility/PatientNotesSlideover.tsx

diff --git a/package-lock.json b/package-lock.json
index 1d07e4fe19e..817cd903efe 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -47,6 +47,7 @@
         "react-dom": "18.2.0",
         "react-google-recaptcha": "^2.1.0",
         "react-i18next": "^11.18.6",
+        "react-infinite-scroll-component": "^6.1.0",
         "react-player": "^2.11.0",
         "react-qr-reader": "^2.2.1",
         "react-redux": "^8.0.4",
@@ -14062,6 +14063,17 @@
         }
       }
     },
+    "node_modules/react-infinite-scroll-component": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz",
+      "integrity": "sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ==",
+      "dependencies": {
+        "throttle-debounce": "^2.1.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.0.0"
+      }
+    },
     "node_modules/react-inspector": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.1.tgz",
@@ -15870,6 +15882,14 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/throttle-debounce": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz",
+      "integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/throttleit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
@@ -27049,6 +27069,14 @@
         "html-parse-stringify": "^3.0.1"
       }
     },
+    "react-infinite-scroll-component": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz",
+      "integrity": "sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ==",
+      "requires": {
+        "throttle-debounce": "^2.1.0"
+      }
+    },
     "react-inspector": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.1.tgz",
@@ -28397,6 +28425,11 @@
       "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
       "dev": true
     },
+    "throttle-debounce": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz",
+      "integrity": "sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ=="
+    },
     "throttleit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
diff --git a/package.json b/package.json
index fb232281bad..64145215a96 100644
--- a/package.json
+++ b/package.json
@@ -87,6 +87,7 @@
     "react-dom": "18.2.0",
     "react-google-recaptcha": "^2.1.0",
     "react-i18next": "^11.18.6",
+    "react-infinite-scroll-component": "^6.1.0",
     "react-player": "^2.11.0",
     "react-qr-reader": "^2.2.1",
     "react-redux": "^8.0.4",
diff --git a/src/Components/Facility/ConsultationDetails.tsx b/src/Components/Facility/ConsultationDetails.tsx
index 08681ba55fc..acdae779bab 100644
--- a/src/Components/Facility/ConsultationDetails.tsx
+++ b/src/Components/Facility/ConsultationDetails.tsx
@@ -53,6 +53,7 @@ import moment from "moment";
 import { navigate } from "raviger";
 import { useDispatch } from "react-redux";
 import { useTranslation } from "react-i18next";
+import PatientNotesSlideover from "./PatientNotesSlideover";
 
 const Loading = loadable(() => import("../Common/Loading"));
 const PageTitle = loadable(() => import("../Common/PageTitle"));
@@ -1236,6 +1237,8 @@ export const ConsultationDetails = (props: any) => {
         show={showDoctors}
         setShow={setShowDoctors}
       />
+
+      <PatientNotesSlideover patientId={patientId} facilityId={facilityId} />
     </div>
   );
 };
diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
new file mode 100644
index 00000000000..b90b089352c
--- /dev/null
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -0,0 +1,39 @@
+import { relativeDate, formatDate } from "../../Utils/utils";
+
+const PatientNoteCard = ({
+  note,
+  facilityId,
+}: {
+  note: any;
+  facilityId: any;
+}) => {
+  return (
+    <div
+      key={note.id}
+      className="flex p-3 bg-white rounded-lg text-gray-800 mt-4 flex-col w-full border border-gray-300"
+    >
+      <div className="flex justify-between">
+        <span className="text-gray-700 text-sm font-semibold">
+          {note.created_by_object?.first_name || "Unknown"}{" "}
+          {note.created_by_object?.last_name}
+        </span>
+        <span className="text-gray-700 text-sm">
+          {note.created_by_object.id === facilityId
+            ? "Remote Specialist"
+            : "Local Doctor"}
+        </span>
+      </div>
+      <span className="whitespace-pre-wrap break-words">{note.note}</span>
+      <div className="mt-3 text-xs text-gray-500 text-end">
+        <div className="tooltip inline">
+          <span className="tooltip-text tooltip-left">
+            {formatDate(note.created_date)}
+          </span>
+          {relativeDate(note.created_date)}
+        </div>
+      </div>
+    </div>
+  );
+};
+
+export default PatientNoteCard;
diff --git a/src/Components/Facility/PatientNotesList.tsx b/src/Components/Facility/PatientNotesList.tsx
new file mode 100644
index 00000000000..45464895697
--- /dev/null
+++ b/src/Components/Facility/PatientNotesList.tsx
@@ -0,0 +1,125 @@
+import { useCallback, useState, useEffect } from "react";
+import { useDispatch } from "react-redux";
+import { statusType, useAbortableEffect } from "../../Common/utils";
+import { getPatientNotes } from "../../Redux/actions";
+import { RESULTS_PER_PAGE_LIMIT } from "../../Common/constants";
+import CircularProgress from "../Common/components/CircularProgress";
+import PatientNoteCard from "./PatientNoteCard";
+import InfiniteScroll from "react-infinite-scroll-component";
+
+interface PatientNotesProps {
+  patientId: any;
+  facilityId: any;
+  reload?: boolean;
+  setReload?: any;
+}
+
+const pageSize = RESULTS_PER_PAGE_LIMIT;
+
+const PatientNotesList = (props: PatientNotesProps) => {
+  const { facilityId, reload, setReload } = props;
+
+  const dispatch: any = useDispatch();
+  const initialData: any = { notes: [], cPage: 1, totalPages: 1 };
+  const [state, setState] = useState(initialData);
+  const [isLoading, setIsLoading] = useState(true);
+
+  const fetchData = useCallback(
+    async (page = 1, status: statusType = { aborted: false }) => {
+      setIsLoading(true);
+      const res = await dispatch(
+        getPatientNotes(props.patientId, pageSize, (page - 1) * pageSize)
+      );
+      if (!status.aborted) {
+        if (res && res.data) {
+          if (page === 1) {
+            setState({
+              notes: res.data?.results,
+              cPage: page,
+              totalPages: Math.ceil(res.data.count / pageSize),
+            });
+          } else {
+            setState((prevState: any) => ({
+              ...prevState,
+              notes: [...prevState.notes, ...res.data.results],
+              cPage: page,
+              totalPages: Math.ceil(res.data.count / pageSize),
+            }));
+          }
+        }
+        setIsLoading(false);
+      }
+    },
+    [props.patientId, dispatch]
+  );
+
+  useEffect(() => {
+    if (reload) {
+      fetchData(1);
+      setReload(false);
+    }
+  }, [reload]);
+
+  useAbortableEffect(
+    (status: statusType) => {
+      fetchData(1, status);
+    },
+    [fetchData]
+  );
+
+  const handleNext = () => {
+    if (state.cPage < state.totalPages) {
+      fetchData(state.cPage + 1);
+      setState((prevState: any) => ({
+        ...prevState,
+        cPage: prevState.cPage + 1,
+      }));
+    }
+  };
+
+  if (isLoading && !state.notes.length) {
+    return (
+      <div className="flex items-center justify-center w-full h-[400px]">
+        <CircularProgress />
+      </div>
+    );
+  }
+
+  return (
+    <div
+      className="flex flex-col-reverse h-[390px] overflow-auto m-2 bg-white"
+      id="patient-notes-list"
+    >
+      {state.notes.length ? (
+        <InfiniteScroll
+          next={handleNext}
+          hasMore={state.cPage < state.totalPages}
+          height={385}
+          loader={
+            <div className="flex items-center justify-center">
+              <CircularProgress />
+            </div>
+          }
+          className="flex flex-col-reverse p-2"
+          inverse={true}
+          dataLength={state.notes.length}
+          scrollableTarget="patient-notes-list"
+        >
+          {state.notes.map((note: any) => (
+            <PatientNoteCard
+              note={note}
+              key={note.id}
+              facilityId={facilityId}
+            />
+          ))}
+        </InfiniteScroll>
+      ) : (
+        <div className="text-gray-500 text-2xl font-bold flex justify-center items-center mt-2">
+          No Notes Found
+        </div>
+      )}
+    </div>
+  );
+};
+
+export default PatientNotesList;
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
new file mode 100644
index 00000000000..a9a9ac72a26
--- /dev/null
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -0,0 +1,117 @@
+import { useState, useEffect } from "react";
+import { getPatient, addPatientNote } from "../../Redux/actions";
+import * as Notification from "../../Utils/Notifications.js";
+import { useDispatch } from "react-redux";
+import PatientNotesList from "./PatientNotesList";
+import AuthorizedChild from "../../CAREUI/misc/AuthorizedChild";
+import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
+import CareIcon from "../../CAREUI/icons/CareIcon";
+
+interface PatientNotesProps {
+  patientId: any;
+  facilityId: any;
+}
+
+export default function PatientNotesSlideover(props: PatientNotesProps) {
+  const [show, setShow] = useState(false);
+  const [patientActive, setPatientActive] = useState(true);
+  const [noteField, setNoteField] = useState("");
+  const [reload, setReload] = useState(false);
+
+  const dispatch = useDispatch();
+
+  const { facilityId, patientId } = props;
+
+  const onAddNote = () => {
+    const payload = {
+      note: noteField,
+    };
+    if (!/\S+/.test(noteField)) {
+      Notification.Error({
+        msg: "Note Should Contain At Least 1 Character",
+      });
+      return;
+    }
+    dispatch(addPatientNote(patientId, payload)).then(() => {
+      Notification.Success({ msg: "Note added successfully" });
+      setNoteField("");
+      setReload(!reload);
+    });
+  };
+
+  useEffect(() => {
+    async function fetchPatientName() {
+      if (patientId) {
+        const res = await dispatch(getPatient({ id: patientId }));
+        if (res.data) {
+          setPatientActive(res.data.is_active);
+        }
+      }
+    }
+    fetchPatientName();
+  }, [dispatch, patientId]);
+
+  return (
+    <div
+      className={`fixed right-0 sm:right-20 bottom-0 ${
+        show ? "w-3/12 min-w-[400px]" : "w-1/6 min-w-[250px]"
+      }`}
+    >
+      {!show ? (
+        <div className="flex justify-around items-center w-full p-2 rounded-t-md bg-primary-800 text-white">
+          <span className="font-semibold">Doctor&apos;s Notes</span>
+          <div
+            className={`flex items-center justify-center w-8 h-8 cursor-pointer rounded text-gray-100 text-opacity-70 hover:text-opacity-100 bg-primary-800 hover:bg-primary-700 ${
+              show ? "rotate-180" : ""
+            }`}
+            onClick={() => setShow(!show)}
+          >
+            <i className="fa-solid fa-chevron-up transition-all duration-300 delay-150 ease-out" />
+          </div>
+        </div>
+      ) : (
+        <div className="bg-white rounded-t-md w-full h-[500px] flex flex-col border-2 border-primary-800 transition-all -translate-y-0 ">
+          {/* Doctor Notes Header */}
+          <div className="flex justify-between items-center w-full p-2 px-4 rounded-t-md bg-primary-800 text-white">
+            <span className="font-semibold">Doctor&apos;s Notes</span>
+            <div
+              className={`flex items-center justify-center w-8 h-8 cursor-pointer rounded text-gray-100 text-opacity-70 hover:text-opacity-100 bg-primary-800 hover:bg-primary-700 ${
+                show ? "rotate-180" : ""
+              }`}
+              onClick={() => setShow(!show)}
+            >
+              <i className="fa-solid fa-chevron-up transition-all duration-300 delay-150 ease-out" />
+            </div>
+          </div>
+          {/* Doctor Notes Body */}
+          <PatientNotesList
+            facilityId={facilityId}
+            patientId={patientId}
+            reload={reload}
+            setReload={setReload}
+          />
+          <AuthorizedChild authorizeFor={NonReadOnlyUsers}>
+            {({ isAuthorized }) => (
+              <div className="mx-4 h-fit relative">
+                <input
+                  placeholder="Type your Note"
+                  className=" inline-block w-full border border-gray-500 rounded-lg p-2 focus:outline-none focus:ring-primary-500 focus:border-primary-500"
+                  value={noteField}
+                  onChange={(e) => setNoteField(e.target.value)}
+                  disabled={!patientActive || !isAuthorized}
+                />
+                <button
+                  className="absolute top-2.5 right-2.5 text-primary-500"
+                  onClick={onAddNote}
+                  disabled={!patientActive || !isAuthorized}
+                >
+                  <CareIcon className="care-l-message" />
+                </button>
+              </div>
+            )}
+          </AuthorizedChild>
+        </div>
+      )}
+    </div>
+  );
+}

From a7155e4d59e2d8b5bee9942c96ebe5c801694445 Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Fri, 7 Jul 2023 13:23:00 +0530
Subject: [PATCH 02/17] Migrate form elements to CAREUI

---
 src/Components/Facility/PatientNotesList.tsx  |  4 +-
 .../Facility/PatientNotesSlideover.tsx        | 72 ++++++++++---------
 2 files changed, 42 insertions(+), 34 deletions(-)

diff --git a/src/Components/Facility/PatientNotesList.tsx b/src/Components/Facility/PatientNotesList.tsx
index 45464895697..95ada03f458 100644
--- a/src/Components/Facility/PatientNotesList.tsx
+++ b/src/Components/Facility/PatientNotesList.tsx
@@ -79,7 +79,7 @@ const PatientNotesList = (props: PatientNotesProps) => {
 
   if (isLoading && !state.notes.length) {
     return (
-      <div className="flex items-center justify-center w-full h-[400px]">
+      <div className=" bg-white flex items-center justify-center w-full h-[400px]">
         <CircularProgress />
       </div>
     );
@@ -94,7 +94,7 @@ const PatientNotesList = (props: PatientNotesProps) => {
         <InfiniteScroll
           next={handleNext}
           hasMore={state.cPage < state.totalPages}
-          height={385}
+          height={380}
           loader={
             <div className="flex items-center justify-center">
               <CircularProgress />
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index a9a9ac72a26..45b6857b412 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -3,9 +3,11 @@ import { getPatient, addPatientNote } from "../../Redux/actions";
 import * as Notification from "../../Utils/Notifications.js";
 import { useDispatch } from "react-redux";
 import PatientNotesList from "./PatientNotesList";
-import AuthorizedChild from "../../CAREUI/misc/AuthorizedChild";
 import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
 import CareIcon from "../../CAREUI/icons/CareIcon";
+import { classNames } from "../../Utils/utils";
+import TextFormField from "../Form/FormFields/TextFormField";
+import ButtonV2 from "../Common/components/ButtonV2";
 
 interface PatientNotesProps {
   patientId: any;
@@ -53,34 +55,37 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
 
   return (
     <div
-      className={`fixed right-0 sm:right-20 bottom-0 ${
-        show ? "w-3/12 min-w-[400px]" : "w-1/6 min-w-[250px]"
-      }`}
+      className={classNames(
+        "fixed right-0 sm:right-20 bottom-0",
+        show ? "w-[400px]" : "w-[250px]"
+      )}
     >
       {!show ? (
         <div className="flex justify-around items-center w-full p-2 rounded-t-md bg-primary-800 text-white">
           <span className="font-semibold">Doctor&apos;s Notes</span>
           <div
-            className={`flex items-center justify-center w-8 h-8 cursor-pointer rounded text-gray-100 text-opacity-70 hover:text-opacity-100 bg-primary-800 hover:bg-primary-700 ${
+            className={classNames(
+              "flex items-center justify-center w-8 h-8 cursor-pointer rounded text-gray-100 text-opacity-70 hover:text-opacity-100 bg-primary-800 hover:bg-primary-700",
               show ? "rotate-180" : ""
-            }`}
+            )}
             onClick={() => setShow(!show)}
           >
-            <i className="fa-solid fa-chevron-up transition-all duration-300 delay-150 ease-out" />
+            <CareIcon className="care-l-angle-up text-lg transition-all duration-300 delay-150 ease-out" />
           </div>
         </div>
       ) : (
-        <div className="bg-white rounded-t-md w-full h-[500px] flex flex-col border-2 border-primary-800 transition-all -translate-y-0 ">
+        <div className="bg-white rounded-t-md w-full h-[500px] flex flex-col border-2 border-b-0 pb-3 border-primary-800 transition-all overflow-clip -translate-y-0 ">
           {/* Doctor Notes Header */}
-          <div className="flex justify-between items-center w-full p-2 px-4 rounded-t-md bg-primary-800 text-white">
+          <div className="flex justify-between items-center w-full p-2 px-4 bg-primary-800 text-white">
             <span className="font-semibold">Doctor&apos;s Notes</span>
             <div
-              className={`flex items-center justify-center w-8 h-8 cursor-pointer rounded text-gray-100 text-opacity-70 hover:text-opacity-100 bg-primary-800 hover:bg-primary-700 ${
+              className={classNames(
+                "flex items-center justify-center w-8 h-8 cursor-pointer rounded text-gray-100 text-opacity-70 hover:text-opacity-100 bg-primary-800 hover:bg-primary-700",
                 show ? "rotate-180" : ""
-              }`}
+              )}
               onClick={() => setShow(!show)}
             >
-              <i className="fa-solid fa-chevron-up transition-all duration-300 delay-150 ease-out" />
+              <CareIcon className="care-l-angle-up text-lg transition-all duration-300 delay-150 ease-out" />
             </div>
           </div>
           {/* Doctor Notes Body */}
@@ -90,26 +95,29 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
             reload={reload}
             setReload={setReload}
           />
-          <AuthorizedChild authorizeFor={NonReadOnlyUsers}>
-            {({ isAuthorized }) => (
-              <div className="mx-4 h-fit relative">
-                <input
-                  placeholder="Type your Note"
-                  className=" inline-block w-full border border-gray-500 rounded-lg p-2 focus:outline-none focus:ring-primary-500 focus:border-primary-500"
-                  value={noteField}
-                  onChange={(e) => setNoteField(e.target.value)}
-                  disabled={!patientActive || !isAuthorized}
-                />
-                <button
-                  className="absolute top-2.5 right-2.5 text-primary-500"
-                  onClick={onAddNote}
-                  disabled={!patientActive || !isAuthorized}
-                >
-                  <CareIcon className="care-l-message" />
-                </button>
-              </div>
-            )}
-          </AuthorizedChild>
+          <div className="flex items-center mx-4 relative">
+            <TextFormField
+              name="note"
+              value={noteField}
+              onChange={(e) => setNoteField(e.value)}
+              className="grow"
+              type="text"
+              errorClassName="hidden"
+              placeholder="Type your Note"
+              disabled={!patientActive}
+            />
+            <ButtonV2
+              onClick={onAddNote}
+              border={false}
+              className="absolute right-2"
+              ghost
+              size="small"
+              disabled={!patientActive}
+              authorizeFor={NonReadOnlyUsers}
+            >
+              <CareIcon className="care-l-message text-lg" />
+            </ButtonV2>
+          </div>
         </div>
       )}
     </div>

From 10a77613a36cce4ac77cf20044efc8f8dd6551b9 Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Sat, 8 Jul 2023 13:33:02 +0530
Subject: [PATCH 03/17] made patient notes popup responsive

---
 src/Components/Facility/PatientNotesList.tsx      | 5 ++---
 src/Components/Facility/PatientNotesSlideover.tsx | 8 +++++---
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/Components/Facility/PatientNotesList.tsx b/src/Components/Facility/PatientNotesList.tsx
index 95ada03f458..69dda827f4c 100644
--- a/src/Components/Facility/PatientNotesList.tsx
+++ b/src/Components/Facility/PatientNotesList.tsx
@@ -87,20 +87,19 @@ const PatientNotesList = (props: PatientNotesProps) => {
 
   return (
     <div
-      className="flex flex-col-reverse h-[390px] overflow-auto m-2 bg-white"
+      className="flex flex-col-reverse grow h-[390px] overflow-auto m-2 bg-white"
       id="patient-notes-list"
     >
       {state.notes.length ? (
         <InfiniteScroll
           next={handleNext}
           hasMore={state.cPage < state.totalPages}
-          height={380}
           loader={
             <div className="flex items-center justify-center">
               <CircularProgress />
             </div>
           }
-          className="flex flex-col-reverse p-2"
+          className="flex flex-col-reverse p-2 h-full"
           inverse={true}
           dataLength={state.notes.length}
           scrollableTarget="patient-notes-list"
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index 45b6857b412..d377064c6dc 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -56,8 +56,10 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
   return (
     <div
       className={classNames(
-        "fixed right-0 sm:right-20 bottom-0",
-        show ? "w-[400px]" : "w-[250px]"
+        "fixed sm:right-20 bottom-0 z-20",
+        show
+          ? "w-screen h-screen sm:h-fit sm:w-[400px] right-0"
+          : "w-[250px] right-10"
       )}
     >
       {!show ? (
@@ -74,7 +76,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
           </div>
         </div>
       ) : (
-        <div className="bg-white rounded-t-md w-full h-[500px] flex flex-col border-2 border-b-0 pb-3 border-primary-800 transition-all overflow-clip -translate-y-0 ">
+        <div className="bg-white sm:rounded-t-md w-full h-screen sm:h-[500px] flex flex-col border-2 border-b-0 pb-3 border-primary-800 transition-all overflow-clip -translate-y-0 ">
           {/* Doctor Notes Header */}
           <div className="flex justify-between items-center w-full p-2 px-4 bg-primary-800 text-white">
             <span className="font-semibold">Doctor&apos;s Notes</span>

From e3c3966fabc82224b1fd78407f4e53415aa177d7 Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Wed, 12 Jul 2023 13:05:35 +0530
Subject: [PATCH 04/17] feat: updated ui of patient notes dedicated page

---
 src/Components/Facility/PatientNoteCard.tsx |   8 +-
 src/Components/Patient/PatientNotes.tsx     | 196 ++++++--------------
 2 files changed, 57 insertions(+), 147 deletions(-)

diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index b90b089352c..8029ec915c1 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -18,9 +18,11 @@ const PatientNoteCard = ({
           {note.created_by_object?.last_name}
         </span>
         <span className="text-gray-700 text-sm">
-          {note.created_by_object.id === facilityId
-            ? "Remote Specialist"
-            : "Local Doctor"}
+          {note.created_by_object.user_type === "Doctor"
+            ? note.created_by_object.home_facility !== facilityId
+              ? "Remote Specialist"
+              : ""
+            : note.created_by_object.user_type}
         </span>
       </div>
       <span className="whitespace-pre-wrap break-words">{note.note}</span>
diff --git a/src/Components/Patient/PatientNotes.tsx b/src/Components/Patient/PatientNotes.tsx
index 0756883d1d2..f5d09c80473 100644
--- a/src/Components/Patient/PatientNotes.tsx
+++ b/src/Components/Patient/PatientNotes.tsx
@@ -1,88 +1,29 @@
-import React, { useCallback, useState, useEffect } from "react";
+import { useState, useEffect } from "react";
 import { useDispatch } from "react-redux";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import {
-  getPatientNotes,
-  addPatientNote,
-  getPatient,
-} from "../../Redux/actions";
+import { addPatientNote, getPatient } from "../../Redux/actions";
 import * as Notification from "../../Utils/Notifications.js";
 import PageTitle from "../Common/PageTitle";
-import Pagination from "../Common/Pagination";
-import { navigate } from "raviger";
-import { RESULTS_PER_PAGE_LIMIT } from "../../Common/constants";
-import Loading from "../Common/Loading";
-import { formatDate } from "../../Utils/utils";
+import CareIcon from "../../CAREUI/icons/CareIcon";
+import TextFormField from "../Form/FormFields/TextFormField";
 import ButtonV2 from "../Common/components/ButtonV2";
 import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
+import PatientNotesList from "../Facility/PatientNotesList";
 
 interface PatientNotesProps {
   patientId: any;
   facilityId: any;
 }
 
-const pageSize = RESULTS_PER_PAGE_LIMIT;
-
 const PatientNotes = (props: PatientNotesProps) => {
   const { patientId, facilityId } = props;
 
-  const dispatch: any = useDispatch();
-  const initialData: any = { notes: [], cPage: 1, count: 1 };
-  const [state, setState] = useState(initialData);
+  const [patientActive, setPatientActive] = useState(true);
   const [noteField, setNoteField] = useState("");
-  const [isLoading, setIsLoading] = useState(true);
+  const [reload, setReload] = useState(false);
   const [facilityName, setFacilityName] = useState("");
   const [patientName, setPatientName] = useState("");
-  const [patientActive, setPatientActive] = useState(true);
-
-  const fetchData = useCallback(
-    async (page = 1, status: statusType = { aborted: false }) => {
-      setIsLoading(true);
-      const res = await dispatch(
-        getPatientNotes(props.patientId, pageSize, (page - 1) * pageSize)
-      );
-      if (!status.aborted) {
-        if (res && res.data) {
-          setState({
-            ...state,
-            count: res.data?.count,
-            notes: res.data?.results,
-            cPage: page,
-          });
-        }
-        setIsLoading(false);
-      }
-    },
-    [props.patientId, dispatch]
-  );
-
-  useAbortableEffect(
-    (status: statusType) => {
-      fetchData(1, status);
-    },
-    [fetchData]
-  );
-
-  useEffect(() => {
-    async function fetchPatientName() {
-      if (patientId) {
-        const res = await dispatch(getPatient({ id: patientId }));
-        if (res.data) {
-          setPatientName(res.data.name);
-          setFacilityName(res.data.facility_object.name);
-          setPatientActive(res.data.is_active);
-        }
-      } else {
-        setPatientName("");
-        setFacilityName("");
-      }
-    }
-    fetchPatientName();
-  }, [dispatch, patientId]);
 
-  function handlePagination(page: number) {
-    fetchData(page);
-  }
+  const dispatch = useDispatch();
 
   const onAddNote = () => {
     const payload = {
@@ -94,16 +35,26 @@ const PatientNotes = (props: PatientNotesProps) => {
       });
       return;
     }
-    dispatch(addPatientNote(props.patientId, payload)).then(() => {
+    dispatch(addPatientNote(patientId, payload)).then(() => {
       Notification.Success({ msg: "Note added successfully" });
       setNoteField("");
-      fetchData();
+      setReload(!reload);
     });
   };
 
-  if (isLoading) {
-    return <Loading />;
-  }
+  useEffect(() => {
+    async function fetchPatientName() {
+      if (patientId) {
+        const res = await dispatch(getPatient({ id: patientId }));
+        if (res.data) {
+          setPatientActive(res.data.is_active);
+          setPatientName(res.data.name);
+          setFacilityName(res.data.facility_object.name);
+        }
+      }
+    }
+    fetchPatientName();
+  }, [dispatch, patientId]);
 
   return (
     <div className="w-full flex flex-col">
@@ -116,80 +67,37 @@ const PatientNotes = (props: PatientNotesProps) => {
         }}
         backUrl={`/facility/${facilityId}/patient/${patientId}`}
       />
-      <h3 className="text-lg pl-10">Add new notes</h3>
-      <textarea
-        rows={3}
-        placeholder="Type your Note"
-        className="mx-10 my-4 border border-gray-500 rounded-lg p-4 focus:outline-none focus:ring-primary-500 focus:border-primary-500"
-        onChange={(e) => setNoteField(e.target.value)}
-      />
-      <div className="flex w-full justify-end pr-10">
-        <ButtonV2
-          authorizeFor={NonReadOnlyUsers}
-          onClick={onAddNote}
-          disabled={!patientActive}
-        >
-          Post Your Note
-        </ButtonV2>
-      </div>
-      <div className="px-10 py-5">
-        <h3 className="text-lg">Added Notes</h3>
-        <div className="w-full">
-          {state.notes.length ? (
-            state.notes.map((note: any) => (
-              <div
-                key={note.id}
-                className="flex p-4 bg-white rounded-lg text-gray-800 mt-4 flex-col w-full border border-gray-300"
-              >
-                <span className="whitespace-pre-wrap break-words">
-                  {note.note}
-                </span>
-                <div className="mt-3">
-                  <span className="text-xs text-gray-500">
-                    {formatDate(note.created_date) || "-"}
-                  </span>
-                </div>
 
-                <div className="sm:flex space-y-2 sm:space-y-0">
-                  <div className="mr-2 inline-flex w-full md:w-auto justify-center bg-gray-100 border items-center rounded-md py-1 pl-2 pr-3">
-                    <div className="flex justify-center items-center w-8 h-8 rounded-full">
-                      <i className="fas fa-user" />
-                    </div>
-                    <span className="text-gray-700 text-sm">
-                      {note.created_by_object?.first_name || "Unknown"}{" "}
-                      {note.created_by_object?.last_name}
-                    </span>
-                  </div>
+      <div className="mx-3 my-2 px-2 py-2 sm:mx-10 sm:my-5 bg-white sm:px-5 sm:py-5 rounded-lg grow">
+        <PatientNotesList
+          patientId={patientId}
+          facilityId={facilityId}
+          reload={reload}
+          setReload={setReload}
+        />
 
-                  <div
-                    className="inline-flex w-full md:w-auto justify-center bg-gray-100 border items-center rounded-md py-1 pl-2 pr-3 cursor-pointer"
-                    onClick={() => navigate(`/facility/${note.facility?.id}`)}
-                  >
-                    <div className="flex justify-center items-center w-8 h-8 rounded-full">
-                      <i className="fas fa-hospital" />
-                    </div>
-                    <span className="text-gray-700 text-sm">
-                      {note.facility?.name || "Unknown"}
-                    </span>
-                  </div>
-                </div>
-              </div>
-            ))
-          ) : (
-            <div className="text-gray-500 text-2xl font-bold flex justify-center items-center mt-2">
-              No Notes Found
-            </div>
-          )}
-          {state.count > pageSize && (
-            <div className="mt-4 flex w-full justify-center">
-              <Pagination
-                data={{ totalCount: state.count }}
-                onChange={handlePagination}
-                defaultPerPage={pageSize}
-                cPage={state.cPage}
-              />
-            </div>
-          )}
+        <div className="flex items-center mx-4 relative">
+          <TextFormField
+            name="note"
+            value={noteField}
+            onChange={(e) => setNoteField(e.value)}
+            className="grow"
+            type="text"
+            errorClassName="hidden"
+            placeholder="Type your Note"
+            disabled={!patientActive}
+          />
+          <ButtonV2
+            onClick={onAddNote}
+            border={false}
+            className="absolute right-2"
+            ghost
+            size="small"
+            disabled={!patientActive}
+            authorizeFor={NonReadOnlyUsers}
+          >
+            <CareIcon className="care-l-message text-lg" />
+          </ButtonV2>
         </div>
       </div>
     </div>

From 16bc28bd4a7630b9e67ba638f26c7706fdbd462a Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Wed, 19 Jul 2023 09:47:58 +0530
Subject: [PATCH 05/17] resolved merge conflicts

---
 package-lock.json | 1503 ++++++++++++++++++++++++++++++++++++++++++++-
 package.json      |    2 +-
 2 files changed, 1476 insertions(+), 29 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 817cd903efe..303bceb6668 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -48,6 +48,7 @@
         "react-google-recaptcha": "^2.1.0",
         "react-i18next": "^11.18.6",
         "react-infinite-scroll-component": "^6.1.0",
+        "react-markdown": "^8.0.7",
         "react-player": "^2.11.0",
         "react-qr-reader": "^2.2.1",
         "react-redux": "^8.0.4",
@@ -58,7 +59,6 @@
         "redux": "^4.1.0",
         "redux-thunk": "^2.3.0",
         "rescript-webapi": "^0.6.1",
-        "screenfull": "^5.1.0",
         "use-keyboard-shortcut": "^1.1.6",
         "uuid": "^8.3.2"
       },
@@ -5265,6 +5265,14 @@
         "cypress": "*"
       }
     },
+    "node_modules/@types/debug": {
+      "version": "4.1.8",
+      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz",
+      "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==",
+      "dependencies": {
+        "@types/ms": "*"
+      }
+    },
     "node_modules/@types/detect-port": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/@types/detect-port/-/detect-port-1.3.2.tgz",
@@ -5356,6 +5364,14 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/hast": {
+      "version": "2.3.5",
+      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz",
+      "integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==",
+      "dependencies": {
+        "@types/unist": "^2"
+      }
+    },
     "node_modules/@types/hoist-non-react-statics": {
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
@@ -5430,6 +5446,14 @@
         "@types/lodash": "*"
       }
     },
+    "node_modules/@types/mdast": {
+      "version": "3.0.12",
+      "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.12.tgz",
+      "integrity": "sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==",
+      "dependencies": {
+        "@types/unist": "^2"
+      }
+    },
     "node_modules/@types/mdx": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.3.tgz",
@@ -5452,6 +5476,11 @@
       "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
       "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA=="
     },
+    "node_modules/@types/ms": {
+      "version": "0.7.31",
+      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
+      "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
+    },
     "node_modules/@types/node": {
       "version": "18.11.18",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
@@ -5659,8 +5688,7 @@
     "node_modules/@types/unist": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==",
-      "dev": true
+      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
     },
     "node_modules/@types/use-sync-external-store": {
       "version": "0.0.3",
@@ -6623,6 +6651,15 @@
         "@babel/core": "^7.0.0-0"
       }
     },
+    "node_modules/bail": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
+      "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -7133,6 +7170,15 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/character-entities": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+      "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/check-more-types": {
       "version": "2.24.0",
       "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
@@ -7395,6 +7441,15 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/comma-separated-tokens": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+      "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -7927,6 +7982,18 @@
         }
       }
     },
+    "node_modules/decode-named-character-reference": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
+      "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
+      "dependencies": {
+        "character-entities": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/deep-equal": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.0.tgz",
@@ -8158,6 +8225,14 @@
       "dev": true,
       "license": "Apache-2.0"
     },
+    "node_modules/diff": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
+      "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
     "node_modules/dir-glob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -9500,7 +9575,6 @@
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
       "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/extract-zip": {
@@ -10554,6 +10628,15 @@
       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
       "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
     },
+    "node_modules/hast-util-whitespace": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz",
+      "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
     "node_modules/hoist-non-react-statics": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@@ -10811,6 +10894,11 @@
         "node": ">=10"
       }
     },
+    "node_modules/inline-style-parser": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz",
+      "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q=="
+    },
     "node_modules/internal-slot": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
@@ -10934,6 +11022,28 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/is-buffer": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/is-callable": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
@@ -11154,6 +11264,17 @@
         "node": ">=8"
       }
     },
+    "node_modules/is-plain-obj": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+      "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/is-plain-object": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
@@ -12297,6 +12418,113 @@
         "url": "https://opencollective.com/unified"
       }
     },
+    "node_modules/mdast-util-from-markdown": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz",
+      "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "@types/unist": "^2.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "mdast-util-to-string": "^3.1.0",
+        "micromark": "^3.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-decode-string": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "unist-util-stringify-position": "^3.0.0",
+        "uvu": "^0.5.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-from-markdown/node_modules/mdast-util-to-string": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz",
+      "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-to-hast": {
+      "version": "12.3.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz",
+      "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==",
+      "dependencies": {
+        "@types/hast": "^2.0.0",
+        "@types/mdast": "^3.0.0",
+        "mdast-util-definitions": "^5.0.0",
+        "micromark-util-sanitize-uri": "^1.1.0",
+        "trim-lines": "^3.0.0",
+        "unist-util-generated": "^2.0.0",
+        "unist-util-position": "^4.0.0",
+        "unist-util-visit": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-to-hast/node_modules/mdast-util-definitions": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz",
+      "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "@types/unist": "^2.0.0",
+        "unist-util-visit": "^4.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-to-hast/node_modules/unist-util-is": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
+      "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
+      "dependencies": {
+        "@types/unist": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz",
+      "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "unist-util-is": "^5.0.0",
+        "unist-util-visit-parents": "^5.1.1"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/mdast-util-to-hast/node_modules/unist-util-visit-parents": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz",
+      "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "unist-util-is": "^5.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
     "node_modules/mdast-util-to-string": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz",
@@ -12359,6 +12587,427 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/micromark": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz",
+      "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "@types/debug": "^4.0.0",
+        "debug": "^4.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-core-commonmark": "^1.0.1",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-combine-extensions": "^1.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-encode": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-sanitize-uri": "^1.0.0",
+        "micromark-util-subtokenize": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.1",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-core-commonmark": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz",
+      "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-factory-destination": "^1.0.0",
+        "micromark-factory-label": "^1.0.0",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-factory-title": "^1.0.0",
+        "micromark-factory-whitespace": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-classify-character": "^1.0.0",
+        "micromark-util-html-tag-name": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-subtokenize": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.1",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-factory-destination": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz",
+      "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-factory-label": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz",
+      "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-factory-space": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz",
+      "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-factory-title": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz",
+      "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-factory-whitespace": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz",
+      "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-character": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz",
+      "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-chunked": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz",
+      "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-classify-character": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz",
+      "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-combine-extensions": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz",
+      "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-decode-numeric-character-reference": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz",
+      "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-decode-string": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz",
+      "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz",
+      "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "node_modules/micromark-util-html-tag-name": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz",
+      "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "node_modules/micromark-util-normalize-identifier": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz",
+      "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-resolve-all": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz",
+      "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-sanitize-uri": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz",
+      "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-encode": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-subtokenize": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz",
+      "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "dependencies": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-util-symbol": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz",
+      "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
+    "node_modules/micromark-util-types": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz",
+      "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ]
+    },
     "node_modules/micromatch": {
       "version": "4.0.5",
       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
@@ -12567,7 +13216,6 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
       "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
-      "dev": true,
       "engines": {
         "node": ">=4"
       }
@@ -13518,6 +14166,15 @@
         "react-is": "^16.13.1"
       }
     },
+    "node_modules/property-information": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz",
+      "integrity": "sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/proxy-addr": {
       "version": "2.0.7",
       "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -14089,6 +14746,89 @@
       "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
       "license": "MIT"
     },
+    "node_modules/react-markdown": {
+      "version": "8.0.7",
+      "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.7.tgz",
+      "integrity": "sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ==",
+      "dependencies": {
+        "@types/hast": "^2.0.0",
+        "@types/prop-types": "^15.0.0",
+        "@types/unist": "^2.0.0",
+        "comma-separated-tokens": "^2.0.0",
+        "hast-util-whitespace": "^2.0.0",
+        "prop-types": "^15.0.0",
+        "property-information": "^6.0.0",
+        "react-is": "^18.0.0",
+        "remark-parse": "^10.0.0",
+        "remark-rehype": "^10.0.0",
+        "space-separated-tokens": "^2.0.0",
+        "style-to-object": "^0.4.0",
+        "unified": "^10.0.0",
+        "unist-util-visit": "^4.0.0",
+        "vfile": "^5.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      },
+      "peerDependencies": {
+        "@types/react": ">=16",
+        "react": ">=16"
+      }
+    },
+    "node_modules/react-markdown/node_modules/react-is": {
+      "version": "18.2.0",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+      "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+    },
+    "node_modules/react-markdown/node_modules/space-separated-tokens": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+      "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/react-markdown/node_modules/unist-util-is": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
+      "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
+      "dependencies": {
+        "@types/unist": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/react-markdown/node_modules/unist-util-visit": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz",
+      "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "unist-util-is": "^5.0.0",
+        "unist-util-visit-parents": "^5.1.1"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/react-markdown/node_modules/unist-util-visit-parents": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz",
+      "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "unist-util-is": "^5.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
     "node_modules/react-player": {
       "version": "2.11.0",
       "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.11.0.tgz",
@@ -14631,6 +15371,35 @@
         "url": "https://opencollective.com/unified"
       }
     },
+    "node_modules/remark-parse": {
+      "version": "10.0.2",
+      "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz",
+      "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==",
+      "dependencies": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-from-markdown": "^1.0.0",
+        "unified": "^10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/remark-rehype": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz",
+      "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==",
+      "dependencies": {
+        "@types/hast": "^2.0.0",
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-hast": "^12.1.0",
+        "unified": "^10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
     "node_modules/remark-slug": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-6.1.0.tgz",
@@ -14878,6 +15647,17 @@
         "tslib": "^2.1.0"
       }
     },
+    "node_modules/sade": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+      "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+      "dependencies": {
+        "mri": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/safe-buffer": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -14898,18 +15678,6 @@
         "loose-envify": "^1.1.0"
       }
     },
-    "node_modules/screenfull": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz",
-      "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "node_modules/sdp": {
       "version": "2.12.0",
       "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz",
@@ -15569,6 +16337,14 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/style-to-object": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz",
+      "integrity": "sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==",
+      "dependencies": {
+        "inline-style-parser": "0.1.1"
+      }
+    },
     "node_modules/supports-color": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -15984,6 +16760,24 @@
         "node": "*"
       }
     },
+    "node_modules/trim-lines": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+      "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/trough": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz",
+      "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/ts-dedent": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
@@ -16196,6 +16990,24 @@
         "node": ">=4"
       }
     },
+    "node_modules/unified": {
+      "version": "10.1.2",
+      "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz",
+      "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "bail": "^2.0.0",
+        "extend": "^3.0.0",
+        "is-buffer": "^2.0.0",
+        "is-plain-obj": "^4.0.0",
+        "trough": "^2.0.0",
+        "vfile": "^5.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
     "node_modules/unique-string": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
@@ -16208,6 +17020,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/unist-util-generated": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz",
+      "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
     "node_modules/unist-util-is": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
@@ -16218,6 +17039,30 @@
         "url": "https://opencollective.com/unified"
       }
     },
+    "node_modules/unist-util-position": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz",
+      "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==",
+      "dependencies": {
+        "@types/unist": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/unist-util-stringify-position": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz",
+      "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==",
+      "dependencies": {
+        "@types/unist": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
     "node_modules/unist-util-visit": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
@@ -16424,6 +17269,31 @@
       "integrity": "sha512-dsNgbLaTrd6l3MMxTtouOCFw4CBFc/3a+GgYA2YyrJvyQ1u6q4pcu3ktLoUZ/VN/Aw9WsauazbgsgdfVWgAKQg==",
       "dev": true
     },
+    "node_modules/uvu": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
+      "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
+      "dependencies": {
+        "dequal": "^2.0.0",
+        "diff": "^5.0.0",
+        "kleur": "^4.0.3",
+        "sade": "^1.7.3"
+      },
+      "bin": {
+        "uvu": "bin.js"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/uvu/node_modules/kleur": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+      "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/uzip": {
       "version": "0.20201231.0",
       "resolved": "https://registry.npmjs.org/uzip/-/uzip-0.20201231.0.tgz",
@@ -16484,6 +17354,34 @@
         "extsprintf": "^1.2.0"
       }
     },
+    "node_modules/vfile": {
+      "version": "5.3.7",
+      "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz",
+      "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "is-buffer": "^2.0.0",
+        "unist-util-stringify-position": "^3.0.0",
+        "vfile-message": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
+    "node_modules/vfile-message": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz",
+      "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==",
+      "dependencies": {
+        "@types/unist": "^2.0.0",
+        "unist-util-stringify-position": "^3.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
     "node_modules/vite": {
       "version": "4.2.1",
       "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz",
@@ -20802,6 +21700,14 @@
         "cypress": "*"
       }
     },
+    "@types/debug": {
+      "version": "4.1.8",
+      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz",
+      "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==",
+      "requires": {
+        "@types/ms": "*"
+      }
+    },
     "@types/detect-port": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/@types/detect-port/-/detect-port-1.3.2.tgz",
@@ -20892,6 +21798,14 @@
         "@types/node": "*"
       }
     },
+    "@types/hast": {
+      "version": "2.3.5",
+      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz",
+      "integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==",
+      "requires": {
+        "@types/unist": "^2"
+      }
+    },
     "@types/hoist-non-react-statics": {
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
@@ -20961,6 +21875,14 @@
         "@types/lodash": "*"
       }
     },
+    "@types/mdast": {
+      "version": "3.0.12",
+      "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.12.tgz",
+      "integrity": "sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==",
+      "requires": {
+        "@types/unist": "^2"
+      }
+    },
     "@types/mdx": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.3.tgz",
@@ -20983,6 +21905,11 @@
       "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
       "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA=="
     },
+    "@types/ms": {
+      "version": "0.7.31",
+      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
+      "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
+    },
     "@types/node": {
       "version": "18.11.18",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
@@ -21179,8 +22106,7 @@
     "@types/unist": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==",
-      "dev": true
+      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
     },
     "@types/use-sync-external-store": {
       "version": "0.0.3",
@@ -21818,6 +22744,11 @@
         "@babel/helper-define-polyfill-provider": "^0.3.3"
       }
     },
+    "bail": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
+      "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="
+    },
     "balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -22171,6 +23102,11 @@
         "supports-color": "^7.1.0"
       }
     },
+    "character-entities": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+      "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="
+    },
     "check-more-types": {
       "version": "2.24.0",
       "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
@@ -22354,6 +23290,11 @@
         "delayed-stream": "~1.0.0"
       }
     },
+    "comma-separated-tokens": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz",
+      "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="
+    },
     "commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -22729,6 +23670,14 @@
         "ms": "2.1.2"
       }
     },
+    "decode-named-character-reference": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
+      "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
+      "requires": {
+        "character-entities": "^2.0.0"
+      }
+    },
     "deep-equal": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.0.tgz",
@@ -22899,6 +23848,11 @@
       "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
       "dev": true
     },
+    "diff": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
+      "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw=="
+    },
     "dir-glob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -23870,8 +24824,7 @@
     "extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "dev": true
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
     },
     "extract-zip": {
       "version": "2.0.1",
@@ -24627,6 +25580,11 @@
       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
       "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
     },
+    "hast-util-whitespace": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz",
+      "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng=="
+    },
     "hoist-non-react-statics": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@@ -24796,6 +25754,11 @@
       "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
       "dev": true
     },
+    "inline-style-parser": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz",
+      "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q=="
+    },
     "internal-slot": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
@@ -24882,6 +25845,11 @@
         "has-tostringtag": "^1.0.0"
       }
     },
+    "is-buffer": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
+      "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="
+    },
     "is-callable": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
@@ -25013,6 +25981,11 @@
       "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
       "dev": true
     },
+    "is-plain-obj": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+      "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="
+    },
     "is-plain-object": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
@@ -25857,6 +26830,89 @@
         "unist-util-visit": "^2.0.0"
       }
     },
+    "mdast-util-from-markdown": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz",
+      "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "@types/unist": "^2.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "mdast-util-to-string": "^3.1.0",
+        "micromark": "^3.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-decode-string": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "unist-util-stringify-position": "^3.0.0",
+        "uvu": "^0.5.0"
+      },
+      "dependencies": {
+        "mdast-util-to-string": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz",
+          "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==",
+          "requires": {
+            "@types/mdast": "^3.0.0"
+          }
+        }
+      }
+    },
+    "mdast-util-to-hast": {
+      "version": "12.3.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz",
+      "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==",
+      "requires": {
+        "@types/hast": "^2.0.0",
+        "@types/mdast": "^3.0.0",
+        "mdast-util-definitions": "^5.0.0",
+        "micromark-util-sanitize-uri": "^1.1.0",
+        "trim-lines": "^3.0.0",
+        "unist-util-generated": "^2.0.0",
+        "unist-util-position": "^4.0.0",
+        "unist-util-visit": "^4.0.0"
+      },
+      "dependencies": {
+        "mdast-util-definitions": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz",
+          "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==",
+          "requires": {
+            "@types/mdast": "^3.0.0",
+            "@types/unist": "^2.0.0",
+            "unist-util-visit": "^4.0.0"
+          }
+        },
+        "unist-util-is": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
+          "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
+          "requires": {
+            "@types/unist": "^2.0.0"
+          }
+        },
+        "unist-util-visit": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz",
+          "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==",
+          "requires": {
+            "@types/unist": "^2.0.0",
+            "unist-util-is": "^5.0.0",
+            "unist-util-visit-parents": "^5.1.1"
+          }
+        },
+        "unist-util-visit-parents": {
+          "version": "5.1.3",
+          "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz",
+          "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==",
+          "requires": {
+            "@types/unist": "^2.0.0",
+            "unist-util-is": "^5.0.0"
+          }
+        }
+      }
+    },
     "mdast-util-to-string": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz",
@@ -25903,6 +26959,217 @@
       "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
       "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
     },
+    "micromark": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz",
+      "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==",
+      "requires": {
+        "@types/debug": "^4.0.0",
+        "debug": "^4.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-core-commonmark": "^1.0.1",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-combine-extensions": "^1.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-encode": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-sanitize-uri": "^1.0.0",
+        "micromark-util-subtokenize": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.1",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-core-commonmark": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz",
+      "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==",
+      "requires": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-factory-destination": "^1.0.0",
+        "micromark-factory-label": "^1.0.0",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-factory-title": "^1.0.0",
+        "micromark-factory-whitespace": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-classify-character": "^1.0.0",
+        "micromark-util-html-tag-name": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-subtokenize": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.1",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-factory-destination": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz",
+      "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-factory-label": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz",
+      "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-factory-space": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz",
+      "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-factory-title": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz",
+      "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==",
+      "requires": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-factory-whitespace": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz",
+      "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==",
+      "requires": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-util-character": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz",
+      "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==",
+      "requires": {
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-util-chunked": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz",
+      "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==",
+      "requires": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "micromark-util-classify-character": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz",
+      "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-util-combine-extensions": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz",
+      "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==",
+      "requires": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-util-decode-numeric-character-reference": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz",
+      "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==",
+      "requires": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "micromark-util-decode-string": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz",
+      "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==",
+      "requires": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "micromark-util-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz",
+      "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw=="
+    },
+    "micromark-util-html-tag-name": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz",
+      "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q=="
+    },
+    "micromark-util-normalize-identifier": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz",
+      "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==",
+      "requires": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "micromark-util-resolve-all": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz",
+      "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==",
+      "requires": {
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "micromark-util-sanitize-uri": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz",
+      "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==",
+      "requires": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-encode": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "micromark-util-subtokenize": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz",
+      "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==",
+      "requires": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "micromark-util-symbol": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz",
+      "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag=="
+    },
+    "micromark-util-types": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz",
+      "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg=="
+    },
     "micromatch": {
       "version": "4.0.5",
       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
@@ -26046,8 +27313,7 @@
     "mri": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
-      "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
-      "dev": true
+      "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="
     },
     "ms": {
       "version": "2.1.2",
@@ -26680,6 +27946,11 @@
         "react-is": "^16.13.1"
       }
     },
+    "property-information": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz",
+      "integrity": "sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg=="
+    },
     "proxy-addr": {
       "version": "2.0.7",
       "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -27088,6 +28359,67 @@
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
       "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
     },
+    "react-markdown": {
+      "version": "8.0.7",
+      "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.7.tgz",
+      "integrity": "sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ==",
+      "requires": {
+        "@types/hast": "^2.0.0",
+        "@types/prop-types": "^15.0.0",
+        "@types/unist": "^2.0.0",
+        "comma-separated-tokens": "^2.0.0",
+        "hast-util-whitespace": "^2.0.0",
+        "prop-types": "^15.0.0",
+        "property-information": "^6.0.0",
+        "react-is": "^18.0.0",
+        "remark-parse": "^10.0.0",
+        "remark-rehype": "^10.0.0",
+        "space-separated-tokens": "^2.0.0",
+        "style-to-object": "^0.4.0",
+        "unified": "^10.0.0",
+        "unist-util-visit": "^4.0.0",
+        "vfile": "^5.0.0"
+      },
+      "dependencies": {
+        "react-is": {
+          "version": "18.2.0",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+          "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+        },
+        "space-separated-tokens": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+          "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="
+        },
+        "unist-util-is": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
+          "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
+          "requires": {
+            "@types/unist": "^2.0.0"
+          }
+        },
+        "unist-util-visit": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz",
+          "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==",
+          "requires": {
+            "@types/unist": "^2.0.0",
+            "unist-util-is": "^5.0.0",
+            "unist-util-visit-parents": "^5.1.1"
+          }
+        },
+        "unist-util-visit-parents": {
+          "version": "5.1.3",
+          "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz",
+          "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==",
+          "requires": {
+            "@types/unist": "^2.0.0",
+            "unist-util-is": "^5.0.0"
+          }
+        }
+      }
+    },
     "react-player": {
       "version": "2.11.0",
       "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.11.0.tgz",
@@ -27496,6 +28828,27 @@
         "unist-util-visit": "^2.0.0"
       }
     },
+    "remark-parse": {
+      "version": "10.0.2",
+      "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz",
+      "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==",
+      "requires": {
+        "@types/mdast": "^3.0.0",
+        "mdast-util-from-markdown": "^1.0.0",
+        "unified": "^10.0.0"
+      }
+    },
+    "remark-rehype": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz",
+      "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==",
+      "requires": {
+        "@types/hast": "^2.0.0",
+        "@types/mdast": "^3.0.0",
+        "mdast-util-to-hast": "^12.1.0",
+        "unified": "^10.0.0"
+      }
+    },
     "remark-slug": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-6.1.0.tgz",
@@ -27660,6 +29013,14 @@
         "tslib": "^2.1.0"
       }
     },
+    "sade": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+      "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+      "requires": {
+        "mri": "^1.1.0"
+      }
+    },
     "safe-buffer": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -27678,11 +29039,6 @@
         "loose-envify": "^1.1.0"
       }
     },
-    "screenfull": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz",
-      "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA=="
-    },
     "sdp": {
       "version": "2.12.0",
       "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz",
@@ -28179,6 +29535,14 @@
       "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
       "dev": true
     },
+    "style-to-object": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz",
+      "integrity": "sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==",
+      "requires": {
+        "inline-style-parser": "0.1.1"
+      }
+    },
     "supports-color": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -28503,6 +29867,16 @@
       "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
       "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ=="
     },
+    "trim-lines": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz",
+      "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="
+    },
+    "trough": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz",
+      "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g=="
+    },
     "ts-dedent": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
@@ -28656,6 +30030,20 @@
       "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
       "dev": true
     },
+    "unified": {
+      "version": "10.1.2",
+      "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz",
+      "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==",
+      "requires": {
+        "@types/unist": "^2.0.0",
+        "bail": "^2.0.0",
+        "extend": "^3.0.0",
+        "is-buffer": "^2.0.0",
+        "is-plain-obj": "^4.0.0",
+        "trough": "^2.0.0",
+        "vfile": "^5.0.0"
+      }
+    },
     "unique-string": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
@@ -28665,12 +30053,33 @@
         "crypto-random-string": "^2.0.0"
       }
     },
+    "unist-util-generated": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz",
+      "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A=="
+    },
     "unist-util-is": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz",
       "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==",
       "dev": true
     },
+    "unist-util-position": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz",
+      "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==",
+      "requires": {
+        "@types/unist": "^2.0.0"
+      }
+    },
+    "unist-util-stringify-position": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz",
+      "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==",
+      "requires": {
+        "@types/unist": "^2.0.0"
+      }
+    },
     "unist-util-visit": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz",
@@ -28820,6 +30229,24 @@
       "integrity": "sha512-dsNgbLaTrd6l3MMxTtouOCFw4CBFc/3a+GgYA2YyrJvyQ1u6q4pcu3ktLoUZ/VN/Aw9WsauazbgsgdfVWgAKQg==",
       "dev": true
     },
+    "uvu": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
+      "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
+      "requires": {
+        "dequal": "^2.0.0",
+        "diff": "^5.0.0",
+        "kleur": "^4.0.3",
+        "sade": "^1.7.3"
+      },
+      "dependencies": {
+        "kleur": {
+          "version": "4.1.5",
+          "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+          "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="
+        }
+      }
+    },
     "uzip": {
       "version": "0.20201231.0",
       "resolved": "https://registry.npmjs.org/uzip/-/uzip-0.20201231.0.tgz",
@@ -28868,6 +30295,26 @@
         "extsprintf": "^1.2.0"
       }
     },
+    "vfile": {
+      "version": "5.3.7",
+      "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz",
+      "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==",
+      "requires": {
+        "@types/unist": "^2.0.0",
+        "is-buffer": "^2.0.0",
+        "unist-util-stringify-position": "^3.0.0",
+        "vfile-message": "^3.0.0"
+      }
+    },
+    "vfile-message": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz",
+      "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==",
+      "requires": {
+        "@types/unist": "^2.0.0",
+        "unist-util-stringify-position": "^3.0.0"
+      }
+    },
     "vite": {
       "version": "4.2.1",
       "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz",
diff --git a/package.json b/package.json
index 64145215a96..79225302cf8 100644
--- a/package.json
+++ b/package.json
@@ -88,6 +88,7 @@
     "react-google-recaptcha": "^2.1.0",
     "react-i18next": "^11.18.6",
     "react-infinite-scroll-component": "^6.1.0",
+    "react-markdown": "^8.0.7",
     "react-player": "^2.11.0",
     "react-qr-reader": "^2.2.1",
     "react-redux": "^8.0.4",
@@ -98,7 +99,6 @@
     "redux": "^4.1.0",
     "redux-thunk": "^2.3.0",
     "rescript-webapi": "^0.6.1",
-    "screenfull": "^5.1.0",
     "use-keyboard-shortcut": "^1.1.6",
     "uuid": "^8.3.2"
   },

From 6eeca25d1b559e66759128c94454e2cfb91fe00c Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Wed, 19 Jul 2023 10:24:39 +0530
Subject: [PATCH 06/17] fix merge develop

---
 cypress/e2e/assets_spec/assets_manage.cy.ts   |  80 +++-
 cypress/e2e/patient_spec/patient_crud.cy.ts   |   8 +-
 cypress/pageobject/Asset/AssetCreation.ts     |  79 ++++
 cypress/pageobject/Asset/AssetSearch.ts       |   6 +
 cypress/pageobject/Login/LoginPage.ts         |  12 +
 public/config.json                            |  15 +-
 src/Common/hooks/useConfig.ts                 |  28 +-
 src/Common/hooks/useFullscreen.ts             |  16 +-
 src/Components/Assets/AssetManage.tsx         |  13 +-
 src/Components/Assets/AssetTypes.tsx          |  19 +
 src/Components/Assets/AssetsList.tsx          |  21 +-
 .../Assets/configure/CameraConfigure.tsx      |   2 +-
 src/Components/Auth/Login.tsx                 |  66 ++--
 src/Components/Common/DateInputV2.tsx         |   2 +-
 src/Components/Common/Sidebar/Sidebar.tsx     |   4 +-
 src/Components/Common/TopBar.tsx              |   4 +-
 src/Components/Common/Uptime.tsx              | 350 ++++++++++++++++++
 .../CriticalCare__API.tsx                     |   8 +-
 src/Components/Facility/AssetCreate.tsx       |   1 +
 .../Facility/ConsultationDetails.tsx          |  50 ++-
 src/Components/Facility/ConsultationForm.tsx  |  33 +-
 .../Facility/Consultations/ABGPlots.tsx       |   9 +-
 .../Facility/Consultations/Beds.tsx           |   2 +-
 .../DailyRounds/LogUpdateCardAttribute.tsx    |   2 +-
 .../Facility/Consultations/DialysisPlots.tsx  |  12 +-
 .../Facility/Consultations/Feed.tsx           |  20 +-
 .../Facility/Consultations/LiveFeed.tsx       |   8 +-
 .../Facility/Consultations/NursingPlot.tsx    |  17 +-
 src/Components/Facility/DischargeModal.tsx    |  14 +-
 src/Components/Facility/TreatmentSummary.tsx  |  16 +-
 src/Components/Facility/models.tsx            |   8 +-
 src/Components/Form/FieldValidators.tsx       |  41 +-
 .../Form/FormFields/Autocomplete.tsx          |  38 +-
 .../Form/FormFields/DateFormField.tsx         |   6 +-
 .../Form/FormFields/PhoneNumberFormField.tsx  |  64 +++-
 src/Components/Form/SelectMenuV2.tsx          |   4 +-
 src/Components/HCX/CreateClaimCard.tsx        |   8 +-
 src/Components/Hub/LiveFeedTile.tsx           |   9 +-
 .../Medicine/CreatePrescriptionForm.tsx       |  17 +-
 .../MedibaseAutocompleteFormField.tsx         |  71 ++++
 .../Medicine/MedicineAdministrationsTable.tsx |   4 +-
 .../Medicine/PrescriptionDetailCard.tsx       |   2 +-
 .../Medicine/PrescriptionsTable.tsx           |   1 +
 src/Components/Medicine/models.ts             |  15 +-
 .../Notifications/ShowPushNotification.tsx    |   9 +-
 .../Patient/DailyRoundListDetails.tsx         |  33 +-
 src/Components/Patient/PatientInfoCard.tsx    |  11 +-
 src/Components/Patient/PatientRegister.tsx    |   6 +-
 src/Components/Patient/SamplePreview.tsx      |   4 +-
 src/Components/Patient/models.tsx             |   6 +
 .../Resource/ResourceDetailsUpdate.tsx        |  26 +-
 src/Components/Shifting/BadgesList.tsx        |  19 +-
 src/Components/Shifting/ShiftDetails.tsx      |  10 +-
 src/Components/Users/ManageUsers.tsx          |   6 +-
 src/Components/Users/UserAdd.tsx              |  24 +-
 src/Components/Users/UserFilter.tsx           |   4 +-
 src/Locale/update_locale.js                   |  18 +-
 src/Redux/actions.tsx                         |  15 +-
 src/Redux/api.tsx                             |  15 +
 src/Router/AppRouter.tsx                      |   4 +-
 src/style/CAREUI.css                          |   2 +-
 61 files changed, 1069 insertions(+), 348 deletions(-)
 create mode 100644 cypress/pageobject/Login/LoginPage.ts
 create mode 100644 src/Components/Common/Uptime.tsx
 create mode 100644 src/Components/Medicine/MedibaseAutocompleteFormField.tsx

diff --git a/cypress/e2e/assets_spec/assets_manage.cy.ts b/cypress/e2e/assets_spec/assets_manage.cy.ts
index 464617b3303..27843d7fa85 100644
--- a/cypress/e2e/assets_spec/assets_manage.cy.ts
+++ b/cypress/e2e/assets_spec/assets_manage.cy.ts
@@ -1,14 +1,18 @@
 /// <reference types="cypress" />
 import { AssetPage } from "../../pageobject/Asset/AssetCreation";
 import { v4 as uuidv4 } from "uuid";
+import LoginPage from "../../pageobject/Login/LoginPage";
+import { AssetSearchPage } from "../../pageobject/Asset/AssetSearch";
 
 describe("Asset", () => {
   const assetPage = new AssetPage();
+  const assetSearchPage = new AssetSearchPage();
+  const loginPage = new LoginPage();
   const phone_number = "9999999999";
   const serialNumber = Math.floor(Math.random() * 10 ** 10).toString();
 
   before(() => {
-    cy.loginByApi("devdistrictadmin", "Coronasafe@123");
+    loginPage.loginAsDisctrictAdmin();
     cy.saveLocalStorage();
   });
 
@@ -17,6 +21,18 @@ describe("Asset", () => {
     cy.awaitUrl("/assets");
   });
 
+  it("Verify asset creation fields throws error if empty", () => {
+    assetPage.createAsset();
+    assetPage.selectFacility("Dummy Facility 1");
+    assetPage.clickCreateAsset();
+
+    assetPage.verifyEmptyAssetNameError();
+    assetPage.verifyEmptyAssetTypeError();
+    assetPage.verifyEmptyLocationError();
+    assetPage.verifyEmptyStatusError();
+    assetPage.verifyEmptyPhoneError();
+  });
+
   //Create an asset
 
   it("Create an Asset", () => {
@@ -26,13 +42,13 @@ describe("Asset", () => {
     assetPage.selectAssetType("Internal");
     assetPage.selectAssetClass("ONVIF Camera");
 
-    const qr_id = uuidv4();
+    const qr_id_1 = uuidv4();
 
     assetPage.enterAssetDetails(
-      "New Test Asset",
+      "New Test Asset 1",
       "Test Description",
       "Working",
-      qr_id,
+      qr_id_1,
       "Manufacturer's Name",
       "2025-12-25",
       "Customer Support's Name",
@@ -44,12 +60,64 @@ describe("Asset", () => {
       "Test note for asset creation!"
     );
 
-    assetPage.clickCreateAsset();
+    assetPage.clickCreateAddMore();
+    assetPage.verifySuccessNotification("Asset created successfully");
+
+    const qr_id_2 = uuidv4();
 
+    assetPage.selectLocation("Camera Loc");
+    assetPage.selectAssetType("Internal");
+    assetPage.selectAssetClass("ONVIF Camera");
+    assetPage.enterAssetDetails(
+      "New Test Asset 2",
+      "Test Description",
+      "Working",
+      qr_id_2,
+      "Manufacturer's Name",
+      "2025-12-25",
+      "Customer Support's Name",
+      phone_number,
+      "email@support.com",
+      "Vendor's Name",
+      serialNumber,
+      "2021-12-25",
+      "Test note for asset creation!"
+    );
+
+    assetPage.clickCreateAsset();
     assetPage.verifySuccessNotification("Asset created successfully");
+
+    assetSearchPage.typeSearchKeyword("New Test Asset 2");
+    assetSearchPage.pressEnter();
+    assetSearchPage.verifyAssetIsPresent("New Test Asset 2");
+  });
+
+  it("Edit an Asset", () => {
+    assetPage.openCreatedAsset();
+
+    const qr_id = uuidv4();
+
+    assetPage.editAssetDetails(
+      "New Test Asset Edited",
+      "Test Description Edited",
+      qr_id,
+      "Manufacturer's Name Edited",
+      "Customer Support's Name Edited",
+      "Vendor's Name Edited",
+      "Test note for asset creation edited!"
+    );
+
+    assetPage.clickUpdateAsset();
+
+    assetPage.verifySuccessNotification("Asset updated successfully");
   });
 
-  // Edit an exisit asset
+  it("Delete an Asset", () => {
+    assetPage.openCreatedAsset();
+    assetPage.deleteAsset();
+
+    assetPage.verifySuccessNotification("Asset deleted successfully");
+  });
 
   afterEach(() => {
     cy.saveLocalStorage();
diff --git a/cypress/e2e/patient_spec/patient_crud.cy.ts b/cypress/e2e/patient_spec/patient_crud.cy.ts
index 53fe7912b32..16ae59e80a6 100644
--- a/cypress/e2e/patient_spec/patient_crud.cy.ts
+++ b/cypress/e2e/patient_spec/patient_crud.cy.ts
@@ -190,11 +190,11 @@ describe("Patient Creation with consultation", () => {
     cy.contains("button", "Add Prescription Medication")
       .should("be.visible")
       .click();
-    cy.get("div#medicine input[placeholder='Select'][role='combobox']")
+    cy.get("div#medicine_object input[placeholder='Select'][role='combobox']")
       .click()
-      .type("paracet");
-    cy.get("div#medicine [role='option']")
-      .contains("PARACETAMOL TAB IP ,500 mg.")
+      .type("dolo");
+    cy.get("div#medicine_object [role='option']")
+      .contains("DOLO")
       .should("be.visible")
       .click();
     cy.get("#dosage").click().type("3");
diff --git a/cypress/pageobject/Asset/AssetCreation.ts b/cypress/pageobject/Asset/AssetCreation.ts
index 2ccd3e0c367..44841a34a65 100644
--- a/cypress/pageobject/Asset/AssetCreation.ts
+++ b/cypress/pageobject/Asset/AssetCreation.ts
@@ -77,7 +77,86 @@ export class AssetPage {
     cy.get("#submit").contains("Create Asset").click();
   }
 
+  clickCreateAddMore() {
+    cy.get("[data-testid=create-asset-add-more-button]").click();
+  }
+
   verifySuccessNotification(message: string) {
     cy.verifyNotification(message);
   }
+
+  openCreatedAsset() {
+    cy.get("[data-testid=created-asset-list]").first().click();
+  }
+
+  editAssetDetails(
+    name: string,
+    description: string,
+    qrId: string,
+    manufacturer: string,
+    supportName: string,
+    vendorName: string,
+    notes: string
+  ) {
+    cy.get("[data-testid=asset-update-button]").click();
+    cy.get("[data-testid=asset-name-input] input").clear().type(name);
+    cy.get("[data-testid=asset-description-input] textarea")
+      .clear()
+      .type(description);
+    cy.get("[data-testid=asset-qr-id-input] input").clear().type(qrId);
+    cy.get("[data-testid=asset-manufacturer-input] input")
+      .clear()
+      .type(manufacturer);
+    cy.get("[data-testid=asset-support-name-input] input")
+      .clear()
+      .type(supportName);
+    cy.get("[data-testid=asset-vendor-name-input] input")
+      .clear()
+      .type(vendorName);
+    cy.get("[data-testid=asset-notes-input] textarea").clear().type(notes);
+  }
+
+  clickUpdateAsset() {
+    cy.get("#submit").contains("Update").click();
+  }
+
+  deleteAsset() {
+    cy.get("[data-testid=asset-delete-button]").click();
+    cy.get("#submit").contains("Confirm").click();
+  }
+
+  verifyEmptyAssetNameError() {
+    cy.get("[data-testid=asset-name-input] span").should(
+      "contain",
+      "Asset name can't be empty"
+    );
+  }
+
+  verifyEmptyLocationError() {
+    cy.get("[data-testid=asset-location-input] span").should(
+      "contain",
+      "Select a location"
+    );
+  }
+
+  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",
+      "Field is required"
+    );
+  }
+
+  verifyEmptyPhoneError() {
+    cy.get("#customer-support-phone-div span").should(
+      "contain",
+      "Please enter valid phone number"
+    );
+  }
 }
diff --git a/cypress/pageobject/Asset/AssetSearch.ts b/cypress/pageobject/Asset/AssetSearch.ts
index 26b9a81c140..315a414a62b 100644
--- a/cypress/pageobject/Asset/AssetSearch.ts
+++ b/cypress/pageobject/Asset/AssetSearch.ts
@@ -12,4 +12,10 @@ export class AssetSearchPage {
       expect(currentUrl).not.to.equal(initialUrl);
     });
   }
+
+  verifyAssetIsPresent(assetName: string) {
+    cy.get("[data-testid=created-asset-list]")
+      .first()
+      .should("contain", assetName);
+  }
 }
diff --git a/cypress/pageobject/Login/LoginPage.ts b/cypress/pageobject/Login/LoginPage.ts
new file mode 100644
index 00000000000..e75524ad3f4
--- /dev/null
+++ b/cypress/pageobject/Login/LoginPage.ts
@@ -0,0 +1,12 @@
+// LoginPage.ts
+class LoginPage {
+  loginAsDisctrictAdmin(): void {
+    cy.loginByApi("devdistrictadmin", "Coronasafe@123");
+  }
+
+  login(username: string, password: string): void {
+    cy.loginByApi(username, password);
+  }
+}
+
+export default LoginPage;
diff --git a/public/config.json b/public/config.json
index 3661597f64b..8bbf94a1d8b 100644
--- a/public/config.json
+++ b/public/config.json
@@ -4,13 +4,14 @@
     "coronasafe_url": "https://coronasafe.network?ref=care",
     "site_url": "care.coronasafe.in",
     "analytics_server_url": "https://plausible.10bedicu.in",
-    "static_header_logo": "https://cdn.coronasafe.network/header_logo.png",
-    "static_light_logo": "https://cdn.coronasafe.network/light-logo.svg",
-    "static_ohc_light_logo": "https://cdn.coronasafe.network/ohc_logo_light.png",
-    "static_ohc_green_logo": "https://cdn.coronasafe.network/ohc_logo_green.png",
-    "static_black_logo": "https://cdn.coronasafe.network/black-logo.svg",
-    "static_dpg_white_logo": "https://digitalpublicgoods.net/wp-content/themes/dpga/images/logo-w.svg",
-    "static_coronasafe_logo": "https://3451063158-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M233b0_JITp4nk0uAFp%2F-M2Dx6gKxOSU45cjfgNX%2F-M2DxFOkMmkPNn0I6U9P%2FCoronasafe-logo.png?alt=media&token=178cc96d-76d9-4e27-9efb-88f3186368e8",
+    "header_logo": {
+        "light":"https://cdn.coronasafe.network/header_logo.png",
+        "dark":"https://cdn.coronasafe.network/header_logo.png"
+    },
+    "main_logo": {
+        "light":"https://cdn.coronasafe.network/light-logo.svg",
+        "dark":"https://cdn.coronasafe.network/black-logo.svg"
+    },
     "gmaps_api_key": "AIzaSyDsBAc3y7deI5ZO3NtK5GuzKwtUzQNJNUk",
     "gov_data_api_key": "579b464db66ec23bdd000001cdd3946e44ce4aad7209ff7b23ac571b",
     "recaptcha_site_key": "6LdvxuQUAAAAADDWVflgBqyHGfq-xmvNJaToM0pN",
diff --git a/src/Common/hooks/useConfig.ts b/src/Common/hooks/useConfig.ts
index 7d064ee92ef..f826a06879c 100644
--- a/src/Common/hooks/useConfig.ts
+++ b/src/Common/hooks/useConfig.ts
@@ -1,22 +1,26 @@
 import { useSelector } from "react-redux";
 
+interface ILogo {
+  light: string;
+  dark: string;
+}
 export interface IConfig {
   dashboard_url: string;
   github_url: string;
   coronasafe_url: string;
-  dpg_url: string;
   site_url: string;
   analytics_server_url: string;
-  static_header_logo: string;
-  static_ohc_light_logo: string;
-  static_ohc_green_logo: string;
-  static_light_logo: string;
-  static_black_logo: string;
+
+  header_logo: ILogo;
+  main_logo: ILogo;
+
   /**
-   * White logo of Digital Public Goods.
+   * Logo and description for custom deployment. (This overrides the state logo)
    */
-  static_dpg_white_logo: string;
-  static_coronasafe_logo: string;
+  custom_logo?: ILogo;
+  custom_logo_alt?: ILogo;
+  custom_description?: string;
+
   /**
    * The API key for the Google Maps API used for location picker.
    */
@@ -40,11 +44,7 @@ export interface IConfig {
   /**
    * If present, the image will be displayed in the login page.
    */
-  state_logo?: string;
-  /**
-   * If true, the state logo will be white by applying "invert brightness-0" classes.
-   */
-  state_logo_white?: boolean;
+  state_logo?: ILogo;
   /**
    * URL of the sample format for asset import.
    */
diff --git a/src/Common/hooks/useFullscreen.ts b/src/Common/hooks/useFullscreen.ts
index d6be0c5eeac..e409af1174c 100644
--- a/src/Common/hooks/useFullscreen.ts
+++ b/src/Common/hooks/useFullscreen.ts
@@ -1,6 +1,9 @@
 import { useEffect, useState } from "react";
 
-export default function useFullscreen(): [boolean, (value: boolean) => void] {
+export default function useFullscreen(): [
+  boolean,
+  (value: boolean, element?: HTMLElement) => void
+] {
   const [isFullscreen, _setIsFullscreen] = useState(
     !!document.fullscreenElement
   );
@@ -15,12 +18,11 @@ export default function useFullscreen(): [boolean, (value: boolean) => void] {
       document.removeEventListener("fullscreenchange", onFullscreenChange);
   }, []);
 
-  const setFullscreen = (value: boolean) => {
-    if (value) {
-      document.documentElement.requestFullscreen();
-    } else {
-      document.exitFullscreen();
-    }
+  const setFullscreen = (value: boolean, element?: HTMLElement) => {
+    const fullscreenElement = element ?? document.documentElement;
+
+    if (value) fullscreenElement.requestFullscreen();
+    else document.exitFullscreen();
   };
 
   return [isFullscreen, setFullscreen];
diff --git a/src/Components/Assets/AssetManage.tsx b/src/Components/Assets/AssetManage.tsx
index 9f340b54850..1146cac5960 100644
--- a/src/Components/Assets/AssetManage.tsx
+++ b/src/Components/Assets/AssetManage.tsx
@@ -26,6 +26,7 @@ const PageTitle = loadable(() => import("../Common/PageTitle"));
 const Loading = loadable(() => import("../Common/Loading"));
 import * as Notification from "../../Utils/Notifications.js";
 import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
+import Uptime from "../Common/Uptime";
 
 interface AssetManageProps {
   assetId: string;
@@ -63,7 +64,7 @@ const AssetManage = (props: AssetManageProps) => {
       const assetData = await dispatch(getAsset(assetId));
       if (!status.aborted) {
         setIsLoading(false);
-        if (assetData && assetData.data) {
+        if (assetData?.data) {
           setAsset(assetData.data);
 
           const transactionFilter = assetData.qr_code_id
@@ -77,7 +78,7 @@ const AssetManage = (props: AssetManageProps) => {
               offset,
             })
           );
-          if (transactionsData && transactionsData.data) {
+          if (transactionsData?.data) {
             setTransactions(transactionsData.data.results);
             setTotalCount(transactionsData.data.count);
           } else {
@@ -124,7 +125,7 @@ const AssetManage = (props: AssetManageProps) => {
       </div>
       <h2 className="text-center">Print Preview</h2>
       <div id="section-to-print" className="print flex justify-center">
-        <QRCode size={200} value={asset?.id || ""} />
+        <QRCode size={200} value={asset?.id ?? ""} />
       </div>
     </div>
   );
@@ -215,6 +216,9 @@ const AssetManage = (props: AssetManageProps) => {
     if (asset) {
       const response = await dispatch(deleteAsset(asset.id));
       if (response && response.status === 204) {
+        Notification.Success({
+          msg: "Asset deleted successfully",
+        });
         navigate("/assets");
       }
     }
@@ -325,6 +329,7 @@ const AssetManage = (props: AssetManageProps) => {
                   )
                 }
                 id="update-asset"
+                data-testid="asset-update-button"
                 authorizeFor={NonReadOnlyUsers}
               >
                 <CareIcon className="care-l-pen h-4 mr-1" />
@@ -349,6 +354,7 @@ const AssetManage = (props: AssetManageProps) => {
                   authorizeFor={NonReadOnlyUsers}
                   onClick={() => setShowDeleteDialog(true)}
                   variant="danger"
+                  data-testid="asset-delete-button"
                   className="inline-flex"
                 >
                   <CareIcon className="care-l-trash h-4" />
@@ -394,6 +400,7 @@ const AssetManage = (props: AssetManageProps) => {
           </div>
         )}
       </div>
+      {asset?.id && <Uptime assetId={asset?.id} />}
       <div className="text-xl font-semibold mt-8 mb-4">Transaction History</div>
       <div className="align-middle min-w-full overflow-x-auto shadow overflow-hidden sm:rounded-lg">
         <table className="min-w-full divide-y divide-gray-200">
diff --git a/src/Components/Assets/AssetTypes.tsx b/src/Components/Assets/AssetTypes.tsx
index 2e739a0a03e..9f3ae5e57ad 100644
--- a/src/Components/Assets/AssetTypes.tsx
+++ b/src/Components/Assets/AssetTypes.tsx
@@ -26,6 +26,13 @@ export enum AssetClass {
   VENTILATOR = "VENTILATOR",
 }
 
+export enum AssetStatus {
+  "not_monitored" = 0,
+  "operational" = 1,
+  "down" = 2,
+  "maintenance" = 3,
+}
+
 export const assetClassProps = {
   ONVIF: {
     name: "ONVIF Camera",
@@ -83,6 +90,18 @@ export interface AssetsResponse {
   results: AssetData[];
 }
 
+export interface AssetUptimeRecord {
+  id: string;
+  asset: {
+    id: string;
+    name: string;
+  };
+  status: number;
+  timestamp: string;
+  created_date: string;
+  modified_date: string;
+}
+
 export interface AssetTransaction {
   id: string;
   asset: {
diff --git a/src/Components/Assets/AssetsList.tsx b/src/Components/Assets/AssetsList.tsx
index c16b2e0a524..88d276b06a2 100644
--- a/src/Components/Assets/AssetsList.tsx
+++ b/src/Components/Assets/AssetsList.tsx
@@ -6,9 +6,9 @@ import {
   getAnyFacility,
   listAssets,
   getFacilityAssetLocation,
+  getAsset,
 } from "../../Redux/actions";
 import { assetClassProps, AssetData } from "./AssetTypes";
-import { getAsset } from "../../Redux/actions";
 import { useState, useCallback, useEffect } from "react";
 import { Link, navigate } from "raviger";
 import loadable from "@loadable/component";
@@ -242,8 +242,10 @@ const AssetsList = () => {
       <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 md:-mx-8 gap-2">
         {assets.map((asset: AssetData) => (
           <Link
+            key={asset.id}
             href={`/facility/${asset?.location_object.facility.id}/assets/${asset.id}`}
             className="text-inherit"
+            data-testid="created-asset-list"
           >
             <div
               key={asset.id}
@@ -262,7 +264,12 @@ const AssetsList = () => {
                       } text-2xl`}
                     />
                   </span>
-                  <p className="truncate w-48">{asset.name}</p>
+                  <p
+                    className="truncate w-48"
+                    data-testid="created-asset-list-name"
+                  >
+                    {asset.name}
+                  </p>
                 </p>
               </div>
               <p className="font-normal text-sm">
@@ -395,12 +402,12 @@ const AssetsList = () => {
         <>
           <FilterBadges
             badges={({ badge, value }) => [
-              value("Facility", "facility", facilityName || ""),
+              value("Facility", "facility", facilityName ?? ""),
               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("Location", "location", locationName || ""),
+              value("Asset Type", "asset_type", asset_type ?? ""),
+              value("Asset Class", "asset_class", asset_class ?? ""),
+              value("Status", "status", status?.replace(/_/g, " ") ?? ""),
+              value("Location", "location", locationName ?? ""),
             ]}
           />
           <div className="grow">
diff --git a/src/Components/Assets/configure/CameraConfigure.tsx b/src/Components/Assets/configure/CameraConfigure.tsx
index ca3389c0c18..d8d9d66fec5 100644
--- a/src/Components/Assets/configure/CameraConfigure.tsx
+++ b/src/Components/Assets/configure/CameraConfigure.tsx
@@ -57,7 +57,7 @@ export default function CameraConfigure(props: CameraConfigureProps) {
                 id="location"
                 type="text"
                 value={newPreset}
-                className="mt-2"
+                className="mt-1"
                 onChange={(e) => setNewPreset(e.value)}
                 error=""
               />
diff --git a/src/Components/Auth/Login.tsx b/src/Components/Auth/Login.tsx
index f7e6a37b8d3..1747de569de 100644
--- a/src/Components/Auth/Login.tsx
+++ b/src/Components/Auth/Login.tsx
@@ -9,22 +9,20 @@ import LegendInput from "../../CAREUI/interactive/LegendInput";
 import LanguageSelectorLogin from "../Common/LanguageSelectorLogin";
 import CareIcon from "../../CAREUI/icons/CareIcon";
 import useConfig from "../../Common/hooks/useConfig";
-import { classNames } from "../../Utils/utils";
 import CircularProgress from "../Common/components/CircularProgress";
 import { LocalStorageKeys } from "../../Common/constants";
+import ReactMarkdown from "react-markdown";
 
 export const Login = (props: { forgot?: boolean }) => {
   const {
-    static_black_logo,
-    static_dpg_white_logo,
-    static_light_logo,
-    static_ohc_light_logo,
+    main_logo,
     recaptcha_site_key,
     github_url,
     coronasafe_url,
-    dpg_url,
     state_logo,
-    state_logo_white,
+    custom_logo,
+    custom_logo_alt,
+    custom_description,
   } = useConfig();
   const dispatch: any = useDispatch();
   const initForm: any = {
@@ -184,14 +182,11 @@ export const Login = (props: { forgot?: boolean }) => {
         <div></div>
         <div className="mt-4 md:mt-12 rounded-lg py-4 flex flex-col items-start">
           <div className="hidden md:flex items-center gap-6 mb-4">
-            {state_logo && (
+            {(custom_logo || state_logo) && (
               <>
                 <img
-                  src={state_logo}
-                  className={classNames(
-                    "rounded-lg p-3 h-24",
-                    state_logo_white && "invert brightness-0"
-                  )}
+                  src={custom_logo?.light ?? state_logo?.light}
+                  className="rounded-lg py-3 h-16"
                   alt="state logo"
                 />
                 <div className="w-0.5 bg-white/50 h-10 rounded-full" />
@@ -204,27 +199,39 @@ export const Login = (props: { forgot?: boolean }) => {
               rel="noopener noreferrer"
             >
               <img
-                src={static_light_logo}
+                src={custom_logo_alt?.light ?? main_logo.light}
                 className="h-8"
                 alt="coronasafe logo"
               />
             </a>
           </div>
           <div className="max-w-lg">
-            <h1 className="text-4xl md:text-5xl lg:text-7xl font-black text-white leading-tight tracking-wider">
+            <h1 className="text-4xl lg:text-5xl font-black text-white leading-tight tracking-wider">
               {t("care")}
             </h1>
-            <div className="text-base md:text-lg lg:text-xl font-semibold py-6 max-w-xl text-gray-400 pl-1">
-              {t("goal")}
-            </div>
+            {custom_description ? (
+              <div className="py-6">
+                <ReactMarkdown className="max-w-xl text-gray-400">
+                  {custom_description || t("goal")}
+                </ReactMarkdown>
+              </div>
+            ) : (
+              <div className="text-base md:text-lg lg:text-xl font-semibold py-6 max-w-xl text-gray-400 pl-1">
+                {t("goal")}
+              </div>
+            )}
           </div>
         </div>
         <div className="flex items-center mb-6">
           <div className="text-xs md:text-sm max-w-lg">
             <div className="ml-1 flex items-center gap-4 mb-2">
-              <a href={dpg_url} rel="noopener noreferrer" target="_blank">
+              <a
+                href="https://digitalpublicgoods.net/registry/coronasafe-care.html"
+                rel="noopener noreferrer"
+                target="_blank"
+              >
                 <img
-                  src={static_dpg_white_logo}
+                  src="https://digitalpublicgoods.net/wp-content/themes/dpga/images/logo-w.svg"
                   className="h-12"
                   alt="Logo of Digital Public Goods Alliance"
                 />
@@ -236,7 +243,7 @@ export const Login = (props: { forgot?: boolean }) => {
                 target="_blank"
               >
                 <img
-                  src={static_ohc_light_logo}
+                  src="https://cdn.coronasafe.network/ohc_logo_light.png"
                   className="h-10 inline-block"
                   alt="coronasafe logo"
                 />
@@ -275,22 +282,19 @@ export const Login = (props: { forgot?: boolean }) => {
             }
           >
             <div className="flex items-center gap-1">
-              {state_logo && (
+              {(custom_logo || state_logo) && (
                 <>
                   <img
-                    src={state_logo}
-                    className={classNames(
-                      "rounded-lg p-3 h-24 md:hidden",
-                      state_logo_white && "invert brightness-0"
-                    )}
+                    src={custom_logo?.dark ?? state_logo?.dark}
+                    className="rounded-lg py-3 h-14 md:hidden"
                     alt="state logo"
                   />
                   <div className="mx-4 w-[1px] md:hidden bg-gray-600 h-8 rounded-full" />
                 </>
               )}
               <img
-                src={static_black_logo}
-                className="h-8 w-auto md:hidden brightness-0 contrast-[0%]"
+                src={custom_logo_alt?.dark ?? main_logo.dark}
+                className="h-8 w-auto md:hidden"
                 alt="care logo"
               />
             </div>{" "}
@@ -371,8 +375,8 @@ export const Login = (props: { forgot?: boolean }) => {
             }
           >
             <img
-              src={static_black_logo}
-              className="h-8 w-auto mb-4 md:hidden brightness-0 contrast-[0%]"
+              src={main_logo.dark}
+              className="h-8 w-auto mb-4 md:hidden"
               alt="care logo"
             />{" "}
             <button
diff --git a/src/Components/Common/DateInputV2.tsx b/src/Components/Common/DateInputV2.tsx
index 6a81f2e917d..97395c23c6c 100644
--- a/src/Components/Common/DateInputV2.tsx
+++ b/src/Components/Common/DateInputV2.tsx
@@ -227,7 +227,7 @@ const DateInputV2: React.FC<Props> = ({
                   readOnly
                   disabled={disabled}
                   className={`cui-input-base cursor-pointer disabled:cursor-not-allowed ${className}`}
-                  placeholder={placeholder || "Select date"}
+                  placeholder={placeholder ?? "Select date"}
                   value={value && format(value, "yyyy-MM-dd")}
                 />
                 <div className="absolute top-1/2 right-0 p-2 -translate-y-1/2">
diff --git a/src/Components/Common/Sidebar/Sidebar.tsx b/src/Components/Common/Sidebar/Sidebar.tsx
index 812348fb601..51398f21f42 100644
--- a/src/Components/Common/Sidebar/Sidebar.tsx
+++ b/src/Components/Common/Sidebar/Sidebar.tsx
@@ -49,7 +49,7 @@ const StatelessSidebar = ({
   setShrinked,
   onItemClick,
 }: StatelessSidebarProps) => {
-  const { static_light_logo } = useConfig();
+  const { main_logo } = useConfig();
   const activeLink = useActiveLink();
   const Item = shrinked ? ShrinkedSidebarItem : SidebarItem;
   const { dashboard_url } = useConfig();
@@ -130,7 +130,7 @@ const StatelessSidebar = ({
           className={`${
             shrinked ? "mx-auto" : "ml-5"
           } h-5 md:h-8 self-start transition mb-2 md:mb-5`}
-          src={shrinked ? LOGO_COLLAPSE : static_light_logo}
+          src={shrinked ? LOGO_COLLAPSE : main_logo.light}
         />
       </Link>
       <div className="h-3" /> {/* flexible spacing */}
diff --git a/src/Components/Common/TopBar.tsx b/src/Components/Common/TopBar.tsx
index 0a1974df5b9..47fe8008309 100644
--- a/src/Components/Common/TopBar.tsx
+++ b/src/Components/Common/TopBar.tsx
@@ -3,14 +3,14 @@ import useConfig from "../../Common/hooks/useConfig";
 import LanguageSelector from "./LanguageSelector";
 
 const TopBar = () => {
-  const { static_black_logo } = useConfig();
+  const { main_logo } = useConfig();
   return (
     <div className="bg-white shadow-md">
       <div className="max-w-6xl mx-auto py-4 px-2 flex items-center justify-between">
         <div>
           <a href={"/"}>
             <img
-              src={static_black_logo}
+              src={main_logo.dark}
               style={{ height: "25px" }}
               alt="care logo"
             />
diff --git a/src/Components/Common/Uptime.tsx b/src/Components/Common/Uptime.tsx
new file mode 100644
index 00000000000..f07c1e0a71c
--- /dev/null
+++ b/src/Components/Common/Uptime.tsx
@@ -0,0 +1,350 @@
+import { Popover } from "@headlessui/react";
+import moment from "moment";
+import { useCallback, useEffect, useRef, useState } from "react";
+import { listAssetAvailability } from "../../Redux/actions";
+import { useDispatch } from "react-redux";
+import * as Notification from "../../Utils/Notifications.js";
+import { AssetStatus, AssetUptimeRecord } from "../Assets/AssetTypes";
+
+const STATUS_COLORS = {
+  operational: "bg-green-500",
+  not_monitored: "bg-gray-400",
+  down: "bg-red-500",
+  maintenance: "bg-blue-500",
+};
+
+const STATUS_COLORS_TEXT = {
+  operational: "text-green-500",
+  not_monitored: "text-gray-400",
+  down: "text-red-500",
+  maintenance: "text-blue-500",
+};
+
+const now = moment();
+const formatDateBeforeDays = Array.from({ length: 100 }, (_, index) =>
+  now.clone().subtract(index, "days").format("Do MMMM YYYY")
+);
+
+export default function Uptime(props: { assetId: string }) {
+  const [summary, setSummary] = useState<{
+    [key: number]: AssetUptimeRecord[];
+  }>([]);
+  const [loading, setLoading] = useState(true);
+  const graphElem = useRef<HTMLDivElement>(null);
+  const [numDays, setNumDays] = useState(
+    Math.floor((window.innerWidth - 1024) / 20)
+  );
+  const [hoveredDay, setHoveredDay] = useState(-1);
+  const dispatch = useDispatch<any>();
+
+  function StatusPopover({
+    records,
+    day,
+    date,
+    numDays,
+  }: {
+    records: AssetUptimeRecord[];
+    day: number;
+    date: string;
+    numDays: number;
+  }) {
+    const incidents =
+      records?.filter(
+        (record) =>
+          record.status !== AssetStatus.operational &&
+          record.status !== AssetStatus.not_monitored
+      ) || [];
+
+    return (
+      <Popover className="mt-10 relative">
+        <Popover.Panel
+          className={`absolute z-50 w-80 transform px-4 sm:px-0 ${
+            day > numDays - 7
+              ? "-translate-x-6"
+              : day < 4
+              ? "-translate-x-full"
+              : "-translate-x-1/2"
+          }`}
+          static
+        >
+          <div className="rounded-lg shadow-lg ring-1 ring-gray-400">
+            <div className="rounded-lg bg-white px-6 py-4">
+              <div className="flow-root rounded-md">
+                <div className="block text-sm text-gray-800 text-center">
+                  <span className="font-bold ">{date}</span>
+                  <div className="border-t border-gray-200 my-2"></div>
+                  {incidents.length === 0 ? (
+                    <span>No incidents for the day</span>
+                  ) : (
+                    <>
+                      <span className="font-bold ">Incidents</span>
+                      {incidents.map((incident, index) => {
+                        const nextIncident = incidents[index + 1];
+                        const endTimestamp = nextIncident
+                          ? moment(nextIncident.timestamp).format("h:mmA")
+                          : moment().format("h:mmA");
+                        const duration = nextIncident
+                          ? moment
+                              .duration(
+                                moment(endTimestamp).diff(
+                                  moment(incident.timestamp)
+                                )
+                              )
+                              .humanize()
+                          : "Ongoing";
+
+                        return (
+                          <div className="flex justify-between" key={index}>
+                            <span
+                              className={`capitalize ${
+                                STATUS_COLORS_TEXT[
+                                  AssetStatus[
+                                    incident.status
+                                  ] as keyof typeof STATUS_COLORS_TEXT
+                                ]
+                              }`}
+                            >
+                              {AssetStatus[incident.status]}
+                            </span>
+                            <span>
+                              {moment(incident.timestamp).format("h:mmA")} -{" "}
+                              {endTimestamp}
+                            </span>
+                            <span>{duration}</span>
+                          </div>
+                        );
+                      })}
+                      <div className="border-t border-gray-200 my-2"></div>
+                      <div className="flex justify-between mt-1">
+                        <span className="font-bold">Total</span>
+                        <span>
+                          {incidents.length === 0
+                            ? "Ongoing"
+                            : moment
+                                .duration(
+                                  incidents.reduce(
+                                    (totalDuration, incident) =>
+                                      totalDuration +
+                                      moment().diff(moment(incident.timestamp)),
+                                    0
+                                  )
+                                )
+                                .humanize()}
+                        </span>
+                      </div>
+                    </>
+                  )}
+                </div>
+              </div>
+            </div>
+          </div>
+        </Popover.Panel>
+      </Popover>
+    );
+  }
+
+  const handleResize = () => {
+    const containerWidth = graphElem.current?.clientWidth ?? window.innerWidth;
+    const newNumDays = Math.floor(containerWidth / 20);
+    setNumDays(newNumDays);
+  };
+
+  const setUptimeRecord = (records: AssetUptimeRecord[]): void => {
+    const recordsByDayBefore: { [key: number]: AssetUptimeRecord[] } = {};
+    records.forEach((record) => {
+      const timestamp = moment(record.timestamp);
+      const today = moment();
+      const diffDays = today.diff(timestamp, "days");
+      if (diffDays < 100) {
+        recordsByDayBefore[diffDays] = recordsByDayBefore[diffDays]
+          ? [...recordsByDayBefore[diffDays], record]
+          : [record];
+      }
+    });
+
+    setSummary(recordsByDayBefore);
+  };
+
+  function getUptimePercent(totalDays: number) {
+    let upStatus = 0;
+
+    for (let i = 0; i < totalDays; i++) {
+      const index = numDays - i - 1;
+      const dayRecords = summary[index];
+      if (
+        dayRecords &&
+        dayRecords[dayRecords.length - 1].status === AssetStatus.operational
+      ) {
+        upStatus++;
+      }
+    }
+
+    return Math.round((upStatus / totalDays) * 100);
+  }
+
+  const fetchData = useCallback(async () => {
+    setLoading(true);
+    setLoading(false);
+
+    const availabilityData = await dispatch(
+      listAssetAvailability({
+        external_id: props.assetId,
+      })
+    );
+    if (availabilityData?.data) {
+      setUptimeRecord(availabilityData.data.results);
+    } else {
+      Notification.Error({
+        msg: "Error fetching availability history",
+      });
+    }
+  }, [dispatch, props.assetId]);
+
+  useEffect(() => {
+    setTimeout(() => {
+      handleResize();
+    }, 100);
+    window.addEventListener("resize", handleResize);
+    return () => window.removeEventListener("resize", handleResize);
+  }, [graphElem, loading]);
+
+  useEffect(() => {
+    handleResize();
+    fetchData();
+  }, [props.assetId, fetchData]);
+
+  const getStatusColor = (day: number) => {
+    if (summary[day]) {
+      const dayRecords = summary[day];
+      const statusColors = [];
+      for (let i = 0; i < 3; i++) {
+        const start = moment()
+          .startOf("day")
+          .add(i * 8, "hours");
+        const end = moment()
+          .startOf("day")
+          .add((i + 1) * 8, "hours");
+        const recordsInPeriod = dayRecords.filter((record) =>
+          moment(record.timestamp).isBetween(start, end)
+        );
+        if (
+          recordsInPeriod.some(
+            (record) => AssetStatus[record.status] === "down"
+          )
+        ) {
+          statusColors.push(STATUS_COLORS["down"]);
+        } else if (
+          recordsInPeriod.some(
+            (record) => AssetStatus[record.status] === "maintenance"
+          )
+        ) {
+          statusColors.push(STATUS_COLORS["maintenance"]);
+        } else if (
+          recordsInPeriod.some(
+            (record) => AssetStatus[record.status] === "operational"
+          )
+        ) {
+          statusColors.push(STATUS_COLORS["operational"]);
+        } else {
+          statusColors.push(STATUS_COLORS["not_monitored"]);
+        }
+      }
+      return statusColors;
+    } else {
+      return [
+        STATUS_COLORS["not_monitored"],
+        STATUS_COLORS["not_monitored"],
+        STATUS_COLORS["not_monitored"],
+      ];
+    }
+  };
+  if (loading) {
+    return (
+      <div className="mt-8 flex flex-col bg-white w-full sm:rounded-lg shadow-sm p-4">
+        <p>Loading status...</p>
+      </div>
+    );
+  } else if (summary) {
+    return (
+      <div className="mt-8 flex flex-col bg-white w-full sm:rounded-lg shadow-sm p-4">
+        <div className="mx-2 w-full">
+          <div className="grid grid-cols-1">
+            <div className="text-xl font-semibold">Availability History</div>
+            <div>
+              <div className="mt-2 px-5 overflow-x-clip">
+                <div className="flex text-gray-700 text-xs mt-2 opacity-70 justify-center mb-1">
+                  {getUptimePercent(numDays)}% uptime
+                </div>
+                <div
+                  className="flex flex-row"
+                  ref={graphElem}
+                  onMouseLeave={() => setHoveredDay(-1)}
+                >
+                  {Array.from({ length: numDays }, (_, revIndex) => {
+                    const index = numDays - revIndex - 1;
+                    const dayStatus = getStatusColor(index);
+                    return (
+                      <>
+                        <span
+                          onMouseEnter={() => setHoveredDay(index)}
+                          key={index}
+                          className="h-8 w-3 flex-1 mx-1"
+                        >
+                          <div
+                            className={`h-[11px] w-3 rounded-t-sm ${
+                              hoveredDay === index
+                                ? "bg-gray-700"
+                                : dayStatus[0]
+                            }`}
+                          ></div>
+                          <div
+                            className={`h-[11px] w-3 ${
+                              hoveredDay === index
+                                ? "bg-gray-700"
+                                : dayStatus[1]
+                            }`}
+                          ></div>
+                          <div
+                            className={`h-[11px] w-3 rounded-b-sm ${
+                              hoveredDay === index
+                                ? "bg-gray-700"
+                                : dayStatus[2]
+                            }`}
+                          ></div>
+                        </span>
+                        {hoveredDay === index && (
+                          <>
+                            <StatusPopover
+                              records={summary[index]}
+                              day={index}
+                              date={formatDateBeforeDays[index]}
+                              numDays={numDays}
+                            />
+                          </>
+                        )}
+                      </>
+                    );
+                  })}
+                </div>
+                <div
+                  className={`flex text-gray-700 text-xs opacity-70 ${
+                    hoveredDay == -1 && "mt-2"
+                  }`}
+                >
+                  <span className="ml-0 mr-auto">{numDays} days ago</span>
+                  <span className="mr-0 ml-auto">Today</span>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  } else {
+    return (
+      <div className="mt-8 flex flex-col bg-white w-full sm:rounded-lg shadow-sm p-4">
+        <p>No status information available.</p>
+      </div>
+    );
+  }
+}
diff --git a/src/Components/CriticalCareRecording/CriticalCare__API.tsx b/src/Components/CriticalCareRecording/CriticalCare__API.tsx
index a1bbdfbc9e6..48b58faa167 100644
--- a/src/Components/CriticalCareRecording/CriticalCare__API.tsx
+++ b/src/Components/CriticalCareRecording/CriticalCare__API.tsx
@@ -3,8 +3,8 @@ import { fireRequestV2 } from "../../Redux/fireRequest";
 export const loadDailyRound = (
   consultationId: string,
   id: string,
-  successCB: any = () => {},
-  errorCB: any = () => {}
+  successCB: any = () => null,
+  errorCB: any = () => null
 ) => {
   fireRequestV2("getDailyReport", [], {}, successCB, errorCB, {
     consultationId,
@@ -16,8 +16,8 @@ export const updateDailyRound = (
   consultationId: string,
   id: string,
   params: object,
-  successCB: any = () => {},
-  errorCB: any = () => {}
+  successCB: any = () => null,
+  errorCB: any = () => null
 ) => {
   fireRequestV2("updateDailyRound", [], params, successCB, errorCB, {
     consultationId,
diff --git a/src/Components/Facility/AssetCreate.tsx b/src/Components/Facility/AssetCreate.tsx
index f8c2c5fce19..96ba51ad73d 100644
--- a/src/Components/Facility/AssetCreate.tsx
+++ b/src/Components/Facility/AssetCreate.tsx
@@ -914,6 +914,7 @@ const AssetCreate = (props: AssetProps) => {
                     />
                     {!assetId && (
                       <Submit
+                        data-testid="create-asset-add-more-button"
                         onClick={(e) => handleSubmit(e, true)}
                         label="Create & Add More"
                       />
diff --git a/src/Components/Facility/ConsultationDetails.tsx b/src/Components/Facility/ConsultationDetails.tsx
index acdae779bab..06681cc7e10 100644
--- a/src/Components/Facility/ConsultationDetails.tsx
+++ b/src/Components/Facility/ConsultationDetails.tsx
@@ -84,11 +84,7 @@ export const ConsultationDetails = (props: any) => {
     `${patientData.address},\n${patientData.ward_object?.name},\n${patientData.local_body_object?.name},\n${patientData.district_object?.name},\n${patientData.state_object?.name}`;
 
   const getPatientComorbidities = (patientData: any) => {
-    if (
-      patientData &&
-      patientData.medical_history &&
-      patientData.medical_history.length
-    ) {
+    if (patientData?.medical_history?.length) {
       const medHis = patientData.medical_history;
       return medHis.map((item: any) => item.disease).join(", ");
     } else {
@@ -158,12 +154,12 @@ export const ConsultationDetails = (props: any) => {
       setIsLoading(true);
       const res = await dispatch(getConsultation(consultationId));
       if (!status.aborted) {
-        if (res && res.data) {
+        if (res?.data) {
           const data: ConsultationModel = {
             ...res.data,
             symptoms_text: "",
           };
-          if (res.data.symptoms && res.data.symptoms.length) {
+          if (res.data.symptoms?.length) {
             const symptoms = res.data.symptoms
               .filter((symptom: number) => symptom !== 9)
               .map((symptom: number) => {
@@ -175,7 +171,7 @@ export const ConsultationDetails = (props: any) => {
           setConsultationData(data);
           const id = res.data.patient;
           const patientRes = await dispatch(getPatient({ id }));
-          if (patientRes && patientRes.data) {
+          if (patientRes?.data) {
             const patientGender = getPatientGender(patientRes.data);
             const patientAddress = getPatientAddress(patientRes.data);
             const patientComorbidities = getPatientComorbidities(
@@ -355,7 +351,7 @@ export const ConsultationDetails = (props: any) => {
                       {consultationData.admitted_to}
                     </span>
                   </div>
-                  {(consultationData.admission_date ||
+                  {(consultationData.admission_date ??
                     consultationData.discharge_date) && (
                     <div className="text-3xl font-bold">
                       {moment(
@@ -404,7 +400,7 @@ export const ConsultationDetails = (props: any) => {
                           },
                         ]
                       : []),
-                    ...(consultationData?.icd11_diagnoses_object || []),
+                    ...(consultationData?.icd11_diagnoses_object ?? []),
                   ]}
                   label="Diagnosis (as per ICD-11 recommended by WHO)"
                 />
@@ -480,7 +476,7 @@ export const ConsultationDetails = (props: any) => {
                 {CONSULTATION_TABS.map((p: OptionsType) => {
                   if (p.text === "FEED") {
                     if (
-                      !consultationData?.current_bed?.bed_object?.id ||
+                      !consultationData?.current_bed?.bed_object?.id ??
                       consultationData?.discharge_date !== null
                     )
                       return null;
@@ -563,7 +559,7 @@ export const ConsultationDetails = (props: any) => {
                               {DISCHARGE_REASONS.find(
                                 (d) =>
                                   d.id === consultationData.discharge_reason
-                              )?.text || "--"}
+                              )?.text ?? "--"}
                             </span>
                           </div>
                           {consultationData.discharge_reason === "REC" && (
@@ -582,12 +578,12 @@ export const ConsultationDetails = (props: any) => {
                               <div>
                                 Advice {" - "}
                                 <span className="font-semibold">
-                                  {consultationData.discharge_notes || "--"}
+                                  {consultationData.discharge_notes ?? "--"}
                                 </span>
                               </div>
                               <div className="overflow-x-auto overflow-y-hidden">
                                 <PrescriptionsTable
-                                  consultation_id={consultationData.id}
+                                  consultation_id={consultationData.id ?? ""}
                                   is_prn={false}
                                   readonly
                                   prescription_type="DISCHARGE"
@@ -596,7 +592,7 @@ export const ConsultationDetails = (props: any) => {
                               <hr className="border border-gray-300 my-2"></hr>
                               <div className="overflow-x-auto overflow-y-hidden">
                                 <PrescriptionsTable
-                                  consultation_id={consultationData.id}
+                                  consultation_id={consultationData.id ?? ""}
                                   is_prn
                                   readonly
                                   prescription_type="DISCHARGE"
@@ -619,20 +615,20 @@ export const ConsultationDetails = (props: any) => {
                               <div>
                                 Cause of death {" - "}
                                 <span className="font-semibold">
-                                  {consultationData.discharge_notes || "--"}
+                                  {consultationData.discharge_notes ?? "--"}
                                 </span>
                               </div>
                               <div>
                                 Confirmed By {" - "}
                                 <span className="font-semibold">
-                                  {consultationData.death_confirmed_doctor ||
+                                  {consultationData.death_confirmed_doctor ??
                                     "--"}
                                 </span>
                               </div>
                             </div>
                           )}
                           {["REF", "LAMA"].includes(
-                            consultationData.discharge_reason || ""
+                            consultationData.discharge_reason ?? ""
                           ) && (
                             <div className="grid gap-4">
                               <div>
@@ -649,7 +645,7 @@ export const ConsultationDetails = (props: any) => {
                               <div>
                                 Notes {" - "}
                                 <span className="font-semibold">
-                                  {consultationData.discharge_notes || "--"}
+                                  {consultationData.discharge_notes ?? "--"}
                                 </span>
                               </div>
                             </div>
@@ -679,7 +675,7 @@ export const ConsultationDetails = (props: any) => {
                                       text={
                                         SYMPTOM_CHOICES.find(
                                           (choice) => choice.id === symptom
-                                        )?.text || "Err. Unknown"
+                                        )?.text ?? "Err. Unknown"
                                       }
                                       color={"primary"}
                                       size={"small"}
@@ -719,7 +715,7 @@ export const ConsultationDetails = (props: any) => {
                                   text={
                                     SYMPTOM_CHOICES.find(
                                       (choice) => choice.id === symptom
-                                    )?.text || "Err. Unknown"
+                                    )?.text ?? "Err. Unknown"
                                   }
                                   color={"primary"}
                                   size={"small"}
@@ -810,7 +806,7 @@ export const ConsultationDetails = (props: any) => {
                     </div>
                   )}
 
-                  {(consultationData.operation ||
+                  {(consultationData.operation ??
                     consultationData.special_instruction) && (
                     <div className="bg-white overflow-hidden shadow rounded-lg">
                       <div className="px-4 py-5 sm:p-6">
@@ -971,25 +967,25 @@ export const ConsultationDetails = (props: any) => {
                       <div>
                         Gender {" - "}
                         <span className="font-semibold">
-                          {patientData.gender || "-"}
+                          {patientData.gender ?? "-"}
                         </span>
                       </div>
                       <div>
                         Age {" - "}
                         <span className="font-semibold">
-                          {patientData.age || "-"}
+                          {patientData.age ?? "-"}
                         </span>
                       </div>
                       <div>
                         Weight {" - "}
                         <span className="font-semibold">
-                          {consultationData.weight || "-"} Kg
+                          {consultationData.weight ?? "-"} Kg
                         </span>
                       </div>
                       <div>
                         Height {" - "}
                         <span className="font-semibold">
-                          {consultationData.height || "-"} cm
+                          {consultationData.height ?? "-"} cm
                         </span>
                       </div>
                       <div>
@@ -1006,7 +1002,7 @@ export const ConsultationDetails = (props: any) => {
                       <div>
                         Blood Group {" - "}
                         <span className="font-semibold">
-                          {patientData.blood_group || "-"}
+                          {patientData.blood_group ?? "-"}
                         </span>
                       </div>
                     </div>
diff --git a/src/Components/Facility/ConsultationForm.tsx b/src/Components/Facility/ConsultationForm.tsx
index fa141aae059..cf187561df1 100644
--- a/src/Components/Facility/ConsultationForm.tsx
+++ b/src/Components/Facility/ConsultationForm.tsx
@@ -16,14 +16,14 @@ import {
   getConsultation,
   updateConsultation,
   getPatient,
+  dischargePatient,
 } from "../../Redux/actions";
 import * as Notification from "../../Utils/Notifications.js";
 import { FacilitySelect } from "../Common/FacilitySelect";
-import { BedModel, FacilityModel } from "./models";
+import { BedModel, FacilityModel, ICD11DiagnosisModel } from "./models";
 import { OnlineUsersSelect } from "../Common/OnlineUsersSelect";
 import { UserModel } from "../Users/models";
 import { BedSelect } from "../Common/BedSelect";
-import { dischargePatient } from "../../Redux/actions";
 import Beds from "./Consultations/Beds";
 import InvestigationBuilder, {
   InvestigationType,
@@ -31,7 +31,6 @@ import InvestigationBuilder, {
 import ProcedureBuilder, {
   ProcedureType,
 } from "../Common/prescription-builder/ProcedureBuilder";
-import { ICD11DiagnosisModel } from "./models";
 import { Cancel, Submit } from "../Common/components/ButtonV2";
 import TextAreaFormField from "../Form/FormFields/TextAreaFormField";
 import { FieldChangeEventHandler } from "../Form/FormFields/Utils";
@@ -47,11 +46,8 @@ import useAppHistory from "../../Common/hooks/useAppHistory";
 import useVisibility from "../../Utils/useVisibility";
 import CareIcon from "../../CAREUI/icons/CareIcon";
 import CheckBoxFormField from "../Form/FormFields/CheckBoxFormField";
-import {
-  DraftSection,
-  FormReducerAction,
-  useAutoSaveReducer,
-} from "../../Utils/AutoSave";
+import { DraftSection, useAutoSaveReducer } from "../../Utils/AutoSave";
+import { FormAction } from "../Form/Utils";
 
 const Loading = loadable(() => import("../Common/Loading"));
 const PageTitle = loadable(() => import("../Common/PageTitle"));
@@ -171,10 +167,7 @@ const fieldRef = formErrorKeys.reduce(
   {}
 );
 
-const consultationFormReducer = (
-  state = initialState,
-  action: FormReducerAction
-) => {
+const consultationFormReducer = (state = initialState, action: FormAction) => {
   switch (action.type) {
     case "set_form": {
       return {
@@ -301,7 +294,7 @@ export const ConsultationForm = (props: any) => {
         else setSelectedFacility(res.data.referred_to_object);
       }
       if (!status.aborted) {
-        if (res && res.data) {
+        if (res?.data) {
           const formData = {
             ...res.data,
             symptoms_onset_date: isoStringToDate(res.data.symptoms_onset_date),
@@ -310,7 +303,7 @@ export const ConsultationForm = (props: any) => {
             admitted_to: res.data.admitted_to ? res.data.admitted_to : "",
             category: res.data.category
               ? PATIENT_CATEGORIES.find((i) => i.text === res.data.category)
-                  ?.id || "Comfort"
+                  ?.id ?? "Comfort"
               : "Comfort",
             ip_no: res.data.ip_no ? res.data.ip_no : "",
             op_no: res.data.op_no ? res.data.op_no : "",
@@ -343,11 +336,7 @@ export const ConsultationForm = (props: any) => {
 
   useAbortableEffect(
     (status: statusType) => {
-      if (id && patientId && patientName) {
-        fetchData(status);
-      } else if (id && !patientId) {
-        fetchData(status);
-      }
+      if (id && ((patientId && patientName) || !patientId)) fetchData(status);
     },
     [fetchData, id, patientId, patientName]
   );
@@ -640,7 +629,7 @@ export const ConsultationForm = (props: any) => {
         id ? updateConsultation(id, data) : createConsultation(data)
       );
       setIsLoading(false);
-      if (res && res.data && res.status !== 400) {
+      if (res?.data && res.status !== 400) {
         dispatch({ type: "set_form", form: initForm });
 
         if (data.suggestion === "DD") {
@@ -755,9 +744,9 @@ export const ConsultationForm = (props: any) => {
     const selectedFacility = selected as FacilityModel;
     setSelectedFacility(selectedFacility);
     const form: FormDetails = { ...state.form };
-    if (selectedFacility && selectedFacility.id) {
+    if (selectedFacility?.id) {
       if (selectedFacility.id === -1) {
-        form.referred_to_external = selectedFacility.name || "";
+        form.referred_to_external = selectedFacility.name ?? "";
         delete form.referred_to;
       } else {
         form.referred_to = selectedFacility.id.toString() || "";
diff --git a/src/Components/Facility/Consultations/ABGPlots.tsx b/src/Components/Facility/Consultations/ABGPlots.tsx
index 280bd0acf36..8d534c1413c 100644
--- a/src/Components/Facility/Consultations/ABGPlots.tsx
+++ b/src/Components/Facility/Consultations/ABGPlots.tsx
@@ -8,16 +8,14 @@ import { PAGINATION_LIMIT } from "../../../Common/constants";
 import { formatDate } from "../../../Utils/utils";
 
 export const ABGPlots = (props: any) => {
-  const { facilityId, patientId, consultationId } = props;
+  const { consultationId } = props;
   const dispatch: any = useDispatch();
-  const [isLoading, setIsLoading] = useState(false);
   const [results, setResults] = useState({});
   const [currentPage, setCurrentPage] = useState(1);
   const [totalCount, setTotalCount] = useState(0);
 
   const fetchDailyRounds = useCallback(
     async (status: statusType) => {
-      setIsLoading(true);
       const res = await dispatch(
         dailyRoundsAnalyse(
           {
@@ -38,11 +36,10 @@ export const ABGPlots = (props: any) => {
         )
       );
       if (!status.aborted) {
-        if (res && res.data) {
+        if (res?.data) {
           setResults(res.data.results);
           setTotalCount(res.data.count);
         }
-        setIsLoading(false);
       }
     },
     [consultationId, dispatch, currentPage]
@@ -55,7 +52,7 @@ export const ABGPlots = (props: any) => {
     [currentPage]
   );
 
-  const handlePagination = (page: number, limit: number) => {
+  const handlePagination = (page: number, _limit: number) => {
     setCurrentPage(page);
   };
 
diff --git a/src/Components/Facility/Consultations/Beds.tsx b/src/Components/Facility/Consultations/Beds.tsx
index ab472cf514e..ac6fa22fc5b 100644
--- a/src/Components/Facility/Consultations/Beds.tsx
+++ b/src/Components/Facility/Consultations/Beds.tsx
@@ -31,7 +31,7 @@ const formatDateTime: () => string = () => {
 interface BedsProps {
   facilityId: string;
   patientId: number;
-  consultationId: number;
+  consultationId: string;
   smallLoader?: boolean;
   discharged?: boolean;
   setState?: Dispatch<SetStateAction<boolean>>;
diff --git a/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx b/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx
index 3ee16b09618..72ca01b3fb3 100644
--- a/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx
+++ b/src/Components/Facility/Consultations/DailyRounds/LogUpdateCardAttribute.tsx
@@ -48,7 +48,7 @@ const LogUpdateCardAttribute = <T extends keyof DailyRoundsModel>({
           <AttributeLabel attributeKey={attributeKey} />
           <span className="flex gap-x-2 gap-y-1 flex-wrap text-sm text-gray-700">
             {attributeValue.map((output: any) => (
-              <span className="font-semibold">
+              <span className="font-semibold" key={output.name}>
                 {output.name}: {output.quantity}
               </span>
             ))}
diff --git a/src/Components/Facility/Consultations/DialysisPlots.tsx b/src/Components/Facility/Consultations/DialysisPlots.tsx
index 1b08420c2c7..392235f8929 100644
--- a/src/Components/Facility/Consultations/DialysisPlots.tsx
+++ b/src/Components/Facility/Consultations/DialysisPlots.tsx
@@ -8,17 +8,14 @@ import { PAGINATION_LIMIT } from "../../../Common/constants";
 import { formatDate } from "../../../Utils/utils";
 
 export const DialysisPlots = (props: any) => {
-  const { facilityId, patientId, consultationId } = props;
+  const { consultationId } = props;
   const dispatch: any = useDispatch();
-  const [isLoading, setIsLoading] = useState(false);
-  const [offset, setOffset] = useState(0);
   const [results, setResults] = useState({});
   const [currentPage, setCurrentPage] = useState(1);
   const [totalCount, setTotalCount] = useState(0);
 
   const fetchDailyRounds = useCallback(
     async (status: statusType) => {
-      setIsLoading(true);
       const res = await dispatch(
         dailyRoundsAnalyse(
           {
@@ -29,11 +26,10 @@ export const DialysisPlots = (props: any) => {
         )
       );
       if (!status.aborted) {
-        if (res && res.data) {
+        if (res?.data) {
           setTotalCount(res.data.count);
           setResults(res.data.results);
         }
-        setIsLoading(false);
       }
     },
     [consultationId, dispatch, currentPage]
@@ -46,10 +42,8 @@ export const DialysisPlots = (props: any) => {
     [consultationId, currentPage]
   );
 
-  const handlePagination = (page: number, limit: number) => {
-    const offset = (page - 1) * limit;
+  const handlePagination = (page: number, _limit: number) => {
     setCurrentPage(page);
-    setOffset(offset);
   };
 
   const dates = Object.keys(results)
diff --git a/src/Components/Facility/Consultations/Feed.tsx b/src/Components/Facility/Consultations/Feed.tsx
index 7352a9bcd0b..cdfbdb40e9d 100644
--- a/src/Components/Facility/Consultations/Feed.tsx
+++ b/src/Components/Facility/Consultations/Feed.tsx
@@ -26,10 +26,10 @@ import FeedButton from "./FeedButton";
 import Loading from "../../Common/Loading";
 import ReactPlayer from "react-player";
 import { classNames } from "../../../Utils/utils";
-import screenfull from "screenfull";
 import { useDispatch } from "react-redux";
 import { useHLSPLayer } from "../../../Common/hooks/useHLSPlayer";
 import useKeyboardShortcut from "use-keyboard-shortcut";
+import useFullscreen from "../../../Common/hooks/useFullscreen.js";
 
 interface IFeedProps {
   facilityId: string;
@@ -54,6 +54,7 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
   const [bed, setBed] = useState<any>();
   const [precision, setPrecision] = useState(1);
   const [cameraState, setCameraState] = useState<PTZState | null>(null);
+  const [isFullscreen, setFullscreen] = useFullscreen();
 
   useEffect(() => {
     const fetchFacility = async () => {
@@ -299,14 +300,13 @@ export const Feed: React.FC<IFeedProps> = ({ consultationId, facilityId }) => {
       });
     },
     fullScreen: () => {
-      if (!(screenfull.isEnabled && liveFeedPlayerRef.current)) return;
-      !screenfull.isFullscreen
-        ? screenfull.request(
-            videoWrapper.current
-              ? videoWrapper.current
-              : (liveFeedPlayerRef.current as HTMLElement)
-          )
-        : screenfull.exit();
+      if (!liveFeedPlayerRef.current) return;
+      setFullscreen(
+        !isFullscreen,
+        videoWrapper.current
+          ? videoWrapper.current
+          : (liveFeedPlayerRef.current as HTMLElement)
+      );
     },
     updatePreset: (option) => {
       getCameraStatus({
@@ -576,7 +576,7 @@ export const FeedCameraPTZHelpButton = (props: { cameraPTZ: CameraPTZ[] }) => {
   return (
     <button
       key="option.action"
-      className="tooltip rounded text-2xl text-white/40"
+      className="tooltip rounded text-2xl text-gray-600"
     >
       <CareIcon className="care-l-question-circle" />
 
diff --git a/src/Components/Facility/Consultations/LiveFeed.tsx b/src/Components/Facility/Consultations/LiveFeed.tsx
index 51c7fae894c..f9ffc0a7cfb 100644
--- a/src/Components/Facility/Consultations/LiveFeed.tsx
+++ b/src/Components/Facility/Consultations/LiveFeed.tsx
@@ -1,6 +1,5 @@
 import { useEffect, useState, useRef } from "react";
 import { useDispatch } from "react-redux";
-import screenfull from "screenfull";
 import useKeyboardShortcut from "use-keyboard-shortcut";
 import {
   listAssetBeds,
@@ -23,6 +22,7 @@ import CareIcon from "../../../CAREUI/icons/CareIcon";
 import Page from "../../Common/components/Page";
 import ConfirmDialog from "../../Common/ConfirmDialog";
 import { FieldLabel } from "../../Form/FormFields/FormField";
+import useFullscreen from "../../../Common/hooks/useFullscreen";
 
 const LiveFeed = (props: any) => {
   const middlewareHostname =
@@ -47,6 +47,8 @@ const LiveFeed = (props: any) => {
   });
   const [toDelete, setToDelete] = useState<any>(null);
   const [toUpdate, setToUpdate] = useState<any>(null);
+  const [_isFullscreen, setFullscreen] = useFullscreen();
+
   const { width } = useWindowDimensions();
   const extremeSmallScreenBreakpoint = 320;
   const isExtremeSmallScreen =
@@ -227,8 +229,8 @@ const LiveFeed = (props: any) => {
       });
     },
     fullScreen: () => {
-      if (!(screenfull.isEnabled && liveFeedPlayerRef.current)) return;
-      screenfull.request(liveFeedPlayerRef.current);
+      if (!liveFeedPlayerRef.current) return;
+      setFullscreen(true, liveFeedPlayerRef.current);
     },
     updatePreset: (option) => {
       getCameraStatus({
diff --git a/src/Components/Facility/Consultations/NursingPlot.tsx b/src/Components/Facility/Consultations/NursingPlot.tsx
index 19b5ae0f90c..6da46b7ae25 100644
--- a/src/Components/Facility/Consultations/NursingPlot.tsx
+++ b/src/Components/Facility/Consultations/NursingPlot.tsx
@@ -1,23 +1,23 @@
 import { useCallback, useState } from "react";
 import { useDispatch } from "react-redux";
-import { NURSING_CARE_FIELDS } from "../../../Common/constants";
+import {
+  NURSING_CARE_FIELDS,
+  PAGINATION_LIMIT,
+} from "../../../Common/constants";
 import { statusType, useAbortableEffect } from "../../../Common/utils";
 import { dailyRoundsAnalyse } from "../../../Redux/actions";
 import Pagination from "../../Common/Pagination";
-import { PAGINATION_LIMIT } from "../../../Common/constants";
 import { formatDate } from "../../../Utils/utils";
 
 export const NursingPlot = (props: any) => {
-  const { facilityId, patientId, consultationId } = props;
+  const { consultationId } = props;
   const dispatch: any = useDispatch();
-  const [isLoading, setIsLoading] = useState(false);
   const [results, setResults] = useState<any>({});
   const [currentPage, setCurrentPage] = useState(1);
   const [totalCount, setTotalCount] = useState(0);
 
   const fetchDailyRounds = useCallback(
     async (status: statusType) => {
-      setIsLoading(true);
       const res = await dispatch(
         dailyRoundsAnalyse(
           {
@@ -28,11 +28,10 @@ export const NursingPlot = (props: any) => {
         )
       );
       if (!status.aborted) {
-        if (res && res.data) {
+        if (res?.data) {
           setResults(res.data.results);
           setTotalCount(res.data.count);
         }
-        setIsLoading(false);
       }
     },
     [consultationId, dispatch, currentPage]
@@ -74,8 +73,8 @@ export const NursingPlot = (props: any) => {
 
   const areFieldsEmpty = () => {
     let emptyFieldCount = 0;
-    for (let i = 0; i < NURSING_CARE_FIELDS.length; i++) {
-      if (!filterEmpty(NURSING_CARE_FIELDS[i])) emptyFieldCount++;
+    for (const field of NURSING_CARE_FIELDS) {
+      if (!filterEmpty(field)) emptyFieldCount++;
     }
     if (emptyFieldCount === NURSING_CARE_FIELDS.length) return true;
     else return false;
diff --git a/src/Components/Facility/DischargeModal.tsx b/src/Components/Facility/DischargeModal.tsx
index d15d88a3353..45f6278b9cd 100644
--- a/src/Components/Facility/DischargeModal.tsx
+++ b/src/Components/Facility/DischargeModal.tsx
@@ -167,7 +167,7 @@ const DischargeModal = ({
     });
   };
 
-  const prescriptionActions = PrescriptionActions(consultationData.id);
+  const prescriptionActions = PrescriptionActions(consultationData.id ?? "");
 
   return (
     <DialogModal
@@ -229,7 +229,7 @@ const DischargeModal = ({
               name="discharge_date"
               value={moment(preDischargeForm?.discharge_date).toDate()}
               min={moment(
-                consultationData?.admission_date ||
+                consultationData?.admission_date ??
                   consultationData?.created_date
               ).toDate()}
               disableFuture={true}
@@ -262,7 +262,7 @@ const DischargeModal = ({
               <input
                 type="datetime-local"
                 className="w-[calc(100%-5px)] focus:ring-primary-500 focus:border-primary-500 block border border-gray-400 rounded py-2 px-4 text-sm bg-gray-100 hover:bg-gray-200 focus:outline-none focus:bg-white"
-                value={preDischargeForm.death_datetime || ""}
+                value={preDischargeForm.death_datetime ?? ""}
                 required
                 min={consultationData?.admission_date?.substring(0, 16)}
                 max={moment(new Date()).format("YYYY-MM-DDThh:mm")}
@@ -279,7 +279,7 @@ const DischargeModal = ({
             <TextFormField
               name="death_confirmed_by"
               label="Confirmed By"
-              value={preDischargeForm.death_confirmed_doctor || ""}
+              value={preDischargeForm.death_confirmed_doctor ?? ""}
               onChange={(e) => {
                 setPreDischargeForm((form) => {
                   return {
@@ -300,7 +300,7 @@ const DischargeModal = ({
               name="discharge_date"
               value={moment(preDischargeForm.discharge_date).toDate()}
               min={moment(
-                consultationData?.admission_date ||
+                consultationData?.admission_date ??
                   consultationData?.created_date
               ).toDate()}
               disableFuture={true}
@@ -319,8 +319,8 @@ const DischargeModal = ({
             <ClaimDetailCard claim={latestClaim} />
           ) : (
             <CreateClaimCard
-              consultationId={consultationData.id}
-              patientId={consultationData.patient}
+              consultationId={consultationData.id ?? ""}
+              patientId={consultationData.patient ?? ""}
               use="claim"
               isCreating={isCreateClaimLoading}
               setIsCreating={setIsCreateClaimLoading}
diff --git a/src/Components/Facility/TreatmentSummary.tsx b/src/Components/Facility/TreatmentSummary.tsx
index 2696b0d7031..5322d072454 100644
--- a/src/Components/Facility/TreatmentSummary.tsx
+++ b/src/Components/Facility/TreatmentSummary.tsx
@@ -1,12 +1,15 @@
 import React, { useCallback, useState } from "react";
 import { useDispatch } from "react-redux";
-import { getPatient, getInvestigation } from "../../Redux/actions";
+import {
+  getPatient,
+  getInvestigation,
+  getConsultation,
+} from "../../Redux/actions";
 import { ConsultationModel } from "./models";
 import { statusType, useAbortableEffect } from "../../Common/utils";
 import { PatientModel } from "../Patient/models";
 import loadable from "@loadable/component";
 import moment from "moment";
-import { getConsultation } from "../../Redux/actions";
 import { GENDER_TYPES } from "../../Common/constants";
 import { formatDate } from "../../Utils/utils";
 const Loading = loadable(() => import("../Common/Loading"));
@@ -28,7 +31,7 @@ const TreatmentSummary = (props: any) => {
       setIsLoading(true);
       const res = await dispatch(getPatient({ id: patientId }));
       if (!status.aborted) {
-        if (res && res.data) {
+        if (res?.data) {
           setPatientData(res.data);
         } else {
           setPatientData({});
@@ -45,7 +48,7 @@ const TreatmentSummary = (props: any) => {
       const res = await dispatch(getInvestigation({}, consultationId));
 
       if (!status.aborted) {
-        if (res && res?.data?.results) {
+        if (res?.data?.results) {
           const valueMap = res.data.results.reduce(
             (acc: any, cur: { id: any }) => ({ ...acc, [cur.id]: cur }),
             {}
@@ -67,7 +70,7 @@ const TreatmentSummary = (props: any) => {
         dispatch(getConsultation(consultationId)),
       ]);
       if (!status.aborted) {
-        if (res && res.data) {
+        if (res?.data) {
           setConsultationData(res.data);
           if (res.data.last_daily_round) {
             setDailyRounds(res.data.last_daily_round);
@@ -255,8 +258,7 @@ const TreatmentSummary = (props: any) => {
 
               <div className="border-b-2 border-gray-800 px-5 py-2">
                 <b>General Instructions :</b>
-                {patientData.last_consultation &&
-                patientData.last_consultation.consultation_notes ? (
+                {patientData?.last_consultation?.consultation_notes ? (
                   <div className="mx-5">
                     {patientData.last_consultation.consultation_notes}
                   </div>
diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx
index 52fdc73e860..488d195354b 100644
--- a/src/Components/Facility/models.tsx
+++ b/src/Components/Facility/models.tsx
@@ -88,17 +88,17 @@ export interface ConsultationModel {
   created_date?: string;
   discharge_date?: string;
   discharge_reason?: string;
-  discharge_prescription: NormalPrescription;
-  discharge_prn_prescription: PRNPrescription;
+  discharge_prescription?: NormalPrescription;
+  discharge_prn_prescription?: PRNPrescription;
   discharge_notes?: string;
   examination_details?: string;
   history_of_present_illness?: string;
   facility?: number;
   facility_name?: string;
-  id: string;
+  id?: string;
   modified_date?: string;
   other_symptoms?: string;
-  patient: string;
+  patient?: string;
   prescribed_medication?: string;
   referred_to?: number | null;
   suggestion?: string;
diff --git a/src/Components/Form/FieldValidators.tsx b/src/Components/Form/FieldValidators.tsx
index 7a7bf72d067..1cd1a67e4e5 100644
--- a/src/Components/Form/FieldValidators.tsx
+++ b/src/Components/Form/FieldValidators.tsx
@@ -29,6 +29,19 @@ export const MultiValidator = <T,>(
   return validator;
 };
 
+export const AnyValidator = <T,>(
+  validators: FieldValidator<T>[]
+): FieldValidator<T> => {
+  const validator = (value: T) => {
+    for (const validate of validators) {
+      const error = validate(value);
+      if (!error) return;
+    }
+    return validators[0](value);
+  };
+  return validator;
+};
+
 export const RequiredFieldValidator = (message = "Field is required") => {
   return <T,>(value: T): FieldError => {
     if (!value) return message;
@@ -36,10 +49,30 @@ export const RequiredFieldValidator = (message = "Field is required") => {
   };
 };
 
-export const EmailValidator = (message = "Invalid email address") => {
+export const RegexValidator = (regex: RegExp, message = "Invalid input") => {
   return (value: string): FieldError => {
-    const pattern =
-      /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
-    return pattern.test(value) ? undefined : message;
+    return regex.test(value) ? undefined : message;
   };
 };
+
+const EMAIL_REGEX =
+  /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+
+export const EmailValidator = (message = "Invalid email address") => {
+  return RegexValidator(EMAIL_REGEX, message);
+};
+
+const PHONE_NUMBER_REGEX =
+  /^(?:(?:(?:\+|0{0,2})91|0{0,2})(?:\()?\d{3}(?:\))?[-]?\d{3}[-]?\d{4})$/;
+
+export const PhoneNumberValidator = (message = "Invalid phone number") => {
+  return RegexValidator(PHONE_NUMBER_REGEX, message);
+};
+
+const SUPPORT_PHONE_NUMBER_REGEX = /^1800[-]?\d{3}[-]?\d{3,4}$/;
+
+export const SupportPhoneNumberValidator = (
+  message = "Invalid support phone number"
+) => {
+  return RegexValidator(SUPPORT_PHONE_NUMBER_REGEX, message);
+};
diff --git a/src/Components/Form/FormFields/Autocomplete.tsx b/src/Components/Form/FormFields/Autocomplete.tsx
index c50d9d772cd..7622f59da42 100644
--- a/src/Components/Form/FormFields/Autocomplete.tsx
+++ b/src/Components/Form/FormFields/Autocomplete.tsx
@@ -5,6 +5,7 @@ import CareIcon from "../../../CAREUI/icons/CareIcon";
 import { dropdownOptionClassNames } from "../MultiSelectMenuV2";
 import { FormFieldBaseProps, useFormFieldPropsResolver } from "./Utils";
 import FormField from "./FormField";
+import { classNames } from "../../../Utils/utils";
 
 type OptionCallback<T, R> = (option: T) => R;
 
@@ -62,7 +63,7 @@ type AutocompleteProps<T, V = T> = {
   optionLabel: OptionCallback<T, string>;
   optionIcon?: OptionCallback<T, React.ReactNode>;
   optionValue?: OptionCallback<T, V>;
-  optionDescription?: OptionCallback<T, string>;
+  optionDescription?: OptionCallback<T, React.ReactNode>;
   className?: string;
   onQuery?: (query: string) => void;
   requiredError?: boolean;
@@ -100,8 +101,7 @@ export const Autocomplete = <T, V>(props: AutocompleteProps<T, V>) => {
     return {
       label,
       description,
-      search:
-        label.toLowerCase() + (description ? description.toLowerCase() : ""),
+      search: label.toLowerCase(),
       icon: props.optionIcon && props.optionIcon(option),
       value: props.optionValue ? props.optionValue(option) : option,
     };
@@ -130,7 +130,10 @@ export const Autocomplete = <T, V>(props: AutocompleteProps<T, V>) => {
   const options = props.allowRawInput ? getOptions() : mappedOptions;
 
   const value = options.find((o) => props.value == o.value);
-  const filteredOptions = options.filter((o) => o.search.includes(query));
+  const filteredOptions =
+    props.onQuery === undefined
+      ? options.filter((o) => o.search.includes(query))
+      : options;
 
   return (
     <div
@@ -181,17 +184,24 @@ export const Autocomplete = <T, V>(props: AutocompleteProps<T, V>) => {
                   className={dropdownOptionClassNames}
                   value={option}
                 >
-                  <div className="flex flex-col">
-                    <div className="flex justify-between">
-                      {option.label}
-                      {option.icon}
-                    </div>
-                    {option.description && (
-                      <div className="text-sm text-gray-500">
-                        {option.description}
+                  {({ active }) => (
+                    <div className="flex flex-col">
+                      <div className="flex justify-between">
+                        <span>{option.label}</span>
+                        <span>{option.icon}</span>
                       </div>
-                    )}
-                  </div>
+                      {option.description && (
+                        <div
+                          className={classNames(
+                            "text-sm",
+                            active ? "text-primary-200" : "text-gray-700"
+                          )}
+                        >
+                          {option.description}
+                        </div>
+                      )}
+                    </div>
+                  )}
                 </Combobox.Option>
               ))}
             </Combobox.Options>
diff --git a/src/Components/Form/FormFields/DateFormField.tsx b/src/Components/Form/FormFields/DateFormField.tsx
index a95b6b79db6..adb8c2538ae 100644
--- a/src/Components/Form/FormFields/DateFormField.tsx
+++ b/src/Components/Form/FormFields/DateFormField.tsx
@@ -44,9 +44,9 @@ const DateFormField = (props: Props) => {
         }
         onChange={field.handleChange}
         disabled={field.disabled}
-        max={props.max || (props.disableFuture ? new Date() : undefined)}
-        min={props.min || (props.disablePast ? yesterday() : undefined)}
-        position={props.position || "RIGHT"}
+        max={props.max ?? (props.disableFuture ? new Date() : undefined)}
+        min={props.min ?? (props.disablePast ? yesterday() : undefined)}
+        position={props.position ?? "RIGHT"}
         placeholder={props.placeholder}
       />
     </FormField>
diff --git a/src/Components/Form/FormFields/PhoneNumberFormField.tsx b/src/Components/Form/FormFields/PhoneNumberFormField.tsx
index 5299cf7550f..a6f472e51e6 100644
--- a/src/Components/Form/FormFields/PhoneNumberFormField.tsx
+++ b/src/Components/Form/FormFields/PhoneNumberFormField.tsx
@@ -1,9 +1,19 @@
 import { FormFieldBaseProps, useFormFieldPropsResolver } from "./Utils";
 import FormField from "./FormField";
-import { AsYouType } from "libphonenumber-js";
-import { useMemo } from "react";
+import {
+  AsYouType,
+  isValidPhoneNumber,
+  parsePhoneNumber,
+} from "libphonenumber-js";
+import { useMemo, useState } from "react";
 import { classNames } from "../../../Utils/utils";
 import phoneCodesJson from "../../../Common/static/countryPhoneAndFlags.json";
+import {
+  AnyValidator,
+  FieldError,
+  PhoneNumberValidator,
+  SupportPhoneNumberValidator,
+} from "../FieldValidators";
 
 interface CountryData {
   flag: string;
@@ -17,10 +27,12 @@ interface Props extends FormFieldBaseProps<string> {
   placeholder?: string;
   autoComplete?: string;
   disableCountry?: boolean;
+  disableValidation?: boolean;
 }
 
 export default function PhoneNumberFormField(props: Props) {
   const field = useFormFieldPropsResolver(props as any);
+  const [error, setError] = useState<FieldError>();
 
   const asYouType = useMemo(() => {
     const asYouType = new AsYouType();
@@ -37,14 +49,40 @@ export default function PhoneNumberFormField(props: Props) {
     return asYouType;
   }, []);
 
+  const validate = useMemo(
+    () => (value: string | undefined, event: "blur" | "change") => {
+      if (!value || props.disableValidation) {
+        return;
+      }
+
+      const newError = AnyValidator([
+        PhoneNumberValidator(),
+        SupportPhoneNumberValidator(),
+      ])(value);
+
+      if (!newError) {
+        return;
+      } else if (event === "blur") {
+        return newError;
+      }
+    },
+    [props.disableValidation]
+  );
+
   const setValue = (value: string) => {
+    value = value.replaceAll(" ", "");
+
     asYouType.reset();
     asYouType.input(value);
+
+    const error = validate(value, "change");
     field.handleChange(value);
+
+    setError(error);
   };
 
   return (
-    <FormField field={field}>
+    <FormField field={{ ...field, error: field.error || error }}>
       <div className="relative rounded-md shadow-sm">
         <input
           type="tel"
@@ -58,9 +96,10 @@ export default function PhoneNumberFormField(props: Props) {
           )}
           maxLength={field.value?.startsWith("1800") ? 11 : 15}
           placeholder={props.placeholder}
-          value={field.value}
+          value={formatPhoneNumber(field.value, props.disableCountry)}
           onChange={(e) => setValue(e.target.value)}
           disabled={field.disabled}
+          onBlur={() => setError(validate(field.value, "blur"))}
         />
         {!props.disableCountry && (
           <div className="absolute inset-y-0 right-0 flex items-center">
@@ -83,9 +122,9 @@ export default function PhoneNumberFormField(props: Props) {
                 setValue(conditionPhoneCode(phoneCodes[e.target.value].code));
               }}
             >
-              {Object.entries(phoneCodes).map(([country, { flag, code }]) => (
+              {Object.entries(phoneCodes).map(([country, { flag }]) => (
                 <option key={country} value={country}>
-                  {flag} {conditionPhoneCode(code)}
+                  {flag} {country}
                 </option>
               ))}
               <option value="Other">Other</option>
@@ -102,3 +141,16 @@ const conditionPhoneCode = (code: string) => {
   code = code.split(" ")[0];
   return code.startsWith("+") ? code : "+" + code;
 };
+
+const formatPhoneNumber = (value: string, disableCountry?: boolean) => {
+  if (value === undefined || value === null) {
+    return disableCountry ? "" : "+91 ";
+  }
+
+  if (!isValidPhoneNumber(value) || disableCountry) {
+    return value;
+  }
+
+  const phoneNumber = parsePhoneNumber(value);
+  return phoneNumber.formatInternational();
+};
diff --git a/src/Components/Form/SelectMenuV2.tsx b/src/Components/Form/SelectMenuV2.tsx
index e9800d733c5..44917b23b26 100644
--- a/src/Components/Form/SelectMenuV2.tsx
+++ b/src/Components/Form/SelectMenuV2.tsx
@@ -59,7 +59,7 @@ const SelectMenuV2 = <T, V>(props: SelectMenuProps<T, V>) => {
 
   const showChevronIcon = props.showChevronIcon ?? true;
 
-  const placeholder = props.placeholder || "Select";
+  const placeholder = props.placeholder ?? "Select";
   const defaultOption = {
     label: placeholder,
     selectedLabel: <p className="font-normal text-gray-600">{placeholder}</p>,
@@ -72,7 +72,7 @@ const SelectMenuV2 = <T, V>(props: SelectMenuProps<T, V>) => {
     ? valueOptions
     : [defaultOption, ...valueOptions];
 
-  const value = options.find((o) => props.value == o.value) || defaultOption;
+  const value = options.find((o) => props.value == o.value) ?? defaultOption;
 
   return (
     <div className={props.className} id={props.id}>
diff --git a/src/Components/HCX/CreateClaimCard.tsx b/src/Components/HCX/CreateClaimCard.tsx
index c0a10f00216..75f726c6e57 100644
--- a/src/Components/HCX/CreateClaimCard.tsx
+++ b/src/Components/HCX/CreateClaimCard.tsx
@@ -52,7 +52,7 @@ export default function CreateClaimCard({
         ).find((o) => o.outcome === "Processing Complete");
         if (latestApprovedPreAuth) {
           setPolicy(latestApprovedPreAuth.policy_object);
-          setItems(latestApprovedPreAuth.items || []);
+          setItems(latestApprovedPreAuth.items ?? []);
           return;
         }
       }
@@ -174,7 +174,7 @@ export default function CreateClaimCard({
             ghost={items?.length !== 0}
             disabled={items === undefined || !policy}
             onClick={() =>
-              setItems([...(items || []), { name: "", id: "", price: 0 }])
+              setItems([...(items ?? []), { name: "", id: "", price: 0 }])
             }
           >
             <CareIcon className="care-l-plus text-lg" />
@@ -219,9 +219,7 @@ export default function CreateClaimCard({
             { id: "claim", label: "Claim" },
           ]}
           value={use_}
-          onChange={({ value }) =>
-            setUse_(value as "preauthorization" | "claim")
-          }
+          onChange={({ value }) => setUse_(value)}
           position="below"
           optionLabel={(value) => value.label}
           optionValue={(value) => value.id as "preauthorization" | "claim"}
diff --git a/src/Components/Hub/LiveFeedTile.tsx b/src/Components/Hub/LiveFeedTile.tsx
index a51e284073a..27a9e2d2bd1 100644
--- a/src/Components/Hub/LiveFeedTile.tsx
+++ b/src/Components/Hub/LiveFeedTile.tsx
@@ -3,10 +3,10 @@ import React, { useEffect, useState, useRef, useCallback } from "react";
 import * as Notification from "../../Utils/Notifications.js";
 import { useDispatch } from "react-redux";
 import ReactPlayer from "react-player";
-import screenfull from "screenfull";
 import { getAsset, listAssetBeds } from "../../Redux/actions";
 import { statusType, useAbortableEffect } from "../../Common/utils";
 import { useTranslation } from "react-i18next";
+import useFullscreen from "../../Common/hooks/useFullscreen.js";
 interface LiveFeedTileProps {
   assetId: string;
 }
@@ -38,6 +38,7 @@ export default function LiveFeedTile(props: LiveFeedTileProps) {
     zoom: 0,
   });
   const { t } = useTranslation();
+  const [_isFullscreen, setFullscreen] = useFullscreen();
 
   useEffect(() => {
     let loadingTimeout: any;
@@ -238,10 +239,8 @@ export default function LiveFeedTile(props: LiveFeedTileProps) {
 
   const liveFeedPlayerRef = useRef<any>(null);
   const handleClickFullscreen = () => {
-    if (screenfull.isEnabled) {
-      if (liveFeedPlayerRef.current) {
-        screenfull.request(liveFeedPlayerRef.current.wrapper);
-      }
+    if (liveFeedPlayerRef.current) {
+      setFullscreen(true, liveFeedPlayerRef.current.wrapper);
     }
   };
 
diff --git a/src/Components/Medicine/CreatePrescriptionForm.tsx b/src/Components/Medicine/CreatePrescriptionForm.tsx
index 42e205c63b6..eb2939da049 100644
--- a/src/Components/Medicine/CreatePrescriptionForm.tsx
+++ b/src/Components/Medicine/CreatePrescriptionForm.tsx
@@ -8,12 +8,9 @@ import { MedicineAdministrationRecord, Prescription } from "./models";
 import { PrescriptionActions } from "../../Redux/actions";
 import { useDispatch } from "react-redux";
 import { useState } from "react";
-import AutocompleteFormField from "../Form/FormFields/Autocomplete";
-import medicines_list from "../Common/prescription-builder/assets/medicines.json";
 import NumericWithUnitsFormField from "../Form/FormFields/NumericWithUnitsFormField";
 import { useTranslation } from "react-i18next";
-
-export const medicines = medicines_list;
+import MedibaseAutocompleteFormField from "./MedibaseAutocompleteFormField";
 
 export default function CreatePrescriptionForm(props: {
   prescription: Prescription;
@@ -30,6 +27,9 @@ export default function CreatePrescriptionForm(props: {
       defaults={props.prescription}
       onCancel={props.onDone}
       onSubmit={async (obj) => {
+        obj["medicine"] = obj.medicine_object?.id;
+        delete obj.medicine_object;
+
         setIsCreating(true);
         const res = await dispatch(props.create(obj));
         setIsCreating(false);
@@ -42,7 +42,7 @@ export default function CreatePrescriptionForm(props: {
       noPadding
       validate={(form) => {
         const errors: Partial<Record<keyof Prescription, FieldError>> = {};
-        errors.medicine = RequiredFieldValidator()(form.medicine);
+        errors.medicine_object = RequiredFieldValidator()(form.medicine_object);
         errors.dosage = RequiredFieldValidator()(form.dosage);
         if (form.is_prn)
           errors.indicator = RequiredFieldValidator()(form.indicator);
@@ -54,13 +54,10 @@ export default function CreatePrescriptionForm(props: {
     >
       {(field) => (
         <>
-          <AutocompleteFormField
+          <MedibaseAutocompleteFormField
             label={t("medicine")}
-            {...field("medicine", RequiredFieldValidator())}
+            {...field("medicine_object", RequiredFieldValidator())}
             required
-            options={medicines}
-            optionLabel={(medicine) => medicine}
-            optionValue={(medicine) => medicine}
           />
           <div className="flex gap-4 items-center">
             <SelectFormField
diff --git a/src/Components/Medicine/MedibaseAutocompleteFormField.tsx b/src/Components/Medicine/MedibaseAutocompleteFormField.tsx
new file mode 100644
index 00000000000..62d0d3fff29
--- /dev/null
+++ b/src/Components/Medicine/MedibaseAutocompleteFormField.tsx
@@ -0,0 +1,71 @@
+import { useAsyncOptions } from "../../Common/hooks/useAsyncOptions";
+import { listMedibaseMedicines } from "../../Redux/actions";
+import { Autocomplete } from "../Form/FormFields/Autocomplete";
+import FormField from "../Form/FormFields/FormField";
+import {
+  FormFieldBaseProps,
+  useFormFieldPropsResolver,
+} from "../Form/FormFields/Utils";
+import { MedibaseMedicine } from "./models";
+
+export default function MedibaseAutocompleteFormField(
+  props: FormFieldBaseProps<MedibaseMedicine>
+) {
+  const field = useFormFieldPropsResolver(props);
+  const { isLoading, options, fetchOptions } =
+    useAsyncOptions<MedibaseMedicine>("id");
+
+  return (
+    <FormField field={field}>
+      <Autocomplete
+        id={field.id}
+        disabled={field.disabled}
+        value={field.value}
+        required
+        onChange={field.handleChange}
+        options={options(field.value && [field.value])}
+        optionLabel={(option) => option.name.toUpperCase()}
+        optionDescription={(option) => <OptionDescription medicine={option} />}
+        optionValue={(option) => option}
+        optionIcon={(option) =>
+          option.type === "brand" ? (
+            <OptionChip name="Brand" value={option.company || ""} />
+          ) : (
+            <OptionChip value={option.type} />
+          )
+        }
+        onQuery={(query) => fetchOptions(listMedibaseMedicines(query))}
+        isLoading={isLoading}
+      />
+    </FormField>
+  );
+}
+
+const OptionDescription = ({ medicine }: { medicine: MedibaseMedicine }) => {
+  return (
+    <div className="p-1">
+      {medicine.atc_classification && (
+        <span className="text-xs">
+          ATC Class: {medicine.atc_classification}
+        </span>
+      )}
+      <div className="mt-2 flex flex-wrap w-full gap-2">
+        <OptionChip name="CIMS Class" value={medicine.cims_class} />
+        {medicine.generic && (
+          <OptionChip name="Generic" value={medicine.generic} />
+        )}
+      </div>
+    </div>
+  );
+};
+
+const OptionChip = (props: { name?: string; value: string }) => {
+  return (
+    <div className="flex gap-1 px-2 mt-1 sm:mt-0 uppercase text-center bg-secondary-100 h-fit max-w-fit rounded-full text-xs border border-secondary-400 whitespace-nowrap">
+      <span className="text-gray-800 font-normal">
+        {props.name && props.name + ":"}
+      </span>
+      <span className="text-gray-900 font-medium">{props.value}</span>
+    </div>
+  );
+};
diff --git a/src/Components/Medicine/MedicineAdministrationsTable.tsx b/src/Components/Medicine/MedicineAdministrationsTable.tsx
index 718f9d037dd..75233639bc4 100644
--- a/src/Components/Medicine/MedicineAdministrationsTable.tsx
+++ b/src/Components/Medicine/MedicineAdministrationsTable.tsx
@@ -59,7 +59,9 @@ export default function MedicineAdministrationsTable({
               list={
                 items?.map((obj) => ({
                   ...obj,
-                  medicine: obj.prescription?.medicine,
+                  medicine:
+                    obj.prescription?.medicine_object?.name ??
+                    obj.prescription?.medicine_old,
                   created_date__pretty: (
                     <span className="flex gap-1">
                       <RecordMeta time={obj.created_date} /> by{" "}
diff --git a/src/Components/Medicine/PrescriptionDetailCard.tsx b/src/Components/Medicine/PrescriptionDetailCard.tsx
index d6be22ad1c1..aa1c1ba643d 100644
--- a/src/Components/Medicine/PrescriptionDetailCard.tsx
+++ b/src/Components/Medicine/PrescriptionDetailCard.tsx
@@ -85,7 +85,7 @@ export default function PrescriptionDetailCard({
 
         <div className="grid grid-cols-9 gap-2 items-center mt-2">
           <Detail className="col-span-9 md:col-span-5" label={t("medicine")}>
-            {prescription.medicine}
+            {prescription.medicine_object?.name ?? prescription.medicine_old}
           </Detail>
           <Detail className="col-span-5 md:col-span-2" label={t("route")}>
             {prescription.route &&
diff --git a/src/Components/Medicine/PrescriptionsTable.tsx b/src/Components/Medicine/PrescriptionsTable.tsx
index 7b6272675b9..42908847eda 100644
--- a/src/Components/Medicine/PrescriptionsTable.tsx
+++ b/src/Components/Medicine/PrescriptionsTable.tsx
@@ -200,6 +200,7 @@ export default function PrescriptionsTable({
               list={
                 prescriptions?.map((obj) => ({
                   ...obj,
+                  medicine: obj.medicine_object?.name ?? obj.medicine_old,
                   route__pretty:
                     obj.route && t("PRESCRIPTION_ROUTE_" + obj.route),
                   frequency__pretty:
diff --git a/src/Components/Medicine/models.ts b/src/Components/Medicine/models.ts
index 2f02e6a84b2..21c52b4a6ec 100644
--- a/src/Components/Medicine/models.ts
+++ b/src/Components/Medicine/models.ts
@@ -2,7 +2,9 @@ import { PerformedByModel } from "../HCX/misc";
 
 interface BasePrescription {
   readonly id?: string;
-  medicine: string;
+  medicine?: string;
+  medicine_object?: MedibaseMedicine;
+  medicine_old?: string;
   route?: "ORAL" | "IV" | "IM" | "SC";
   dosage: string;
   notes?: string;
@@ -56,3 +58,14 @@ export type MedicineAdministrationRecord = {
   readonly created_date?: string;
   readonly modified_date?: string;
 };
+
+export type MedibaseMedicine = {
+  id: string;
+  name: string;
+  type: "brand" | "generic";
+  company?: string;
+  contents: string;
+  cims_class: string;
+  atc_classification?: string;
+  generic?: string;
+};
diff --git a/src/Components/Notifications/ShowPushNotification.tsx b/src/Components/Notifications/ShowPushNotification.tsx
index 2352b9ccdd9..616ebb5ef2b 100644
--- a/src/Components/Notifications/ShowPushNotification.tsx
+++ b/src/Components/Notifications/ShowPushNotification.tsx
@@ -1,13 +1,11 @@
-import React, { useState } from "react";
+import React from "react";
 import { useDispatch } from "react-redux";
 import { getNotificationData } from "../../Redux/actions";
 
 export default function ShowPushNotification({ external_id }: any) {
-  const [isLoading, setIsLoading] = useState(true);
   const dispatch: any = useDispatch();
 
-  let resultUrl = async () => {
-    setIsLoading(true);
+  const resultUrl = async () => {
     console.log("ID:", external_id.id);
     const res = await dispatch(getNotificationData({ id: external_id.id }));
     const data = res.data.caused_objects;
@@ -27,7 +25,7 @@ export default function ShowPushNotification({ external_id }: any) {
       case "INVESTIGATION_SESSION_CREATED":
         return `/facility/${data.facility}/patient/${data.patient}/consultation/${data.consultation}/investigation/${data.session}`;
       case "MESSAGE":
-        return `/notice_board/`;
+        return "/notice_board/";
       default:
         return "#";
     }
@@ -35,7 +33,6 @@ export default function ShowPushNotification({ external_id }: any) {
 
   resultUrl()
     .then((url) => {
-      setIsLoading(false);
       window.location.href = url;
     })
     .catch((err) => console.log(err));
diff --git a/src/Components/Patient/DailyRoundListDetails.tsx b/src/Components/Patient/DailyRoundListDetails.tsx
index 8e355f7b313..486544e0fb8 100644
--- a/src/Components/Patient/DailyRoundListDetails.tsx
+++ b/src/Components/Patient/DailyRoundListDetails.tsx
@@ -45,10 +45,7 @@ export const DailyRoundListDetails = (props: any) => {
               ? currentHealth.desc
               : res.data.current_health,
           };
-          if (
-            res.data.additional_symptoms &&
-            res.data.additional_symptoms.length
-          ) {
+          if (res.data.additional_symptoms?.length) {
             const symptoms = res.data.additional_symptoms.map(
               (symptom: number) => {
                 const option = symptomChoices.find((i) => i.id === symptom);
@@ -87,7 +84,7 @@ export const DailyRoundListDetails = (props: any) => {
               <span className="font-semibold leading-relaxed">
                 Patient Category:{" "}
               </span>
-              {dailyRoundListDetailsData.patient_category || "-"}
+              {dailyRoundListDetailsData.patient_category ?? "-"}
             </div>
           </div>
 
@@ -105,7 +102,7 @@ export const DailyRoundListDetails = (props: any) => {
         <div className="mt-4 grid gap-4 grid-cols-1 md:grid-cols-2">
           <div>
             <span className="font-semibold leading-relaxed">Temperature: </span>
-            {dailyRoundListDetailsData.temperature || "-"}
+            {dailyRoundListDetailsData.temperature ?? "-"}
           </div>
           <div>
             <span className="font-semibold leading-relaxed">Taken at: </span>
@@ -115,41 +112,41 @@ export const DailyRoundListDetails = (props: any) => {
           </div>
           <div>
             <span className="font-semibold leading-relaxed">SpO2: </span>
-            {dailyRoundListDetailsData.ventilator_spo2 || "-"}
+            {dailyRoundListDetailsData.ventilator_spo2 ?? "-"}
           </div>
           <div className="md:col-span-2 capitalize">
             <span className="font-semibold leading-relaxed">
               Additional Symptoms:{" "}
             </span>
-            {dailyRoundListDetailsData.additional_symptoms_text || "-"}
+            {dailyRoundListDetailsData.additional_symptoms_text ?? "-"}
           </div>
           <div className="md:col-span-2 capitalize">
             <span className="font-semibold leading-relaxed">
               Admitted To *:{" "}
             </span>
-            {dailyRoundListDetailsData.admitted_to || "-"}
+            {dailyRoundListDetailsData.admitted_to ?? "-"}
           </div>
           <div className="md:col-span-2">
             <span className="font-semibold leading-relaxed">
               Physical Examination Info:{" "}
             </span>
-            {dailyRoundListDetailsData.physical_examination_info || "-"}
+            {dailyRoundListDetailsData.physical_examination_info ?? "-"}
           </div>
           <div className="md:col-span-2">
             <span className="font-semibold leading-relaxed">
               Other Symptoms:{" "}
             </span>
-            {dailyRoundListDetailsData.other_symptoms || "-"}
+            {dailyRoundListDetailsData.other_symptoms ?? "-"}
           </div>
           <div className="md:col-span-2">
             <span className="font-semibold leading-relaxed">
               Other Details:{" "}
             </span>
-            {dailyRoundListDetailsData.other_details || "-"}
+            {dailyRoundListDetailsData.other_details ?? "-"}
           </div>
           <div className="md:col-span-2">
             <span className="font-semibold leading-relaxed">Pulse(bpm): </span>
-            {dailyRoundListDetailsData.pulse || "-"}
+            {dailyRoundListDetailsData.pulse ?? "-"}
           </div>
           <div className="md:col-span-2 ">
             <span className="font-semibold leading-relaxed">BP</span>
@@ -158,14 +155,14 @@ export const DailyRoundListDetails = (props: any) => {
                 <span className="font-semibold leading-relaxed">
                   Systolic:{" "}
                 </span>
-                {dailyRoundListDetailsData.bp?.systolic || "-"}
+                {dailyRoundListDetailsData.bp?.systolic ?? "-"}
               </div>
               <div className="flex">
                 {" "}
                 <span className="font-semibold leading-relaxed">
                   Diastolic:
                 </span>
-                {dailyRoundListDetailsData.bp?.diastolic || "-"}
+                {dailyRoundListDetailsData.bp?.diastolic ?? "-"}
               </div>
             </div>
           </div>
@@ -175,17 +172,17 @@ export const DailyRoundListDetails = (props: any) => {
               Respiratory Rate (bpm):
             </span>
 
-            {dailyRoundListDetailsData.resp || "-"}
+            {dailyRoundListDetailsData.resp ?? "-"}
           </div>
           <div className="md:col-span-2">
             <span className="font-semibold leading-relaxed">Rhythm: </span>
-            {dailyRoundListDetailsData.rhythm || "-"}
+            {dailyRoundListDetailsData.rhythm ?? "-"}
           </div>
           <div className="md:col-span-2">
             <span className="font-semibold leading-relaxed">
               Rhythm Description:{" "}
             </span>
-            {dailyRoundListDetailsData.rhythm_detail || "-"}
+            {dailyRoundListDetailsData.rhythm_detail ?? "-"}
           </div>
           <div>
             <span className="font-semibold leading-relaxed">
diff --git a/src/Components/Patient/PatientInfoCard.tsx b/src/Components/Patient/PatientInfoCard.tsx
index 2077a2de5e9..3e2db9b2b7d 100644
--- a/src/Components/Patient/PatientInfoCard.tsx
+++ b/src/Components/Patient/PatientInfoCard.tsx
@@ -57,7 +57,7 @@ export default function PatientInfoCard(props: {
             facilityId={patient?.facility}
             patientId={patient?.id}
             discharged={!!consultation?.discharge_date}
-            consultationId={consultation?.id}
+            consultationId={consultation?.id ?? ""}
             setState={setOpen}
             fetchPatientData={props.fetchPatientData}
             smallLoader
@@ -74,8 +74,7 @@ export default function PatientInfoCard(props: {
             <div
               className={`w-24 h-24 min-w-[5rem] bg-gray-200 ${categoryClass}-profile`}
             >
-              {consultation &&
-              consultation?.current_bed &&
+              {consultation?.current_bed &&
               consultation?.discharge_date === null ? (
                 <div
                   className="flex flex-col items-center justify-center h-full"
@@ -185,7 +184,7 @@ export default function PatientInfoCard(props: {
                     (resp) =>
                       resp.text ===
                       consultation?.last_daily_round?.ventilator_interface
-                  )?.id || "UNKNOWN",
+                  )?.id ?? "UNKNOWN",
                   consultation?.last_daily_round?.ventilator_interface,
                 ],
               ].map((stat, i) => {
@@ -279,7 +278,7 @@ export default function PatientInfoCard(props: {
                 !consultation?.discharge_date,
               [
                 !(consultation?.facility !== patient.facility) &&
-                  !(consultation?.discharge_date || !patient.is_active) &&
+                  !(consultation?.discharge_date ?? !patient.is_active) &&
                   moment(consultation?.modified_date).isBefore(
                     new Date().getTime() - 24 * 60 * 60 * 1000
                   ),
@@ -320,7 +319,7 @@ export default function PatientInfoCard(props: {
                   <div className="relative" key={i}>
                     <ButtonV2
                       key={i}
-                      variant={action[4] && action[4][0] ? "danger" : "primary"}
+                      variant={action?.[4]?.[0] ? "danger" : "primary"}
                       href={
                         consultation?.admitted &&
                         !consultation?.current_bed &&
diff --git a/src/Components/Patient/PatientRegister.tsx b/src/Components/Patient/PatientRegister.tsx
index 7fec6b87519..ab73f52739b 100644
--- a/src/Components/Patient/PatientRegister.tsx
+++ b/src/Components/Patient/PatientRegister.tsx
@@ -285,7 +285,7 @@ export const PatientRegister = (props: PatientRegisterProps) => {
     if (!careExtId) return;
     const res = await dispatchAction(externalResult({ id: careExtId }));
 
-    if (res && res.data) {
+    if (res?.data) {
       const form = { ...state.form };
       form["name"] = res.data.name ? res.data.name : state.form.name;
       form["address"] = res.data.address
@@ -451,7 +451,7 @@ export const PatientRegister = (props: PatientRegisterProps) => {
       const res = await dispatchAction(
         HCXActions.policies.list({ patient: id })
       );
-      if (res && res.data) {
+      if (res?.data) {
         setInsuranceDetails(res.data.results);
       }
     };
@@ -846,7 +846,7 @@ export const PatientRegister = (props: PatientRegisterProps) => {
           phone_number: parsePhoneNumberFromString(phoneNo)?.format("E.164"),
         };
         const res = await dispatchAction(searchPatient(query));
-        if (res && res.data && res.data.results) {
+        if (res?.data?.results) {
           const duplicateList = !id
             ? res.data.results
             : res.data.results.filter(
diff --git a/src/Components/Patient/SamplePreview.tsx b/src/Components/Patient/SamplePreview.tsx
index 480e2f1b7da..cf1edb0d87c 100644
--- a/src/Components/Patient/SamplePreview.tsx
+++ b/src/Components/Patient/SamplePreview.tsx
@@ -7,7 +7,6 @@ import Page from "../Common/components/Page";
 import { SampleReportModel } from "./models";
 import loadable from "@loadable/component";
 import { sampleReport } from "../../Redux/actions";
-import useConfig from "../../Common/hooks/useConfig";
 import { useDispatch } from "react-redux";
 
 const Loading = loadable(() => import("../Common/Loading"));
@@ -61,7 +60,6 @@ export default function SampleReport(props: ISamplePreviewProps) {
   const { id, sampleId } = props;
   const [isLoading, setIsLoading] = useState(false);
   const [sampleData, setSampleData] = useState<SampleReportModel>({});
-  const { static_ohc_green_logo } = useConfig();
 
   let report: JSX.Element = <></>;
   let reportData: JSX.Element = <></>;
@@ -103,7 +101,7 @@ export default function SampleReport(props: ISamplePreviewProps) {
               <div className="flex justify-end">
                 <div className="p-2">
                   <img
-                    src={static_ohc_green_logo}
+                    src="https://cdn.coronasafe.network/ohc_logo_green.png"
                     className="max-w-[400px] h-[50px] object-contain"
                     alt="Open HealthCare Network"
                   />
diff --git a/src/Components/Patient/models.tsx b/src/Components/Patient/models.tsx
index d8e624fe543..d0b75e43bb4 100644
--- a/src/Components/Patient/models.tsx
+++ b/src/Components/Patient/models.tsx
@@ -249,6 +249,11 @@ export interface SampleListModel {
   fast_track?: string;
 }
 
+export interface DailyRoundsOutput {
+  name: string;
+  quantity: number;
+}
+
 export interface DailyRoundsModel {
   ventilator_spo2?: number;
   spo2?: string;
@@ -274,6 +279,7 @@ export interface DailyRoundsModel {
   other_symptoms?: string;
   admitted_to?: string;
   patient_category?: PatientCategory;
+  output?: DailyRoundsOutput;
   recommend_discharge?: boolean;
   created_date?: string;
   modified_date?: string;
diff --git a/src/Components/Resource/ResourceDetailsUpdate.tsx b/src/Components/Resource/ResourceDetailsUpdate.tsx
index a6ae7261aaa..d090a350cc0 100644
--- a/src/Components/Resource/ResourceDetailsUpdate.tsx
+++ b/src/Components/Resource/ResourceDetailsUpdate.tsx
@@ -217,12 +217,11 @@ export const ResourceDetailsUpdate = (props: resourceProps) => {
   }
 
   return (
-
-    <Page 
-    title="Update Resource Request"
-    backUrl={`/resource/${props.id}`}
-    crumbsReplacements={{ [props.id]: { name: requestTitle } }}>
-    
+    <Page
+      title="Update Resource Request"
+      backUrl={`/resource/${props.id}`}
+      crumbsReplacements={{ [props.id]: { name: requestTitle } }}
+    >
       <div className="mt-4">
         <Card className="w-full flex flex-col">
           <div className="grid gap-4 grid-cols-1 md:grid-cols-2">
@@ -242,12 +241,12 @@ export const ResourceDetailsUpdate = (props: resourceProps) => {
                   <CircularProgress />
                 ) : (
                   <UserAutocompleteFormField
-                      label="Assigned To"
-                      value = {assignedUser===null?undefined:assignedUser}
-                      onChange={handleOnSelect}
-                      error=""
-                      name="assigned_to"
-                      />
+                    label="Assigned To"
+                    value={assignedUser === null ? undefined : assignedUser}
+                    onChange={handleOnSelect}
+                    error=""
+                    name="assigned_to"
+                  />
                 )}
               </div>
             </div>
@@ -332,10 +331,9 @@ export const ResourceDetailsUpdate = (props: resourceProps) => {
                 options={[true, false]}
                 optionDisplay={(o) => (o ? "Yes" : "No")}
                 optionValue={(o) => String(o)}
-                value={state.form.emergency}
+                value={String(state.form.emergency)}
                 error={state.errors.emergency}
               />
-
             </div>
 
             <div className="md:col-span-2 flex flex-col md:flex-row gap-2 justify-between mt-4">
diff --git a/src/Components/Shifting/BadgesList.tsx b/src/Components/Shifting/BadgesList.tsx
index 748fb15316c..38ce8434945 100644
--- a/src/Components/Shifting/BadgesList.tsx
+++ b/src/Components/Shifting/BadgesList.tsx
@@ -22,7 +22,9 @@ export default function BadgesList(props: any) {
   useEffect(() => {
     async function fetchData() {
       if (!qParams.assigned_to) return setAssignedUsername("");
-      const res = await dispatch(getUserList({ id: qParams.assigned_to }));
+      const res = await dispatch(
+        getUserList({ id: qParams.assigned_to }, "assigned_user_name")
+      );
       const { first_name, last_name } = res?.data?.results[0];
       setAssignedUsername(`${first_name} ${last_name}`);
     }
@@ -77,19 +79,12 @@ export default function BadgesList(props: any) {
 
   return (
     <FilterBadges
-      badges={({
-        badge,
-        boolean,
-        phoneNumber,
-        dateRange,
-        kasp,
-        value,
-      }: any) => [
+      badges={({ badge, phoneNumber, dateRange, kasp, value }: any) => [
         badge(t("status"), "status"),
-        boolean(t("emergency"), "emergency", booleanFilterOptions),
+        badge(t("emergency"), "emergency", booleanFilterOptions),
         kasp(),
-        boolean(t("up_shift"), "is_up_shift", booleanFilterOptions),
-        boolean(t("antenatal"), "is_antenatal", booleanFilterOptions),
+        badge(t("up_shift"), "is_up_shift", booleanFilterOptions),
+        badge(t("antenatal"), "is_antenatal", booleanFilterOptions),
         phoneNumber(t("phone_no"), "patient_phone_number"),
         badge(t("patient_name"), "patient_name"),
         ...dateRange(t("created"), "created_date"),
diff --git a/src/Components/Shifting/ShiftDetails.tsx b/src/Components/Shifting/ShiftDetails.tsx
index dbc51218b4b..51c1b326422 100644
--- a/src/Components/Shifting/ShiftDetails.tsx
+++ b/src/Components/Shifting/ShiftDetails.tsx
@@ -27,12 +27,8 @@ import { useTranslation } from "react-i18next";
 const Loading = loadable(() => import("../Common/Loading"));
 
 export default function ShiftDetails(props: { id: string }) {
-  const {
-    static_header_logo,
-    kasp_full_string,
-    wartime_shifting,
-    kasp_enabled,
-  } = useConfig();
+  const { header_logo, kasp_full_string, wartime_shifting, kasp_enabled } =
+    useConfig();
   const dispatch: any = useDispatch();
   const initialData: any = {};
   const [data, setData] = useState(initialData);
@@ -344,7 +340,7 @@ export default function ShiftDetails(props: { id: string }) {
 
     return (
       <div id="section-to-print" className="print bg-white ">
-        <div>{data.is_kasp && <img alt="logo" src={static_header_logo} />}</div>
+        <div>{data.is_kasp && <img alt="logo" src={header_logo.dark} />}</div>
         <div className="mx-2">
           <div className="mt-6">
             <span className="font-semibold leading-relaxed mt-4">
diff --git a/src/Components/Users/ManageUsers.tsx b/src/Components/Users/ManageUsers.tsx
index fb79ca6b7f2..d3e055d0700 100644
--- a/src/Components/Users/ManageUsers.tsx
+++ b/src/Components/Users/ManageUsers.tsx
@@ -413,11 +413,7 @@ export default function ManageUsers() {
   }
 
   return (
-    <Page
-      title="User Management"
-      hideBack={true}
-      breadcrumbs={false}
-    >
+    <Page title="User Management" hideBack={true} breadcrumbs={false}>
       {expandSkillList && (
         <SkillsSlideOver
           show={expandSkillList}
diff --git a/src/Components/Users/UserAdd.tsx b/src/Components/Users/UserAdd.tsx
index dfa0c0e8f93..edb1f61a0bd 100644
--- a/src/Components/Users/UserAdd.tsx
+++ b/src/Components/Users/UserAdd.tsx
@@ -59,7 +59,7 @@ type UserForm = {
   gender: string;
   password: string;
   c_password: string;
-  facilities: Array<FacilityModel>;
+  facilities: Array<number>;
   home_facility: FacilityModel | null;
   username: string;
   first_name: string;
@@ -120,7 +120,7 @@ const user_create_reducer = (state = initialState, action: any) => {
         form: action.form,
       };
     }
-    case "set_error": {
+    case "set_errors": {
       return {
         ...state,
         errors: action.errors,
@@ -163,7 +163,7 @@ export const UserAdd = (props: UserProps) => {
   const dispatchAction: any = useDispatch();
   const { userId } = props;
 
-  const [state, dispatch] = useAutoSaveReducer(
+  const [state, dispatch] = useAutoSaveReducer<UserForm>(
     user_create_reducer,
     initialState
   );
@@ -384,7 +384,7 @@ export const UserAdd = (props: UserProps) => {
     setSelectedFacility(selected as FacilityModel[]);
     const form = { ...state.form };
     form.facilities = selected
-      ? (selected as FacilityModel[]).map((i) => i.id)
+      ? (selected as FacilityModel[]).map((i) => i.id ?? -1)
       : [];
     dispatch({ type: "set_form", form });
   };
@@ -531,7 +531,7 @@ export const UserAdd = (props: UserProps) => {
           }
           return;
         case "district":
-          if (!Number(state.form[field]) || state.form[field] === "") {
+          if (!Number(state.form[field])) {
             errors[field] = "Please select the district";
             invalidForm = true;
           }
@@ -548,10 +548,10 @@ export const UserAdd = (props: UserProps) => {
       }
     });
     if (invalidForm) {
-      dispatch({ type: "set_error", errors });
+      dispatch({ type: "set_errors", errors });
       return false;
     }
-    dispatch({ type: "set_error", errors });
+    dispatch({ type: "set_errors", errors });
     return true;
   };
 
@@ -581,7 +581,7 @@ export const UserAdd = (props: UserProps) => {
             state.form.phone_number_is_whatsapp
               ? state.form.phone_number
               : state.form.alt_phone_number
-          )?.format("E.164") || "",
+          )?.format("E.164") ?? "",
         date_of_birth: moment(state.form.date_of_birth).format("YYYY-MM-DD"),
         age: Number(moment().diff(state.form.date_of_birth, "years", false)),
         doctor_qualification:
@@ -601,14 +601,12 @@ export const UserAdd = (props: UserProps) => {
       };
 
       const res = await dispatchAction(addUser(data));
-      // userId ? updateUser(userId, data) : addUser(data)
       if (
         res &&
         (res.data || res.data === "") &&
         res.status >= 200 &&
         res.status < 300
       ) {
-        // const id = res.data.id;
         dispatch({ type: "set_form", form: initForm });
         if (!userId) {
           Notification.Success({
@@ -678,9 +676,7 @@ export const UserAdd = (props: UserProps) => {
               required
               label="User Type"
               options={userTypes}
-              optionLabel={(o) =>
-                o.role + ((o.readOnly && " (Read Only)") || "")
-              }
+              optionLabel={(o) => o.role + (o.readOnly ? " (Read Only)" : "")}
               optionValue={(o) => o.id}
             />
 
@@ -714,7 +710,7 @@ export const UserAdd = (props: UserProps) => {
             <SelectFormField
               {...field("home_facility")}
               label="Home facility"
-              options={selectedFacility || []}
+              options={selectedFacility ?? []}
               optionLabel={(option) => option.name}
               optionValue={(option) => option.id}
               onChange={handleFieldChange}
diff --git a/src/Components/Users/UserFilter.tsx b/src/Components/Users/UserFilter.tsx
index da93cc37179..b8884b314d5 100644
--- a/src/Components/Users/UserFilter.tsx
+++ b/src/Components/Users/UserFilter.tsx
@@ -14,7 +14,9 @@ import FiltersSlideover from "../../CAREUI/interactive/FiltersSlideover";
 
 const parsePhoneNumberForFilterParam = (phoneNumber: string) => {
   if (!phoneNumber) return "";
-  return parsePhoneNumberFromString(phoneNumber)?.format("E.164") || "";
+  if (phoneNumber.startsWith("+"))
+    return parsePhoneNumberFromString(phoneNumber)?.format("E.164") || "";
+  return phoneNumber;
 };
 
 export default function UserFilter(props: any) {
diff --git a/src/Locale/update_locale.js b/src/Locale/update_locale.js
index 319cca6bf95..b6c0b17c5e3 100644
--- a/src/Locale/update_locale.js
+++ b/src/Locale/update_locale.js
@@ -1,6 +1,12 @@
 /* eslint-disable no-undef */
 
-const fs = require("fs");
+import {
+  existsSync,
+  mkdirSync,
+  readdirSync,
+  writeFileSync,
+  readFileSync,
+} from "fs";
 
 const DEFAULT_LOCALE = "en";
 
@@ -18,11 +24,11 @@ if (lng === DEFAULT_LOCALE) {
 const defaultEntryFile = readFile(`./${DEFAULT_LOCALE}/index.js`);
 const defaultAllJsonFiles = getAllJSONFiles(DEFAULT_LOCALE);
 
-if (fs.existsSync(lng)) {
+if (existsSync(lng)) {
   const allJsonFiles = getAllJSONFiles(lng);
   compareBothFiles(defaultAllJsonFiles, allJsonFiles);
 } else {
-  fs.mkdirSync(`./${lng}`);
+  mkdirSync(`./${lng}`);
 
   for (const file in defaultAllJsonFiles) {
     const defaultJSON = defaultAllJsonFiles[file];
@@ -51,7 +57,7 @@ function compareBothFiles(defaultFile, newFile) {
 }
 
 function getAllJSONFiles(folderName) {
-  const dir = fs.readdirSync(folderName).filter((e) => e.includes(".json"));
+  const dir = readdirSync(folderName).filter((e) => e.includes(".json"));
   const files = {};
   dir.forEach((file) => {
     try {
@@ -64,8 +70,8 @@ function getAllJSONFiles(folderName) {
 }
 
 function writeFile(name, data) {
-  return fs.writeFileSync(name, data);
+  return writeFileSync(name, data);
 }
 function readFile(name) {
-  return fs.readFileSync(name, { encoding: "utf-8" });
+  return readFileSync(name, { encoding: "utf-8" });
 }
diff --git a/src/Redux/actions.tsx b/src/Redux/actions.tsx
index 0a80040dc72..06c92e6662d 100644
--- a/src/Redux/actions.tsx
+++ b/src/Redux/actions.tsx
@@ -65,8 +65,8 @@ export const deleteFacility = (id: string) => {
 export const deleteFacilityCoverImage = (id: string) => {
   return fireRequest("deleteFacilityCoverImage", [], {}, { id });
 };
-export const getUserList = (params: object) => {
-  return fireRequest("userList", [], params);
+export const getUserList = (params: object, key?: string) => {
+  return fireRequest("userList", [], params, null, key);
 };
 
 export const getUserListSkills = (pathParam: object) => {
@@ -290,7 +290,7 @@ export const listConsultationBeds = (params: object) =>
   fireRequest("listConsultationBeds", [], params, {});
 export const createConsultationBed = (
   params: object,
-  consultation_id: number,
+  consultation_id: string,
   bed_id: string
 ) =>
   fireRequest(
@@ -800,6 +800,10 @@ export const editInvestigation = (
 export const listICD11Diagnosis = (params: object, key: string) => {
   return fireRequest("listICD11Diagnosis", [], params, null, key);
 };
+// Medibase
+export const listMedibaseMedicines = (query: string) => {
+  return fireRequest("listMedibaseMedicines", [], { query });
+};
 
 // Resource
 export const createResource = (params: object) => {
@@ -851,6 +855,11 @@ export const listAssetTransaction = (params: object) =>
 export const getAssetTransaction = (id: string) =>
   fireRequest("getAssetTransaction", [], {}, { id });
 
+export const listAssetAvailability = (params: object) =>
+  fireRequest("listAssetAvailability", [], params);
+export const getAssetAvailability = (id: string) =>
+  fireRequest("getAssetAvailability", [], {}, { id });
+
 export const listPMJYPackages = (query?: string) =>
   fireRequest("listPMJYPackages", [], { query });
 
diff --git a/src/Redux/api.tsx b/src/Redux/api.tsx
index 3918fabe0da..ddda010630b 100644
--- a/src/Redux/api.tsx
+++ b/src/Redux/api.tsx
@@ -733,6 +733,10 @@ const routes: Routes = {
   listICD11Diagnosis: {
     path: "/api/v1/icd/",
   },
+  // Medibase
+  listMedibaseMedicines: {
+    path: "/api/v1/medibase/",
+  },
 
   // Resource
   createResource: {
@@ -813,6 +817,17 @@ const routes: Routes = {
     method: "GET",
   },
 
+  // Asset Availability endpoints
+
+  listAssetAvailability: {
+    path: "/api/v1/asset_availability/",
+    method: "GET",
+  },
+  getAssetAvailability: {
+    path: "/api/v1/asset_availability/{id}",
+    method: "GET",
+  },
+
   // Prescription endpoints
 
   listPrescriptions: {
diff --git a/src/Router/AppRouter.tsx b/src/Router/AppRouter.tsx
index cbd9bff1738..6e07ae2da76 100644
--- a/src/Router/AppRouter.tsx
+++ b/src/Router/AppRouter.tsx
@@ -76,7 +76,7 @@ import ManagePrescriptions from "../Components/Medicine/ManagePrescriptions";
 import CentralNursingStation from "../Components/Facility/CentralNursingStation";
 
 export default function AppRouter() {
-  const { static_black_logo, enable_hcx } = useConfig();
+  const { main_logo, enable_hcx } = useConfig();
 
   const routes = {
     "/hub": () => <HubDashboard />,
@@ -486,7 +486,7 @@ export default function AppRouter() {
             >
               <img
                 className="h-6 w-auto"
-                src={static_black_logo}
+                src={main_logo.dark}
                 alt="care logo"
               />
             </a>
diff --git a/src/style/CAREUI.css b/src/style/CAREUI.css
index ba57bbb502e..b61a52e3fc5 100644
--- a/src/style/CAREUI.css
+++ b/src/style/CAREUI.css
@@ -25,7 +25,7 @@
 }
 
 .cui-dropdown-base {
-    @apply z-40 w-full rounded-md xl:rounded-lg shadow-lg overflow-auto max-h-96 bg-gray-100 divide-y divide-gray-300 ring-1 ring-gray-400 focus:outline-none
+    @apply z-40 w-full rounded-b-md xl:rounded-lg shadow-lg overflow-auto max-h-96 bg-gray-100 divide-y divide-gray-300 ring-1 ring-gray-400 focus:outline-none
 }
 
 .cui-card {

From 91561153a97b21454d5cb85efa0854a8506f75d0 Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Fri, 21 Jul 2023 10:31:00 +0530
Subject: [PATCH 07/17] added doctor location

---
 src/Components/Facility/PatientNoteCard.tsx  | 14 ++++----------
 src/Components/Facility/PatientNotesList.tsx |  8 ++------
 2 files changed, 6 insertions(+), 16 deletions(-)

diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index 8029ec915c1..e3e9234afd3 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -1,12 +1,6 @@
 import { relativeDate, formatDate } from "../../Utils/utils";
 
-const PatientNoteCard = ({
-  note,
-  facilityId,
-}: {
-  note: any;
-  facilityId: any;
-}) => {
+const PatientNoteCard = ({ note }: { note: any }) => {
   return (
     <div
       key={note.id}
@@ -19,9 +13,9 @@ const PatientNoteCard = ({
         </span>
         <span className="text-gray-700 text-sm">
           {note.created_by_object.user_type === "Doctor"
-            ? note.created_by_object.home_facility !== facilityId
-              ? "Remote Specialist"
-              : ""
+            ? note.created_by_local_user
+              ? ""
+              : "Remote Specialist"
             : note.created_by_object.user_type}
         </span>
       </div>
diff --git a/src/Components/Facility/PatientNotesList.tsx b/src/Components/Facility/PatientNotesList.tsx
index 69dda827f4c..92dacb16958 100644
--- a/src/Components/Facility/PatientNotesList.tsx
+++ b/src/Components/Facility/PatientNotesList.tsx
@@ -17,7 +17,7 @@ interface PatientNotesProps {
 const pageSize = RESULTS_PER_PAGE_LIMIT;
 
 const PatientNotesList = (props: PatientNotesProps) => {
-  const { facilityId, reload, setReload } = props;
+  const { reload, setReload } = props;
 
   const dispatch: any = useDispatch();
   const initialData: any = { notes: [], cPage: 1, totalPages: 1 };
@@ -105,11 +105,7 @@ const PatientNotesList = (props: PatientNotesProps) => {
           scrollableTarget="patient-notes-list"
         >
           {state.notes.map((note: any) => (
-            <PatientNoteCard
-              note={note}
-              key={note.id}
-              facilityId={facilityId}
-            />
+            <PatientNoteCard note={note} key={note.id} />
           ))}
         </InfiniteScroll>
       ) : (

From 746f19e0b2b6980d4833e462a94ab1aa912ae8ae Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Fri, 21 Jul 2023 12:18:31 +0530
Subject: [PATCH 08/17] used Page component in PatientNotes page

---
 src/Components/Patient/PatientNotes.tsx | 26 ++++++++++++-------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/src/Components/Patient/PatientNotes.tsx b/src/Components/Patient/PatientNotes.tsx
index f5d09c80473..3b67cc87b84 100644
--- a/src/Components/Patient/PatientNotes.tsx
+++ b/src/Components/Patient/PatientNotes.tsx
@@ -2,12 +2,12 @@ import { useState, useEffect } from "react";
 import { useDispatch } from "react-redux";
 import { addPatientNote, getPatient } from "../../Redux/actions";
 import * as Notification from "../../Utils/Notifications.js";
-import PageTitle from "../Common/PageTitle";
 import CareIcon from "../../CAREUI/icons/CareIcon";
 import TextFormField from "../Form/FormFields/TextFormField";
 import ButtonV2 from "../Common/components/ButtonV2";
 import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
 import PatientNotesList from "../Facility/PatientNotesList";
+import Page from "../Common/components/Page";
 
 interface PatientNotesProps {
   patientId: any;
@@ -57,18 +57,16 @@ const PatientNotes = (props: PatientNotesProps) => {
   }, [dispatch, patientId]);
 
   return (
-    <div className="w-full flex flex-col">
-      <PageTitle
-        title="Patient Notes"
-        className="mb-5"
-        crumbsReplacements={{
-          [facilityId]: { name: facilityName },
-          [patientId]: { name: patientName },
-        }}
-        backUrl={`/facility/${facilityId}/patient/${patientId}`}
-      />
-
-      <div className="mx-3 my-2 px-2 py-2 sm:mx-10 sm:my-5 bg-white sm:px-5 sm:py-5 rounded-lg grow">
+    <Page
+      title="Patient Notes"
+      className="h-screen flex flex-col"
+      crumbsReplacements={{
+        [facilityId]: { name: facilityName },
+        [patientId]: { name: patientName },
+      }}
+      backUrl={`/facility/${facilityId}/patient/${patientId}`}
+    >
+      <div className="mx-3 my-2 px-2 py-2 sm:mx-10 sm:my-5 bg-white sm:px-5 sm:py-5 rounded-lg grow flex flex-col">
         <PatientNotesList
           patientId={patientId}
           facilityId={facilityId}
@@ -100,7 +98,7 @@ const PatientNotes = (props: PatientNotesProps) => {
           </ButtonV2>
         </div>
       </div>
-    </div>
+    </Page>
   );
 };
 

From 4cf45f61e529eca23ea81fc60e2c772336abbfb6 Mon Sep 17 00:00:00 2001
From: Rithvik Nishad <rithvikn2001@gmail.com>
Date: Fri, 21 Jul 2023 07:05:29 +0000
Subject: [PATCH 09/17] Apply suggestions from code review

---
 src/Components/Facility/PatientNotesSlideover.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index d377064c6dc..e35004932d2 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -64,7 +64,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
     >
       {!show ? (
         <div className="flex justify-around items-center w-full p-2 rounded-t-md bg-primary-800 text-white">
-          <span className="font-semibold">Doctor&apos;s Notes</span>
+          <span className="font-semibold">{"Doctor's Notes"}</span>
           <div
             className={classNames(
               "flex items-center justify-center w-8 h-8 cursor-pointer rounded text-gray-100 text-opacity-70 hover:text-opacity-100 bg-primary-800 hover:bg-primary-700",
@@ -79,7 +79,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
         <div className="bg-white sm:rounded-t-md w-full h-screen sm:h-[500px] flex flex-col border-2 border-b-0 pb-3 border-primary-800 transition-all overflow-clip -translate-y-0 ">
           {/* Doctor Notes Header */}
           <div className="flex justify-between items-center w-full p-2 px-4 bg-primary-800 text-white">
-            <span className="font-semibold">Doctor&apos;s Notes</span>
+            <span className="font-semibold">{"Doctor's Notes"}</span>
             <div
               className={classNames(
                 "flex items-center justify-center w-8 h-8 cursor-pointer rounded text-gray-100 text-opacity-70 hover:text-opacity-100 bg-primary-800 hover:bg-primary-700",

From 5afb43f87163de346c1fe6701aaeaffef3d16b9d Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Wed, 26 Jul 2023 22:38:28 +0530
Subject: [PATCH 10/17] added close button

---
 .../Facility/ConsultationDetails.tsx          | 15 +++-
 .../Facility/PatientNotesSlideover.tsx        | 76 ++++++++++++-------
 2 files changed, 58 insertions(+), 33 deletions(-)

diff --git a/src/Components/Facility/ConsultationDetails.tsx b/src/Components/Facility/ConsultationDetails.tsx
index 6848c6cbe3a..24655a2f7de 100644
--- a/src/Components/Facility/ConsultationDetails.tsx
+++ b/src/Components/Facility/ConsultationDetails.tsx
@@ -78,6 +78,7 @@ export const ConsultationDetails = (props: any) => {
     useState(false);
   const [openDischargeDialog, setOpenDischargeDialog] = useState(false);
   const [showAutomatedRounds, setShowAutomatedRounds] = useState(true);
+  const [showPatientNotesPopup, setShowPatientNotesPopup] = useState(false);
 
   const getPatientGender = (patientData: any) =>
     GENDER_TYPES.find((i) => i.id === patientData.gender)?.text;
@@ -325,12 +326,12 @@ export const ConsultationDetails = (props: any) => {
               >
                 Patient Details
               </Link>
-              <Link
-                href={`/facility/${patientData.facility}/patient/${patientData.id}/notes`}
+              <ButtonV2
+                onClick={() => setShowPatientNotesPopup(true)}
                 className="btn btn-primary m-1 w-full hover:text-white"
               >
                 Doctor&apos;s Notes
-              </Link>
+              </ButtonV2>
             </div>
           </div>
         </nav>
@@ -1239,7 +1240,13 @@ export const ConsultationDetails = (props: any) => {
         setShow={setShowDoctors}
       />
 
-      <PatientNotesSlideover patientId={patientId} facilityId={facilityId} />
+      {showPatientNotesPopup && (
+        <PatientNotesSlideover
+          patientId={patientId}
+          facilityId={facilityId}
+          setShowPatientNotesPopup={setShowPatientNotesPopup}
+        />
+      )}
     </div>
   );
 };
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index e35004932d2..784d856b01f 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -1,4 +1,4 @@
-import { useState, useEffect } from "react";
+import { useState, useEffect, Dispatch, SetStateAction } from "react";
 import { getPatient, addPatientNote } from "../../Redux/actions";
 import * as Notification from "../../Utils/Notifications.js";
 import { useDispatch } from "react-redux";
@@ -8,10 +8,12 @@ import CareIcon from "../../CAREUI/icons/CareIcon";
 import { classNames } from "../../Utils/utils";
 import TextFormField from "../Form/FormFields/TextFormField";
 import ButtonV2 from "../Common/components/ButtonV2";
+import { make as Link } from "../Common/components/Link.bs";
 
 interface PatientNotesProps {
-  patientId: any;
-  facilityId: any;
+  patientId: string;
+  facilityId: string;
+  setShowPatientNotesPopup: Dispatch<SetStateAction<boolean>>;
 }
 
 export default function PatientNotesSlideover(props: PatientNotesProps) {
@@ -22,7 +24,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
 
   const dispatch = useDispatch();
 
-  const { facilityId, patientId } = props;
+  const { facilityId, patientId, setShowPatientNotesPopup } = props;
 
   const onAddNote = () => {
     const payload = {
@@ -53,42 +55,58 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
     fetchPatientName();
   }, [dispatch, patientId]);
 
+  const notesActionIcons = (
+    <div className="flex gap-1">
+      {show && (
+        <Link
+          className={classNames(
+            "flex h-8 w-8 cursor-pointer items-center justify-center rounded bg-primary-800 text-gray-100 text-opacity-70 hover:bg-primary-700 hover:text-opacity-100"
+          )}
+          href={`/facility/${facilityId}/patient/${patientId}/notes`}
+        >
+          <CareIcon className="care-l-window-maximize text-lg transition-all delay-150 duration-300 ease-out" />
+        </Link>
+      )}
+      <div
+        className={classNames(
+          "flex h-8 w-8 cursor-pointer items-center justify-center rounded bg-primary-800 text-gray-100 text-opacity-70 hover:bg-primary-700 hover:text-opacity-100",
+          show ? "rotate-180" : ""
+        )}
+        onClick={() => setShow(!show)}
+      >
+        <CareIcon className="care-l-angle-up text-lg transition-all delay-150 duration-300 ease-out" />
+      </div>
+      <div
+        className={classNames(
+          "flex h-8 w-8 cursor-pointer items-center justify-center rounded bg-primary-800 text-gray-100 text-opacity-70 hover:bg-primary-700 hover:text-opacity-100"
+        )}
+        onClick={() => setShowPatientNotesPopup(false)}
+      >
+        <CareIcon className="care-l-times text-lg transition-all delay-150 duration-300 ease-out" />
+      </div>
+    </div>
+  );
+
   return (
     <div
       className={classNames(
-        "fixed sm:right-20 bottom-0 z-20",
+        "fixed bottom-0 z-20 sm:right-8",
         show
-          ? "w-screen h-screen sm:h-fit sm:w-[400px] right-0"
-          : "w-[250px] right-10"
+          ? "right-0 h-screen w-screen sm:h-fit sm:w-[400px]"
+          : "right-8 w-[250px]"
       )}
     >
       {!show ? (
-        <div className="flex justify-around items-center w-full p-2 rounded-t-md bg-primary-800 text-white">
+        <div className="flex w-full items-center justify-around rounded-t-md bg-primary-800 p-2 text-white">
           <span className="font-semibold">{"Doctor's Notes"}</span>
-          <div
-            className={classNames(
-              "flex items-center justify-center w-8 h-8 cursor-pointer rounded text-gray-100 text-opacity-70 hover:text-opacity-100 bg-primary-800 hover:bg-primary-700",
-              show ? "rotate-180" : ""
-            )}
-            onClick={() => setShow(!show)}
-          >
-            <CareIcon className="care-l-angle-up text-lg transition-all duration-300 delay-150 ease-out" />
-          </div>
+          {notesActionIcons}
         </div>
       ) : (
-        <div className="bg-white sm:rounded-t-md w-full h-screen sm:h-[500px] flex flex-col border-2 border-b-0 pb-3 border-primary-800 transition-all overflow-clip -translate-y-0 ">
+        <div className="flex h-screen w-full -translate-y-0 flex-col text-clip border-2 border-b-0 border-primary-800 bg-white pb-3 transition-all sm:h-[500px] sm:rounded-t-md ">
           {/* Doctor Notes Header */}
-          <div className="flex justify-between items-center w-full p-2 px-4 bg-primary-800 text-white">
+          <div className="flex w-full items-center justify-between bg-primary-800 p-2 px-4 text-white">
             <span className="font-semibold">{"Doctor's Notes"}</span>
-            <div
-              className={classNames(
-                "flex items-center justify-center w-8 h-8 cursor-pointer rounded text-gray-100 text-opacity-70 hover:text-opacity-100 bg-primary-800 hover:bg-primary-700",
-                show ? "rotate-180" : ""
-              )}
-              onClick={() => setShow(!show)}
-            >
-              <CareIcon className="care-l-angle-up text-lg transition-all duration-300 delay-150 ease-out" />
-            </div>
+            {notesActionIcons}
           </div>
           {/* Doctor Notes Body */}
           <PatientNotesList
@@ -97,7 +115,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
             reload={reload}
             setReload={setReload}
           />
-          <div className="flex items-center mx-4 relative">
+          <div className="relative mx-4 flex items-center">
             <TextFormField
               name="note"
               value={noteField}

From 5ee889da2f08c5ec857432b940b6270abfcb3654 Mon Sep 17 00:00:00 2001
From: Rithvik Nishad <rithvikn2001@gmail.com>
Date: Thu, 27 Jul 2023 04:44:07 +0000
Subject: [PATCH 11/17] Apply suggestions from code review

---
 src/Components/Facility/PatientNotesSlideover.tsx | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index 784d856b01f..2832898e20b 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -59,9 +59,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
     <div className="flex gap-1">
       {show && (
         <Link
-          className={classNames(
-            "flex h-8 w-8 cursor-pointer items-center justify-center rounded bg-primary-800 text-gray-100 text-opacity-70 hover:bg-primary-700 hover:text-opacity-100"
-          )}
+          className="flex h-8 w-8 cursor-pointer items-center justify-center rounded bg-primary-800 text-gray-100 text-opacity-70 hover:bg-primary-700 hover:text-opacity-100"
           href={`/facility/${facilityId}/patient/${patientId}/notes`}
         >
           <CareIcon className="care-l-window-maximize text-lg transition-all delay-150 duration-300 ease-out" />
@@ -70,16 +68,14 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
       <div
         className={classNames(
           "flex h-8 w-8 cursor-pointer items-center justify-center rounded bg-primary-800 text-gray-100 text-opacity-70 hover:bg-primary-700 hover:text-opacity-100",
-          show ? "rotate-180" : ""
+          show && "rotate-180"
         )}
         onClick={() => setShow(!show)}
       >
         <CareIcon className="care-l-angle-up text-lg transition-all delay-150 duration-300 ease-out" />
       </div>
       <div
-        className={classNames(
-          "flex h-8 w-8 cursor-pointer items-center justify-center rounded bg-primary-800 text-gray-100 text-opacity-70 hover:bg-primary-700 hover:text-opacity-100"
-        )}
+        className="flex h-8 w-8 cursor-pointer items-center justify-center rounded bg-primary-800 text-gray-100 text-opacity-70 hover:bg-primary-700 hover:text-opacity-100"
         onClick={() => setShowPatientNotesPopup(false)}
       >
         <CareIcon className="care-l-times text-lg transition-all delay-150 duration-300 ease-out" />

From f41f7f6097e9df59b67c5250f564611c667a5de3 Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Thu, 27 Jul 2023 20:27:19 +0530
Subject: [PATCH 12/17] enchance doctor notes ux

---
 src/Components/Facility/PatientNotesSlideover.tsx | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index 2832898e20b..ccfc950e674 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -93,7 +93,10 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
       )}
     >
       {!show ? (
-        <div className="flex w-full items-center justify-around rounded-t-md bg-primary-800 p-2 text-white">
+        <div
+          className="flex w-full cursor-pointer items-center justify-around rounded-t-md bg-primary-800 p-2 text-white"
+          onClick={() => setShow(!show)}
+        >
           <span className="font-semibold">{"Doctor's Notes"}</span>
           {notesActionIcons}
         </div>

From f63731d937bb865a7bb596d7d1ea04e67af9812b Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Tue, 8 Aug 2023 00:41:22 +0530
Subject: [PATCH 13/17] Merge branch 'develop' into doctor-notes-redesign


From 73df9f487a6cc6fcc1e7fa82dbaf8e64906fc1af Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Wed, 9 Aug 2023 16:47:10 +0530
Subject: [PATCH 14/17] replace usages of moment with dayjs

---
 src/Components/Facility/PatientNoteCard.tsx | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index e3e9234afd3..6308869dffc 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -1,17 +1,17 @@
-import { relativeDate, formatDate } from "../../Utils/utils";
+import { relativeDate, formatDateTime } from "../../Utils/utils";
 
 const PatientNoteCard = ({ note }: { note: any }) => {
   return (
     <div
       key={note.id}
-      className="flex p-3 bg-white rounded-lg text-gray-800 mt-4 flex-col w-full border border-gray-300"
+      className="mt-4 flex w-full flex-col rounded-lg border border-gray-300 bg-white p-3 text-gray-800"
     >
       <div className="flex justify-between">
-        <span className="text-gray-700 text-sm font-semibold">
+        <span className="text-sm font-semibold text-gray-700">
           {note.created_by_object?.first_name || "Unknown"}{" "}
           {note.created_by_object?.last_name}
         </span>
-        <span className="text-gray-700 text-sm">
+        <span className="text-sm text-gray-700">
           {note.created_by_object.user_type === "Doctor"
             ? note.created_by_local_user
               ? ""
@@ -20,10 +20,10 @@ const PatientNoteCard = ({ note }: { note: any }) => {
         </span>
       </div>
       <span className="whitespace-pre-wrap break-words">{note.note}</span>
-      <div className="mt-3 text-xs text-gray-500 text-end">
+      <div className="mt-3 text-end text-xs text-gray-500">
         <div className="tooltip inline">
           <span className="tooltip-text tooltip-left">
-            {formatDate(note.created_date)}
+            {formatDateTime(note.created_date)}
           </span>
           {relativeDate(note.created_date)}
         </div>

From 3bea8c1c9987bfd9c5bc3dc97af5fa5a7bbf0baf Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Tue, 22 Aug 2023 19:12:41 +0530
Subject: [PATCH 15/17] Added user role in brackets

---
 src/Components/Facility/PatientNoteCard.tsx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/Components/Facility/PatientNoteCard.tsx b/src/Components/Facility/PatientNoteCard.tsx
index 6308869dffc..c1249c2021a 100644
--- a/src/Components/Facility/PatientNoteCard.tsx
+++ b/src/Components/Facility/PatientNoteCard.tsx
@@ -6,17 +6,19 @@ const PatientNoteCard = ({ note }: { note: any }) => {
       key={note.id}
       className="mt-4 flex w-full flex-col rounded-lg border border-gray-300 bg-white p-3 text-gray-800"
     >
-      <div className="flex justify-between">
+      <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>
-        <span className="text-sm text-gray-700">
+        <span className="pl-1 text-sm text-gray-700">
+          {" ("}
           {note.created_by_object.user_type === "Doctor"
             ? note.created_by_local_user
               ? ""
               : "Remote Specialist"
             : note.created_by_object.user_type}
+          {")"}
         </span>
       </div>
       <span className="whitespace-pre-wrap break-words">{note.note}</span>

From 5ce435aebe8141d51fdc58c52c5a36ea6c05a2b6 Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Thu, 24 Aug 2023 16:41:54 +0530
Subject: [PATCH 16/17] added message listener for patient notes

---
 src/Components/Facility/PatientNotesSlideover.tsx | 11 +++++++++++
 src/Components/Patient/PatientNotes.tsx           | 11 +++++++++++
 2 files changed, 22 insertions(+)

diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index ccfc950e674..be95d768188 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -9,6 +9,7 @@ import { classNames } 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";
 
 interface PatientNotesProps {
   patientId: string;
@@ -43,6 +44,16 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
     });
   };
 
+  useMessageListener((data) => {
+    if (
+      data?.status == "updated" &&
+      data?.facility_id == facilityId &&
+      data?.patient_id == patientId
+    ) {
+      setReload(true);
+    }
+  });
+
   useEffect(() => {
     async function fetchPatientName() {
       if (patientId) {
diff --git a/src/Components/Patient/PatientNotes.tsx b/src/Components/Patient/PatientNotes.tsx
index 6011be6b30d..4513c196d9f 100644
--- a/src/Components/Patient/PatientNotes.tsx
+++ b/src/Components/Patient/PatientNotes.tsx
@@ -8,6 +8,7 @@ import ButtonV2 from "../Common/components/ButtonV2";
 import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
 import PatientNotesList from "../Facility/PatientNotesList";
 import Page from "../Common/components/Page";
+import { useMessageListener } from "../../Common/hooks/useMessageListener";
 
 interface PatientNotesProps {
   patientId: any;
@@ -56,6 +57,16 @@ const PatientNotes = (props: PatientNotesProps) => {
     fetchPatientName();
   }, [dispatch, patientId]);
 
+  useMessageListener((data) => {
+    if (
+      data?.status == "updated" &&
+      data?.facility_id == facilityId &&
+      data?.patient_id == patientId
+    ) {
+      setReload(true);
+    }
+  });
+
   return (
     <Page
       title="Patient Notes"

From 580a5777c479090f87251d812ade6345504b6e16 Mon Sep 17 00:00:00 2001
From: Bhavik Agarwal <bhavikiitian@gmail.com>
Date: Mon, 28 Aug 2023 21:19:26 +0530
Subject: [PATCH 17/17] added notification on patient note creation

---
 src/Common/constants.tsx                           | 5 +++++
 src/Components/Notifications/NotificationsList.tsx | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/src/Common/constants.tsx b/src/Common/constants.tsx
index e8ab4867764..09ce7463f71 100644
--- a/src/Common/constants.tsx
+++ b/src/Common/constants.tsx
@@ -608,6 +608,11 @@ export const NOTIFICATION_EVENTS = [
     text: "Shifting Updated",
     icon: "fa-solid fa-truck-medical",
   },
+  {
+    id: "PATIENT_NOTE_ADDED",
+    text: "Patient Note Added",
+    icon: "fa-solid fa-message",
+  },
 ];
 
 export const BREATHLESSNESS_LEVEL = [
diff --git a/src/Components/Notifications/NotificationsList.tsx b/src/Components/Notifications/NotificationsList.tsx
index f6afa6cccd8..141038340a0 100644
--- a/src/Components/Notifications/NotificationsList.tsx
+++ b/src/Components/Notifications/NotificationsList.tsx
@@ -66,6 +66,8 @@ const NotificationTile = ({
         return `/facility/${data.facility}/patient/${data.patient}/consultation/${data.consultation}/daily-rounds/${data.daily_round}`;
       case "INVESTIGATION_SESSION_CREATED":
         return `/facility/${data.facility}/patient/${data.patient}/consultation/${data.consultation}/investigation/${data.session}`;
+      case "PATIENT_NOTE_ADDED":
+        return `/facility/${data.facility}/patient/${data.patient}/notes`;
       case "MESSAGE":
         return "/notice_board/";
       default: