- Add date format hook

- add Ui for Activities
This commit is contained in:
Vikas Nale 2025-08-06 18:32:43 +05:30
parent b85b812981
commit 6883d87bdc
12 changed files with 246 additions and 22 deletions

10
package-lock.json generated
View File

@ -18,6 +18,7 @@
"apexcharts": "^4.5.0",
"axios": "^1.7.9",
"axios-retry": "^4.5.0",
"date-fns": "^4.1.0",
"dotenv": "^16.4.7",
"dotenv-webpack": "^8.1.0",
"eventemitter3": "^5.0.1",
@ -2455,6 +2456,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/date-fns": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/debug": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",

View File

@ -21,6 +21,7 @@
"apexcharts": "^4.5.0",
"axios": "^1.7.9",
"axios-retry": "^4.5.0",
"date-fns": "^4.1.0",
"dotenv": "^16.4.7",
"dotenv-webpack": "^8.1.0",
"eventemitter3": "^5.0.1",

View File

@ -0,0 +1,155 @@
import React, { useState, useEffect } from "react";
import moment from "moment";
import DateRangePicker from "../common/DateRangePicker";
import useFormattedDate from "../../hooks/useFormattedDate";
import { useProjectTasksByEmployee } from "../../hooks/useProjects";
const EmpActivities = ({ employee }) => {
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
const myDate = new Date("2025-08-06T10:30:00Z");
const formattedToday = useFormattedDate(myDate, "dd-MMM-yyyy");
console.log(employee);
const {
ProjectTaskList,
loading: selectedProjectLoding,
refetch,
} = useProjectTasksByEmployee(employee?.id);
console.log(ProjectTaskList);
return (
<>
<div className="card h-100 mt-4">
<div className="card-body">
<div className="my-0 text-start">
<DateRangePicker
DateDifference="30"
onRangeChange={setDateRange}
endDateMode="today"
/>
</div>
<ul className="timeline mb-0 mt-5 text-start">
<li className="timeline-item timeline-item-transparent">
<span className="timeline-point timeline-point-primary"></span>
<div className="timeline-event">
<div className="timeline-header mb-3">
<h6 className="mb-0">Matrix Properties</h6>
<small className="text-body-secondary">
{formattedToday}
</small>
</div>
<p className="mb-2">Branch Fitting</p>
<p className="mb-2">
Building 1 &gt; First Floor &gt; Zone One
</p>
<p className="mb-2">
<span>Planned: 22 Meter</span>
<span className="ms-2">Completed: 22 Meter</span>
</p>
</div>
</li>
<li className="timeline-item timeline-item-transparent">
<span className="timeline-point timeline-point-success"></span>
<div className="timeline-event">
<div className="timeline-header mb-3">
<h6 className="mb-0">Client Meeting</h6>
<small className="text-body-secondary">45 min ago</small>
</div>
<p className="mb-2">Project meeting with john @10:15am</p>
<div className="d-flex justify-content-between flex-wrap gap-2 mb-2">
<div className="d-flex flex-wrap align-items-center mb-50">
<div className="avatar avatar-sm me-2">
<img
src="../../assets/img/avatars/1.png"
alt="Avatar"
className="rounded-circle"
/>
</div>
<div>
<p className="mb-0 small fw-medium">
Lester McCarthy (Client)
</p>
<small>CEO of ThemeSelection</small>
</div>
</div>
</div>
</div>
</li>
<li className="timeline-item timeline-item-transparent">
<span className="timeline-point timeline-point-info"></span>
<div className="timeline-event">
<div className="timeline-header mb-3">
<h6 className="mb-0">Create a new project for client</h6>
<small className="text-body-secondary">2 Day Ago</small>
</div>
<p className="mb-2">6 team members in a project</p>
<ul className="list-group list-group-flush">
<li className="list-group-item d-flex justify-content-between align-items-center flex-wrap border-top-0 p-0">
<div className="d-flex flex-wrap align-items-center">
<ul className="list-unstyled users-list d-flex align-items-center avatar-group m-0 me-2">
<li
data-bs-toggle="tooltip"
data-popup="tooltip-custom"
data-bs-placement="top"
className="avatar pull-up"
aria-label="Vinnie Mostowy"
data-bs-original-title="Vinnie Mostowy"
>
<img
className="rounded-circle"
src="../../assets/img/avatars/5.png"
alt="Avatar"
/>
</li>
<li
data-bs-toggle="tooltip"
data-popup="tooltip-custom"
data-bs-placement="top"
className="avatar pull-up"
aria-label="Allen Rieske"
data-bs-original-title="Allen Rieske"
>
<img
className="rounded-circle"
src="../../assets/img/avatars/12.png"
alt="Avatar"
/>
</li>
<li
data-bs-toggle="tooltip"
data-popup="tooltip-custom"
data-bs-placement="top"
className="avatar pull-up"
aria-label="Julee Rossignol"
data-bs-original-title="Julee Rossignol"
>
<img
className="rounded-circle"
src="../../assets/img/avatars/6.png"
alt="Avatar"
/>
</li>
<li className="avatar">
<span
className="avatar-initial rounded-circle pull-up"
data-bs-toggle="tooltip"
data-bs-placement="bottom"
data-bs-original-title="3 more"
>
+3
</span>
</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</>
);
};
export default EmpActivities;

View File

@ -120,7 +120,7 @@ const EmpAttendance = ({ employee }) => {
<AttendLogs Id={attendanceId} />
</GlobalModel>
)}
<div className="card px-4 mt-0 py-2 " style={{ minHeight: "500px" }}>
<div className="card px-4 mt-5 py-2 " style={{ minHeight: "500px" }}>
<div
className="dataTables_length text-start py-2 d-flex justify-content-between "
id="DataTables_Table_0_length"

