import React, { useEffect, useState } from "react"; import { useForm, useFieldArray, FormProvider } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import TagInput from "../common/TagInput"; import { useBuckets, useContactDetails, useCreateContact, useDesignation, useOrganization, useUpdateContact, } from "../../hooks/useDirectory"; import { useProjects } from "../../hooks/useProjects"; import { useContactCategory, useContactTags, } from "../../hooks/masterHook/useMaster"; import SelectMultiple from "../common/SelectMultiple"; import { ContactSchema, defaultContactValue } from "./DirectorySchema"; import InputSuggestions from "../common/InputSuggestion"; import Label from "../common/Label"; const ManageContact = ({ contactId, closeModal }) => { // fetch master data const { buckets, loading: bucketsLoaging } = useBuckets(); const { projects, loading: projectLoading } = useProjects(); const { contactCategory, loading: contactCategoryLoading } = useContactCategory(); const { organizationList } = useOrganization(); const { designationList } = useDesignation(); const { contactTags } = useContactTags(); // fetch contact details if editing const { data: contactData, isLoading: isContactLoading } = useContactDetails( contactId, { enabled: !!contactId, } ); const [showSuggestions, setShowSuggestions] = useState(false); const [filteredDesignationList, setFilteredDesignationList] = useState([]); const methods = useForm({ resolver: zodResolver(ContactSchema), defaultValues: defaultContactValue, }); const { register, handleSubmit, control, getValues, setValue, watch, reset, formState: { errors }, } = methods; const { fields: emailFields, append: appendEmail, remove: removeEmail, } = useFieldArray({ control, name: "contactEmails" }); const { fields: phoneFields, append: appendPhone, remove: removePhone, } = useFieldArray({ control, name: "contactPhones" }); useEffect(() => { if (contactId && contactData) { reset({ name: contactData.name || "", description: contactData.description || "", designation: contactData.designation || "", organization: contactData.organization || "", contactEmails: contactData.contactEmails?.length ? contactData.contactEmails : [{ label: "Work", emailAddress: "" }], contactPhones: contactData.contactPhones?.length ? contactData.contactPhones : [{ label: "Office", phoneNumber: "" }], contactCategoryId: contactData.contactCategory?.id || "", address: contactData?.address || "", projectIds: contactData.projects?.map((p) => p.id) || [], bucketIds: contactData.buckets?.map((b) => b.id) || [], tags: contactData.tags || [], }); } }, [contactId, contactData, reset]); useEffect(() => { if (!contactId) { if (emailFields.length === 0) appendEmail({ label: "Work", emailAddress: "" }); if (phoneFields.length === 0) appendPhone({ label: "Office", phoneNumber: "" }); } }, [ contactId, emailFields.length, phoneFields.length, appendEmail, appendPhone, ]); const watchBucketIds = watch("bucketIds") || []; const handleDesignationChange = (e) => { const val = e.target.value; const matches = designationList.filter((org) => org.toLowerCase().includes(val.toLowerCase()) ); setFilteredDesignationList(matches); setShowSuggestions(true); setTimeout(() => setShowSuggestions(false), 5000); }; const handleSelectDesignation = (val) => { setShowSuggestions(false); setValue("designation", val); }; // bucket toggle const handleCheckboxChange = (id) => { const updated = watchBucketIds.includes(id) ? watchBucketIds.filter((i) => i !== id) : [...watchBucketIds, id]; setValue("bucketIds", updated, { shouldValidate: true }); }; // create & update mutations const { mutate: CreateContact, isPending: creating } = useCreateContact(() => handleClosed() ); const { mutate: UpdateContact, isPending: updating } = useUpdateContact(() => handleClosed() ); const onSubmit = (data) => { const payload = { ...data, contactEmails: (data.contactEmails || []).filter( (e) => e.emailAddress?.trim() !== "" ), contactPhones: (data.contactPhones || []).filter( (p) => p.phoneNumber?.trim() !== "" ), }; if (contactId) { const contactPayload = { ...data, id: contactId }; UpdateContact({ contactId: contactData.id, contactPayload: contactPayload, }); } else { CreateContact(payload); } }; const handleClosed = () => { closeModal(); }; const handleAddEmail = () => { appendEmail({ label: "Work", emailAddress: "" }); }; const handleAddPhone = () => { appendPhone({ label: "Office", phoneNumber: "" }); }; const isPending = updating || creating; return (
{contactId ? "Edit Contact" : "Create New Contact"}
{/* Name + Organization */}
{errors.name && ( {errors.name.message} )}
setValue("organization", val, { shouldValidate: true })} error={errors.organization?.message} />
{/* Designation */}
{showSuggestions && filteredDesignationList.length > 0 && (
    {filteredDesignationList.map((designation) => (
  • handleSelectDesignation(designation)} > {designation}
  • ))}
)} {errors.designation && ( {errors.designation.message} )}
{/* Emails + Phones */}
{emailFields.map((field, index) => (
{index === emailFields.length - 1 ? ( ) : ( removeEmail(index)} /> )}
{errors.contactEmails?.[index]?.emailAddress && ( {errors.contactEmails[index].emailAddress.message} )}
))}
{phoneFields.map((field, index) => (
{index === phoneFields.length - 1 ? ( ) : ( removePhone(index)} /> )}
{errors.contactPhones?.[index]?.phoneNumber && ( {errors.contactPhones[index].phoneNumber.message} )}
))}
{/* Category + Projects */}
{errors.contactCategoryId && ( {errors.contactCategoryId.message} )}
{errors.projectIds && ( {errors.projectIds.message} )}
{/* Tags */}
{errors.tags && ( {errors.tags.message} )}
{/* Buckets */}
    {bucketsLoaging &&

    Loading...

    } {buckets?.map((item) => (
  • handleCheckboxChange(item.id)} />
  • ))}
{errors.bucketIds && ( {errors.bucketIds.message} )}
{/* Address + Description */}