diff --git a/public/assets/css/default.css b/public/assets/css/default.css index 08b78aa8..919d49dc 100644 --- a/public/assets/css/default.css +++ b/public/assets/css/default.css @@ -189,3 +189,7 @@ text-align: left; padding-left: 50px; } */ + +.small-text{ + font-size: 12px; +} \ No newline at end of file diff --git a/public/assets/vendor/css/core.css b/public/assets/vendor/css/core.css index b8e659cb..46f34f42 100644 --- a/public/assets/vendor/css/core.css +++ b/public/assets/vendor/css/core.css @@ -29002,7 +29002,6 @@ li:not(:first-child) .dropdown-item, /* Only for menu example */ .menu-collapsed:not(:hover) { inline-size: var(--bs-menu-collapsed-width); - /* Custom for sneat only */ } .menu-collapsed:not(:hover) .menu-inner > .menu-item { inline-size: var(--bs-menu-collapsed-width); @@ -29682,7 +29681,6 @@ li:not(:first-child) .dropdown-item, ) .layout-menu.menu-vertical { inline-size: var(--bs-menu-collapsed-width); - /* Custom for sneat only */ } .layout-menu-collapsed:not( .layout-menu-hover, diff --git a/public/scss/_components/_menu.scss b/public/scss/_components/_menu.scss index 09f9c658..50c58126 100644 --- a/public/scss/_components/_menu.scss +++ b/public/scss/_components/_menu.scss @@ -186,7 +186,6 @@ > .menu-item { margin: $menu-item-spacer 0; - // Sneat menu-link spacing .menu-link { margin: $menu-vertical-link-margin-y $menu-vertical-link-margin-x; } @@ -197,7 +196,6 @@ .menu-block { padding: $menu-vertical-link-padding-y $menu-vertical-link-padding-x; } - // Sneat menu-header spacing .menu-header { margin: $menu-vertical-header-margin-y 0 $menu-vertical-header-margin-y * 0.5 0; padding: $menu-vertical-link-padding-y $menu-vertical-link-padding-x * 2 $menu-vertical-link-padding-y @@ -276,7 +274,7 @@ // Vertical Menu Collapsed // ******************************************************************************* -// ! Updated menu collapsed styles for sneat in this mixin +// ! Updated menu collapsed styles for in this mixin @mixin layout-menu-collapsed() { width: $menu-collapsed-width; @@ -312,7 +310,6 @@ top: 1.1875rem; } } - // Custom for sneat only .menu-block { &::before { bottom: 0.75rem; diff --git a/src/components/Activities/ReportTaskComments.jsx b/src/components/Activities/ReportTaskComments.jsx index 94ee1c7b..efe62d0a 100644 --- a/src/components/Activities/ReportTaskComments.jsx +++ b/src/components/Activities/ReportTaskComments.jsx @@ -27,15 +27,21 @@ const ReportTaskComments = ({ commentsData, closeModal }) => { }); const containerRef = useRef(null); + const firstRender = useRef(true); + + useEffect(() => { setComment(commentsData?.comments); }, [commentsData]); + // Scroll logic: scroll to bottom when new comments are added useEffect(() => { - if (containerRef.current) { + if (!firstRender.current && containerRef.current) { containerRef.current.scrollTop = containerRef.current.scrollHeight; + } else { + firstRender.current = false; // Mark the first render as complete } - }, [comments]); + }, [comments]); // Run this when comments array is updated const onSubmit = async (data) => { let sendComment = { @@ -70,9 +76,10 @@ const ReportTaskComments = ({ commentsData, closeModal }) => { // closeModal(); } catch (error) { setloading(false); - showToast(error.response.data?.message || "Something wrong", "error"); + showToast(error.response.data?.message || "Something went wrong", "error"); } }; + return (
{ onClick={closeModal} aria-label="Close" > -

- {`${commentsData?.workItem?.workArea?.floor?.building?.name}`}{" "} - {" "} - {`${commentsData?.workItem?.workArea?.floor?.floorName} `}{" "} - - {`${commentsData?.workItem?.workArea?.areaName}`} - - {` ${commentsData?.workItem?.activityMaster?.activityName}`} +

Activity Summary

+

+ {comments && comments[0]?.comment} +

+

+ Assigned By : + + {commentsData?.assignedBy.firstName + + " " + + commentsData?.assignedBy.lastName} + {" "}

- -
+ +
@@ -438,12 +448,12 @@ const ManageEmployee = ({ employeeId, onClosed }) => { {500 - currentAddressLength} characters left
- {errors.CurrentAddress && ( + {errors.currentAddress && (
- {errors.CurrentAddress.message} + {errors.currentAddress.message}
)}
@@ -453,7 +463,7 @@ const ManageEmployee = ({ employeeId, onClosed }) => {
@@ -470,12 +480,12 @@ const ManageEmployee = ({ employeeId, onClosed }) => { {500 - permanentAddressLength} characters left
- {errors.PermanentAddress && ( + {errors.permanentAddress && (
- {errors.PermanentAddress.message} + {errors.permanentAddress.message}
)} @@ -493,7 +503,7 @@ const ManageEmployee = ({ employeeId, onClosed }) => { - {errors.JobRoleId && ( + {errors.jobRoleId && (
- {errors.JobRoleId.message} + {errors.jobRoleId.message}
)} @@ -523,16 +533,16 @@ const ManageEmployee = ({ employeeId, onClosed }) => { type="text" {...register("emergencyContactPerson")} className="form-control form-control-sm" - id="EmergencyContactPerson" + id="emergencyContactPerson" maxLength={50} placeholder="Contact Person" /> - {errors.EmergencyContactPerson && ( + {errors.emergencyContactPerson && (
- {errors.EmergencyContactPerson.message} + {errors.emergencyContactPerson.message}
)} @@ -544,17 +554,17 @@ const ManageEmployee = ({ employeeId, onClosed }) => { type="text" {...register("emergencyPhoneNumber")} className="form-control form-control-sm phone-mask" - id="EmergencyPhoneNumber" + id="emergencyPhoneNumber" placeholder="Phone Number" inputMode="numeric" maxLength={10} /> - {errors.EmergencyPhoneNumber && ( + {errors.emergencyPhoneNumber && (
- {errors.EmergencyPhoneNumber.message} + {errors.emergencyPhoneNumber.message}
)} @@ -567,14 +577,14 @@ const ManageEmployee = ({ employeeId, onClosed }) => { type="text" {...register("aadharNumber")} className="form-control form-control-sm" - id="AadharNumber" + id="aadharNumber" placeholder="AADHAR Number" maxLength={12} inputMode="numeric" /> - {errors.AadharNumber && ( + {errors.aadharNumber && (
- {errors.AadharNumber.message} + {errors.aadharNumber.message}
)} @@ -585,16 +595,16 @@ const ManageEmployee = ({ employeeId, onClosed }) => { type="text" {...register("panNumber")} className="form-control form-control-sm" - id="PanNumber" + id="panNumber" placeholder="PAN Number" maxLength={10} /> - {errors.PanNumber && ( + {errors.panNumber && (
- {errors.PanNumber.message} + {errors.panNumber.message}
)} diff --git a/src/components/Layout/LayoutMenu.tsx b/src/components/Layout/LayoutMenu.tsx index 66b18b65..48d38c05 100644 --- a/src/components/Layout/LayoutMenu.tsx +++ b/src/components/Layout/LayoutMenu.tsx @@ -58,7 +58,7 @@ const LayoutMenu = () => { - Sneat + Marco diff --git a/src/components/Project/Infrastructure/EditActivityModal.jsx b/src/components/Project/Infrastructure/EditActivityModal.jsx index 60c5403c..e539df96 100644 --- a/src/components/Project/Infrastructure/EditActivityModal.jsx +++ b/src/components/Project/Infrastructure/EditActivityModal.jsx @@ -3,7 +3,7 @@ import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; -import { useActivitiesMaster } from "../../../hooks/masterHook/useMaster"; +import { useActivitiesMaster, useWorkCategoriesMaster } from "../../../hooks/masterHook/useMaster"; import { useProjectDetails } from "../../../hooks/useProjects"; import { useDispatch, useSelector } from "react-redux"; import ProjectRepository from "../../../repositories/ProjectRepository"; @@ -18,6 +18,7 @@ import showToast from "../../../services/toastService"; const taskSchema = z .object({ activityID: z.string().min(1, "Activity is required"), + workCategoryId: z.string().min(1, "Work Category is required"), plannedWork: z.number().min(1, "Planned Work must be greater than 0"), completedWork: z.number().min(0, "Completed Work must be greater than 0"), }) @@ -43,17 +44,21 @@ const EditActivityModal = ({ ); const defaultModel = { activityID: 0, + workCategoryId: 0, plannedWork: 0, completedWork: 0, }; - const {projects_Details, refetch} = useProjectDetails( selectedProject ); - const [ActivityUnit,setActivityUnit]= useState("") + const { projects_Details, refetch } = useProjectDetails(selectedProject); + const [ActivityUnit, setActivityUnit] = useState(""); const { activities, loading, error } = useActivitiesMaster(); + const { categories, categoryLoading, categoryError } = + useWorkCategoriesMaster(); const [formData, setFormData] = useState(defaultModel); const [selectedActivity, setSelectedActivity] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const [activityData, setActivityData] = useState([]); + const [categoryData, setCategoryData] = useState([]); const dispatch = useDispatch(); const { @@ -70,12 +75,19 @@ const EditActivityModal = ({ }); const handleActivityChange = (e) => { - const selectedId = Number(e.target.value); - const selected = activityData.find( ( a ) => a.id === selectedId ); + const selectedId = String(e.target.value); + const selected = activityData.find((a) => a.id === selectedId); setSelectedActivity(selected || null); setValue("activityID", selectedId); }; + const handleCategoryChange = (e) => { + const selectedId = String(e.target.value); + const category = categoryData.find((b) => b.id === selectedId); + setSelectedCategory(category || null); + setValue("workCategoryId", selectedId); + }; + const onSubmitForm = async ( data ) => { setIsSubmitting(true) @@ -167,6 +179,8 @@ const EditActivityModal = ({ useEffect(() => { reset({ activityID: workItem?.workItem?.activityId || workItem?.activityId || 0, + workCategoryId: + workItem?.workItem?.workCategoryId || workItem?.workCategoryId || 0, plannedWork: workItem?.workItem?.plannedWork || workItem?.plannedWork || 0, completedWork: @@ -177,14 +191,13 @@ const EditActivityModal = ({ const ISselectedActivity = watch("activityID"); useEffect(() => { - if( ISselectedActivity ){ + if (ISselectedActivity) { const selected = activities.find((a) => a.id === ISselectedActivity); - setSelectedActivity( selected || null ); - setActivityUnit(selected?.unitOfMeasurement) - } - }, [ ISselectedActivity,activities] ); - - + setSelectedActivity(selected || null); + setActivityUnit(selected?.unitOfMeasurement); + } + }, [ISselectedActivity, activities]); + return (
@@ -279,6 +292,45 @@ const EditActivityModal = ({ )}
+ {/* Select Category */} +
+ + + + {errors.workCategoryId && ( +

{errors.workCategoryId.message}

+ )} +
+ {/* Planned Work */} {/* {ISselectedActivity && ( */}
diff --git a/src/components/Project/Infrastructure/TaskModel.jsx b/src/components/Project/Infrastructure/TaskModel.jsx index 43cb1c5b..087a731e 100644 --- a/src/components/Project/Infrastructure/TaskModel.jsx +++ b/src/components/Project/Infrastructure/TaskModel.jsx @@ -2,23 +2,28 @@ import React, { useState, useEffect } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; -import {useActivitiesMaster} from "../../../hooks/masterHook/useMaster"; +import { + useActivitiesMaster, + useWorkCategoriesMaster, +} from "../../../hooks/masterHook/useMaster"; const taskSchema = z.object({ buildingID: z.string().min(1, "Building is required"), floorId: z.string().min(1, "Floor is required"), workAreaId: z.string().min(1, "Work Area is required"), activityID: z.string().min(1, "Activity is required"), + workCategoryId: z.string().min(1, "Work Category is required"), plannedWork: z.number().min(1, "Planned Work must be greater than 0"), completedWork: z.number().min(0, "Completed Work must be greater than 0"), }); const defaultModel = { id: null, - buildingID:"0", + buildingID: "0", floorId: "0", workAreaId: "0", activityID: null, + workCategoryId: "", plannedWork: 0, completedWork: 0, }; @@ -30,15 +35,18 @@ const TaskModel = ({ onClearComplete, onClose, }) => { - const [formData, setFormData] = useState(defaultModel); const [selectedBuilding, setSelectedBuilding] = useState(null); const [selectedFloor, setSelectedFloor] = useState(null); const [selectedWorkArea, setSelectedWorkArea] = useState(null); const [selectedActivity, setSelectedActivity] = useState(null); + const [selectedCategory, setSelectedCategory] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const [activityData, setActivityData] = useState([]); - const {activities, loading, error} = useActivitiesMaster(); + const [categoryData, setCategoryData] = useState([]); + const { activities, loading, error } = useActivitiesMaster(); + const { categories, categoryLoading, categoryError } = + useWorkCategoriesMaster(); const { register, @@ -79,6 +87,7 @@ const TaskModel = ({ floorId: value, workAreaId: 0, activityID: 0, + workCategoryId: categoryData?.[0]?.id?.toString() ?? "", })); }; @@ -104,13 +113,24 @@ const TaskModel = ({ })); }; - const onSubmitForm = async ( data ) => - { + const handleCategoryChange = (e) => { + const { value } = e.target; + const category = categoryData.find((b) => b.id === String(value)); + setSelectedCategory(category); + reset((prev) => ({ + ...prev, + workCategoryId: String(value), + })); + }; + + const onSubmitForm = async (data) => { + console.log(data); setIsSubmitting(true); await onSubmit(data); setValue("plannedWork", 0); - setValue( "completedWork", 0 ); - setValue("activityID",0) + setValue("completedWork", 0); + setValue("activityID", 0); + setValue("workCategoryId", categoryData?.[0]?.id?.toString() ?? ""); setIsSubmitting(false); }; @@ -120,15 +140,32 @@ const TaskModel = ({ setSelectedFloor(null); setSelectedWorkArea(null); setSelectedActivity(null); + setSelectedCategory(categoryData?.[0]?.id?.toString() ?? ""); reset(defaultModel); }; useEffect(() => { if (!loading && Array.isArray(activities) && activities.length > 0) { - setActivityData(activities); } }, [activities, loading]); + + useEffect(() => { + if ( + !categoryLoading && + Array.isArray(categories) && + categories.length > 0 + ) { + const newCategories = categories?.slice()?.sort((a, b) => { + const nameA = a?.name || ""; + const nameB = b?.name || ""; + return nameA.localeCompare(nameB); + }); + setCategoryData(newCategories); + setSelectedCategory(newCategories[0]) + } + }, [categories, categoryLoading]); + return (
@@ -247,9 +284,7 @@ const TaskModel = ({ {selectedWorkArea && (
- + {errors.activityID && ( @@ -287,7 +319,38 @@ const TaskModel = ({
)} - {selectedActivity && ( + {selectedWorkArea && ( +
+ + + + {errors.workCategoryId && ( +

+ {errors.workCategoryId.message} +

+ )} +
+ )} + + {selectedActivity && selectedCategory && (
)} - {selectedActivity && ( + {selectedActivity && selectedCategory && (
+
)} {IsDeleteModalOpen && (
{ const projectID = useSelector((store) => store.localVariables.projectId); const { employeeId } = useParams(); @@ -26,11 +27,18 @@ const EmployeeProfile = () => { const tab = SearchParams.get("for"); const [activePill, setActivePill] = useState(tab); const [currentEmployee, setCurrentEmployee] = useState(); + const [showModal, setShowModal] = useState(false); const handlePillClick = (pillKey) => { setActivePill(pillKey); }; + const closeModal = () => { + setShowModal(false); + fetchEmployeeProfile(employeeId); + }; + const handleShow = () => setShowModal(true); + const fetchEmployeeProfile = async (employeeID) => { try { const resp = await EmployeeRepository.getEmployeeProfile(employeeID); @@ -89,6 +97,26 @@ const EmployeeProfile = () => { } return ( + <> {showModal && (
+
+
+ +
+
+
)} +
{
+ + ); }; diff --git a/src/router/AppRoutes.jsx b/src/router/AppRoutes.jsx index ad38bc2d..6fbeefa0 100644 --- a/src/router/AppRoutes.jsx +++ b/src/router/AppRoutes.jsx @@ -51,7 +51,7 @@ const router = createBrowserRouter( }, { element: , - errorElement:, + errorElement: , children: [ { element: , @@ -90,6 +90,10 @@ const router = createBrowserRouter( future: { v7_relativeSplatPath: true, v7_startTransition: true, + v7_fetcherPersist: true, + v7_normalizeFormMethod: true, + v7_partialHydration: true, + v7_skipActionErrorRevalidation: true, }, } );