Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit feature for facilities in organization | pincode, geo_organization info auto populates #9662

Open
wants to merge 43 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
03fd617
pincode updated
Mahendar0701 Jan 2, 2025
d1a6ca1
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 2, 2025
7db9c3a
populated geo_organization values
Mahendar0701 Jan 3, 2025
080f442
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 3, 2025
8159f13
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 3, 2025
fc0413e
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 3, 2025
d0daf9c
autofill of state and districts
Mahendar0701 Jan 4, 2025
f7db9bc
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 4, 2025
02a4ca0
Merge branch 'facility-edit' of https://github.com/Mahendar0701/care_…
Mahendar0701 Jan 4, 2025
ab383d5
translation
Mahendar0701 Jan 4, 2025
7dff65f
commit
Mahendar0701 Jan 4, 2025
4eda986
added usequery
Mahendar0701 Jan 4, 2025
c811b60
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 4, 2025
d9078ad
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 5, 2025
884fc82
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 5, 2025
0f49a53
Merge branch 'facility-edit' of https://github.com/Mahendar0701/care_…
Mahendar0701 Jan 5, 2025
b6b2318
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 5, 2025
fd3241f
moved useFetchOrganizationByName organizationapi.ts
Mahendar0701 Jan 5, 2025
f9d4e49
Merge branch 'facility-edit' of https://github.com/Mahendar0701/care_…
Mahendar0701 Jan 5, 2025
3a9dcbf
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 5, 2025
e87535d
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 5, 2025
213eb95
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 6, 2025
87db767
added conditions
Mahendar0701 Jan 6, 2025
4599c93
Merge branch 'facility-edit' of https://github.com/Mahendar0701/care_…
Mahendar0701 Jan 6, 2025
8df1055
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 9, 2025
80dde3f
added edit option
Mahendar0701 Jan 9, 2025
f63a324
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 9, 2025
dcad86a
added edit option
Mahendar0701 Jan 9, 2025
0e370c9
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 10, 2025
9b57759
resolved conflicts
Mahendar0701 Jan 10, 2025
a5d9d6e
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 11, 2025
a932b00
autopopulation of existing details
Mahendar0701 Jan 11, 2025
15eb9d3
added i18n and pincode limit
Mahendar0701 Jan 11, 2025
f735ac9
added i18n and pincode limit
Mahendar0701 Jan 11, 2025
a68184f
link wrap in button
Mahendar0701 Jan 11, 2025
4a9f3a6
autofill pincode
Mahendar0701 Jan 11, 2025
43caefd
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 12, 2025
5ffb199
added form.watch
Mahendar0701 Jan 12, 2025
5bda95e
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 12, 2025
ed06a75
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 13, 2025
f763eba
facility edit sheet
Mahendar0701 Jan 13, 2025
8dbda7e
Merge branch 'facility-edit' of https://github.com/Mahendar0701/care_…
Mahendar0701 Jan 13, 2025
ec1014e
Merge branch 'develop' into facility-edit
Mahendar0701 Jan 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1758,6 +1758,7 @@
"select_investigation_groups": "Select Investigation Groups",
"select_investigations": "Select Investigations",
"select_local_body": "Select Local Body",
"select_location_from": "Select location from",
"select_new_role": "Select New Role",
"select_patient": "Select Patient",
"select_policy": "Select an Insurance Policy",
Expand Down Expand Up @@ -2056,6 +2057,7 @@
"view_users": "View Users",
"village": "Village",
"virtual_nursing_assistant": "Virtual Nursing Assistant",
"visibility_settings": "Visibility Settings",
"vitals": "Vitals",
"vitals_monitor": "Vitals Monitor",
"vitals_present": "Vitals Monitor present",
Expand Down
56 changes: 51 additions & 5 deletions src/components/Facility/FacilityCreate.tsx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file could be deleted now, no? 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Jacobjeevan this file is being used for updating facility in facility detials page