View File

@ -24,7 +24,7 @@ const EmpBanner = ({ profile, loggedInUser }) => {
)}
<div className="user-profile-header d-flex flex-column flex-lg-row text-sm-start text-center mb-8">
<div className="flex-shrink-0 mt-1 mx-sm-0 mx-auto">
{profile.gender.toLowerCase() == "male" && (
{profile?.gender?.toLowerCase() == "male" && (
<img
width={125}
src="../../assets/img/avatars/avatar_m_01.png"
@ -32,7 +32,7 @@ const EmpBanner = ({ profile, loggedInUser }) => {
className="d-block h-auto ms-0 ms-sm-6 rounded-3 user-profile-img"
/>
)}
{profile.gender.toLowerCase() == "female" && (
{profile?.gender?.toLowerCase() == "female" && (
<img
width={125}
src="../../assets/img/avatars/avatar_f_02.png"

View File

@ -5,7 +5,7 @@ const EmpDocuments = ({ profile, loggedInUser }) => {
<>
<div
id="DataTables_Table_0_wrapper"
class="dt-container dt-bootstrap5 dt-empty-footer"
class=" card mt-5 dt-container dt-bootstrap5 dt-empty-footer"
>
<div class="row card-header border-bottom mx-0 px-3 py-2">
<div class="d-md-flex justify-content-between align-items-center dt-layout-start col-md-auto me-auto">

View File

@ -0,0 +1,26 @@
import { format } from "date-fns";
/**
* A custom hook to format a date string, object, or number.
* @param {string | Date | number} date - The date to be formatted.
* @param {string} formatString - The format string (e.g., 'MMMM do, yyyy').
* @returns {string} The formatted date string.
*/
const useFormattedDate = (date, formatString) => {
// Return early if no date is provided
if (!date) {
return "";
}
try {
const dateObj = new Date(date);
// You could also add error handling for invalid dates
// if (!isValid(dateObj)) return 'Invalid Date';
return format(dateObj, formatString);
} catch (error) {
console.error("Error formatting date:", error);
return ""; // Return an empty string or a default value on error
}
};
export default useFormattedDate;

View File

@ -395,6 +395,34 @@ export const useProjectTasks = (workAreaId, IsExpandedArea = false) => {
return { ProjectTaskList, isLoading, error };
};
export const useProjectTasksByEmployee = (
employeeId,
fromDate,
toDate,
IsExpandedArea = false
) => {
const {
data: ProjectTaskList,
isLoading,
error,
} = useQuery({
queryKey: ["TasksByEmployee", employeeId],
queryFn: async () => {
const res = await ProjectRepository.getProjectTasksByEmployee(
employeeId,
fromDate,
toDate
);
return res.data;
},
enabled: !!employeeId && !!IsExpandedArea,
onError: (error) => {
showToast(error.message || "Error while Fetching project Tasks", "error");
},
});
return { ProjectTaskList, isLoading, error };
};
// -- -------------Mutation-------------------------------
export const useCreateProject = ({ onSuccessCallback }) => {

View File

@ -21,6 +21,7 @@ import ManageEmployee from "../../components/Employee/ManageEmployee";
import EmpBanner from "../../components/Employee/EmpBanner";
import EmpDashboard from "../../components/Employee/EmpDashboard";
import EmpDocuments from "../../components/Employee/EmpDocuments";
import EmpActivities from "../../components/Employee/EmpActivities";
const EmployeeProfile = () => {
const { profile } = useProfile();
@ -85,7 +86,7 @@ const EmployeeProfile = () => {
case "activities": {
return (
<>
<ComingSoonPage />
<EmpActivities employee={currentEmployee} />
</>
);
break;

View File

@ -1,17 +1,16 @@
import { api } from "../utils/axiosClient";
const EmployeeRepository = {
getAllEmployeeList:(showInactive)=>api.get(`api/employee/list?showInactive=${showInactive}`),
getAllEmployeeList: (showInactive) =>
api.get(`api/employee/list?showInactive=${showInactive}`),
getEmployeeListByproject: (projectid) =>
api.get(`/api/employee/list/${projectid}`),
searchEmployees: (query) =>
api.get(`/api/employee/search/${query}`),
manageEmployee: (data) =>
api.post("/api/employee/manage", data),
searchEmployees: (query) => api.get(`/api/employee/search/${query}`),
manageEmployee: (data) => api.post("/api/employee/manage", data),
updateEmployee: (id, data) => api.put(`/users/${id}`, data),
// deleteEmployee: ( id ) => api.delete( `/users/${ id }` ),
getEmployeeProfile:(id)=>api.get(`/api/employee/profile/get/${id}`),
deleteEmployee:(id)=>api.delete(`/api/employee/${id}`)
getEmployeeProfile: (id) => api.get(`/api/employee/profile/get/${id}`),
deleteEmployee: (id) => api.delete(`/api/employee/${id}`),
};
export default EmployeeRepository;

View File

@ -33,6 +33,10 @@ const ProjectRepository = {
getProjectDetails: (id) => api.get(`/api/project/details/${id}`),
getProjectInfraByproject: (id) => api.get(`/api/project/infra-details/${id}`),
getProjectTasksByWorkArea: (id) => api.get(`/api/project/tasks/${id}`),
getProjectTasksByEmployee: (id, fromDate, toDate) =>
api.get(
`/api/project/tasks-employee/${id}?fromDate=${fromDate}&toDate:${toDate}`
),
};
export const TasksRepository = {