diff --git a/src/components/Charts/Circle.jsx b/src/components/Charts/Circle.jsx
new file mode 100644
index 00000000..6b0669bf
--- /dev/null
+++ b/src/components/Charts/Circle.jsx
@@ -0,0 +1,80 @@
+import React from "react";
+import ReactApexChart from "react-apexcharts";
+
+const ApexChart = ({ completed = 0, planned = 1 }) => {
+const percentage = planned > 0 ? Math.round((completed / planned) * 100) : 0;
+
+const options = {
+chart: {
+height: 200,
+type: "radialBar",
+toolbar: { show: false },
+},
+plotOptions: {
+radialBar: {
+startAngle: -135,
+endAngle: 225,
+hollow: {
+margin: 0,
+size: "60%",
+background: "#fff",
+dropShadow: {
+enabled: true,
+top: 2,
+left: 0,
+blur: 3,
+opacity: 0.45,
+},
+},
+track: {
+background: "#f5f5f5",
+strokeWidth: "67%",
+dropShadow: { enabled: false },
+},
+dataLabels: {
+show: true,
+name: {
+offsetY: -10,
+color: "#888",
+fontSize: "14px",
+},
+value: {
+formatter: (val) => `${val}%`,
+color: "#111",
+fontSize: "24px",
+show: true,
+},
+},
+},
+},
+fill: {
+type: "gradient",
+gradient: {
+shade: "dark",
+type: "horizontal",
+shadeIntensity: 0.5,
+gradientToColors: ["#ABE5A1"],
+opacityFrom: 1,
+opacityTo: 1,
+stops: [0, 100],
+},
+},
+stroke: {
+lineCap: "round",
+},
+labels: ["Progress"],
+};
+
+return (
+
+
+
+);
+};
+
+export default ApexChart;
\ No newline at end of file
diff --git a/src/components/Charts/Circlechart.jsx b/src/components/Charts/Circlechart.jsx
new file mode 100644
index 00000000..ab1c1116
--- /dev/null
+++ b/src/components/Charts/Circlechart.jsx
@@ -0,0 +1,85 @@
+import React from "react";
+import ReactApexChart from "react-apexcharts";
+
+const ApexChart = () => {
+ const [state] = React.useState({
+ series: [75], // Replace this with dynamic value if needed
+ options: {
+ chart: {
+ height: 200, // Smaller height
+ type: "radialBar",
+ toolbar: {
+ show: false, // Hide toolbar
+ },
+ },
+ plotOptions: {
+ radialBar: {
+ startAngle: -135,
+ endAngle: 225,
+ hollow: {
+ margin: 0,
+ size: "60%", // Smaller inner circle
+ background: "#fff",
+ dropShadow: {
+ enabled: true,
+ top: 2,
+ left: 0,
+ blur: 3,
+ opacity: 0.45,
+ },
+ },
+ track: {
+ background: "#f5f5f5",
+ strokeWidth: "67%",
+ dropShadow: {
+ enabled: false,
+ },
+ },
+ dataLabels: {
+ show: true,
+ name: {
+ offsetY: -10,
+ color: "#888",
+ fontSize: "14px",
+ },
+ value: {
+ formatter: (val) => parseInt(val),
+ color: "#111",
+ fontSize: "24px", // Smaller number
+ show: true,
+ },
+ },
+ },
+ },
+ fill: {
+ type: "gradient",
+ gradient: {
+ shade: "dark",
+ type: "horizontal",
+ shadeIntensity: 0.5,
+ gradientToColors: ["#ABE5A1"],
+ opacityFrom: 1,
+ opacityTo: 1,
+ stops: [0, 100],
+ },
+ },
+ stroke: {
+ lineCap: "round",
+ },
+ labels: ["Percent"],
+ },
+ });
+
+ return (
+
+
+
+ );
+};
+
+export default ApexChart;
diff --git a/src/components/Dashboard/Activity.jsx b/src/components/Dashboard/Activity.jsx
new file mode 100644
index 00000000..a1f9c5fc
--- /dev/null
+++ b/src/components/Dashboard/Activity.jsx
@@ -0,0 +1,194 @@
+import React, { useState, useEffect } from "react";
+import LineChart from "../Charts/LineChart";
+import { useProjects } from "../../hooks/useProjects";
+import { useDashboard_ActivityData } from "../../hooks/useDashboard_Data";
+import ApexChart from "../Charts/Circlechart";
+
+const LOCAL_STORAGE_PROJECT_KEY = "selectedActivityProjectId";
+
+const Activity = () => {
+ const { projects } = useProjects();
+ const today = new Date().toISOString().split("T")[0]; // Format: YYYY-MM-DD
+ const [selectedDate, setSelectedDate] = useState(today);
+ const storedProjectId = localStorage.getItem(LOCAL_STORAGE_PROJECT_KEY);
+ const initialProjectId = storedProjectId || "all";
+ const [selectedProjectId, setSelectedProjectId] = useState(initialProjectId);
+ const [displayedProjectName, setDisplayedProjectName] = useState("Select Project");
+ const [activeTab, setActiveTab] = useState("all");
+
+ const { dashboard_Activitydata: ActivityData, isLoading, error: isError } =
+ useDashboard_ActivityData(selectedDate, selectedProjectId);
+
+ useEffect(() => {
+ if (selectedProjectId === "all") {
+ setDisplayedProjectName("All Projects");
+ } else if (projects) {
+ const foundProject = projects.find((p) => p.id === selectedProjectId);
+ setDisplayedProjectName(foundProject ? foundProject.name : "Select Project");
+ } else {
+ setDisplayedProjectName("Select Project");
+ }
+
+ localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, selectedProjectId);
+ }, [selectedProjectId, projects]);
+
+ const handleProjectSelect = (projectId) => {
+ setSelectedProjectId(projectId);
+ };
+
+ const handleDateChange = (e) => {
+ setSelectedDate(e.target.value);
+ };
+
+ return (
+
+
+
+
+
Activity
+
Activity Progress Chart
+
+
+
+
+
+ -
+
+
+ {projects?.map((project) => (
+ -
+
+
+ ))}
+
+
+
+
+
+ {/* ✅ Date Picker Aligned Left with Padding */}
+
+
+ {/* Tabs */}
+
+ -
+
+
+ -
+
+
+
+
+
+ {activeTab === "all" && (
+
+
+ {isLoading ? (
+
Loading activity data...
+ ) : isError ? (
+
No data available.
+ ) : (
+ ActivityData && (
+ <>
+
+ Allocated Task
+
+
+ {ActivityData.totalCompletedWork?.toLocaleString()}/
+ {ActivityData.totalPlannedWork?.toLocaleString()}
+
+
Completed / Assigned
+
+ >
+ )
+ )}
+
+
+
+ {!isLoading && !isError && ActivityData && (
+ <>
+
+ Activities
+
+
+ {ActivityData.totalCompletedWork?.toLocaleString()}/
+ {ActivityData.totalPlannedWork?.toLocaleString()}
+
+
Pending / Assigned
+
+ >
+ )}
+
+
+ )}
+
+ {activeTab === "logs" && (
+
+
+
+
+ | Activity / Location |
+ Assigned / Completed |
+
+
+
+ {[{
+ activity: "Code Review / Remote",
+ assignedToday: 3,
+ completed: 2
+ }].map((log, index) => (
+
+ | {log.activity} |
+ {log.assignedToday} / {log.completed} |
+
+ ))}
+
+
+
+ )}
+
+
+ );
+};
+
+export default Activity;
diff --git a/src/components/Dashboard/Attendance.jsx b/src/components/Dashboard/Attendance.jsx
new file mode 100644
index 00000000..168fb065
--- /dev/null
+++ b/src/components/Dashboard/Attendance.jsx
@@ -0,0 +1,218 @@
+import React, { useState, useEffect } from "react";
+import LineChart from "../Charts/LineChart";
+import { useProjects } from "../../hooks/useProjects";
+import { useDashboard_AttendanceData } from "../../hooks/useDashboard_Data";
+import ApexChart from "../Charts/Circle";
+
+const LOCAL_STORAGE_PROJECT_KEY = "selectedAttendanceProjectId";
+
+const Attendance = () => {
+ const { projects } = useProjects();
+ const today = new Date().toISOString().split("T")[0]; // Format: YYYY-MM-DD
+ const [selectedDate, setSelectedDate] = useState(today);
+ const storedProjectId = localStorage.getItem(LOCAL_STORAGE_PROJECT_KEY);
+ const initialProjectId = storedProjectId || "all";
+ const [selectedProjectId, setSelectedProjectId] = useState(initialProjectId);
+ const [displayedProjectName, setDisplayedProjectName] =
+ useState("Select Project");
+ const [activeTab, setActiveTab] = useState("Summary");
+
+ const {
+ dashboard_Attendancedata: AttendanceData,
+ isLoading,
+ error: isError,
+ } = useDashboard_AttendanceData(selectedDate, selectedProjectId);
+
+ useEffect(() => {
+ if (selectedProjectId === "all") {
+ setDisplayedProjectName("All Projects");
+ } else if (projects) {
+ const foundProject = projects.find((p) => p.id === selectedProjectId);
+ setDisplayedProjectName(
+ foundProject ? foundProject.name : "Select Project"
+ );
+ } else {
+ setDisplayedProjectName("Select Project");
+ }
+
+ localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, selectedProjectId);
+ }, [selectedProjectId, projects]);
+
+ const handleProjectSelect = (projectId) => {
+ setSelectedProjectId(projectId);
+ };
+
+ const handleDateChange = (e) => {
+ setSelectedDate(e.target.value);
+ };
+
+ return (
+
+
+
+
+
Attendance
+
Daily Attendance Data
+
+
+
+
+
+ -
+
+
+ {projects?.map((project) => (
+ -
+
+
+ ))}
+
+
+
+
+
+
+ {/* Tabs */}
+
+
+ -
+
+
+ -
+
+
+
+
+ {/* ✅ Date Picker Aligned Left with Padding */}
+
+
+
+
+ {activeTab === "Summary" && (
+
+
+ {isLoading ? (
+
Loading Attendance data...
+ ) : isError ? (
+
No data available.
+ ) : (
+ AttendanceData && (
+ <>
+
+ Attendance
+
+
+ {AttendanceData.checkedInEmployee?.toLocaleString()}/
+ {AttendanceData.assignedEmployee?.toLocaleString()}
+
+
Checked-In / Assigned
+
+ >
+ )
+ )}
+
+
+ )}
+
+ {activeTab === "Details" && (
+
+
+
+
+ | Name |
+ Checkin |
+ Checkout |
+
+
+
+ {AttendanceData?.attendanceTable &&
+ AttendanceData.attendanceTable.length > 0 ? (
+ AttendanceData.attendanceTable.map((record, index) => (
+
+ |
+ {record.firstName} {record.lastName}
+ |
+
+ {new Date(record.inTime).toLocaleTimeString([], {
+ hour: "2-digit",
+ minute: "2-digit",
+ })}
+ |
+
+ {new Date(record.outTime).toLocaleTimeString([], {
+ hour: "2-digit",
+ minute: "2-digit",
+ })}
+ |
+
+ ))
+ ) : (
+
+ |
+ No attendance data available
+ |
+
+ )}
+
+
+
+ )}
+
+
+ );
+};
+
+export default Attendance;
diff --git a/src/components/Dashboard/Dashboard.jsx b/src/components/Dashboard/Dashboard.jsx
index 1e4cceaf..b2c6b904 100644
--- a/src/components/Dashboard/Dashboard.jsx
+++ b/src/components/Dashboard/Dashboard.jsx
@@ -9,6 +9,7 @@ import Teams from "./Teams";
import TasksCard from "./Tasks";
import ProjectCompletionChart from "./ProjectCompletionChart";
import ProjectProgressChart from "./ProjectProgressChart";
+// import Attendance from "./Attendance";
const Dashboard = () => {
const { projectsCardData } = useDashboardProjectsCardData();
@@ -42,6 +43,10 @@ const Dashboard = () => {
+
+ {/* */}
);
diff --git a/src/components/Dashboard/PendingAttendance.jsx b/src/components/Dashboard/PendingAttendance.jsx
new file mode 100644
index 00000000..f3f1ec04
--- /dev/null
+++ b/src/components/Dashboard/PendingAttendance.jsx
@@ -0,0 +1,32 @@
+import React from "react";
+import { useDashboardPendingAttendenceData } from "../../hooks/useDashboard_Data";
+
+const PendingAttendance = () => {
+ const { PendingAttendenceData } = useDashboardPendingAttendenceData();
+
+ return (
+
+
+
+ Pending Attendence
+
+
+
+
+
+ {PendingAttendenceData.pendingCheckOut?.toLocaleString()}
+
+ Checkout
+
+
+
+ {PendingAttendenceData.pendingRegularization?.toLocaleString()}
+
+ Regularization
+
+
+
+ );
+};
+
+export default PendingAttendance;
\ No newline at end of file
diff --git a/src/components/Project/MapUsers.jsx b/src/components/Project/MapUsers.jsx
index bb429789..512b0985 100644
--- a/src/components/Project/MapUsers.jsx
+++ b/src/components/Project/MapUsers.jsx
@@ -14,9 +14,13 @@ const MapUsers = ({
assignedLoading,
setAssignedLoading,
}) => {
- const { employeesList, loading: employeeLoading, error } = useAllEmployees(false);
+ const {
+ employeesList,
+ loading: employeeLoading,
+ error,
+ } = useAllEmployees(false);
const [selectedEmployees, setSelectedEmployees] = useState([]);
- const [ searchText, setSearchText ] = useState( "" );
+ const [searchText, setSearchText] = useState("");
const handleAllocationData = Array.isArray(allocation) ? allocation : [];
@@ -96,9 +100,8 @@ const MapUsers = ({
});
};
- const handleSubmit = () =>
- {
- setAssignedLoading(true)
+ const handleSubmit = () => {
+ setAssignedLoading(true);
const selected = selectedEmployees
.filter((emp) => emp.isSelected)
.map((emp) => ({ empID: emp.id, jobRoleId: emp.jobRoleId }));
@@ -108,32 +111,33 @@ const MapUsers = ({
} else {
showToast("Please select Employee", "error");
}
-
};
return (
<>
-
-
- {(filteredData.length > 0 ||
- allocationEmployeesData.length > 0)&& (
-
- setSearchQuery(e.target.value)}
- />
-
- )}
-
+
+
-
-
- Select Employee
-
-
+
Assign Employee
+
+
+ {(filteredData.length > 0 ||
+ allocationEmployeesData.length > 0) && (
+
+ setSearchQuery(e.target.value)}
+ />
+
+ )}
+
+
Select Employee
+
+
-
{employeeLoading && allocationEmployeesData.length === 0 && (
- Loading...
+
+ | Loading.. |
+
)}
{!employeeLoading &&
allocationEmployeesData.length === 0 &&
filteredData.length === 0 && (
- All employee assigned to Project.
+
+ | All employee assigned to Project. |
+
)}
- {!employeeLoading && allocationEmployeesData.length > 0 && filteredData.length === 0 && (
- No matching employees found.
- )}
+ {!employeeLoading &&
+ allocationEmployeesData.length > 0 &&
+ filteredData.length === 0 && (
+
+ | No matching employees found. |
+
+ )}
{(filteredData.length > 0 ||
allocationEmployeesData.length > 0) &&
@@ -174,14 +185,11 @@ const MapUsers = ({
{(filteredData.length > 0 ||
- allocationEmployeesData.length > 0) && (
-
- )}
+ allocationEmployeesData.length > 0) && (
+
+ )}