image

Copy link
Contributor

@Jacobjeevan Jacobjeevan Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an EditFacilitySheet (instead of modifying AddFacilitySheet) and call that component here and for the edit link in Organization Facilities page.

Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import careConfig from "@careConfig";
import {
Popover,
PopoverButton,
Expand Down Expand Up @@ -59,8 +60,10 @@ import {
import routes from "@/Utils/request/api";
import query from "@/Utils/request/query";
import request from "@/Utils/request/request";
import { parsePhoneNumber } from "@/Utils/utils";
import { getPincodeDetails, parsePhoneNumber } from "@/Utils/utils";
Mahendar0701 marked this conversation as resolved.
Show resolved Hide resolved
import OrganizationSelector from "@/pages/Organization/components/OrganizationSelector";
import { Organization } from "@/types/organization/organization";
import { useFetchOrganizationByName } from "@/types/organization/organizationApi";

interface FacilityProps {
facilityId?: string;
Expand All @@ -69,6 +72,9 @@ export const FacilityCreate = (props: FacilityProps) => {
const { t } = useTranslation();
const { facilityId } = props;
const [isLoading, setIsLoading] = useState(false);
const [selectedLevels, setSelectedLevels] = useState<Organization[]>([]);
const [pincode, setPincode] = useState("");

const { goBack } = useAppHistory();

const facilityFormSchema = z.object({
Expand Down Expand Up @@ -215,9 +221,42 @@ export const FacilityCreate = (props: FacilityProps) => {
}
};

const { data: pincodeData, isError: isPincodeError } = useQuery({
queryKey: ["pincodeDetails", pincode],
queryFn: () => getPincodeDetails(pincode, careConfig.govDataApiKey),
enabled: validatePincode(pincode) && pincode != facilityData?.pincode,
});

if (isPincodeError) {
toast.error("Invalid pincode");
}
Mahendar0701 marked this conversation as resolved.
Show resolved Hide resolved

const stateName = pincodeData?.statename;

const districtName = pincodeData?.districtname;

const { data: stateOrg } = useFetchOrganizationByName(stateName);
const { data: districtOrg } = useFetchOrganizationByName(
districtName,
stateOrg?.id,
);

useEffect(() => {
if (stateOrg && districtOrg) {
setSelectedLevels([stateOrg, districtOrg]);
} else {
setSelectedLevels([]);
}
}, [stateOrg, districtOrg]);
Mahendar0701 marked this conversation as resolved.
Show resolved Hide resolved

const handlePincodeChange = (value: string) => {
setPincode(value);
setSelectedLevels([]);
};

return (
<Page
title={facilityId ? "Update Facility" : "Create Facility"}
title={facilityId ? t("update_facility") : t("create_facility")}
crumbsReplacements={{
[facilityId || "????"]: { name: form.watch("name") },
}}
Expand Down Expand Up @@ -321,6 +360,7 @@ export const FacilityCreate = (props: FacilityProps) => {
required
onChange={(value) => {
field.onChange(value.value);
handlePincodeChange(value.value);
}}
error={form.formState.errors.pincode?.message}
/>
Expand All @@ -332,7 +372,11 @@ export const FacilityCreate = (props: FacilityProps) => {
<div className="col-span-2 grid grid-cols-2 gap-5">
<OrganizationSelector
required={true}
onChange={(value) => form.setValue("geo_organization", value)}
value={facilityData?.geo_organization}
parentSelectedLevels={selectedLevels}
onChange={(value) => {
form.setValue("geo_organization", value);
}}
Mahendar0701 marked this conversation as resolved.
Show resolved Hide resolved
/>
</div>

Expand Down Expand Up @@ -414,7 +458,7 @@ export const FacilityCreate = (props: FacilityProps) => {
>
<CareIcon icon="l-map-marker" className="text-xl" />
<span className="tooltip-text tooltip-bottom">
Select location from map
{t("select_location_from")}
</span>
</Button>
</PopoverButton>
Expand Down Expand Up @@ -466,7 +510,9 @@ export const FacilityCreate = (props: FacilityProps) => {

{/* Visibility Settings */}
<div className="space-y-4 rounded-lg border p-4">
<h3 className="text-lg font-medium">Visibility Settings</h3>
<h3 className="text-lg font-medium">
{t("visibility_settings")}
</h3>
<FormField
control={form.control}
name="is_public"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import careConfig from "@careConfig";
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
Expand Down Expand Up @@ -39,16 +40,22 @@ import {

import routes from "@/Utils/request/api";
import mutate from "@/Utils/request/mutate";
import { parsePhoneNumber } from "@/Utils/utils";
import query from "@/Utils/request/query";
import { getPincodeDetails, parsePhoneNumber } from "@/Utils/utils";
import OrganizationSelector from "@/pages/Organization/components/OrganizationSelector";
import { BaseFacility } from "@/types/facility/facility";
import { Organization } from "@/types/organization/organization";
import { useFetchOrganizationByName } from "@/types/organization/organizationApi";

import { FacilityModel } from "./models";

const facilityFormSchema = z.object({
facility_type: z.string().min(1, "Facility type is required"),
name: z.string().min(1, "Name is required"),
description: z.string().optional(),
features: z.array(z.number()).default([]),
pincode: z.string().refine(validatePincode, "Invalid pincode"),
geo_organization: z.string().min(1, { message: "required" }),
address: z.string().min(1, "Address is required"),
phone_number: z
.string()
Expand All @@ -69,18 +76,19 @@ const facilityFormSchema = z.object({

type FacilityFormValues = z.infer<typeof facilityFormSchema>;

interface Props {
interface FacilityProps {
organizationId: string;
facilityId?: string;
onSubmitSuccess?: () => void;
}

export default function CreateFacilityForm({
organizationId,
onSubmitSuccess,
}: Props) {
export default function CreateFacilityForm(props: FacilityProps) {
const { t } = useTranslation();
const queryClient = useQueryClient();
const [isGettingLocation, setIsGettingLocation] = useState(false);
const { organizationId, facilityId, onSubmitSuccess } = props;
const [selectedLevels, setSelectedLevels] = useState<Organization[]>([]);
const [pincode, setPincode] = useState("");

const form = useForm<FacilityFormValues>({
resolver: zodResolver(facilityFormSchema),
Expand All @@ -90,6 +98,7 @@ export default function CreateFacilityForm({
description: "",
features: [],
pincode: "",
geo_organization: "",
address: "",
phone_number: "+91",
latitude: "",
Expand Down Expand Up @@ -118,19 +127,76 @@ export default function CreateFacilityForm({
},
});

const onSubmit = (data: FacilityFormValues) => {
createFacility({
const { mutate: updateFacility, isPending: isUpdatePending } = useMutation({
mutationFn: mutate(routes.updateFacility, {
pathParams: { id: facilityId || "" },
}),
onSuccess: (_data: FacilityModel) => {
toast.success(t("facility_updated_successfully"));
queryClient.invalidateQueries({ queryKey: ["organizationFacilities"] });
form.reset();
onSubmitSuccess?.();
},
onError: (error: Error) => {
const errorData = error.cause as { errors: { msg: string[] } };
Mahendar0701 marked this conversation as resolved.
Show resolved Hide resolved
if (errorData?.errors?.msg) {
errorData.errors.msg.forEach((msg) => {
toast.error(msg);
});
} else {
toast.error(t("facility_update_error"));
}
},
});

const { data: facilityData } = useQuery({
queryKey: ["facility", facilityId],
queryFn: query(routes.getPermittedFacility, {
pathParams: { id: facilityId || "" },
}),
enabled: !!facilityId,
});

const onSubmit: (data: FacilityFormValues) => void = (
data: FacilityFormValues,
) => {
const requestData = {
...data,
phone_number: parsePhoneNumber(data.phone_number),
geo_organization: organizationId,
});
};

if (facilityId) {
updateFacility(requestData);
} else {
createFacility(requestData);
}
};

const handleFeatureChange = (value: any) => {
const { value: features }: { value: Array<number> } = value;
form.setValue("features", features);
};

// Update form when facility data is loaded
useEffect(() => {
if (facilityData) {
console.log(facilityData);
Mahendar0701 marked this conversation as resolved.
Show resolved Hide resolved
form.reset({
facility_type: facilityData.facility_type,
name: facilityData.name,
description: facilityData.description || "",
features: facilityData.features || [],
pincode: facilityData.pincode?.toString() || "",
geo_organization: facilityData.geo_organization,
address: facilityData.address,
phone_number: facilityData.phone_number,
latitude: facilityData.latitude?.toString() || "",
longitude: facilityData.longitude?.toString() || "",
is_public: facilityData.is_public,
});
}
}, [facilityData, form]);

const handleGetCurrentLocation = () => {
if (navigator.geolocation) {
setIsGettingLocation(true);
Expand All @@ -145,13 +211,46 @@ export default function CreateFacilityForm({
setIsGettingLocation(false);
toast.error(t("unable_to_get_location") + error.message);
},
{ timeout: 10000 }, // 10 second timeout
{ timeout: 10000 },
);
} else {
toast.error(t("geolocation_is_not_supported_by_this_browser"));
}
};

const { data: pincodeData, isError: isPincodeError } = useQuery({
queryKey: ["pincodeDetails", pincode],
queryFn: () => getPincodeDetails(pincode, careConfig.govDataApiKey),
enabled: validatePincode(pincode) && pincode != facilityData?.pincode,
});

if (isPincodeError) {
toast.error("Invalid pincode");
}
Mahendar0701 marked this conversation as resolved.
Show resolved Hide resolved

const stateName = pincodeData?.statename;

const districtName = pincodeData?.districtname;
Mahendar0701 marked this conversation as resolved.
Show resolved Hide resolved

const { data: stateOrg } = useFetchOrganizationByName(stateName);
const { data: districtOrg } = useFetchOrganizationByName(
districtName,
stateOrg?.id,
);

useEffect(() => {
if (stateOrg && districtOrg) {
setSelectedLevels([stateOrg, districtOrg]);
} else {
setSelectedLevels([]);
}
}, [stateOrg, districtOrg]);

const handlePincodeChange = (value: string) => {
setPincode(value);
setSelectedLevels([]);
};

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
Expand Down Expand Up @@ -284,12 +383,26 @@ export default function CreateFacilityForm({
data-cy="facility-pincode"
placeholder="Enter pincode"
{...field}
onChange={(e) => {
field.onChange(e);
handlePincodeChange(e.target.value);
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="col-span-2 grid grid-cols-2 gap-5">
<OrganizationSelector
required={true}
value={facilityData?.geo_organization}
parentSelectedLevels={selectedLevels}
onChange={(value) => {
form.setValue("geo_organization", value);
}}
/>
</div>
</div>

<FormField
Expand Down Expand Up @@ -434,10 +547,22 @@ export default function CreateFacilityForm({
<Button
type="submit"
className="w-full"
disabled={isPending}
data-cy="submit-facility"
disabled={facilityId ? isUpdatePending : isPending}
data-cy={facilityId ? "update-facility" : "submit-facility"}
>
{isPending ? (
{facilityId ? (
isUpdatePending ? (
<>
<CareIcon
icon="l-spinner"
className="mr-2 h-4 w-4 animate-spin"
/>
Updating Facility...
</>
) : (
"Update Facility"
)
) : isPending ? (
<>
<CareIcon
icon="l-spinner"
Expand Down
Loading
Loading