Repository: ohcnetwork/care_fe
Pull request #10950: Add Support for Location Association History of Devices
Author: login: rajku-dev
Labels: name: needs testing
name: needs review
Created: 2025-03-03T04:21:25Z | Merged: 2025-03-04T12:27:14Z

## Proposed Changes

- Fixes #10823 

![image](https://github.com/user-attachments/assets/889ac996-61e0-4668-8c9c-c9786592ac5d)
![image](https://github.com/user-attachments/assets/b4e8972c-541c-4267-b034-c92d0c8d8ddf)

@ohcnetwork/care-fe-code-reviewers

## Merge Checklist

- [ ] Add specs that demonstrate bug / test a new feature.
- [ ] Update [product documentation](https://docs.ohc.network).
- [ ] Ensure that UI text is kept in I18n files.
- [ ] Prep screenshot or demo video for changelog entry, and attach it to issue.
- [ ] Request for Peer Reviews
- [ ] Completion of QA


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Introduced a new "Device Location History" navigation option in the device details view, allowing quick access to location history.
  - Added a dedicated page that displays detailed device location history with intuitive pagination and responsive design.
  - Enhanced data refresh behavior to ensure the displayed location history remains current.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Linked issue #10823: Show location association history of devices
**Is your feature request related to a problem? Please describe.**
Devices can be associated to a location. 
Show history of location association for a device.

**Describe the solution you'd like**

Refer: https://careapi.ohc.network/swagger/#/device_location_history/api_v1_facility_device_location_history_list



Linked issue comments: user: login: Sulochan-khadka
created_at: 2025-02-26T10:37:31Z
body: @rithviknishad could you assgin this to me

author_association: CONTRIBUTOR
user: login: AdityaJ2305
created_at: 2025-02-26T10:40:17Z
body: Hey @rithviknishad , I would like to work on this issue 

author_association: MEMBER
user: login: Mahendar0701
created_at: 2025-02-26T10:41:41Z
body: @rithviknishad i would like to work on this
author_association: CONTRIBUTOR
user: login: rithviknishad
created_at: 2025-02-27T16:19:10Z
body: Will reassign with an ETA provided for when this would be completed;
author_association: MEMBER
user: login: Sulochan-khadka
created_at: 2025-02-27T16:26:03Z
body: @rithviknishad i was working on it, but had certain doubts... Like its significance, and the implementation of it... Will update you when i am done...
author_association: CONTRIBUTOR
user: login: rajku-dev
created_at: 2025-03-02T17:22:20Z
body: @rithviknishad I would like to work on this, since encounter history is done in my another PR opened
ETA : 4 March
author_association: CONTRIBUTOR

Diff:
diff --git a/public/locale/en.json b/public/locale/en.json
index 9d6df393904..868701b253b 100644
--- a/public/locale/en.json
+++ b/public/locale/en.json
@@ -782,6 +782,7 @@
   "device_availability_status_lost": "Lost",
   "device_contact_description": "Contact points associated with this device",
   "device_information": "Device Information",
+  "device_location_history": "Device Location History",
   "device_not_found": "Device not found",
   "device_status_active": "Active",
   "device_status_entered_in_error": "Entered in Error",
diff --git a/src/pages/Facility/settings/devices/DeviceDetail.tsx b/src/pages/Facility/settings/devices/DeviceDetail.tsx
index d252f111c08..407005ed07f 100644
--- a/src/pages/Facility/settings/devices/DeviceDetail.tsx
+++ b/src/pages/Facility/settings/devices/DeviceDetail.tsx
@@ -7,6 +7,8 @@ import { useTranslation } from "react-i18next";
 
 import { cn } from "@/lib/utils";
 
+import CareIcon from "@/CAREUI/icons/CareIcon";
+
 import {
   AlertDialog,
   AlertDialogAction,
@@ -144,6 +146,12 @@ export default function DeviceDetail({ facilityId, deviceId }: Props) {
       <div className="flex items-center justify-between">
         <PageTitle title={device.registered_name} />
         <div className="flex items-center gap-2">
+          <Link href={`/devices/${deviceId}/locationHistory`}>
+            <Button variant="outline_primary" className="mr-3">
+              <CareIcon icon="l-location-point" className="h-4 w-4" />
+              {t("location_history")}
+            </Button>
+          </Link>
           <Link href={`/devices/${deviceId}/edit`}>
             <Button variant="outline">{t("edit")}</Button>
           </Link>
diff --git a/src/pages/Facility/settings/devices/DeviceLocationHistory.tsx b/src/pages/Facility/settings/devices/DeviceLocationHistory.tsx
new file mode 100644
index 00000000000..60367aa2dff
--- /dev/null
+++ b/src/pages/Facility/settings/devices/DeviceLocationHistory.tsx
@@ -0,0 +1,100 @@
+import { useQuery } from "@tanstack/react-query";
+import { useQueryParams } from "raviger";
+import { useTranslation } from "react-i18next";
+
+import { cn } from "@/lib/utils";
+
+import Page from "@/components/Common/Page";
+import PaginationComponent from "@/components/Common/Pagination";
+import { CardListSkeleton } from "@/components/Common/SkeletonLoading";
+
+import { RESULTS_PER_PAGE_LIMIT } from "@/common/constants";
+
+import query from "@/Utils/request/query";
+import { DeviceLocationCard } from "@/pages/Facility/settings/devices/components/DeviceLocationCard";
+import deviceApi from "@/types/device/deviceApi";
+
+interface Props {
+  facilityId: string;
+  deviceId: string;
+}
+
+const DeviceLocationHistory = ({ facilityId, deviceId }: Props) => {
+  const { t } = useTranslation();
+
+  const [qParams, setQueryParams] = useQueryParams<{ page?: number }>();
+
+  const { data: locationsData, isLoading } = useQuery({
+    queryKey: ["deviceLocationHistory", facilityId, deviceId, qParams],
+    queryFn: query(deviceApi.locationHistory, {
+      queryParams: {
+        limit: RESULTS_PER_PAGE_LIMIT,
+        offset: ((qParams.page ?? 1) - 1) * RESULTS_PER_PAGE_LIMIT,
+      },
+      pathParams: {
+        facilityId,
+        id: deviceId,
+      },
+    }),
+  });
+
+  return (
+    <Page title={t("device_location_history")} className="mt-8">
+      <div>
+        {isLoading ? (
+          <div>
+            <div className="grid gap-5 my-5">
+              <CardListSkeleton count={RESULTS_PER_PAGE_LIMIT} />
+            </div>
+          </div>
+        ) : (
+          <div>
+            {locationsData?.results?.length === 0 ? (
+              <div className="p-2">
+                <div className="h-full space-y-2 rounded-lg bg-white px-7 py-12 border border-secondary-300">
+                  <div className="flex w-full items-center justify-center text-lg text-secondary-600">
+                    <div className="h-full flex w-full items-center justify-center">
+                      <span className="text-sm text-gray-500">
+                        {t("no_locations_found")}
+                      </span>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            ) : (
+              <ul className="grid gap-4 my-5">
+                {locationsData?.results?.map((locationData) => (
+                  <li key={locationData.id} className="w-full">
+                    <DeviceLocationCard
+                      key={locationData.id}
+                      locationData={locationData}
+                    />
+                  </li>
+                ))}
+                <div className="flex w-full items-center justify-center">
+                  <div
+                    className={cn(
+                      "flex w-full justify-center",
+                      (locationsData?.count ?? 0) > RESULTS_PER_PAGE_LIMIT
+                        ? "visible"
+                        : "invisible",
+                    )}
+                  >
+                    <PaginationComponent
+                      cPage={qParams.page ?? 1}
+                      defaultPerPage={RESULTS_PER_PAGE_LIMIT}
+                      data={{ totalCount: locationsData?.count ?? 0 }}
+                      onChange={(page) => setQueryParams({ page })}
+                    />
+                  </div>
+                </div>
+              </ul>
+            )}
+          </div>
+        )}
+      </div>
+    </Page>
+  );
+};
+
+export default DeviceLocationHistory;
diff --git a/src/pages/Facility/settings/devices/components/AssociateLocationSheet.tsx b/src/pages/Facility/settings/devices/components/AssociateLocationSheet.tsx
index 86b1c8c0761..046f4a47015 100644
--- a/src/pages/Facility/settings/devices/components/AssociateLocationSheet.tsx
+++ b/src/pages/Facility/settings/devices/components/AssociateLocationSheet.tsx
@@ -46,6 +46,9 @@ export default function AssociateLocationSheet({
       queryClient.invalidateQueries({
         queryKey: ["device", facilityId, deviceId],
       });
+      queryClient.invalidateQueries({
+        queryKey: ["deviceLocationHistory", facilityId, deviceId],
+      });
       toast.success(t("location_associated_successfully"));
       onOpenChange(false);
       setSelectedLocation(null);
diff --git a/src/pages/Facility/settings/devices/components/DeviceLocationCard.tsx b/src/pages/Facility/settings/devices/components/DeviceLocationCard.tsx
new file mode 100644
index 00000000000..b7b1abecbd6
--- /dev/null
+++ b/src/pages/Facility/settings/devices/components/DeviceLocationCard.tsx
@@ -0,0 +1,81 @@
+import { t } from "i18next";
+import { Link } from "raviger";
+
+import CareIcon from "@/CAREUI/icons/CareIcon";
+
+import { Badge } from "@/components/ui/badge";
+import { Card, CardContent } from "@/components/ui/card";
+
+import { formatDateTime } from "@/Utils/utils";
+import { DeviceLocationHistory } from "@/types/device/device";
+
+interface LocationCardProps {
+  locationData: DeviceLocationHistory;
+}
+
+export const DeviceLocationCard = ({ locationData }: LocationCardProps) => {
+  const { start, end, location, created_by } = locationData;
+
+  return (
+    <Card className="flex-1 p-4">
+      <CardContent className="p-4 sm:p-3 space-y-4">
+        <div className="flex flex-wrap gap-6 sm:gap-6">
+          <div className="flex gap-3 text-xl font-semibold capitalize">
+            <Link
+              href={`/location/${location.id}`}
+              className="text-gray-950 font-semibold flex items-start gap-0.5"
+              id="patient-details"
+            >
+              {location.name}
+              <CareIcon
+                icon="l-external-link-alt"
+                className="w-3 h-3 opacity-50 mt-1"
+              />
+            </Link>
+          </div>
+        </div>
+
+        <div className="flex gap-3">
+          <h2 className="text-lg font-semibold">{t("locations")}</h2>
+          <Badge variant="outline">
+            {t(`location_form__${location?.form}`)}
+          </Badge>
+          <Badge
+            variant={location?.status === "active" ? "default" : "secondary"}
+          >
+            {location?.status}
+          </Badge>
+        </div>
+
+        <div className="grid sm:flex sm:flex-wrap gap-7">
+          <div className="w-full mx-2 sm:w-auto">
+            <div className="text-gray-600 text-sm">{t("associated_by")}</div>
+            <div className="font-semibold text-base flex items-center gap-2">
+              {`${created_by.first_name} ${created_by.last_name}`}
+            </div>
+          </div>
+
+          <div className="w-full mx-3 sm:w-auto">
+            <div className="text-gray-600 text-sm">
+              {t("association_start_date")}
+            </div>
+            <div className="font-semibold text-base">
+              {start ? formatDateTime(start) : t("not_started")}
+            </div>
+          </div>
+
+          {
+            <div className="w-full mx-3 sm:w-auto">
+              <div className="text-gray-600 text-sm">
+                {t("association_end_date")}
+              </div>
+              <div className="font-semibold text-base">
+                {end ? formatDateTime(end) : "-"}
+              </div>
+            </div>
+          }
+        </div>
+      </CardContent>
+    </Card>
+  );
+};
diff --git a/src/pages/Facility/settings/layout.tsx b/src/pages/Facility/settings/layout.tsx
index 6d256ec4cff..c92dec3537d 100644
--- a/src/pages/Facility/settings/layout.tsx
+++ b/src/pages/Facility/settings/layout.tsx
@@ -8,6 +8,7 @@ import ErrorPage from "@/components/ErrorPages/DefaultErrorPage";
 
 import CreateDevice from "@/pages/Facility/settings/devices/CreateDevice";
 import DeviceDetail from "@/pages/Facility/settings/devices/DeviceDetail";
+import DeviceLocationHistory from "@/pages/Facility/settings/devices/DeviceLocationHistory";
 import DevicesList from "@/pages/Facility/settings/devices/DevicesList";
 import UpdateDevice from "@/pages/Facility/settings/devices/UpdateDevice";
 
@@ -43,6 +44,9 @@ const getRoutes = (facilityId: string) => ({
   "/devices/:id/edit": ({ id }: { id: string }) => (
     <UpdateDevice facilityId={facilityId} deviceId={id} />
   ),
+  "/devices/:id/locationHistory": ({ id }: { id: string }) => (
+    <DeviceLocationHistory facilityId={facilityId} deviceId={id} />
+  ),
   "*": () => <ErrorPage />,
 });
 
diff --git a/src/types/device/device.ts b/src/types/device/device.ts
index 60ec9aa9ff8..6c24e9a7e39 100644
--- a/src/types/device/device.ts
+++ b/src/types/device/device.ts
@@ -50,4 +50,12 @@ export interface DeviceList extends DeviceBase {
   id: string;
 }
 
+export interface DeviceLocationHistory {
+  id: string;
+  created_by: UserBase;
+  location: LocationList;
+  start: string;
+  end: string;
+}
+
 export type DeviceWrite = DeviceBase;
diff --git a/src/types/device/deviceApi.ts b/src/types/device/deviceApi.ts
index 929c13a25a6..330460bf923 100644
--- a/src/types/device/deviceApi.ts
+++ b/src/types/device/deviceApi.ts
@@ -1,7 +1,12 @@
 import { HttpMethod, Type } from "@/Utils/request/api";
 import { PaginatedResponse } from "@/Utils/request/types";
 
-import { DeviceDetail, DeviceList, DeviceWrite } from "./device";
+import {
+  DeviceDetail,
+  DeviceList,
+  DeviceLocationHistory,
+  DeviceWrite,
+} from "./device";
 
 export default {
   list: {
@@ -44,4 +49,9 @@ export default {
     TRes: Type<DeviceDetail>(),
     TBody: Type<{ location: string }>(),
   },
+  locationHistory: {
+    path: "/api/v1/facility/{facilityId}/device/{id}/location_history/",
+    method: HttpMethod.GET,
+    TRes: Type<PaginatedResponse<DeviceLocationHistory>>(),
+  },
 };


Reviews:
user: login: rithviknishad
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T05:35:02Z
user: login: rajku-dev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T08:44:36Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 3**

<details>
<summary>🧹 Nitpick comments (4)</summary><blockquote>

<details>
<summary>src/types/device/device.ts (1)</summary><blockquote>

`53-59`: **Well-structured interface for device location history**

The interface provides all necessary fields to track when a device was associated with a location, who created the association, and the duration of the association.


Consider adding optional documentation comments to clarify that:
1. `start` and `end` are timestamps
2. `end` would be null/empty for the current active location

```diff
export interface DeviceLocationHistory {
  id: string;
  created_by: UserBase;
  location: LocationList;
+  /** ISO timestamp when this location association started */
  start: string;
+  /** ISO timestamp when this location association ended, empty for current active location */
  end: string;
}
```

</blockquote></details>
<details>
<summary>src/pages/Facility/settings/devices/components/DeviceLocationCard.tsx (2)</summary><blockquote>

`50-77`: **Consider adding a tooltip for dates that need explanation**

For dates like association start and end, users might benefit from a tooltip explaining what these dates represent, especially for the case when end date is missing (displayed as "-").

```diff
<div className="font-semibold text-base">
-  {end ? formatDateTime(end) : "-"}
+  <span title={!end ? t("currently_associated") : ""}>
+    {end ? formatDateTime(end) : "-"}
+  </span>
</div>
```

---

`19-81`: **Improve responsive design for better mobile experience**

The current layout may not provide optimal spacing on very small screens. Consider adjusting the spacing and grid layout for better mobile experience.

```diff
-<Card className="flex-1 p-4">
+<Card className="flex-1 p-3 sm:p-4">
-  <CardContent className="p-4 sm:p-3 space-y-4">
+  <CardContent className="p-3 sm:p-4 space-y-3 sm:space-y-4">
   
     {/* Rest of the content */}
   
-    <div className="grid sm:flex sm:flex-wrap gap-7">
+    <div className="grid grid-cols-1 sm:flex sm:flex-wrap gap-4 sm:gap-7">
```

</blockquote></details>
<details>
<summary>src/pages/Facility/settings/devices/DeviceLocationHistory.tsx (1)</summary><blockquote>

`65-73`: **Consider adding a separator or timestamp between location entries**

To improve readability and distinguish between different location history entries, consider adding a visual separator or timestamp indicator between entries. This can help users better understand the chronological sequence of location changes.

```diff
<ul className="grid gap-4 my-5">
  {locationsData?.results?.map((locationData) => (
-    <li key={locationData.id} className="w-full">
+    <li key={locationData.id} className="w-full relative">
+      {locationData.start && (
+        <div className="absolute -left-3 h-full w-1 bg-gray-200 rounded-full"></div>
+      )}
      <DeviceLocationCard
        key={locationData.id}
        locationData={locationData}
      />
    </li>
  ))}
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 91601ee3ead5a9ab1706c1f498d5c57b57c29b7e and 5bd74bf8f4a42b586cb1f20eea588b6a055ff80c.

</details>

<details>
<summary>📒 Files selected for processing (8)</summary>

* `public/locale/en.json` (1 hunks)
* `src/pages/Facility/settings/devices/DeviceDetail.tsx` (2 hunks)
* `src/pages/Facility/settings/devices/DeviceLocationHistory.tsx` (1 hunks)
* `src/pages/Facility/settings/devices/components/AssociateLocationSheet.tsx` (1 hunks)
* `src/pages/Facility/settings/devices/components/DeviceLocationCard.tsx` (1 hunks)
* `src/pages/Facility/settings/layout.tsx` (2 hunks)
* `src/types/device/device.ts` (1 hunks)
* `src/types/device/deviceApi.ts` (2 hunks)

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (1)</summary>

* GitHub Check: cypress-run (1)

</details>

<details>
<summary>🔇 Additional comments (18)</summary><blockquote>

<details>
<summary>public/locale/en.json (1)</summary>

`785-785`: **Added localization for Device Location History feature**

Good addition of the localization key for the new device location history feature.

</details>
<details>
<summary>src/pages/Facility/settings/devices/components/AssociateLocationSheet.tsx (1)</summary>

`49-51`: **Properly invalidating location history queries after mutation**

Good implementation of cache invalidation for the device location history after associating a new location. This ensures that the UI will display the most up-to-date information.

</details>
<details>
<summary>src/types/device/deviceApi.ts (1)</summary>

`4-9`: **Well-organized imports for device types**

Clean organization of imports to include the new `DeviceLocationHistory` type.

</details>
<details>
<summary>src/pages/Facility/settings/devices/components/DeviceLocationCard.tsx (5)</summary>

`1-15`: **Component structure and props look well-defined**

The `DeviceLocationCard` component has a clean interface with properly typed props. The use of the `DeviceLocationHistory` type ensures type safety for the component's data requirements.

---

`16-35`: **Good implementation of location link with proper accessibility**

The component correctly extracts data from the `locationData` prop and provides a proper link to navigate to the location details. The addition of the external link icon is a good UI pattern to indicate navigation.

---

`38-48`: **Appropriate use of badges for visual status indicators**

The badges for location form and status provide clear visual indicators with proper styling. The variant selection based on active status is a good practice.

---

`58-61`: **Confirm translations are available**

Based on the past review comment, these translation keys are defined in the encounter history PR. Please ensure that these translations are merged or available when this PR is deployed.

---

`63-74`: **Proper date handling with fallback**

Good implementation of date formatting with appropriate fallback for null values. The usage of the `formatDateTime` utility ensures consistent date formatting across the application.

</details>
<details>
<summary>src/pages/Facility/settings/devices/DeviceDetail.tsx (2)</summary>

`10-11`: **Appropriate import addition**

Good addition of the CareIcon import which is needed for the new location history button.

---

`149-155`: **Well-implemented location history button**

The location history button is correctly implemented with appropriate styling, icon and translation key. The positioning next to the edit button is logical from a UX perspective.

</details>
<details>
<summary>src/pages/Facility/settings/layout.tsx (3)</summary>

`11-11`: **Appropriate component import**

The import for the DeviceLocationHistory component is correctly added.

---

`47-49`: **Well-defined route configuration**

The route for device location history is properly defined with the correct props being passed to the component.

---

`47-49`: <details>
<summary>✅ Verification successful</summary>

**Verify URL consistency with the Link in DeviceDetail component**

The route pattern here is `/devices/:id/locationHistory` but in DeviceDetail.tsx, the href is structured as `/devices/${deviceId}/locationHistory`. Make sure these are consistent in the entire application context (especially considering the facility prefix).

---

🏁 Script executed:

```shell
#!/bin/bash
# Description: Check for consistency between route definitions and link hrefs for device location history

# Find route definition for device location history
echo "Route definition in layout.tsx:"
rg -A 1 "devices/:id/locationHistory" --glob "*.tsx"

# Find links to device location history
echo "Links to device location history:"
rg -A 1 "devices/.*locationHistory" --glob "*.tsx" | grep -E "href|to"
```

Length of output: 928

---



</details>

**URL Consistency Verified**  
The device location history route in `src/pages/Facility/settings/layout.tsx` (`"/devices/:id/locationHistory"`) is used consistently with the link in `DeviceDetail.tsx` (`<Link href={`/devices/${deviceId}/locationHistory`}>`). Both paths follow the same structure. Please ensure that any facility prefixing intended by the application's routing architecture is correctly handled at the parent level.

</details>
<details>
<summary>src/pages/Facility/settings/devices/DeviceLocationHistory.tsx (5)</summary>

`1-16`: **Proper imports and interface definition**

All necessary imports are included and the Props interface is well-defined with appropriate types.

---

`27-39`: **Well-implemented data fetching with React Query**

The component correctly uses the useQuery hook with appropriate queryKey dependencies including pagination parameters. The query function is properly structured with the necessary path and query parameters.

---

`44-49`: **Good loading state implementation**

The component properly handles the loading state by showing a skeleton loader, which provides a better user experience than a blank screen or loading spinner.

---

`52-63`: **Appropriate empty state handling**

The component correctly handles the case when no location data is found by displaying a user-friendly message.

---

`74-90`: **Well-implemented pagination**

The pagination component is properly implemented with conditional visibility based on result count, and it correctly updates the query parameters when page changes.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T08:51:07Z
user: login: Jacobjeevan
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-04T09:36:28Z
user: login: khavinshankar
body: Nice work
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-04T12:27:05Z

Review comments:
diff_hunk: @@ -50,4 +50,14 @@ export interface DeviceList extends DeviceBase {
   id: string;
 }
 
+export interface DeviceHistoryBase {
+  id: string;
+  created_by: UserBase;
+  start: string;
+  end: string;
+}
+export interface DeviceLocations extends DeviceHistoryBase {
+  location: LocationList;
+}
path: src/types/device/device.ts
user: login: rithviknishad
body: let's keep it simple? 🤔 1 interface for "DeviceLocationHistory"
created_at: 2025-03-03T05:34:58Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,81 @@
+import { t } from "i18next";
+import { Link } from "raviger";
+
+import CareIcon from "@/CAREUI/icons/CareIcon";
+
+import { Badge } from "@/components/ui/badge";
+import { Card, CardContent } from "@/components/ui/card";
+
+import { formatDateTime } from "@/Utils/utils";
+import { DeviceLocationHistory } from "@/types/device/device";
+
+interface LocationCardProps {
+  locationData: DeviceLocationHistory;
+}
+
+export const DeviceLocationCard = ({ locationData }: LocationCardProps) => {
+  const { start, end, location, created_by } = locationData;
+
+  return (
+    <Card className="flex-1 p-4">
+      <CardContent className="p-4 sm:p-3 space-y-4">
+        <div className="flex flex-wrap gap-6 sm:gap-6">
+          <div className="flex gap-3 text-xl font-semibold capitalize">
+            <Link
+              href={`/location/${location.id}`}
+              className="text-gray-950 font-semibold flex items-start gap-0.5"
+              id="patient-details"
+            >
+              {location.name}
+              <CareIcon
+                icon="l-external-link-alt"
+                className="w-3 h-3 opacity-50 mt-1"
+              />
+            </Link>
+          </div>
+        </div>
+
+        <div className="flex gap-3">
+          <h2 className="text-lg font-semibold">{t("locations")}</h2>
+          <Badge variant="outline">
+            {t(`location_form__${location?.form}`)}
+          </Badge>
+          <Badge
+            variant={location?.status === "active" ? "default" : "secondary"}
+          >
+            {location?.status}
+          </Badge>
+        </div>
+
+        <div className="grid sm:flex sm:flex-wrap gap-7">
+          <div className="w-full mx-2 sm:w-auto">
+            <div className="text-gray-600 text-sm">{t("associated_by")}</div>
+            <div className="font-semibold text-base flex items-center gap-2">
+              {`${created_by.first_name} ${created_by.last_name}`}
+            </div>
+          </div>
+
+          <div className="w-full mx-3 sm:w-auto">
+            <div className="text-gray-600 text-sm">
+              {t("association_start_date")}
+            </div>
path: src/pages/Facility/settings/devices/components/DeviceLocationCard.tsx
user: login: rajku-dev
body: translations for these keys are defined in encounter history PR #10904 
created_at: 2025-03-03T08:44:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -44,4 +49,9 @@ export default {
     TRes: Type<DeviceDetail>(),
     TBody: Type<{ location: string }>(),
   },
+  locationHistory: {
+    path: "/api/v1/facility/{facilityId}/device/{id}/location_history/",
+    method: HttpMethod.GET,
+    TRes: Type<PaginatedResponse<DeviceLocationHistory>>(),
+  },
path: src/types/device/deviceApi.ts
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**Inconsistent parameter naming in API path**

There's an inconsistency in the parameter naming convention in the API path. Other endpoints use snake_case `facility_id` while this new endpoint uses camelCase `facilityId`.


```diff
locationHistory: {
-  path: "/api/v1/facility/{facilityId}/device/{id}/location_history/",
+  path: "/api/v1/facility/{facility_id}/device/{id}/location_history/",
  method: HttpMethod.GET,
  TRes: Type<PaginatedResponse<DeviceLocationHistory>>(),
},
```

To verify this is actually an issue, let's check the other API usages:

---

🏁 Script executed:

```shell
#!/bin/bash
# Find all usages of facilityId and facility_id in the API paths

echo "Checking all API paths in deviceApi.ts:"
cat src/types/device/deviceApi.ts | grep -o 'path:.*' | cat

echo -e "\nSearching for other API path definitions in the codebase:"
rg 'path: "/api/v1/facility/\{[^}]*\}' --type ts
```

Length of output: 6228

---



</details>

**API Parameter Naming Inconsistency: Use snake_case for facility identifier**

The `locationHistory` endpoint in `src/types/device/deviceApi.ts` currently uses `{facilityId}`, which deviates from the consistent use of snake_case seen in all other endpoints in this file. Our verification confirms that all other API paths in this file use `{facility_id}`. Please update the `locationHistory` path accordingly to ensure consistency across the device API endpoints.

```diff
locationHistory: {
-  path: "/api/v1/facility/{facilityId}/device/{id}/location_history/",
+  path: "/api/v1/facility/{facility_id}/device/{id}/location_history/",
  method: HttpMethod.GET,
  TRes: Type<PaginatedResponse<DeviceLocationHistory>>(),
},
```



<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
  locationHistory: {
    path: "/api/v1/facility/{facility_id}/device/{id}/location_history/",
    method: HttpMethod.GET,
    TRes: Type<PaginatedResponse<DeviceLocationHistory>>(),
  },
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-03T08:51:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -144,6 +146,12 @@ export default function DeviceDetail({ facilityId, deviceId }: Props) {
       <div className="flex items-center justify-between">
         <PageTitle title={device.registered_name} />
         <div className="flex items-center gap-2">
+          <Link href={`/devices/${deviceId}/locationHistory`}>
+            <Button variant="outline_primary" className="mr-3">
+              <CareIcon icon="l-location-point" className="h-4 w-4" />
+              {t("location_history")}
+            </Button>
+          </Link>
           <Link href={`/devices/${deviceId}/edit`}>
path: src/pages/Facility/settings/devices/DeviceDetail.tsx
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**Consider updating href to use facilityId in route path**

The current implementation uses an absolute path `/devices/${deviceId}/locationHistory` which doesn't include the facility context. This might cause issues if facility context is required in the URL structure. Consider updating to use the facility-based route.

```diff
-<Link href={`/devices/${deviceId}/locationHistory`}>
+<Link href={`/facility/${facilityId}/settings/devices/${deviceId}/locationHistory`}>
```

Run the following script to verify if the route structure is consistent throughout the application:

---

🏁 Script executed:

```shell
#!/bin/bash
# Description: Check if device routes consistently use facility context in the application

# Find device-related route definitions and links
echo "Checking route definitions:"
rg -A 2 -B 2 "devices/.*" --glob "*.tsx" | grep -E "(href|path)"

# Check for any deviceId-related routes
echo "Checking deviceId usage in routes:"
rg -A 3 "\{.*deviceId.*\}" --glob "*.tsx" | grep -E "(href|path|route)"
```

Length of output: 1691

---



</details>

**Update DeviceDetail route links to include facility context**

The facility context is used correctly in other parts of the application (e.g., in `UpdateDevice.tsx`). In `DeviceDetail.tsx`, both the location history and edit links should follow this updated routing pattern:

- **Location History Link:**  
  **Before:**  
  ```tsx
  <Link href={`/devices/${deviceId}/locationHistory`}>
  ```  
  **After:**  
  ```tsx
  <Link href={`/facility/${facilityId}/settings/devices/${deviceId}/locationHistory`}>
  ```

- **Edit Link:**  
  **Before:**  
  ```tsx
  <Link href={`/devices/${deviceId}/edit`}>
  ```  
  **After:**  
  ```tsx
  <Link href={`/facility/${facilityId}/settings/devices/${deviceId}/edit`}>
  ```

Please update both instances to ensure consistency across the application.

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-03T08:51:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,100 @@
+import { useQuery } from "@tanstack/react-query";
+import { useQueryParams } from "raviger";
+import { useTranslation } from "react-i18next";
+
+import { cn } from "@/lib/utils";
+
+import Page from "@/components/Common/Page";
+import PaginationComponent from "@/components/Common/Pagination";
+import { CardListSkeleton } from "@/components/Common/SkeletonLoading";
+
+import { RESULTS_PER_PAGE_LIMIT } from "@/common/constants";
+
+import query from "@/Utils/request/query";
+import { DeviceLocationCard } from "@/pages/Facility/settings/devices/components/DeviceLocationCard";
+import deviceApi from "@/types/device/deviceApi";
+
+interface Props {
+  facilityId: string;
+  deviceId: string;
+}
+
+const DeviceLocationHistory = ({ facilityId, deviceId }: Props) => {
+  const { t } = useTranslation();
+
+  const [qParams, setQueryParams] = useQueryParams<{ page?: number }>();
+
+  const { data: locationsData, isLoading } = useQuery({
+    queryKey: ["deviceLocationHistory", facilityId, deviceId, qParams],
+    queryFn: query(deviceApi.locationHistory, {
+      queryParams: {
+        limit: RESULTS_PER_PAGE_LIMIT,
+        offset: ((qParams.page ?? 1) - 1) * RESULTS_PER_PAGE_LIMIT,
+      },
+      pathParams: {
+        facilityId,
+        id: deviceId,
+      },
+    }),
+  });
path: src/pages/Facility/settings/devices/DeviceLocationHistory.tsx
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add error handling for the API request**

The component doesn't handle potential API errors. Consider adding error handling to provide feedback to the user when data fetching fails.

```diff
const { data: locationsData, isLoading, error } = useQuery({
  queryKey: ["deviceLocationHistory", facilityId, deviceId, qParams],
  queryFn: query(deviceApi.locationHistory, {
    queryParams: {
      limit: RESULTS_PER_PAGE_LIMIT,
      offset: ((qParams.page ?? 1) - 1) * RESULTS_PER_PAGE_LIMIT,
    },
    pathParams: {
      facilityId,
      id: deviceId,
    },
  }),
});

return (
  <Page title={t("device_location_history")} className="mt-8">
    <div>
+     {error && (
+       <div className="p-2">
+         <div className="h-full space-y-2 rounded-lg bg-red-50 px-7 py-12 border border-red-300">
+           <div className="flex w-full items-center justify-center text-lg text-red-600">
+             <div className="h-full flex w-full items-center justify-center">
+               <span className="text-sm">
+                 {t("error_fetching_location_history")}
+               </span>
+             </div>
+           </div>
+         </div>
+       </div>
+     )}
      {isLoading ? (
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
  const { data: locationsData, isLoading, error } = useQuery({
    queryKey: ["deviceLocationHistory", facilityId, deviceId, qParams],
    queryFn: query(deviceApi.locationHistory, {
      queryParams: {
        limit: RESULTS_PER_PAGE_LIMIT,
        offset: ((qParams.page ?? 1) - 1) * RESULTS_PER_PAGE_LIMIT,
      },
      pathParams: {
        facilityId,
        id: deviceId,
      },
    }),
  });

  return (
    <Page title={t("device_location_history")} className="mt-8">
      <div>
        {error && (
          <div className="p-2">
            <div className="h-full space-y-2 rounded-lg bg-red-50 px-7 py-12 border border-red-300">
              <div className="flex w-full items-center justify-center text-lg text-red-600">
                <div className="h-full flex w-full items-center justify-center">
                  <span className="text-sm">
                    {t("error_fetching_location_history")}
                  </span>
                </div>
              </div>
            </div>
          </div>
        )}
        {isLoading ? (
          // ... your loading UI here
        ) : (
          // ... remaining UI for displaying locationsData
        )}
      </div>
    </Page>
  );
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-03-03T08:51:07Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-03-03T04:21:31Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough
This pull request integrates a new device location history feature. It adds a localization entry, updates the DeviceDetail component to include a location history button, and introduces new components for displaying device location history. Additionally, a new route is established for navigation, and corresponding type definitions and API endpoints are added for proper data handling.

## Changes

| File(s) | Change Summary |
|---------|----------------|
| `public/locale/en.json` | Added `"device_location_history": "Device Location History"` entry. |
| `src/.../devices/DeviceDetail.tsx` | Introduced a new button with `CareIcon` and translation for navigating to location history. |
| `src/.../devices/DeviceLocationHistory.tsx`, `src/.../devices/components/DeviceLocationCard.tsx`, `src/.../devices/components/AssociateLocationSheet.tsx` | Added new components for fetching, displaying, and managing device location history; updated mutation onSuccess to invalidate cache. |
| `src/.../settings/layout.tsx` | Updated routing to include a new route `"/devices/:id/locationHistory"` mapping to `DeviceLocationHistory`. |
| `src/.../device/device.ts`, `src/.../device/deviceApi.ts` | Added `DeviceLocationHistory` interface and a new API endpoint (`locationHistory`) for retrieving paginated device location history data. |

## Sequence Diagram(s)
```mermaid
sequenceDiagram
    participant U as User
    participant DD as DeviceDetail
    participant DL as DeviceLocationHistory
    participant API as deviceApi
    participant DCard as DeviceLocationCard

    U->>DD: Click "Location History" button
    DD->>DL: Navigate to DeviceLocationHistory route
    DL->>API: Request device location history data
    API-->>DL: Return paginated location data
    DL->>DCard: Render each device location card
    note right of DL: Pagination is managed via query parameters
```

## Possibly related PRs
- **ohcnetwork/care_fe#10810**: Modifies the localization JSON with additional entries for location management.
- **ohcnetwork/care_fe#9935**: Enhances localization strings in a similar context, adding multiple related entries.
- **ohcnetwork/care_fe#10540**: Adds localization entries including "location_history", directly aligning with this update.

## Suggested labels
`needs review`, `tested`

## Suggested reviewers
- rithviknishad
- Jacobjeevan

## Poem
> I'm a coding rabbit on the run,  
> Hopping through changes one by one,  
> New routes and cards in a digital glen,  
> Location history now for everyone!  
> With buttons and icons shining bright,  
> I nibble on code deep into the night.  
> Happy hops to a future so light!  


<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: netlify[bot]
created_at: 2025-03-03T04:21:49Z
body: ### <span aria-hidden="true">✅</span> Deploy Preview for *care-ohc* ready!


|  Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | 5bd74bf8f4a42b586cb1f20eea588b6a055ff80c |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/care-ohc/deploys/67c56c1b37c5c70008059e2e |
|<span aria-hidden="true">😎</span> Deploy Preview | [https://deploy-preview-10950.preview.ohc.network](https://deploy-preview-10950.preview.ohc.network) |
|<span aria-hidden="true">📱</span> Preview on mobile | <details><summary> Toggle QR Code... </summary><br /><br />![QR Code](https://app.netlify.com/qr-code/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2RlcGxveS1wcmV2aWV3LTEwOTUwLnByZXZpZXcub2hjLm5ldHdvcmsifQ.U5IQdokT9Apov56mkTfGNUPK7I9OkeYE-hCLo3pXCuQ)<br /><br />_Use your smartphone camera to open QR code link._</details> |
---
<!-- [care-ohc Preview](https://deploy-preview-10950.preview.ohc.network) -->
_To edit notification comments on pull requests, go to your [Netlify site configuration](https://app.netlify.com/sites/care-ohc/configuration/notifications#deploy-webhooks)._
author_association: NONE
user: login: rajku-dev
created_at: 2025-03-03T08:48:22Z
body: should we create tabs for overview, location history and encounter history, rather than buttons
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-04T12:27:30Z
body: @rajku-dev Your efforts have helped advance digital healthcare and TeleICU systems. :rocket: Thank you for taking the time out to make CARE better. We hope you continue to innovate and contribute; your impact is immense! :raised_hands:
author_association: NONE