Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
46 changes: 28 additions & 18 deletions src/components/Facility/FacilityForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ import { PhoneInput } from "@/components/ui/phone-input";
import { Textarea } from "@/components/ui/textarea";

import LocationPicker from "@/components/Common/GeoLocationPicker";
import GovtOrganizationPicker from "@/components/Organization/GovtOrganizationPicker";

import mutate from "@/Utils/request/mutate";
import query from "@/Utils/request/query";
import validators from "@/Utils/validators";
import GovtOrganizationSelector from "@/pages/Organization/components/GovtOrganizationSelector";
import {
FACILITY_FEATURE_TYPES,
FACILITY_TYPES,
Expand All @@ -53,7 +53,9 @@ export default function FacilityForm({
const { t } = useTranslation();
const queryClient = useQueryClient();
const [isGettingLocation, setIsGettingLocation] = useState(false);
const [selectedLevels, setSelectedLevels] = useState<Organization[]>([]);
const [selectedGeoOrg, setSelectedGeoOrg] = useState<Organization | null>(
null,
);

const facilityFormSchema = z.object({
facility_type: z.string().min(1, t("facility_type_required")),
Expand Down Expand Up @@ -101,10 +103,15 @@ export default function FacilityForm({
});

useEffect(() => {
const levels: Organization[] = [];
if (org && org.org_type === "govt") levels.push(org);
setSelectedLevels(levels);
}, [org, organizationId]);
if (!organizationId || facilityId) {
return;
}

const govtOrg = org && org.org_type === "govt" ? org : null;

setSelectedGeoOrg(govtOrg);
form.setValue("geo_organization", govtOrg?.id ?? "");
}, [org, organizationId, facilityId, form]);

const { mutate: createFacility, isPending } = useMutation({
mutationFn: mutate(facilityApi.create),
Expand Down Expand Up @@ -194,7 +201,7 @@ export default function FacilityForm({
// Update form when facility data is loaded
useEffect(() => {
if (facilityData) {
setSelectedLevels([facilityData.geo_organization]);
setSelectedGeoOrg(facilityData.geo_organization);
form.reset({
facility_type: facilityData.facility_type,
Comment thread
rithviknishad marked this conversation as resolved.
name: facilityData.name,
Expand Down Expand Up @@ -354,20 +361,23 @@ export default function FacilityForm({
<FormField
name="geo_organization"
control={form.control}
render={({ field }) => (
render={({ field, fieldState }) => (
<FormItem className="md:col-span-2">
<FormControl>
<div className="grid-cols-1 grid md:grid-cols-2 gap-5">
<GovtOrganizationSelector
{...field}
value={form.watch("geo_organization")}
selected={selectedLevels}
onChange={(value) =>
form.setValue("geo_organization", value, {
shouldDirty: true,
})
}
required
<GovtOrganizationPicker
ref={field.ref}
aria-invalid={!!fieldState.error}
requiredDepth={1}
value={selectedGeoOrg}
onChange={(organization) => {
setSelectedGeoOrg(organization);
form.setValue(
"geo_organization",
organization?.id ?? "",
{ shouldDirty: true },
);
}}
/>
</div>
</FormControl>
Expand Down
36 changes: 17 additions & 19 deletions src/components/Users/UserForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import { GENDERS, GENDER_TYPES, NAME_PREFIXES } from "@/common/constants";
import mutate from "@/Utils/request/mutate";
import query from "@/Utils/request/query";
import validators from "@/Utils/validators";
import GovtOrganizationSelector from "@/pages/Organization/components/GovtOrganizationSelector";
import GovtOrganizationPicker from "@/components/Organization/GovtOrganizationPicker";
import { Organization } from "@/types/organization/organization";
import organizationApi from "@/types/organization/organizationApi";
import { UserCreate, UserReadMinimal, UserUpdate } from "@/types/user/user";
Expand All @@ -70,9 +70,10 @@ export default function UserForm({
const { t } = useTranslation();
const isEditMode = !!existingUsername;
const queryClient = useQueryClient();
const [selectedLevels, setSelectedLevels] = useState<Organization[]>([]);
const [selectedGeoOrg, setSelectedGeoOrg] = useState<Organization | null>(
null,
);
const [isPasswordFieldFocused, setIsPasswordFieldFocused] = useState(false);

const roleOrgSchema = z.object({
organization: z.string().min(1, t("select_role_organization")),
role: z.string().min(1, t("please_select_role")),
Expand Down Expand Up @@ -377,16 +378,12 @@ export default function UserForm({
});

useEffect(() => {
const levels: Organization[] = [];
if (org && org.org_type === "govt") levels.push(org);
setSelectedLevels(levels);
setSelectedGeoOrg(org && org.org_type === "govt" ? org : null);
}, [org, organizationId]);

useEffect(() => {
const levels: Organization[] = [];
if (isEditMode && userData?.geo_organization) {
levels.push(userData.geo_organization);
setSelectedLevels(levels);
setSelectedGeoOrg(userData.geo_organization);
}
}, [userData, isEditMode]);

Expand Down Expand Up @@ -798,19 +795,20 @@ export default function UserForm({
<FormField
control={form.control}
name="geo_organization"
render={({ field }) => (
render={({ field, fieldState }) => (
<FormItem>
<FormControl>
<GovtOrganizationSelector
{...field}
value={form.watch("geo_organization")}
selected={selectedLevels}
onChange={(value) =>
form.setValue("geo_organization", value, {
<GovtOrganizationPicker
ref={field.ref}
aria-invalid={!!fieldState.error}
requiredDepth={1}
value={selectedGeoOrg}
onChange={(organization) => {
setSelectedGeoOrg(organization);
form.setValue("geo_organization", organization?.id ?? "", {
shouldDirty: true,
})
}
required={false}
});
Comment on lines +804 to +810

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Sync preselected picker value into the form state in create mode.

Line 805 renders selectedGeoOrg as selected, but Lines 808-810 update geo_organization only after user interaction. In create flow, the org bootstrap effect can prefill the picker while data.geo_organization stays empty on submit.

Suggested fix
 useEffect(() => {
-  setSelectedGeoOrg(org && org.org_type === "govt" ? org : null);
-}, [org, organizationId]);
+  const govtOrg = org && org.org_type === "govt" ? org : null;
+  setSelectedGeoOrg(govtOrg);
+  if (!isEditMode) {
+    form.setValue("geo_organization", govtOrg?.id ?? "", {
+      shouldDirty: false,
+    });
+  }
+}, [org, isEditMode, form]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/Users/UserForm.tsx` around lines 804 - 810, The selectedGeoOrg
picker value shown in the component (line 805) is not being synced into the form
state when it is programmatically set during the create flow. While the onChange
handler in lines 808-810 updates the form field when the user manually interacts
with the picker, there is no mechanism to sync the preselected value into the
form's geo_organization field when selectedGeoOrg is initially populated by the
org bootstrap effect. Add an effect that watches selectedGeoOrg and updates the
form's geo_organization field via form.setValue whenever selectedGeoOrg changes,
ensuring the form state stays in sync with the picker's displayed value during
create mode.

}}
/>
</FormControl>
<FormMessage />
Expand Down
79 changes: 0 additions & 79 deletions src/hooks/useGovtOrganizationLevel.ts

This file was deleted.

Loading
Loading