diff --git a/src/components/RecurringExpense/RecurringExpenseList.jsx b/src/components/RecurringExpense/RecurringExpenseList.jsx
index a4c45fba..c1bb9e13 100644
--- a/src/components/RecurringExpense/RecurringExpenseList.jsx
+++ b/src/components/RecurringExpense/RecurringExpenseList.jsx
@@ -166,7 +166,6 @@ const RecurringExpenseList = ({ search, filterStatuses }) => {
}
);
};
-console.log("Tanish",filteredData)
return (
<>
{IsDeleteModalOpen && (
diff --git a/src/components/ServiceProject/ServiceProjectBranch/ServiceBranch.jsx b/src/components/ServiceProject/ServiceProjectBranch/ServiceBranch.jsx
index b33e7cce..63bdb09c 100644
--- a/src/components/ServiceProject/ServiceProjectBranch/ServiceBranch.jsx
+++ b/src/components/ServiceProject/ServiceProjectBranch/ServiceBranch.jsx
@@ -237,15 +237,17 @@ const ServiceBranch = () => {
!isError &&
(!data?.data || data.data.length === 0) && (
- |
- No Branch Found
+ |
+
+ No Branch Found
+
|
)}
+
diff --git a/src/components/common/HoverPopup.jsx b/src/components/common/HoverPopup.jsx
index 1063745b..232ced5d 100644
--- a/src/components/common/HoverPopup.jsx
+++ b/src/components/common/HoverPopup.jsx
@@ -58,139 +58,66 @@ const HoverPopup = ({
return () => document.removeEventListener("click", handler);
}, [Mode, visible, dispatch, id]);
- // Positioning effect: respects align prop and stays inside boundary (drawer)
useEffect(() => {
if (!visible || !popupRef.current || !triggerRef.current) return;
- // run in next frame so DOM/layout settles
requestAnimationFrame(() => {
const popup = popupRef.current;
-
- // choose boundary: provided boundaryRef or nearest positioned parent (popup.parentElement)
- const boundaryEl =
- (boundaryRef && boundaryRef.current) || popup.parentElement;
+ const boundaryEl = (boundaryRef && boundaryRef.current) || popup.parentElement;
if (!boundaryEl) return;
const boundaryRect = boundaryEl.getBoundingClientRect();
const triggerRect = triggerRef.current.getBoundingClientRect();
-
- // reset styles first
popup.style.left = "";
popup.style.right = "";
popup.style.transform = "";
popup.style.top = "";
const popupRect = popup.getBoundingClientRect();
- const parentRect = boundaryRect; // alias
+ const triggerCenterX = triggerRect.left + triggerRect.width / 2 - boundaryRect.left;
+ let left = triggerCenterX - popupRect.width / 2;
- // Convert trigger center to parent coordinates
- const triggerCenterX =
- triggerRect.left + triggerRect.width / 2 - parentRect.left;
-
- // preferred left so popup center aligns to trigger center:
- const preferredLeft = triggerCenterX - popupRect.width / 2;
-
- // Helpers to set styles in parent's coordinate system:
- const setLeft = (leftPx) => {
- popup.style.left = `${leftPx}px`;
- popup.style.right = "auto";
- popup.style.transform = "none";
- };
- const setRight = (rightPx) => {
- popup.style.left = "auto";
- popup.style.right = `${rightPx}px`;
- popup.style.transform = "none";
- };
-
- // If user forced align:
- if (align === "left") {
- // align popup's left to parent's left (0)
- setLeft(0);
- return;
- }
- if (align === "right") {
- // align popup's right to parent's right (0)
- setRight(0);
- return;
- }
- if (align === "center") {
- popup.style.left = "50%";
- popup.style.right = "auto";
- popup.style.transform = "translateX(-50%)";
- return;
- }
-
- // align === "auto": try preferred centered position, but flip fully if overflow
- // clamp preferredLeft to boundaries so it doesn't render partially outside
- const leftIfCentered = Math.max(
- 0,
- Math.min(preferredLeft, parentRect.width - popupRect.width)
- );
-
- // if centered fits, use it
- if (leftIfCentered === preferredLeft) {
- setLeft(leftIfCentered);
- return;
- }
-
- // if centering would overflow right -> stick popup fully to left (left=0)
- if (preferredLeft > parentRect.width - popupRect.width) {
- // place popup so its right aligns to parent's right
- // i.e., left = parent width - popup width
- setLeft(parentRect.width - popupRect.width);
- return;
- }
-
- // if centering would overflow left -> stick popup fully to left=0
- if (preferredLeft < 0) {
- setLeft(0);
- return;
- }
-
- // fallback center
- setLeft(leftIfCentered);
+ // Clamp to boundaries
+ left = Math.max(0, Math.min(left, boundaryRect.width - popupRect.width));
+ popup.style.left = `${left}px`;
});
}, [visible, align, boundaryRef]);
- return (
-
+ return (
- {children}
-
-
- {visible && (
e.stopPropagation()}
+
+ ref={triggerRef}
+ onMouseEnter={handleMouseEnter}
+ onMouseLeave={handleMouseLeave}
+ onClick={handleClick}
+ style={{ cursor: "pointer", display: "inline-block" }}
>
- {title &&
{title}
}
-
{content}
+ {children}
- )}
-
-);
+
+ {visible && (
+
e.stopPropagation()}
+ >
+ {title &&
{title}
}
+
{content}
+
+ )}
+
+ );
};
diff --git a/src/components/common/InputSuggestion.jsx b/src/components/common/InputSuggestion.jsx
index b586abe1..add306f8 100644
--- a/src/components/common/InputSuggestion.jsx
+++ b/src/components/common/InputSuggestion.jsx
@@ -4,6 +4,7 @@ const InputSuggestions = ({
organizationList = [],
value,
onChange,
+ size = "sm",
error,
disabled = false,
}) => {
@@ -27,7 +28,7 @@ const InputSuggestions = ({
return (
setTimeout(() => setShowSuggestions(false), 150)}
@@ -57,15 +58,14 @@ const InputSuggestions = ({
transition: "background-color 0.2s",
}}
onMouseDown={() => handleSelectSuggestion(org)}
- className={`dropdown-item ${
- org === value ? "active" : ""
+ className={`dropdown-item ${org === value ? "active" : ""
}`}
>
{org}
))}
-
+
)}
{error &&
{error}}
diff --git a/src/pages/Expense/ExpensePage.jsx b/src/pages/Expense/ExpensePage.jsx
index e7ac3638..d7b2b594 100644
--- a/src/pages/Expense/ExpensePage.jsx
+++ b/src/pages/Expense/ExpensePage.jsx
@@ -62,7 +62,7 @@ const ExpensePage = () => {
const [ViewDocument, setDocumentView] = useState({
IsOpen: false,
- Image: null,
+ Images: null,
});
const IsCreatedAble = useHasUserPermission(CREATE_EXEPENSE);
@@ -208,10 +208,10 @@ const ExpensePage = () => {
setDocumentView({ IsOpen: false, Image: null })}
+ key={ViewDocument.Images ?? "doc"}
+ closeModal={() => setDocumentView({ IsOpen: false, Images: null })}
>
-
+
)}
diff --git a/src/pages/project/ProjectDetails.jsx b/src/pages/project/ProjectDetails.jsx
index 298e95fb..b8ab45d6 100644
--- a/src/pages/project/ProjectDetails.jsx
+++ b/src/pages/project/ProjectDetails.jsx
@@ -24,6 +24,9 @@ import { useProjectAccess } from "../../hooks/useProjectAccess";
import "./ProjectDetails.css";
import ProjectOrganizations from "../../components/Project/ProjectOrganizations";
+import ProjectStatistics from "../../components/Project/ProjectStatistics";
+import { useHasUserPermission } from "../../hooks/useHasUserPermission";
+import { REGULARIZE_ATTENDANCE, SELF_ATTENDANCE, TEAM_ATTENDANCE } from "../../utils/constants";
const ProjectDetails = () => {
const projectId = useSelectedProject();
@@ -34,6 +37,10 @@ const ProjectDetails = () => {
useProjectDetails(projectId);
const { canView, loading: permsLoading } = useProjectAccess(projectId);
+ const canRegularize = useHasUserPermission(REGULARIZE_ATTENDANCE);
+ const canTeamAttendance = useHasUserPermission(TEAM_ATTENDANCE);
+ const canSelfAttendance = useHasUserPermission(SELF_ATTENDANCE);
+
useEffect(() => {
if (!projectId && projectNames.length > 0) {
@@ -82,13 +89,16 @@ const ProjectDetails = () => {
+
-
+ {(canRegularize || canTeamAttendance || canSelfAttendance) && (
+
+ )}
);