Skip to content

Commit

Permalink
Add Facility Map Link (#10755)
Browse files Browse the repository at this point in the history
  • Loading branch information
AdityaJ2305 authored Feb 27, 2025
1 parent 5c0a73c commit 6a6d67a
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .example.env
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,6 @@ REACT_ALLOWED_LOCALES="en,hi,ta,ml,mr,kn"

# ISO 3166-1 Alpha-2 code for the default country code (default: "IN")
REACT_DEFAULT_COUNTRY=

# Maps fallback URL template (default:"https://www.openstreetmap.org/?mlat={lat}&mlon={long}&zoom=15")
REACT_MAPS_FALLBACK_URL_TEMPLATE=
4 changes: 4 additions & 0 deletions care.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ const careConfig = {
defaultEncounterType: (env.REACT_DEFAULT_ENCOUNTER_TYPE ||
"hh") as EncounterClass,

mapFallbackUrlTemplate:
env.REACT_MAPS_FALLBACK_URL_TEMPLATE ||
"https://www.openstreetmap.org/?mlat={lat}&mlon={long}&zoom=15",

gmapsApiKey:
env.REACT_GMAPS_API_KEY || "AIzaSyDsBAc3y7deI5ZO3NtK5GuzKwtUzQNJNUk",

Expand Down
1 change: 1 addition & 0 deletions public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2134,6 +2134,7 @@
"select_policy_to_add_items": "Select a Policy to Add Items",
"select_practitioner": "Select Practitioner",
"select_previous": "Select Previous Fields",
"show_on_map": "Show on Map",
"select_priority": "Select Priority",
"select_prn_reason": "Select reason for PRN",
"select_register_patient": "Select/Register Patient",
Expand Down
11 changes: 11 additions & 0 deletions src/Utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import careConfig from "@careConfig";
import { differenceInMinutes, format } from "date-fns";
import { toPng } from "html-to-image";

Expand Down Expand Up @@ -94,6 +95,16 @@ export const isUserOnline = (user: { last_login: DateLike }) => {
: false;
};

export const isAndroidDevice = /android/i.test(navigator.userAgent);

export const getMapUrl = (latitude: string, longitude: string) => {
return isAndroidDevice
? `geo:${latitude},${longitude}`
: careConfig.mapFallbackUrlTemplate
.replace("{lat}", latitude)
.replace("{long}", longitude);
};

const getRelativeDateSuffix = (abbreviated: boolean) => {
return {
day: abbreviated ? "d" : "days",
Expand Down
11 changes: 9 additions & 2 deletions src/components/Facility/FacilityHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import type {
} from "@/types/organization/organization";
import { getOrgLabel } from "@/types/organization/organization";

import { FacilityMapsLink } from "./FacilityMapLink";

type Props = {
facilityId: string;
};
Expand Down Expand Up @@ -322,8 +324,13 @@ export const FacilityHome = ({ facilityId }: Props) => {
<span className="font-semibold text-lg">
{t("location_details")}
</span>
<span className="text-gray-800 truncate">
{/* Add Location Link Here */}
<span>
{facilityData.latitude && facilityData.longitude && (
<FacilityMapsLink
latitude={facilityData.latitude.toString()}
longitude={facilityData.longitude.toString()}
/>
)}
</span>
</div>
</div>
Expand Down
42 changes: 42 additions & 0 deletions src/components/Facility/FacilityMapLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { SquareArrowOutUpRight } from "lucide-react";
import { Link } from "raviger";
import { useTranslation } from "react-i18next";

import { getMapUrl, isAndroidDevice } from "@/Utils/utils";

const isValidLatitude = (latitude: string) => {
const lat = parseFloat(latitude.trim());
return Number.isFinite(lat) && lat >= -90 && lat <= 90;
};

const isValidLongitude = (longitude: string) => {
const long = parseFloat(longitude.trim());
return Number.isFinite(long) && long >= -180 && long <= 180;
};

export const FacilityMapsLink = ({
latitude,
longitude,
}: {
latitude: string;
longitude: string;
}) => {
const { t } = useTranslation();

if (!isValidLatitude(latitude) || !isValidLongitude(longitude)) {
return null;
}
const target = isAndroidDevice ? "_self" : "_blank";

return (
<Link
className="text-primary flex items-center gap-1 w-max"
href={getMapUrl(latitude, longitude)}
target={target}
rel="noreferrer"
>
{t("show_on_map")}
<SquareArrowOutUpRight className="h-3 w-3" />
</Link>
);
};
7 changes: 7 additions & 0 deletions src/pages/Facility/FacilityDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Markdown } from "@/components/ui/markdown";

import { Avatar } from "@/components/Common/Avatar";
import { LoginHeader } from "@/components/Common/LoginHeader";
import { FacilityMapsLink } from "@/components/Facility/FacilityMapLink";
import { FacilityModel } from "@/components/Facility/models";
import { UserAssignedModel } from "@/components/Users/models";

Expand Down Expand Up @@ -115,6 +116,12 @@ export function FacilityDetailsPage({ id }: Props) {
<h1 className="text-3xl font-bold">{facility.name}</h1>
<p className="text-lg text-gray-500">
{[facility.address].filter(Boolean).join(", ")}
{facility.latitude && facility.longitude && (
<FacilityMapsLink
latitude={facility.latitude.toString()}
longitude={facility.longitude.toString()}
/>
)}
</p>
</div>

Expand Down
7 changes: 7 additions & 0 deletions src/pages/Facility/components/FacilityCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";

import { Avatar } from "@/components/Common/Avatar";
import { FacilityMapsLink } from "@/components/Facility/FacilityMapLink";

import { FeatureBadge } from "@/pages/Facility/Utils";
import { FacilityData } from "@/types/facility/facility";
Expand Down Expand Up @@ -36,6 +37,12 @@ export function FacilityCard({ facility, className }: Props) {
{facility.facility_type?.name}
<p className="text-sm text-gray-500 truncate">
{[facility.address].filter(Boolean).join(", ")}
{facility.latitude && facility.longitude && (
<FacilityMapsLink
latitude={facility.latitude.toString()}
longitude={facility.longitude.toString()}
/>
)}
</p>

<div className="mt-2 flex flex-wrap gap-2">
Expand Down
1 change: 1 addition & 0 deletions src/vite-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface ImportMetaEnv {
readonly REACT_ENABLE_ABDM?: string;
readonly REACT_ENABLE_SCRIBE?: string;
readonly REACT_DEFAULT_COUNTRY?: string;
readonly REACT_MAPS_FALLBACK_URL_TEMPLATE?: string;
}

interface ImportMeta {
Expand Down

0 comments on commit 6a6d67a

Please sign in to comment.