diff --git a/src/components/Directory/CardViewDirectory.jsx b/src/components/Directory/CardViewDirectory.jsx index 0d955810..31b56c9b 100644 --- a/src/components/Directory/CardViewDirectory.jsx +++ b/src/components/Directory/CardViewDirectory.jsx @@ -107,13 +107,13 @@ const CardViewDirectory = ({ {/*
  • */} -
  • +
  • {contact.organization}
  • { if (IsActive) { diff --git a/src/components/Directory/NotesDirectory.jsx b/src/components/Directory/NotesDirectory.jsx index 61908853..1dc56232 100644 --- a/src/components/Directory/NotesDirectory.jsx +++ b/src/components/Directory/NotesDirectory.jsx @@ -4,7 +4,6 @@ import Avatar from "../common/Avatar"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; -import { showText } from "pdf-lib"; import { DirectoryRepository } from "../../repositories/DirectoryRepository"; import moment from "moment"; import { cacheData, getCachedData } from "../../slices/apiDataManager"; @@ -19,15 +18,17 @@ const schema = z.object({ const NotesDirectory = ({ refetchProfile, isLoading, - contactProfile, + contactProfile, // This contactProfile now reliably includes firstName, middleName, lastName, and fullName setProfileContact, }) => { const [IsActive, setIsActive] = useState(true); - const { contactNotes, refetch } = useContactNotes(contactProfile?.id, true); + const { contactNotes, refetch } = useContactNotes( + contactProfile?.id, + IsActive + ); - const [NotesData, setNotesData] = useState(); const [IsSubmitting, setIsSubmitting] = useState(false); - const [addNote, setAddNote] = useState(true); + const [showEditor, setShowEditor] = useState(false); const { register, handleSubmit, @@ -67,102 +68,118 @@ const NotesDirectory = ({ ) { const updatedProfile = { ...cached_contactProfile.data, - notes: [...(cached_contactProfile.notes || []), createdNote], + notes: [...(cached_contactProfile.data.notes || []), createdNote], }; - cacheData("Contact Profile", updatedProfile); + cacheData("Contact Profile", { + contactId: contactProfile?.id, + data: updatedProfile, + }); } setValue("note", ""); setIsSubmitting(false); showToast("Note added successfully!", "success"); - setAddNote(true); + setShowEditor(false); setIsActive(true); + refetch(contactProfile?.id, true); } catch (error) { setIsSubmitting(false); const msg = - error.response.data.message || - error.message || - "Error occured during API calling"; + error.response?.data?.message || error.message || "Error occurred during API calling"; showToast(msg, "error"); } }; const onCancel = () => { - setValue( "note", "" ); - + setValue("note", ""); + setShowEditor(false); }; + const handleSwitch = () => { - setIsActive(!IsActive); - if (IsActive) { - refetch(contactProfile?.id, false); - } + setIsActive((prevIsActive) => { + const newState = !prevIsActive; + refetch(contactProfile?.id, newState); + return newState; + }); }; + // Use the fullName from contactProfile, which now includes middle and last names if available + const contactName = + contactProfile?.fullName || contactProfile?.firstName || "Contact"; + const noNotesMessage = `Be the first to share your insights! ${contactName} currently has no notes.`; + + const notesToDisplay = IsActive + ? contactProfile?.notes || [] + : contactNotes || []; + return ( -
    +
    -

    Notes :

    +
    +
    +

    Notes :

    +
    +
    + {" "} +
    + + {!showEditor && ( +
    + +
    + )} +
    +
    +
    -
    -
    - {contactNotes?.length > 0 ? ( - - ) : ( -
    - -
    - )} -
    -
    - setAddNote(!addNote)} - > - {addNote ? "Hide Editor" : "Add a Note"} - -
    -
    - - - {addNote && ( -
    - - {/*
    - setAddNote(!addNote)} - > - {addNote ? "Hide Editor" : "Add Note"} - -
    */} + onClick={() => setShowEditor(false)} + > + +
    - {errors.notes && ( + {errors.note && (

    {errors.note.message}

    )}
    )} -
    +
    {isLoading && (
    {" "}

    Loading...

    {" "}
    )} - {!isLoading && - [...(IsActive ? contactProfile?.notes || [] : contactNotes || [])] - .reverse() - .map((noteItem) => ( - - ))} - - {IsActive && ( -
    - {!isLoading && contactProfile?.notes.length == 0 && !addNote && ( -
    No Notes Found
    + {!isLoading && notesToDisplay.length > 0 + ? notesToDisplay + .slice() + .reverse() + .map((noteItem) => ( + + )) + : !isLoading && + !showEditor && ( +
    {noNotesMessage}
    )} -
    - )} - {!IsActive && ( -
    - {!isLoading && contactNotes.length == 0 && !addNote && ( -
    No Notes Found
    - )} -
    - )}
    ); }; -export default NotesDirectory; +export default NotesDirectory; \ No newline at end of file diff --git a/src/components/Directory/ProfileContactDirectory.jsx b/src/components/Directory/ProfileContactDirectory.jsx index 41e1dadd..52b35549 100644 --- a/src/components/Directory/ProfileContactDirectory.jsx +++ b/src/components/Directory/ProfileContactDirectory.jsx @@ -8,9 +8,10 @@ const ProfileContactDirectory = ({ contact, setOpen_contact, closeModal }) => { const { contactProfile, loading, refetch } = useContactProfile(contact?.id); const [copiedIndex, setCopiedIndex] = useState(null); - const [profileContact, setProfileContact] = useState(); + const [profileContactState, setProfileContactState] = useState(null); const [expanded, setExpanded] = useState(false); - const description = contactProfile?.description || ""; + + const description = profileContactState?.description || ""; const limit = 500; const toggleReadMore = () => setExpanded(!expanded); @@ -19,14 +20,51 @@ const ProfileContactDirectory = ({ contact, setOpen_contact, closeModal }) => { const displayText = expanded ? description : description.slice(0, limit) + (isLong ? "..." : ""); + useEffect(() => { - setProfileContact(contactProfile); - }, [contactProfile]); + if (contactProfile) { + const names = (contact?.name || "").trim().split(" "); + let firstName = ""; + let middleName = ""; + let lastName = ""; + let fullName = contact?.name || ""; + + // Logic to determine first, middle, and last names + if (names.length === 1) { + firstName = names[0]; + } else if (names.length === 2) { + firstName = names[0]; + lastName = names[1]; + } else if (names.length >= 3) { + firstName = names[0]; + middleName = names[1]; // This was an error in the original prompt, corrected to names[1] + lastName = names[names.length - 1]; + // Reconstruct full name to be precise with spacing + fullName = `${firstName} ${middleName ? middleName + ' ' : ''}${lastName}`; + } else { + // Fallback if no names or empty string + firstName = "Contact"; + fullName = "Contact"; + } + + + setProfileContactState({ + ...contactProfile, + firstName: contactProfile.firstName || firstName, + // Adding middleName and lastName to the state for potential future use or more granular access + middleName: contactProfile.middleName || middleName, + lastName: contactProfile.lastName || lastName, + fullName: contactProfile.fullName || fullName, // Prioritize fetched fullName, fallback to derived + }); + } + }, [contactProfile, contact?.name]); + const handleCopy = (email, index) => { navigator.clipboard.writeText(email); setCopiedIndex(index); - setTimeout(() => setCopiedIndex(null), 2000); // Reset after 2 seconds + setTimeout(() => setCopiedIndex(null), 2000); }; + return (
    @@ -47,32 +85,35 @@ const ProfileContactDirectory = ({ contact, setOpen_contact, closeModal }) => {
    {contact?.name} - {/* {contactProfile?.tags?.map((tag) => tag.name).join(" | ")} */} - {contactProfile?.designation} + {profileContactState?.designation}
    -
    +
    - {contactProfile?.contactEmails?.length > 0 && ( -
    -
    -

    Email:

    + {profileContactState?.contactEmails?.length > 0 && ( +
    +
    + + + Email + + :
    +
      - {contactProfile.contactEmails.map((email, idx) => ( + {profileContactState.contactEmails.map((email, idx) => (
    • - - + {email.emailAddress} handleCopy(email.emailAddress, idx)} @@ -84,17 +125,22 @@ const ProfileContactDirectory = ({ contact, setOpen_contact, closeModal }) => {
    )} - {contactProfile?.contactPhones?.length > 0 && ( -
    -
    -

    Phone :

    + {profileContactState?.contactPhones?.length > 0 && ( +
    +
    + + + Phone + + :
    +
      - {contactProfile?.contactPhones.map((phone, idx) => ( -
    • - + {profileContactState.contactPhones.map((phone, idx) => ( +
    • {phone.phoneNumber} + {idx < profileContactState.contactPhones.length - 1 && ","}
    • ))}
    @@ -102,74 +148,93 @@ const ProfileContactDirectory = ({ contact, setOpen_contact, closeModal }) => {
    )} - {contactProfile?.createdAt && ( -
    -
    -

    Created :

    + {profileContactState?.createdAt && ( +
    +
    + + + Created + + :
    +
    -
  • - - {moment(contactProfile.createdAt).format("MMMM, DD YYYY")} -
  • + + {moment(profileContactState.createdAt).format("MMMM DD, YYYY")} +
    )} - {contactProfile?.address && ( -
    -
    -

    Location:

    -
    -
    - - - {contactProfile.address} + + {profileContactState?.address && ( +
    +
    + + + Location + : +
    +
    + {profileContactState.address}
    )}
    - {contactProfile?.organization && ( -
    -
    -

    Orgnization :

    + {profileContactState?.organization && ( +
    +
    + + + Organization + + :
    -
    - +
    - {contactProfile.organization} + {profileContactState.organization}
    )} - {contactProfile?.contactCategory && ( -
    -
    -

    Category :

    + + {profileContactState?.contactCategory && ( +
    +
    + + + Category + + :
    +
    • - - {contactProfile.contactCategory.name} + {profileContactState.contactCategory.name}
    )} - {contactProfile?.tags?.length > 0 && ( -
    -
    -

    Tags :

    + + {profileContactState?.tags?.length > 0 && ( +
    +
    + + + Tags + + :
    +
      - {contactProfile.tags.map((tag, index) => ( + {profileContactState.tags.map((tag, index) => (
    • - {tag.name}
    • ))} @@ -178,75 +243,93 @@ const ProfileContactDirectory = ({ contact, setOpen_contact, closeModal }) => {
    )} - {contactProfile?.buckets?.length > 0 && ( -
    - {contactProfile?.contactEmails?.length > 0 && ( -
    -
    -

    Buckets :

    -
    -
    -
      - {contactProfile.buckets.map((bucket) => ( -
    • - - {bucket.name} - -
    • - ))} -
    -
    -
    - )} + {profileContactState?.buckets?.length > 0 && ( +
    +
    + + + Buckets + + : +
    + +
    +
      + {profileContactState.buckets.map((bucket) => ( +
    • + + {bucket.name} + +
    • + ))} +
    +
    )}
    -
    - {contactProfile?.projects?.length > 0 && ( -
    -
    -

    Projects :

    -
    -
    -
      - {contactProfile.projects.map((project, index) => ( -
    • - {project.name} - {index < contactProfile.projects.length - 1 && ","} -
    • - ))} -
    -
    -
    - )} -
    -
    -

    Description :

    + {profileContactState?.projects?.length > 0 && ( +
    +
    + + + Projects + + : +
    + +
    +
      + {profileContactState.projects.map((project, index) => ( +
    • + {project.name} + {index < profileContactState.projects.length - 1 && ","} +
    • + ))} +
    +
    +
    + )} +
    + +
    +
    + + + Description + + :
    +
    {displayText} {isLong && ( - - {expanded ? "Read less" : "Read more"} - + <> +
    + + {expanded ? "Read less" : "Read more"} + + )}
    + + +
    ); }; -export default ProfileContactDirectory; +export default ProfileContactDirectory; \ No newline at end of file diff --git a/src/pages/Activities/AttendancePage.jsx b/src/pages/Activities/AttendancePage.jsx index f65d06c8..65cd069d 100644 --- a/src/pages/Activities/AttendancePage.jsx +++ b/src/pages/Activities/AttendancePage.jsx @@ -8,7 +8,6 @@ import { import Breadcrumb from "../../components/common/Breadcrumb"; import AttendanceLog from "../../components/Activities/AttendcesLogs"; import Attendance from "../../components/Activities/Attendance"; -// import AttendanceModel from "../../components/Activities/AttendanceModel"; import showToast from "../../services/toastService"; import Regularization from "../../components/Activities/Regularization"; import { useAttendance } from "../../hooks/useAttendance"; @@ -18,12 +17,12 @@ import { markCurrentAttendance } from "../../slices/apiSlice/attendanceAllSlice" import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { REGULARIZE_ATTENDANCE } from "../../utils/constants"; import eventBus from "../../services/eventBus"; -// import AttendanceRepository from "../../repositories/AttendanceRepository"; +import AttendanceRepository from "../../repositories/AttendanceRepository"; // Make sure this is imported if used import { useProjectName } from "../../hooks/useProjects"; import GlobalModel from "../../components/common/GlobalModel"; import CheckCheckOutmodel from "../../components/Activities/CheckCheckOutForm"; import AttendLogs from "../../components/Activities/AttendLogs"; -// import Confirmation from "../../components/Activities/Confirmation"; +import Confirmation from "../../components/Activities/Confirmation"; // Make sure this is imported if used import { useQueryClient } from "@tanstack/react-query"; const AttendancePage = () => { @@ -37,7 +36,7 @@ const AttendancePage = () => { attendance, loading: attLoading, recall: attrecall, - } = useAttendace(selectedProject); + } = useAttendance(selectedProject); // Corrected typo: useAttendace to useAttendance const [attendances, setAttendances] = useState(); const [empRoles, setEmpRoles] = useState(null); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); @@ -58,10 +57,10 @@ const AttendancePage = () => { // Ensure attendances is not null before mapping const updatedAttendance = attendances ? attendances.map((item) => - item.employeeId === msg.response.employeeId - ? { ...item, ...msg.response } - : item - ) + item.employeeId === msg.response.employeeId + ? { ...item, ...msg.response } + : item + ) : [msg.response]; // If attendances is null, initialize with new response cacheData("Attendance", { @@ -71,12 +70,13 @@ const AttendancePage = () => { setAttendances(updatedAttendance); } }, - [selectedProject, attendances] // Removed attrecall as it's not a direct dependency for this state update + [selectedProject, attendances] ); const employeeHandler = useCallback( (msg) => { if (attendances?.some((item) => item.employeeId === msg.employeeId)) { + // Ensure AttendanceRepository is imported and available AttendanceRepository.getAttendance(selectedProject) .then((response) => { cacheData("Attendance", { data: response.data, selectedProject }); @@ -127,10 +127,10 @@ const AttendancePage = () => { if (action.payload && action.payload.employeeId) { const updatedAttendance = attendances ? attendances.map((item) => - item.employeeId === action.payload.employeeId - ? { ...item, ...action.payload } - : item - ) + item.employeeId === action.payload.employeeId + ? { ...item, ...action.payload } + : item + ) : [action.payload]; // If attendances is null, initialize with new payload cacheData("Attendance", { @@ -151,6 +151,7 @@ const AttendancePage = () => { const handleToggle = (event) => { setShowPending(event.target.checked); }; + useEffect(() => { if (selectedProject === null && projectNames.length > 0) { dispatch(setProjectId(projectNames[0]?.id)); @@ -162,8 +163,8 @@ const AttendancePage = () => { if (modelConfig !== null) { openModel(); } - }, [modelConfig]); // Removed isCreateModalOpen from here as it's set by openModel() - + }, [modelConfig]); + useEffect(() => { setAttendances(attendance); }, [attendance]); @@ -204,27 +205,8 @@ const AttendancePage = () => { return () => eventBus.off("attendance", handler); }, [handler]); - // useEffect(() => { - // eventBus.on("employee", employeeHandler); - // return () => eventBus.off("employee", employeeHandler); - // }, [employeeHandler]); return ( <> - {/* {isCreateModalOpen && modelConfig && ( - - )} */} {isCreateModalOpen && modelConfig && ( {
    {activeTab === "all" && ( -
    - -
    - )} +
    + {!attLoading && filteredAndSearchedTodayAttendance()?.length === 0 && (

    {" "} @@ -327,7 +307,7 @@ const AttendancePage = () => { : "No Employee assigned yet."}{" "}

    )} - +
    )} {activeTab === "logs" && (