From 75a47966c3a4db30b7cf03a34cdff30a9c4790e5 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Tue, 10 Dec 2024 19:29:53 +0530
Subject: [PATCH 01/16] prefilled middleware

prefilled middleware displayed as message in asset congiguration, added new attributes `message` and `messageClass` to `FormFeild` component`
---
 .../Assets/AssetType/HL7Monitor.tsx           | 17 ++++----------
 src/components/CameraFeed/ConfigureCamera.tsx | 22 +++++++-----------
 src/components/Form/FormFields/FormField.tsx  | 23 +++++++++++++++++++
 src/components/Form/FormFields/Utils.ts       |  2 ++
 4 files changed, 38 insertions(+), 26 deletions(-)

diff --git a/src/components/Assets/AssetType/HL7Monitor.tsx b/src/components/Assets/AssetType/HL7Monitor.tsx
index 76d761383bd..c53ae325111 100644
--- a/src/components/Assets/AssetType/HL7Monitor.tsx
+++ b/src/components/Assets/AssetType/HL7Monitor.tsx
@@ -100,20 +100,13 @@ const HL7Monitor = (props: HL7MonitorProps) => {
                     label={
                       <div className="flex flex-row gap-1">
                         <p>Middleware Hostname</p>
-                        {resolvedMiddleware?.source != "asset" && (
-                          <div className="tooltip">
-                            <CareIcon
-                              icon="l-info-circle"
-                              className="tooltip text-indigo-500 hover:text-indigo-600"
-                            />
-                            <span className="tooltip-text w-56 whitespace-normal">
-                              Middleware hostname sourced from asset{" "}
-                              {resolvedMiddleware?.source}
-                            </span>
-                          </div>
-                        )}
                       </div>
                     }
+                    message={
+                      resolvedMiddleware?.source != "asset"
+                        ? `Middleware hostname sourced from asset ${resolvedMiddleware?.source}`
+                        : undefined
+                    }
                     placeholder={resolvedMiddleware?.hostname}
                     value={middlewareHostname}
                     onChange={(e) => setMiddlewareHostname(e.value)}
diff --git a/src/components/CameraFeed/ConfigureCamera.tsx b/src/components/CameraFeed/ConfigureCamera.tsx
index eec453053d6..3a80a585b16 100644
--- a/src/components/CameraFeed/ConfigureCamera.tsx
+++ b/src/components/CameraFeed/ConfigureCamera.tsx
@@ -149,22 +149,16 @@ export default function ConfigureCamera(props: Props) {
               label={
                 <div className="flex flex-row gap-1">
                   <p>{t("middleware_hostname")}</p>
-                  {!!props.asset.resolved_middleware &&
-                    props.asset.resolved_middleware.source != "asset" && (
-                      <div className="tooltip">
-                        <CareIcon
-                          icon="l-info-circle"
-                          className="tooltip text-indigo-500 hover:text-indigo-600"
-                        />
-                        <span className="tooltip-text w-56 whitespace-normal">
-                          {t("middleware_hostname_sourced_from", {
-                            source: props.asset.resolved_middleware?.source,
-                          })}
-                        </span>
-                      </div>
-                    )}
                 </div>
               }
+              message={
+                !!props.asset.resolved_middleware &&
+                props.asset.resolved_middleware.source != "asset"
+                  ? t("middleware_hostname_sourced_from", {
+                      source: props.asset.resolved_middleware?.source,
+                    })
+                  : undefined
+              }
               placeholder={
                 props.asset.resolved_middleware?.hostname ??
                 t("middleware_hostname_example")
diff --git a/src/components/Form/FormFields/FormField.tsx b/src/components/Form/FormFields/FormField.tsx
index 7f9c2699d64..d5533877fbc 100644
--- a/src/components/Form/FormFields/FormField.tsx
+++ b/src/components/Form/FormFields/FormField.tsx
@@ -48,6 +48,25 @@ export const FieldErrorText = (props: ErrorProps) => {
   );
 };
 
+type MessageProps = {
+  message: string | undefined;
+  className?: string | undefined;
+};
+
+export const FieldMessageText = (props: MessageProps) => {
+  return (
+    <span
+      className={classNames(
+        "text-primary-400 ml-1 mt-2 text-xs tracking-wide transition-opacity duration-300",
+        props.message ? "opacity-100" : "opacity-0",
+        props.className,
+      )}
+    >
+      {props.message}
+    </span>
+  );
+};
+
 const FormField = ({
   field,
   ...props
@@ -73,6 +92,10 @@ const FormField = ({
       </div>
       <div className={field?.className}>{props.children}</div>
       <FieldErrorText error={field?.error} className={field?.errorClassName} />
+      <FieldMessageText
+        message={field?.message}
+        className={field?.messageClassName}
+      />
     </div>
   );
 };
diff --git a/src/components/Form/FormFields/Utils.ts b/src/components/Form/FormFields/Utils.ts
index 1e88bcbd6a0..b017f7b92ee 100644
--- a/src/components/Form/FormFields/Utils.ts
+++ b/src/components/Form/FormFields/Utils.ts
@@ -20,9 +20,11 @@ export type FieldChangeEventHandler<T> = (event: FieldChangeEvent<T>) => void;
 export type FormFieldBaseProps<T> = {
   label?: React.ReactNode;
   labelSuffix?: React.ReactNode;
+  message?: string;
   disabled?: boolean;
   className?: string;
   required?: boolean;
+  messageClassName?: string;
   labelClassName?: string;
   errorClassName?: string;
   name: string;

From 4effcf0e9e0649fa410528d21a1239849b126c73 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Tue, 10 Dec 2024 20:05:31 +0530
Subject: [PATCH 02/16] add fine message text in create location form

---
 src/components/Facility/AddLocationForm.tsx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/Facility/AddLocationForm.tsx b/src/components/Facility/AddLocationForm.tsx
index bb0039285f5..ff4bec38382 100644
--- a/src/components/Facility/AddLocationForm.tsx
+++ b/src/components/Facility/AddLocationForm.tsx
@@ -209,6 +209,7 @@ export const AddLocationForm = ({ facilityId, locationId }: Props) => {
                   name="Location Middleware Address"
                   type="text"
                   label="Location Middleware Address"
+                  message="Leave blank to apply facility middleware to assets"
                   value={middlewareAddress}
                   onChange={(e) => setMiddlewareAddress(e.value)}
                   error={errors.middlewareAddress}

From 3c9172071436bc98d07a3721997c2a64cd45b0eb Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Tue, 10 Dec 2024 20:27:37 +0530
Subject: [PATCH 03/16] Add fine text facility confiuration page add fine
 default behaviour text in facility configuration page

---
 src/components/Facility/FacilityConfigure.tsx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/Facility/FacilityConfigure.tsx b/src/components/Facility/FacilityConfigure.tsx
index 1cb7c7d69cf..a4b9bc5756b 100644
--- a/src/components/Facility/FacilityConfigure.tsx
+++ b/src/components/Facility/FacilityConfigure.tsx
@@ -150,6 +150,7 @@ export const FacilityConfigure = (props: IProps) => {
                 <TextFormField
                   name="middleware_address"
                   label="Facility Middleware Address"
+                  message="This addredd will be applied to all assets when asset and location middleware are Unspecified"
                   required
                   value={state.form.middleware_address}
                   onChange={handleChange}

From 4d2cf0d6d2ba41609fe0492281ada7bab00a5586 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Tue, 10 Dec 2024 20:55:31 +0530
Subject: [PATCH 04/16] corrected mispelled address word

---
 src/components/Facility/FacilityConfigure.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/Facility/FacilityConfigure.tsx b/src/components/Facility/FacilityConfigure.tsx
index a4b9bc5756b..315181a3ab0 100644
--- a/src/components/Facility/FacilityConfigure.tsx
+++ b/src/components/Facility/FacilityConfigure.tsx
@@ -150,7 +150,7 @@ export const FacilityConfigure = (props: IProps) => {
                 <TextFormField
                   name="middleware_address"
                   label="Facility Middleware Address"
-                  message="This addredd will be applied to all assets when asset and location middleware are Unspecified"
+                  message="This address will be applied to all assets when asset and location middleware are Unspecified"
                   required
                   value={state.form.middleware_address}
                   onChange={handleChange}

From 937e6fd87db1d651b7d4b44a7632486d57f177d1 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Wed, 11 Dec 2024 00:10:14 +0530
Subject: [PATCH 05/16] added resolved middleware text at location management

---
 .../Facility/LocationManagement.tsx           | 26 ++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/components/Facility/LocationManagement.tsx b/src/components/Facility/LocationManagement.tsx
index 2f80a879651..ab6865ebf88 100644
--- a/src/components/Facility/LocationManagement.tsx
+++ b/src/components/Facility/LocationManagement.tsx
@@ -27,6 +27,7 @@ interface Props {
 interface LocationProps extends LocationModel {
   facilityId: string;
   disabled: boolean;
+  facilityMiddleware?: string;
   setShowDeletePopup: (e: { open: boolean; name: string; id: string }) => void;
 }
 
@@ -42,6 +43,18 @@ export default function LocationManagement({ facilityId }: Props) {
     name: "",
     id: "",
   });
+  const [facilityMiddleware, setFacilityMiddleware] = useState<
+    string | undefined
+  >(undefined);
+
+  useQuery(routes.getPermittedFacility, {
+    pathParams: { id: facilityId },
+    onResponse: (res) => {
+      if (res.data) {
+        setFacilityMiddleware(res.data?.middleware_address);
+      }
+    },
+  });
 
   const closeDeleteFailModal = () => {
     setShowDeleteFailModal({ ...showDeleteFailModal, open: false });
@@ -121,6 +134,7 @@ export default function LocationManagement({ facilityId }: Props) {
                 <Location
                   setShowDeletePopup={setShowDeletePopup}
                   facilityId={facilityId}
+                  facilityMiddleware={facilityMiddleware}
                   {...item}
                   disabled={
                     ["DistrictAdmin", "StateAdmin"].includes(authUser.user_type)
@@ -221,6 +235,7 @@ const Location = ({
   name,
   description,
   middleware_address,
+  facilityMiddleware,
   location_type,
   created_date,
   modified_date,
@@ -268,14 +283,19 @@ const Location = ({
         >
           {description || "-"}
         </p>
-        <p className="mt-3 text-sm font-semibold text-secondary-700">
+        <span className="mt-3 text-sm font-semibold text-secondary-700">
           Middleware Address:
-        </p>
+        </span>
+        {!middleware_address && facilityMiddleware && (
+          <span className="ml-1 text-xs text-primary-400 opaticy-70">
+            Fetched from facility
+          </span>
+        )}
         <p
           className="mt-1 break-all font-mono text-sm font-bold text-secondary-700"
           id="view-location-middleware"
         >
-          {middleware_address || "-"}
+          {middleware_address || facilityMiddleware || "-"}
         </p>
         <Uptime
           route={routes.listFacilityAssetLocationAvailability}

From 6c38aa900a781aee492f648a2371350e308ee4ad Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Wed, 11 Dec 2024 00:37:59 +0530
Subject: [PATCH 06/16] Fixed typo in CSS class name

---
 src/components/Facility/LocationManagement.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/Facility/LocationManagement.tsx b/src/components/Facility/LocationManagement.tsx
index ab6865ebf88..4ff0f3a1655 100644
--- a/src/components/Facility/LocationManagement.tsx
+++ b/src/components/Facility/LocationManagement.tsx
@@ -287,7 +287,7 @@ const Location = ({
           Middleware Address:
         </span>
         {!middleware_address && facilityMiddleware && (
-          <span className="ml-1 text-xs text-primary-400 opaticy-70">
+          <span className="ml-1 text-xs text-primary-400">
             Fetched from facility
           </span>
         )}

From 6fa2c556a798866897073059c1c0da812d8beb35 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Thu, 12 Dec 2024 12:32:52 +0530
Subject: [PATCH 07/16] added (fetched from facility) badge in location
 management page

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

diff --git a/src/components/Facility/LocationManagement.tsx b/src/components/Facility/LocationManagement.tsx
index 4ff0f3a1655..954badd8e05 100644
--- a/src/components/Facility/LocationManagement.tsx
+++ b/src/components/Facility/LocationManagement.tsx
@@ -287,8 +287,10 @@ const Location = ({
           Middleware Address:
         </span>
         {!middleware_address && facilityMiddleware && (
-          <span className="ml-1 text-xs text-primary-400">
-            Fetched from facility
+          <span className="ml-2 mt-2 text-xs h-fit rounded-full border-2 border-primary-500 bg-primary-100 px-3 py-[3px]">
+            <span className="text-xs font-bold text-primary-500">
+              Fetched from facility
+            </span>
           </span>
         )}
         <p

From e5d881e002efddbad9ce1bb034493dd5f267b326 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Thu, 12 Dec 2024 12:52:40 +0530
Subject: [PATCH 08/16] used shadcn label component in formfeild, changed color
 of message to gray

---
 src/components/Form/FormFields/FormField.tsx | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/components/Form/FormFields/FormField.tsx b/src/components/Form/FormFields/FormField.tsx
index d5533877fbc..1a90f059586 100644
--- a/src/components/Form/FormFields/FormField.tsx
+++ b/src/components/Form/FormFields/FormField.tsx
@@ -1,3 +1,5 @@
+import { Label } from "@radix-ui/react-label";
+
 import { FieldError } from "@/components/Form/FieldValidators";
 import { FormFieldBaseProps } from "@/components/Form/FormFields/Utils";
 
@@ -14,7 +16,7 @@ type LabelProps = {
 
 export const FieldLabel = (props: LabelProps) => {
   return (
-    <label
+    <Label
       id={props.id}
       className={classNames(
         "block text-base font-normal text-secondary-900",
@@ -25,7 +27,7 @@ export const FieldLabel = (props: LabelProps) => {
     >
       {props.children}
       {props.required && <span className="text-danger-500">{" *"}</span>}
-    </label>
+    </Label>
   );
 };
 
@@ -57,8 +59,8 @@ export const FieldMessageText = (props: MessageProps) => {
   return (
     <span
       className={classNames(
-        "text-primary-400 ml-1 mt-2 text-xs tracking-wide transition-opacity duration-300",
-        props.message ? "opacity-100" : "opacity-0",
+        "text-secondary-700 ml-1 mt-2 text-xs tracking-wide transition-opacity duration-300",
+        props.message ? "opacity-80" : "opacity-0",
         props.className,
       )}
     >

From d7e4a45a802d52aa18b3d68fcd45ea3afb62d7d2 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Thu, 12 Dec 2024 13:00:29 +0530
Subject: [PATCH 09/16] minor changes

---
 src/components/Form/FormFields/FormField.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/Form/FormFields/FormField.tsx b/src/components/Form/FormFields/FormField.tsx
index 1a90f059586..7013f7caa37 100644
--- a/src/components/Form/FormFields/FormField.tsx
+++ b/src/components/Form/FormFields/FormField.tsx
@@ -1,4 +1,4 @@
-import { Label } from "@radix-ui/react-label";
+import { Label } from "@/components/ui/label";
 
 import { FieldError } from "@/components/Form/FieldValidators";
 import { FormFieldBaseProps } from "@/components/Form/FormFields/Utils";

From be5285de04928340dfff978e4974216eaadb2bca Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Sun, 15 Dec 2024 19:27:11 +0530
Subject: [PATCH 10/16] used shadcn badge in location management page

---
 .../Facility/LocationManagement.tsx           | 21 +++++++------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/src/components/Facility/LocationManagement.tsx b/src/components/Facility/LocationManagement.tsx
index 954badd8e05..674a922dbe0 100644
--- a/src/components/Facility/LocationManagement.tsx
+++ b/src/components/Facility/LocationManagement.tsx
@@ -20,6 +20,8 @@ import routes from "@/Utils/request/api";
 import request from "@/Utils/request/request";
 import useQuery from "@/Utils/request/useQuery";
 
+import { Badge } from "../ui/badge";
+
 interface Props {
   facilityId: string;
 }
@@ -267,14 +269,9 @@ const Location = ({
             >
               {name}
             </p>
-            <div
-              className="mt-2 h-fit rounded-full border-2 border-primary-500 bg-primary-100 px-3 py-[3px]"
-              id="location-type"
-            >
-              <p className="text-xs font-bold text-primary-500">
-                {location_type}
-              </p>
-            </div>
+            <Badge className="rounded-full bg-primary-100 text-primary-500 hover:bg-primary-100 border-2 border-primary-500 font-bold px-3 py-[3px] ml-2">
+              {location_type}
+            </Badge>
           </div>
         </div>
         <p
@@ -287,11 +284,9 @@ const Location = ({
           Middleware Address:
         </span>
         {!middleware_address && facilityMiddleware && (
-          <span className="ml-2 mt-2 text-xs h-fit rounded-full border-2 border-primary-500 bg-primary-100 px-3 py-[3px]">
-            <span className="text-xs font-bold text-primary-500">
-              Fetched from facility
-            </span>
-          </span>
+          <Badge className="rounded-full bg-primary-100 text-primary-500 hover:bg-primary-100 border-2 border-primary-500 font-bold px-3 py-[3px] ml-2">
+            Fetched from facility
+          </Badge>
         )}
         <p
           className="mt-1 break-all font-mono text-sm font-bold text-secondary-700"

From 33ae347992b7185640018f7e6cce8739f027e2b6 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Mon, 16 Dec 2024 13:37:39 +0530
Subject: [PATCH 11/16] updated useQuery

---
 src/components/Facility/LocationManagement.tsx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/components/Facility/LocationManagement.tsx b/src/components/Facility/LocationManagement.tsx
index 4e6e77c0a3f..1fe0551b4d3 100644
--- a/src/components/Facility/LocationManagement.tsx
+++ b/src/components/Facility/LocationManagement.tsx
@@ -4,6 +4,8 @@ import RecordMeta from "@/CAREUI/display/RecordMeta";
 import CareIcon from "@/CAREUI/icons/CareIcon";
 import PaginatedList from "@/CAREUI/misc/PaginatedList";
 
+import { Badge } from "@/components/ui/badge";
+
 import ButtonV2, { Cancel } from "@/components/Common/ButtonV2";
 import ConfirmDialog from "@/components/Common/ConfirmDialog";
 import DialogModal from "@/components/Common/Dialog";
@@ -20,8 +22,6 @@ import routes from "@/Utils/request/api";
 import request from "@/Utils/request/request";
 import useTanStackQueryInstead from "@/Utils/request/useQuery";
 
-import { Badge } from "../ui/badge";
-
 interface Props {
   facilityId: string;
 }
@@ -49,7 +49,7 @@ export default function LocationManagement({ facilityId }: Props) {
     string | undefined
   >(undefined);
 
-  useQuery(routes.getPermittedFacility, {
+  useTanStackQueryInstead(routes.getPermittedFacility, {
     pathParams: { id: facilityId },
     onResponse: (res) => {
       if (res.data) {

From b9b0ed0ca7c1089884d2ae32b19ed72c01c100b6 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Wed, 18 Dec 2024 10:39:55 +0530
Subject: [PATCH 12/16] changed useTanstackuseQuery to useQuery

---
 .../Facility/LocationManagement.tsx           | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/src/components/Facility/LocationManagement.tsx b/src/components/Facility/LocationManagement.tsx
index 1fe0551b4d3..e9c1323142f 100644
--- a/src/components/Facility/LocationManagement.tsx
+++ b/src/components/Facility/LocationManagement.tsx
@@ -1,3 +1,4 @@
+import { useQuery } from "@tanstack/react-query";
 import { useState } from "react";
 
 import RecordMeta from "@/CAREUI/display/RecordMeta";
@@ -19,6 +20,7 @@ import useAuthUser from "@/hooks/useAuthUser";
 import AuthorizeFor, { NonReadOnlyUsers } from "@/Utils/AuthorizeFor";
 import * as Notification from "@/Utils/Notifications";
 import routes from "@/Utils/request/api";
+import query from "@/Utils/request/query";
 import request from "@/Utils/request/request";
 import useTanStackQueryInstead from "@/Utils/request/useQuery";
 
@@ -45,19 +47,16 @@ export default function LocationManagement({ facilityId }: Props) {
     name: "",
     id: "",
   });
-  const [facilityMiddleware, setFacilityMiddleware] = useState<
-    string | undefined
-  >(undefined);
 
-  useTanStackQueryInstead(routes.getPermittedFacility, {
-    pathParams: { id: facilityId },
-    onResponse: (res) => {
-      if (res.data) {
-        setFacilityMiddleware(res.data?.middleware_address);
-      }
-    },
+  const { data } = useQuery({
+    queryKey: [routes.getPermittedFacility.path, facilityId],
+    queryFn: query(routes.getPermittedFacility, {
+      pathParams: { id: facilityId },
+    }),
   });
 
+  const facilityMiddleware = data?.middleware_address;
+
   const closeDeleteFailModal = () => {
     setShowDeleteFailModal({ ...showDeleteFailModal, open: false });
   };

From c28d3a08d15ee1b4131f51aa9bbab0cd139340ef Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Wed, 18 Dec 2024 15:52:22 +0530
Subject: [PATCH 13/16] used react forms in facility configuration page

---
 package-lock.json                             | 202 ++++++++++++++++--
 package.json                                  |   8 +-
 src/components/Facility/FacilityConfigure.tsx | 191 ++++++++---------
 src/components/ui/form.tsx                    | 184 ++++++++++++++++
 4 files changed, 462 insertions(+), 123 deletions(-)
 create mode 100644 src/components/ui/form.tsx

diff --git a/package-lock.json b/package-lock.json
index 94a84d3d179..d3057b01be0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,15 +17,16 @@
         "@googlemaps/typescript-guards": "^2.0.3",
         "@headlessui/react": "^2.2.0",
         "@hello-pangea/dnd": "^17.0.0",
+        "@hookform/resolvers": "^3.9.1",
         "@pnotify/core": "^5.2.0",
         "@pnotify/mobile": "^5.2.0",
         "@radix-ui/react-dialog": "^1.1.2",
         "@radix-ui/react-dropdown-menu": "^2.1.2",
         "@radix-ui/react-icons": "^1.3.2",
-        "@radix-ui/react-label": "^2.1.0",
+        "@radix-ui/react-label": "^2.1.1",
         "@radix-ui/react-popover": "^1.1.2",
         "@radix-ui/react-scroll-area": "^1.2.0",
-        "@radix-ui/react-slot": "^1.1.0",
+        "@radix-ui/react-slot": "^1.1.1",
         "@radix-ui/react-toast": "^1.2.2",
         "@radix-ui/react-tooltip": "^1.1.4",
         "@sentry/browser": "^8.42.0",
@@ -56,6 +57,7 @@
         "react-copy-to-clipboard": "^5.1.0",
         "react-dom": "18.3.1",
         "react-google-recaptcha": "^3.1.0",
+        "react-hook-form": "^7.54.1",
         "react-i18next": "^15.1.3",
         "react-infinite-scroll-component": "^6.1.0",
         "react-pdf": "^9.1.1",
@@ -113,7 +115,7 @@
         "vite-plugin-checker": "^0.8.0",
         "vite-plugin-pwa": "^0.20.5",
         "vite-plugin-static-copy": "^2.0.0",
-        "zod": "^3.23.8"
+        "zod": "^3.24.1"
       },
       "engines": {
         "node": ">=22.11.0"
@@ -2646,6 +2648,15 @@
         "react-dom": "^18.0.0"
       }
     },
+    "node_modules/@hookform/resolvers": {
+      "version": "3.9.1",
+      "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.9.1.tgz",
+      "integrity": "sha512-ud2HqmGBM0P0IABqoskKWI6PEf6ZDDBZkFqe2Vnl+mTHCEHzr3ISjjZyCwTjC/qpL25JC9aIDkloQejvMeq0ug==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react-hook-form": "^7.0.0"
+      }
+    },
     "node_modules/@humanwhocodes/config-array": {
       "version": "0.13.0",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
@@ -3687,6 +3698,24 @@
         }
       }
     },
+    "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+      "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+      "license": "MIT",
+      "dependencies": {
+        "@radix-ui/react-compose-refs": "1.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": "*",
+        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@radix-ui/react-compose-refs": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
@@ -3752,6 +3781,24 @@
         }
       }
     },
+    "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+      "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+      "license": "MIT",
+      "dependencies": {
+        "@radix-ui/react-compose-refs": "1.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": "*",
+        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@radix-ui/react-direction": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
@@ -3891,11 +3938,35 @@
       }
     },
     "node_modules/@radix-ui/react-label": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.0.tgz",
-      "integrity": "sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==",
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.1.tgz",
+      "integrity": "sha512-UUw5E4e/2+4kFMH7+YxORXGWggtY6sM8WIwh5RZchhLuUg2H1hc98Py+pr8HMz6rdaYrK2t296ZEjYLOCO5uUw==",
+      "license": "MIT",
       "dependencies": {
-        "@radix-ui/react-primitive": "2.0.0"
+        "@radix-ui/react-primitive": "2.0.1"
+      },
+      "peerDependencies": {
+        "@types/react": "*",
+        "@types/react-dom": "*",
+        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        },
+        "@types/react-dom": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-primitive": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz",
+      "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==",
+      "license": "MIT",
+      "dependencies": {
+        "@radix-ui/react-slot": "1.1.1"
       },
       "peerDependencies": {
         "@types/react": "*",
@@ -3952,6 +4023,24 @@
         }
       }
     },
+    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+      "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+      "license": "MIT",
+      "dependencies": {
+        "@radix-ui/react-compose-refs": "1.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": "*",
+        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@radix-ui/react-popover": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.2.tgz",
@@ -3988,6 +4077,24 @@
         }
       }
     },
+    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+      "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+      "license": "MIT",
+      "dependencies": {
+        "@radix-ui/react-compose-refs": "1.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": "*",
+        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@radix-ui/react-popper": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
@@ -4106,6 +4213,24 @@
         }
       }
     },
+    "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+      "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+      "license": "MIT",
+      "dependencies": {
+        "@radix-ui/react-compose-refs": "1.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": "*",
+        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@radix-ui/react-roving-focus": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz",
@@ -4183,12 +4308,12 @@
       }
     },
     "node_modules/@radix-ui/react-slot": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
-      "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz",
+      "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==",
       "license": "MIT",
       "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.0"
+        "@radix-ui/react-compose-refs": "1.1.1"
       },
       "peerDependencies": {
         "@types/react": "*",
@@ -4200,6 +4325,21 @@
         }
       }
     },
+    "node_modules/@radix-ui/react-slot/node_modules/@radix-ui/react-compose-refs": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
+      "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
+      "license": "MIT",
+      "peerDependencies": {
+        "@types/react": "*",
+        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@radix-ui/react-toast": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.2.tgz",
@@ -4268,6 +4408,24 @@
         }
       }
     },
+    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+      "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+      "license": "MIT",
+      "dependencies": {
+        "@radix-ui/react-compose-refs": "1.1.0"
+      },
+      "peerDependencies": {
+        "@types/react": "*",
+        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@radix-ui/react-use-callback-ref": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
@@ -15776,6 +15934,22 @@
         "react": ">=16.4.1"
       }
     },
+    "node_modules/react-hook-form": {
+      "version": "7.54.1",
+      "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.54.1.tgz",
+      "integrity": "sha512-PUNzFwQeQ5oHiiTUO7GO/EJXGEtuun2Y1A59rLnZBBj+vNEOWt/3ERTiG1/zt7dVeJEM+4vDX/7XQ/qanuvPMg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/react-hook-form"
+      },
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17 || ^18 || ^19"
+      }
+    },
     "node_modules/react-i18next": {
       "version": "15.1.3",
       "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.1.3.tgz",
@@ -20931,9 +21105,9 @@
       }
     },
     "node_modules/zod": {
-      "version": "3.23.8",
-      "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
-      "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
+      "version": "3.24.1",
+      "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz",
+      "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==",
       "dev": true,
       "license": "MIT",
       "funding": {
diff --git a/package.json b/package.json
index e5eaf3342c9..8edf7842d55 100644
--- a/package.json
+++ b/package.json
@@ -56,15 +56,16 @@
     "@googlemaps/typescript-guards": "^2.0.3",
     "@headlessui/react": "^2.2.0",
     "@hello-pangea/dnd": "^17.0.0",
+    "@hookform/resolvers": "^3.9.1",
     "@pnotify/core": "^5.2.0",
     "@pnotify/mobile": "^5.2.0",
     "@radix-ui/react-dialog": "^1.1.2",
     "@radix-ui/react-dropdown-menu": "^2.1.2",
     "@radix-ui/react-icons": "^1.3.2",
-    "@radix-ui/react-label": "^2.1.0",
+    "@radix-ui/react-label": "^2.1.1",
     "@radix-ui/react-popover": "^1.1.2",
     "@radix-ui/react-scroll-area": "^1.2.0",
-    "@radix-ui/react-slot": "^1.1.0",
+    "@radix-ui/react-slot": "^1.1.1",
     "@radix-ui/react-toast": "^1.2.2",
     "@radix-ui/react-tooltip": "^1.1.4",
     "@sentry/browser": "^8.42.0",
@@ -95,6 +96,7 @@
     "react-copy-to-clipboard": "^5.1.0",
     "react-dom": "18.3.1",
     "react-google-recaptcha": "^3.1.0",
+    "react-hook-form": "^7.54.1",
     "react-i18next": "^15.1.3",
     "react-infinite-scroll-component": "^6.1.0",
     "react-pdf": "^9.1.1",
@@ -152,7 +154,7 @@
     "vite-plugin-checker": "^0.8.0",
     "vite-plugin-pwa": "^0.20.5",
     "vite-plugin-static-copy": "^2.0.0",
-    "zod": "^3.23.8"
+    "zod": "^3.24.1"
   },
   "browserslist": {
     "production": [
diff --git a/src/components/Facility/FacilityConfigure.tsx b/src/components/Facility/FacilityConfigure.tsx
index 5dc938df99b..501b6959fd3 100644
--- a/src/components/Facility/FacilityConfigure.tsx
+++ b/src/components/Facility/FacilityConfigure.tsx
@@ -1,109 +1,72 @@
+import { zodResolver } from "@hookform/resolvers/zod";
+import { useQuery } from "@tanstack/react-query";
 import { t } from "i18next";
 import { navigate } from "raviger";
-import { useReducer, useState } from "react";
+import { useEffect, useState } from "react";
+import { useForm } from "react-hook-form";
+import { z } from "zod";
+
+import {
+  Form,
+  FormControl,
+  FormDescription,
+  FormField,
+  FormItem,
+  FormLabel,
+  FormMessage,
+} from "@/components/ui/form";
+import { Input } from "@/components/ui/input";
 
-import { Submit } from "@/components/Common/ButtonV2";
 import Loading from "@/components/Common/Loading";
 import Page from "@/components/Common/Page";
-import TextFormField from "@/components/Form/FormFields/TextFormField";
-import { FieldChangeEvent } from "@/components/Form/FormFields/Utils";
 
 import { PLUGIN_Component } from "@/PluginEngine";
 import * as Notification from "@/Utils/Notifications";
 import routes from "@/Utils/request/api";
+import query from "@/Utils/request/query";
 import request from "@/Utils/request/request";
-import useTanStackQueryInstead from "@/Utils/request/useQuery";
-
-const initForm = {
-  name: "",
-  state: 0,
-  district: 0,
-  localbody: 0,
-  ward: 0,
-  middleware_address: "",
-};
 
-const initialState = {
-  form: { ...initForm },
-  errors: {},
-};
-
-const FormReducer = (state = initialState, action: any) => {
-  switch (action.type) {
-    case "set_form": {
-      return {
-        ...state,
-        form: action.form,
-      };
-    }
-    case "set_error": {
-      return {
-        ...state,
-        errors: action.errors,
-      };
-    }
-    default:
-      return state;
-  }
-};
+import { Submit } from "../Common/ButtonV2";
 
 interface IProps {
   facilityId: string;
 }
 
+const formSchema = z.object({
+  middleware_address: z
+    .string()
+    .nonempty({ message: "Middleware Address is required" })
+    .regex(/^(?!https?:\/\/)[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)*\.[a-zA-Z]{2,}$/, {
+      message: "Invalid Middleware Address",
+    }),
+});
+
 export const FacilityConfigure = (props: IProps) => {
-  const [state, dispatch] = useReducer(FormReducer, initialState);
   const { facilityId } = props;
   const [isLoading, setIsLoading] = useState(false);
 
-  const { loading } = useTanStackQueryInstead(routes.getPermittedFacility, {
-    pathParams: { id: facilityId },
-    onResponse: (res) => {
-      if (res.data) {
-        const formData = {
-          name: res.data.name,
-          state: res.data.state,
-          district: res.data.district,
-          local_body: res.data.local_body,
-          ward: res.data.ward,
-          middleware_address: res.data.middleware_address,
-        };
-        dispatch({ type: "set_form", form: formData });
-      }
-    },
+  const { isPending: loading, data } = useQuery({
+    queryKey: [routes.getPermittedFacility.path, facilityId],
+    queryFn: query(routes.getPermittedFacility, {
+      pathParams: { id: facilityId },
+    }),
   });
 
-  const handleSubmit = async (e: React.FormEvent) => {
-    e.preventDefault();
-    setIsLoading(true);
-    if (!state.form.middleware_address) {
-      dispatch({
-        type: "set_error",
-        errors: { middleware_address: ["Middleware Address is required"] },
-      });
-      setIsLoading(false);
-      return;
-    }
-    if (
-      state.form.middleware_address.match(
-        /^(?!https?:\/\/)[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)*\.[a-zA-Z]{2,}$/,
-      ) === null
-    ) {
-      dispatch({
-        type: "set_error",
-        errors: {
-          middleware_address: ["Invalid Middleware Address"],
-        },
-      });
-      setIsLoading(false);
-      return;
-    }
+  const onSubmit = async (values: z.infer<typeof formSchema>) => {
+    if (!data) return;
 
-    const data = {
-      ...state.form,
-      middleware_address: state.form.middleware_address,
+    const formData = {
+      name: data.name,
+      state: data.state,
+      district: data.district,
+      local_body: data.local_body,
+      ward: data.ward,
+      middleware_address: values.middleware_address,
     };
 
+    setIsLoading(true);
+    console.log(formData);
+
     const { res, error } = await request(routes.partialUpdateFacility, {
       pathParams: { id: facilityId },
       body: data,
@@ -123,14 +86,18 @@ export const FacilityConfigure = (props: IProps) => {
     setIsLoading(false);
   };
 
-  const handleChange = (e: FieldChangeEvent<string>) => {
-    dispatch({
-      type: "set_form",
-      form: { ...state.form, [e.name]: e.value },
-    });
-  };
+  const form = useForm({
+    resolver: zodResolver(formSchema),
+    defaultValues: { middleware_address: "" },
+  });
+
+  useEffect(() => {
+    if (data && data.middleware_address) {
+      form.setValue("middleware_address", data.middleware_address);
+    }
+  }, [form, data]);
 
-  if (isLoading || loading) {
+  if (isLoading || !data || loading) {
     return <Loading />;
   }
 
@@ -138,30 +105,42 @@ export const FacilityConfigure = (props: IProps) => {
     <Page
       title="Configure Facility"
       crumbsReplacements={{
-        [facilityId]: { name: state.form.name },
+        [facilityId]: { name: data.name },
       }}
       className="w-full overflow-x-hidden"
     >
       <div className="mx-auto max-w-3xl">
         <div className="cui-card mt-4">
-          <form onSubmit={handleSubmit}>
-            <div className="mt-2 grid grid-cols-1 gap-4">
-              <div>
-                <TextFormField
-                  name="middleware_address"
-                  label="Facility Middleware Address"
-                  message="This address will be applied to all assets when asset and location middleware are Unspecified"
-                  required
-                  value={state.form.middleware_address}
-                  onChange={handleChange}
-                  error={state.errors?.middleware_address}
-                />
+          <Form {...form}>
+            <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
+              <FormField
+                control={form.control}
+                name="middleware_address"
+                render={({ field }) => (
+                  <FormItem>
+                    <FormLabel className="block text-base font-normal text-secondary-900">
+                      Facility Middleware Address
+                      <span className="text-danger-500"> *</span>
+                    </FormLabel>
+                    <FormControl>
+                      <Input
+                        {...field}
+                        placeholder="Enter Middleware Address"
+                      />
+                    </FormControl>
+                    <FormDescription>
+                      This address will be applied to all assets when asset and
+                      location middleware are Unspecified.
+                    </FormDescription>
+                    <FormMessage />
+                  </FormItem>
+                )}
+              />
+              <div className="flex flex-col gap-3 sm:flex-row sm:justify-end">
+                <Submit label="Update" />
               </div>
-            </div>
-            <div className="flex flex-col gap-3 sm:flex-row sm:justify-end">
-              <Submit onClick={handleSubmit} label="Update" />
-            </div>
-          </form>
+            </form>
+          </Form>
         </div>
 
         <PLUGIN_Component
diff --git a/src/components/ui/form.tsx b/src/components/ui/form.tsx
new file mode 100644
index 00000000000..d642a211c7d
--- /dev/null
+++ b/src/components/ui/form.tsx
@@ -0,0 +1,184 @@
+import * as LabelPrimitive from "@radix-ui/react-label";
+import { Slot } from "@radix-ui/react-slot";
+import * as React from "react";
+import {
+  Controller,
+  ControllerProps,
+  FieldPath,
+  FieldValues,
+  FormProvider,
+  useFormContext,
+} from "react-hook-form";
+
+import { cn } from "@/lib/utils";
+
+import { Label } from "@/components/ui/label";
+
+const Form = FormProvider;
+
+type FormFieldContextValue<
+  TFieldValues extends FieldValues = FieldValues,
+  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
+> = {
+  name: TName;
+};
+
+const FormFieldContext = React.createContext<FormFieldContextValue>(
+  {} as FormFieldContextValue,
+);
+
+const FormField = <
+  TFieldValues extends FieldValues = FieldValues,
+  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
+>({
+  ...props
+}: ControllerProps<TFieldValues, TName>) => {
+  return (
+    <FormFieldContext.Provider value={{ name: props.name }}>
+      <Controller {...props} />
+    </FormFieldContext.Provider>
+  );
+};
+
+const useFormField = () => {
+  const fieldContext = React.useContext(FormFieldContext);
+  const itemContext = React.useContext(FormItemContext);
+  const { getFieldState, formState } = useFormContext();
+
+  const fieldState = getFieldState(fieldContext.name, formState);
+
+  if (!fieldContext) {
+    throw new Error("useFormField should be used within <FormField>");
+  }
+
+  const { id } = itemContext;
+
+  return {
+    id,
+    name: fieldContext.name,
+    formItemId: `${id}-form-item`,
+    formDescriptionId: `${id}-form-item-description`,
+    formMessageId: `${id}-form-item-message`,
+    ...fieldState,
+  };
+};
+
+type FormItemContextValue = {
+  id: string;
+};
+
+const FormItemContext = React.createContext<FormItemContextValue>(
+  {} as FormItemContextValue,
+);
+
+const FormItem = React.forwardRef<
+  HTMLDivElement,
+  React.HTMLAttributes<HTMLDivElement>
+>(({ className, ...props }, ref) => {
+  const id = React.useId();
+
+  return (
+    <FormItemContext.Provider value={{ id }}>
+      <div ref={ref} className={cn("space-y-2", className)} {...props} />
+    </FormItemContext.Provider>
+  );
+});
+FormItem.displayName = "FormItem";
+
+const FormLabel = React.forwardRef<
+  React.ElementRef<typeof LabelPrimitive.Root>,
+  React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
+>(({ className, ...props }, ref) => {
+  const { error, formItemId } = useFormField();
+
+  return (
+    <Label
+      ref={ref}
+      className={cn(error && "text-red-500 dark:text-red-900", className)}
+      htmlFor={formItemId}
+      {...props}
+    />
+  );
+});
+FormLabel.displayName = "FormLabel";
+
+const FormControl = React.forwardRef<
+  React.ElementRef<typeof Slot>,
+  React.ComponentPropsWithoutRef<typeof Slot>
+>(({ ...props }, ref) => {
+  const { error, formItemId, formDescriptionId, formMessageId } =
+    useFormField();
+
+  return (
+    <Slot
+      ref={ref}
+      id={formItemId}
+      aria-describedby={
+        !error
+          ? `${formDescriptionId}`
+          : `${formDescriptionId} ${formMessageId}`
+      }
+      aria-invalid={!!error}
+      {...props}
+    />
+  );
+});
+FormControl.displayName = "FormControl";
+
+const FormDescription = React.forwardRef<
+  HTMLParagraphElement,
+  React.HTMLAttributes<HTMLParagraphElement>
+>(({ className, ...props }, ref) => {
+  const { formDescriptionId } = useFormField();
+
+  return (
+    <p
+      ref={ref}
+      id={formDescriptionId}
+      className={cn(
+        "text-[0.8rem] text-gray-500 dark:text-gray-400",
+        className,
+      )}
+      {...props}
+    />
+  );
+});
+FormDescription.displayName = "FormDescription";
+
+const FormMessage = React.forwardRef<
+  HTMLParagraphElement,
+  React.HTMLAttributes<HTMLParagraphElement>
+>(({ className, children, ...props }, ref) => {
+  const { error, formMessageId } = useFormField();
+  const body = error ? String(error?.message) : children;
+
+  if (!body) {
+    return null;
+  }
+
+  return (
+    <p
+      ref={ref}
+      id={formMessageId}
+      className={cn(
+        "text-[0.8rem] font-medium text-red-500 dark:text-red-900",
+        className,
+      )}
+      {...props}
+    >
+      {body}
+    </p>
+  );
+});
+FormMessage.displayName = "FormMessage";
+
+export {
+  useFormField,
+  Form,
+  FormItem,
+  FormLabel,
+  FormControl,
+  FormDescription,
+  FormMessage,
+  FormField,
+};

From c3d564c5c7f412b376c38c68a747dd95fb1b841c Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Wed, 18 Dec 2024 15:59:16 +0530
Subject: [PATCH 14/16] minor changes

---
 src/components/Facility/FacilityConfigure.tsx | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/components/Facility/FacilityConfigure.tsx b/src/components/Facility/FacilityConfigure.tsx
index 501b6959fd3..d6bab357bfd 100644
--- a/src/components/Facility/FacilityConfigure.tsx
+++ b/src/components/Facility/FacilityConfigure.tsx
@@ -65,11 +65,10 @@ export const FacilityConfigure = (props: IProps) => {
     };
 
     setIsLoading(true);
-    console.log(formData);
 
     const { res, error } = await request(routes.partialUpdateFacility, {
       pathParams: { id: facilityId },
-      body: data,
+      body: formData,
     });
 
     setIsLoading(false);

From 9aca644707c6f85bac7b8da08ef0353eae255884 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Tue, 24 Dec 2024 14:14:45 +0530
Subject: [PATCH 15/16] used useMutation and shadcn button in faciility
 configuration page

---
 src/components/Facility/FacilityConfigure.tsx | 58 ++++++++++---------
 1 file changed, 30 insertions(+), 28 deletions(-)

diff --git a/src/components/Facility/FacilityConfigure.tsx b/src/components/Facility/FacilityConfigure.tsx
index d6bab357bfd..8dee8f47163 100644
--- a/src/components/Facility/FacilityConfigure.tsx
+++ b/src/components/Facility/FacilityConfigure.tsx
@@ -1,11 +1,13 @@
 import { zodResolver } from "@hookform/resolvers/zod";
-import { useQuery } from "@tanstack/react-query";
+import { useMutation, useQuery } from "@tanstack/react-query";
 import { t } from "i18next";
 import { navigate } from "raviger";
-import { useEffect, useState } from "react";
+import { useEffect } from "react";
 import { useForm } from "react-hook-form";
 import { z } from "zod";
 
+import CareIcon from "@/CAREUI/icons/CareIcon";
+
 import {
   Form,
   FormControl,
@@ -23,10 +25,10 @@ import Page from "@/components/Common/Page";
 import { PLUGIN_Component } from "@/PluginEngine";
 import * as Notification from "@/Utils/Notifications";
 import routes from "@/Utils/request/api";
+import mutate from "@/Utils/request/mutate";
 import query from "@/Utils/request/query";
-import request from "@/Utils/request/request";
 
-import { Submit } from "../Common/ButtonV2";
+import { Button } from "../ui/button";
 
 interface IProps {
   facilityId: string;
@@ -43,16 +45,27 @@ const formSchema = z.object({
 
 export const FacilityConfigure = (props: IProps) => {
   const { facilityId } = props;
-  const [isLoading, setIsLoading] = useState(false);
 
-  const { isPending: loading, data } = useQuery({
+  const { isPending: queryLoading, data } = useQuery({
     queryKey: [routes.getPermittedFacility.path, facilityId],
     queryFn: query(routes.getPermittedFacility, {
       pathParams: { id: facilityId },
     }),
   });
 
-  const onSubmit = async (values: z.infer<typeof formSchema>) => {
+  const { isPending: mutateLoading, mutate: updateFacility } = useMutation({
+    mutationFn: mutate(routes.partialUpdateFacility, {
+      pathParams: { id: facilityId },
+    }),
+    onSuccess: () => {
+      Notification.Success({
+        msg: t("update_facility_middleware_success"),
+      });
+      navigate(`/facility/${facilityId}`);
+    },
+  });
+
+  const onSubmit = (values: z.infer<typeof formSchema>) => {
     if (!data) return;
 
     const formData = {
@@ -64,25 +77,7 @@ export const FacilityConfigure = (props: IProps) => {
       middleware_address: values.middleware_address,
     };
 
-    setIsLoading(true);
-
-    const { res, error } = await request(routes.partialUpdateFacility, {
-      pathParams: { id: facilityId },
-      body: formData,
-    });
-
-    setIsLoading(false);
-    if (res?.ok) {
-      Notification.Success({
-        msg: t("update_facility_middleware_success"),
-      });
-      navigate(`/facility/${facilityId}`);
-    } else {
-      Notification.Error({
-        msg: error?.detail ?? "Something went wrong",
-      });
-    }
-    setIsLoading(false);
+    updateFacility(formData);
   };
 
   const form = useForm({
@@ -96,7 +91,7 @@ export const FacilityConfigure = (props: IProps) => {
     }
   }, [form, data]);
 
-  if (isLoading || !data || loading) {
+  if (queryLoading || !data || mutateLoading) {
     return <Loading />;
   }
 
@@ -136,7 +131,14 @@ export const FacilityConfigure = (props: IProps) => {
                 )}
               />
               <div className="flex flex-col gap-3 sm:flex-row sm:justify-end">
-                <Submit label="Update" />
+                <Button
+                  variant="primary"
+                  type="submit"
+                  className="bg-primary-500 gap-2 px-4 py-2 rounded-sm hover:bg-primary-400"
+                >
+                  <CareIcon icon="l-check-circle" className="text-lg" />
+                  Update
+                </Button>
               </div>
             </form>
           </Form>

From ccf886f9c6382454e8e76f00a57610e429c218e2 Mon Sep 17 00:00:00 2001
From: Saikiran Patil <84263946+saikiranpatil@users.noreply.github.com>
Date: Sat, 28 Dec 2024 22:47:15 +0530
Subject: [PATCH 16/16] used shadcn buttons in location management page

---
 src/components/Common/AuthorizedButton.tsx    |   2 +-
 src/components/Common/CancelButton.tsx        |  32 ++++++
 src/components/Facility/FacilityConfigure.tsx |   3 +-
 .../Facility/LocationManagement.tsx           | 107 +++++++++++-------
 4 files changed, 99 insertions(+), 45 deletions(-)
 create mode 100644 src/components/Common/CancelButton.tsx

diff --git a/src/components/Common/AuthorizedButton.tsx b/src/components/Common/AuthorizedButton.tsx
index 2b611a0c9f2..94eca834f00 100644
--- a/src/components/Common/AuthorizedButton.tsx
+++ b/src/components/Common/AuthorizedButton.tsx
@@ -5,7 +5,7 @@ import AuthorizedChild from "@/CAREUI/misc/AuthorizedChild";
 import { AuthorizedElementProps } from "@/Utils/AuthorizeFor";
 
 export const AuthorizedButton: React.FC<
-  AuthorizedElementProps & ButtonProps
+  AuthorizedElementProps & ButtonProps & { variant?: string }
 > = ({ authorizeFor = () => true, ...props }) => {
   return (
     <AuthorizedChild authorizeFor={authorizeFor}>
diff --git a/src/components/Common/CancelButton.tsx b/src/components/Common/CancelButton.tsx
new file mode 100644
index 00000000000..092fbac5398
--- /dev/null
+++ b/src/components/Common/CancelButton.tsx
@@ -0,0 +1,32 @@
+import { useTranslation } from "react-i18next";
+
+import { cn } from "@/lib/utils";
+
+import CareIcon from "@/CAREUI/icons/CareIcon";
+
+import { Button, ButtonProps } from "@/components/ui/button";
+
+export interface CancelButtonProps extends ButtonProps {
+  label?: string;
+}
+
+const CancelButton = ({ label = "Cancel", ...props }: CancelButtonProps) => {
+  const { t } = useTranslation();
+  return (
+    <Button
+      id="cancel"
+      type="button"
+      variant="secondary"
+      {...props}
+      className={cn(
+        "w-full md:w-auto button-secondary-border",
+        props.className,
+      )}
+    >
+      <CareIcon icon="l-times-circle" className="text-lg" />
+      {label && <span className="whitespace-pre-wrap">{t(label)}</span>}
+    </Button>
+  );
+};
+
+export default CancelButton;
diff --git a/src/components/Facility/FacilityConfigure.tsx b/src/components/Facility/FacilityConfigure.tsx
index 8dee8f47163..af4816de0c7 100644
--- a/src/components/Facility/FacilityConfigure.tsx
+++ b/src/components/Facility/FacilityConfigure.tsx
@@ -8,6 +8,7 @@ import { z } from "zod";
 
 import CareIcon from "@/CAREUI/icons/CareIcon";
 
+import { Button } from "@/components/ui/button";
 import {
   Form,
   FormControl,
@@ -28,8 +29,6 @@ import routes from "@/Utils/request/api";
 import mutate from "@/Utils/request/mutate";
 import query from "@/Utils/request/query";
 
-import { Button } from "../ui/button";
-
 interface IProps {
   facilityId: string;
 }
diff --git a/src/components/Facility/LocationManagement.tsx b/src/components/Facility/LocationManagement.tsx
index e9c1323142f..36cd3ce1c26 100644
--- a/src/components/Facility/LocationManagement.tsx
+++ b/src/components/Facility/LocationManagement.tsx
@@ -1,4 +1,5 @@
 import { useQuery } from "@tanstack/react-query";
+import { navigate } from "raviger";
 import { useState } from "react";
 
 import RecordMeta from "@/CAREUI/display/RecordMeta";
@@ -6,8 +7,16 @@ import CareIcon from "@/CAREUI/icons/CareIcon";
 import PaginatedList from "@/CAREUI/misc/PaginatedList";
 
 import { Badge } from "@/components/ui/badge";
+import { Button } from "@/components/ui/button";
+import {
+  Tooltip,
+  TooltipContent,
+  TooltipProvider,
+  TooltipTrigger,
+} from "@/components/ui/tooltip";
 
-import ButtonV2, { Cancel } from "@/components/Common/ButtonV2";
+import { AuthorizedButton } from "@/components/Common/AuthorizedButton";
+import CancelButton from "@/components/Common/CancelButton";
 import ConfirmDialog from "@/components/Common/ConfirmDialog";
 import DialogModal from "@/components/Common/Dialog";
 import Loading from "@/components/Common/Loading";
@@ -101,26 +110,26 @@ export default function LocationManagement({ facilityId }: Props) {
           title="Location Management"
           backUrl={`/facility/${facilityId}`}
           options={
-            <ButtonV2
+            <AuthorizedButton
               id="add-new-location"
-              href={`/facility/${facilityId}/location/add`}
+              onClick={() => navigate(`/facility/${facilityId}/location/add`)}
               authorizeFor={NonReadOnlyUsers}
               className="hidden lg:block"
             >
               <CareIcon icon="l-plus" className="text-lg" />
               Add New Location
-            </ButtonV2>
+            </AuthorizedButton>
           }
         >
           <div className="mx-auto mt-4 lg:mt-0">
-            <ButtonV2
-              href={`/facility/${facilityId}/location/add`}
+            <AuthorizedButton
+              onClick={() => navigate(`/facility/${facilityId}/location/add`)}
               authorizeFor={NonReadOnlyUsers}
               className="w-full lg:hidden"
             >
               <CareIcon icon="l-plus" className="text-lg" />
               Add New Location
-            </ButtonV2>
+            </AuthorizedButton>
           </div>
           <div className="w-full @container">
             <PaginatedList.WhenEmpty className="flex w-full justify-center border-b border-secondary-200 bg-white p-5 text-center text-2xl font-bold text-secondary-500">
@@ -186,19 +195,23 @@ export default function LocationManagement({ facilityId }: Props) {
                     deleted first before the location can be removed
                   </div>
                   <div className="mt-2 flex flex-col justify-end gap-2 md:flex-row">
-                    <Cancel
+                    <CancelButton
                       onClick={() => {
                         closeDeleteFailModal();
                       }}
                     />
-                    <ButtonV2
+                    <AuthorizedButton
                       id="manage-beds"
-                      href={`/facility/${facilityId}/location/${showDeleteFailModal.id}/beds`}
+                      onClick={() =>
+                        navigate(
+                          `/facility/${facilityId}/location/${showDeleteFailModal.id}/beds`,
+                        )
+                      }
                       authorizeFor={NonReadOnlyUsers}
                       className="w-full"
                     >
                       Manage Beds
-                    </ButtonV2>
+                    </AuthorizedButton>
                   </div>
                 </div>
               ) : (
@@ -208,19 +221,23 @@ export default function LocationManagement({ facilityId }: Props) {
                     be deleted first before the location can be removed
                   </div>
                   <div className="mt-2 flex flex-col justify-end gap-2 md:flex-row">
-                    <Cancel
+                    <CancelButton
                       onClick={() => {
                         closeDeleteFailModal();
                       }}
                     />
-                    <ButtonV2
+                    <AuthorizedButton
                       id="manage-assets"
-                      href={`/assets?page=1&limit=18&facility=${facilityId}&asset_type=&asset_class=&status=&location=${showDeleteFailModal.id}&warranty_amc_end_of_validity_before=&warranty_amc_end_of_validity_after=`}
+                      onClick={() =>
+                        navigate(
+                          `/assets?page=1&limit=18&facility=${facilityId}&asset_type=&asset_class=&status=&location=${showDeleteFailModal.id}&warranty_amc_end_of_validity_before=&warranty_amc_end_of_validity_after=`,
+                        )
+                      }
                       authorizeFor={NonReadOnlyUsers}
                       className="w-full"
                     >
                       Manage Assets
-                    </ButtonV2>
+                    </AuthorizedButton>
                   </div>
                 </div>
               )}
@@ -305,12 +322,11 @@ const Location = ({
         />
       </div>
 
-      <ButtonV2
+      <Button
         id="manage-bed-button"
         variant="secondary"
-        border
-        className="mt-3 flex w-full items-center justify-between"
-        href={`location/${id}/beds`}
+        className="mt-3 flex w-full items-center justify-between button-secondary-border"
+        onClick={() => navigate(`location/${id}/beds`)}
         disabled={totalBeds == null}
       >
         Manage Beds
@@ -318,39 +334,46 @@ const Location = ({
           <CareIcon icon="l-bed" className="text-lg" />
           {totalBeds ?? "--"}
         </span>
-      </ButtonV2>
+      </Button>
       <div className="mt-2 flex w-full flex-col gap-2 md:flex-row">
         <div className="w-full md:w-1/2">
-          <ButtonV2
+          <AuthorizedButton
             id="edit-location-button"
             variant="secondary"
-            border
-            className="w-full"
-            href={`location/${id}/update`}
+            className="w-full button-secondary-border"
+            onClick={() => navigate(`location/${id}/update`)}
             authorizeFor={NonReadOnlyUsers}
           >
             <CareIcon icon="l-pen" className="text-lg" />
             Edit
-          </ButtonV2>
+          </AuthorizedButton>
         </div>
         <div className="w-full md:w-1/2">
-          <ButtonV2
-            authorizeFor={AuthorizeFor(["DistrictAdmin", "StateAdmin"])}
-            id="delete-location-button"
-            variant="secondary"
-            border
-            className="w-full"
-            tooltip={
-              disabled ? "Contact your admin to delete the location" : ""
-            }
-            tooltipClassName=" text-xs w-full lg:w-auto"
-            onClick={() =>
-              setShowDeletePopup({ open: true, name: name ?? "", id: id ?? "" })
-            }
-          >
-            <CareIcon icon="l-trash" className="text-lg" />
-            Delete
-          </ButtonV2>
+          <TooltipProvider>
+            <Tooltip>
+              <TooltipTrigger asChild>
+                <AuthorizedButton
+                  authorizeFor={AuthorizeFor(["DistrictAdmin", "StateAdmin"])}
+                  id="delete-location-button"
+                  variant="secondary"
+                  className="w-full button-secondary-border"
+                  onClick={() =>
+                    setShowDeletePopup({
+                      open: true,
+                      name: name ?? "",
+                      id: id ?? "",
+                    })
+                  }
+                >
+                  <CareIcon icon="l-trash" className="text-lg" />
+                  Delete
+                </AuthorizedButton>
+              </TooltipTrigger>
+              <TooltipContent className="text-xs w-full lg:w-auto">
+                {disabled ? "Contact your admin to delete the location" : ""}
+              </TooltipContent>
+            </Tooltip>
+          </TooltipProvider>
         </div>
       </div>