Compare commits

..

5 Commits

8 changed files with 70 additions and 55 deletions

View File

@ -20,14 +20,21 @@ import { SpinnerLoader } from "../common/Loader";
const usePagination = (data, itemsPerPage) => { const usePagination = (data, itemsPerPage) => {
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const maxPage = Math.ceil(data.length / itemsPerPage); // const maxPage = Math.ceil(data.length / itemsPerPage);
const maxPage = Math.max(1, Math.ceil(data.length / itemsPerPage));
const currentItems = useMemo(() => { const currentItems = useMemo(() => {
const startIndex = (currentPage - 1) * itemsPerPage; const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage; const endIndex = startIndex + itemsPerPage;
return data.slice(startIndex, endIndex); return data.slice(startIndex, endIndex);
}, [data, currentPage, itemsPerPage]); }, [data, currentPage, itemsPerPage]);
const paginate = useCallback((pageNumber) => setCurrentPage(pageNumber), []); // const paginate = useCallback((pageNumber) => setCurrentPage(pageNumber), []);
const paginate = useCallback((pageNumber) => {
// keep page within 1..maxPage
const p = Math.max(1, Math.min(pageNumber, maxPage));
setCurrentPage(p);
}, [maxPage]);
const resetPage = useCallback(() => setCurrentPage(1), []); const resetPage = useCallback(() => setCurrentPage(1), []);
return { return {
@ -36,6 +43,7 @@ const usePagination = (data, itemsPerPage) => {
currentItems, currentItems,
paginate, paginate,
resetPage, resetPage,
setCurrentPage,
}; };
}; };
@ -125,9 +133,16 @@ const AttendanceLog = ({ handleModalData, searchTerm, organizationId }) => {
resetPage, resetPage,
} = usePagination(filteredSearchData, 20); } = usePagination(filteredSearchData, 20);
// useEffect(() => {
// resetPage();
// }, [filteredSearchData]);
useEffect(() => { useEffect(() => {
resetPage(); if (currentPage > totalPages) {
}, [filteredSearchData]); paginate(totalPages || 1);
}
// NOTE: do NOT force reset to page 1 here keep the same page if still valid
}, [filteredSearchData, totalPages, currentPage, paginate]);
const handler = useCallback( const handler = useCallback(
(msg) => { (msg) => {
@ -144,10 +159,9 @@ const AttendanceLog = ({ handleModalData, searchTerm, organizationId }) => {
record.id === msg.response.id ? { ...record, ...msg.response } : record record.id === msg.response.id ? { ...record, ...msg.response } : record
); );
}); });
resetPage();
} }
}, },
[selectedProject, dateRange, resetPage] [selectedProject, dateRange]
); );
useEffect(() => { useEffect(() => {

View File

@ -9,6 +9,7 @@ import ConfirmModal from "../common/ConfirmModal"; // Make sure path is correct
import "../common/TextEditor/Editor.css"; import "../common/TextEditor/Editor.css";
import GlobalModel from "../common/GlobalModel"; import GlobalModel from "../common/GlobalModel";
import { useActiveInActiveNote, useUpdateNote } from "../../hooks/useDirectory"; import { useActiveInActiveNote, useUpdateNote } from "../../hooks/useDirectory";
import { useDirectoryContext } from "../../pages/Directory/DirectoryPage";
const NoteCardDirectoryEditable = ({ const NoteCardDirectoryEditable = ({
noteItem, noteItem,
@ -22,14 +23,14 @@ const NoteCardDirectoryEditable = ({
const [isDeleting, setIsDeleting] = useState(false); const [isDeleting, setIsDeleting] = useState(false);
const [isRestoring, setIsRestoring] = useState(false); const [isRestoring, setIsRestoring] = useState(false);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [open_contact, setOpen_contact] = useState(null);
const [isOpenModalNote, setIsOpenModalNote] = useState(false);
const { mutate: UpdateNote, isPending: isUpatingNote } = useUpdateNote(() => const { mutate: UpdateNote, isPending: isUpatingNote } = useUpdateNote(() =>
setEditing(false) setEditing(false)
); );
const { mutate: ActiveInactive, isPending: isUpdatingStatus } = const { mutate: ActiveInactive, isPending: isUpdatingStatus } =
useActiveInActiveNote(() => setIsDeleteModalOpen(false)); useActiveInActiveNote(() => setIsDeleteModalOpen(false));
const { setContactOpen } = useDirectoryContext();
const handleUpdateNote = async () => { const handleUpdateNote = async () => {
const payload = { const payload = {
@ -45,12 +46,6 @@ const NoteCardDirectoryEditable = ({
ActiveInactive({ noteId: noteItem.id, noteStatus: !noteItem.isActive }); ActiveInactive({ noteId: noteItem.id, noteStatus: !noteItem.isActive });
}; };
const contactProfile = (contactId) => {
DirectoryRepository.GetContactProfile(contactId).then((res) => {
setOpen_contact(res?.data);
setIsOpenModalNote(true);
});
};
const handleRestore = async () => { const handleRestore = async () => {
try { try {
@ -88,7 +83,9 @@ const NoteCardDirectoryEditable = ({
<div> <div>
<div <div
className="d-flex ms-3 align-middle cursor-pointer" className="d-flex ms-3 align-middle cursor-pointer"
onClick={() => contactProfile(noteItem.contactId)} onClick={() =>
setContactOpen({ contact: { id: noteItem.contactId }, Open: true })
}
> >
<span> <span>
<span className="fw-bold "> {noteItem?.contactName} </span>{" "} <span className="fw-bold "> {noteItem?.contactName} </span>{" "}
@ -97,6 +94,7 @@ const NoteCardDirectoryEditable = ({
</span> </span>
</span> </span>
</div> </div>
<div className="d-flex ms-0 align-middle"></div> <div className="d-flex ms-0 align-middle"></div>
<div className="d-flex ms-3 mt-2"> <div className="d-flex ms-3 mt-2">
<span className="text-muted"> <span className="text-muted">

View File

@ -25,7 +25,9 @@ const Sidebar = () => {
/> />
</span> */} </span> */}
<small className="app-brand-link fw-bold navbar-brand text-green fs-6"> <small
className="app-brand-link fw-bold navbar-brand text-green fs-6"
>
<span className="app-brand-logo demo"> <span className="app-brand-logo demo">
<img src="/img/brand/marco.png" width="50" /> <img src="/img/brand/marco.png" width="50" />
</span> </span>
@ -36,6 +38,7 @@ const Sidebar = () => {
</Link> </Link>
<small className="layout-menu-toggle menu-link text-large ms-auto"> <small className="layout-menu-toggle menu-link text-large ms-auto">
<i className="bx bx-chevron-left bx-sm d-flex align-items-center justify-content-center"></i> <i className="bx bx-chevron-left bx-sm d-flex align-items-center justify-content-center"></i>
</small> </small>
</div> </div>
@ -58,7 +61,7 @@ const Sidebar = () => {
</> </>
)} )}
{data && {data &&
data?.data?.map((section) => ( data?.data.map((section) => (
<React.Fragment <React.Fragment
key={section.id || section.header || section.items[0]?.id} key={section.id || section.header || section.items[0]?.id}
> >

View File

@ -10,13 +10,11 @@ import {
import useMaster, { useServices } from "../../../hooks/masterHook/useMaster"; import useMaster, { useServices } from "../../../hooks/masterHook/useMaster";
import showToast from "../../../services/toastService"; import showToast from "../../../services/toastService";
import { useOrganizationEmployees } from "../../../hooks/useOrganization"; import { useOrganizationEmployees } from "../../../hooks/useOrganization";
import { useDispatch } from "react-redux";
import { changeMaster } from "../../../slices/localVariablesSlice";
const TeamEmployeeList = ({ organizationId, searchTerm, closeModal }) => { const TeamEmployeeList = ({ organizationId, searchTerm, closeModal }) => {
const selectedProject = useSelectedProject(); const selectedProject = useSelectedProject();
const debounceSearchTerm = useDebounce(searchTerm, 500); const debounceSearchTerm = useDebounce(searchTerm, 500);
const dispatch = useDispatch();
const { const {
data: employeesData = [], data: employeesData = [],
isLoading, isLoading,
@ -47,7 +45,6 @@ const TeamEmployeeList = ({ organizationId, searchTerm, closeModal }) => {
}); });
useEffect(() => { useEffect(() => {
dispatch(changeMaster("Job Role"));
if (employeesData?.data?.length > 0) { if (employeesData?.data?.length > 0) {
const available = employeesData.data.filter((emp) => { const available = employeesData.data.filter((emp) => {
const projEmp = projectEmployees.find((pe) => pe.employeeId === emp.id); const projEmp = projectEmployees.find((pe) => pe.employeeId === emp.id);
@ -186,7 +183,8 @@ const TeamEmployeeList = ({ organizationId, searchTerm, closeModal }) => {
onChange={(e) => onChange={(e) =>
handleSelectChange(index, "serviceId", e.target.value) handleSelectChange(index, "serviceId", e.target.value)
} }
className={`form-select form-select-sm w-auto border-none rounded-0 py-1 px-auto ${emp.errors.serviceId ? "is-invalid" : "" className={`form-select form-select-sm w-auto border-none rounded-0 py-1 px-auto ${
emp.errors.serviceId ? "is-invalid" : ""
}`} }`}
> >
<option value="">Select Service</option> <option value="">Select Service</option>
@ -207,7 +205,8 @@ const TeamEmployeeList = ({ organizationId, searchTerm, closeModal }) => {
onChange={(e) => onChange={(e) =>
handleSelectChange(index, "jobRole", e.target.value) handleSelectChange(index, "jobRole", e.target.value)
} }
className={`form-select form-select-sm w-auto border-none rounded-0 py-1 px-auto ${emp.errors.jobRole ? "is-invalid" : "" className={`form-select form-select-sm w-auto border-none rounded-0 py-1 px-auto ${
emp.errors.jobRole ? "is-invalid" : ""
}`} }`}
> >
<option value="">Select Job Role</option> <option value="">Select Job Role</option>

View File

@ -140,6 +140,7 @@ const ManageJob = ({ Job }) => {
formData.projectId = projectId; formData.projectId = projectId;
CreateJob(formData); CreateJob(formData);
setManageJob({ isOpen: false, jobId: null });
} }
}; };

View File

@ -134,7 +134,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
control={control} control={control}
placeholder="DD-MM-YYYY" placeholder="DD-MM-YYYY"
maxDate={new Date()} maxDate={new Date()}
className={errors.onBoardingDate ? "is-invalid" : ""} className={`w-100 ${errors.onBoardingDate ? "is-invalid" : ""}`}
/> />
{errors.onBoardingDate && ( {errors.onBoardingDate && (
<div className="invalid-feedback"> <div className="invalid-feedback">

View File

@ -109,7 +109,7 @@ const ServiceGroups = ({ service }) => {
/> />
</span> </span>
)} )}
<p className="m-0 fw-bold ">{group.name}</p> <p className="m-0 ">{group.name}</p>
</div> </div>
<div className="d-flex flex-row gap-3"> <div className="d-flex flex-row gap-3">
<div className="d-flex flex-row gap-2"> <div className="d-flex flex-row gap-2">

View File

@ -132,7 +132,7 @@ export const useAddSubscription = (onSuccessCallback) => {
onSuccess: (data, variables) => { onSuccess: (data, variables) => {
const { tenantId } = variables; const { tenantId } = variables;
showToast("Tenant Plan Added SuccessFully", "success"); showToast("Tenant Plan Added SuccessFully", "success");
queryClient.invalidateQueries({ queryKey: ["Tenant", tenantId] }); queryClient.invalidateQueries({ queryKey: ["Tenants", tenantId] });
if (onSuccessCallback) onSuccessCallback(); if (onSuccessCallback) onSuccessCallback();
}, },
onError: (error) => { onError: (error) => {