diff --git a/src/components/Project/Infrastructure/DleleteActivity.jsx b/src/components/Project/Infrastructure/DleleteActivity.jsx new file mode 100644 index 00000000..efdc32b7 --- /dev/null +++ b/src/components/Project/Infrastructure/DleleteActivity.jsx @@ -0,0 +1,104 @@ +import React, {useState} from 'react' +import ProjectRepository from '../../../repositories/ProjectRepository' +import {useProjectDetails} from '../../../hooks/useProjects' + +const DleleteActivity = ( {workItem, workArea, building, floor, onClose} ) => +{ + const {projects_Details, refetch} = useProjectDetails() + const [loading,setLoading] = useState(false) + + + const handleDeleteActivity =async () => + { + try + { + setLoading(false) + const updatedProject = { ...projects_Details }; + const response = await ProjectRepository.deleteProjectTask( workItem.workItemId ); + const newProject = { + ...updatedProject, + buildings: updatedProject.buildings.map((building) => + building.id === building.buildingID + ? { + ...building, + floors: building.floors.map((floor) => + floor.id === building.floorId + ? { + ...floor, + workAreas: floor.workAreas.map((workArea) => + workArea.id === workItem?.workAreaId + ? { + ...workArea, + workItems: (() => { + const exists = workArea.workItems.some( + (item) => + String( + item?.workItem?.id ?? item?.id + ) === String(finalData.id) + ); + + finalUpdatedWorkItem = workItem; + + return exists + ? workArea.workItems.map((item) => + String( + item?.workItem?.id ?? item?.id + ) === String(finalData.id) + ? workItem + : item + ) + : [...workArea.workItems, workItem]; + })(), + } + : workArea + ), + } + : floor + ), + } + : building + ), + }; + cacheData("projectInfo", { + projectId: newProject.id, + data: newProject, + }); + resetForm(); + dispatch( refreshData( true ) ); + setLoading(false) + showToast("Activity Updated Successfully","success") + + onClose(); + } catch ( error ) + { + console.log(error) + } + } + return ( +
+
+
+
+
+ + +
+
+
+
+
+ + + ) +} + +export default DleleteActivity \ No newline at end of file diff --git a/src/components/Project/Infrastructure/EditActivityModal.jsx b/src/components/Project/Infrastructure/EditActivityModal.jsx index 884e7aba..d4504350 100644 --- a/src/components/Project/Infrastructure/EditActivityModal.jsx +++ b/src/components/Project/Infrastructure/EditActivityModal.jsx @@ -47,7 +47,8 @@ const EditActivityModal = ({ completedWork: 0, }; - const { projects_Details, refetch } = useProjectDetails(selectedProject); + const {projects_Details, refetch} = useProjectDetails( selectedProject ); + const [ActivityUnit,setActivityUnit]= useState("") const { activities, loading, error } = useActivitiesMaster(); const [formData, setFormData] = useState(defaultModel); const [selectedActivity, setSelectedActivity] = useState(null); @@ -84,7 +85,6 @@ const EditActivityModal = ({ floorId: floor?.id, workAreaId: workArea?.id, }; - console.log(finalData); ProjectRepository.manageProjectTasks([finalData]) .then((response) => { @@ -171,9 +171,14 @@ const EditActivityModal = ({ const ISselectedActivity = watch("activityID"); useEffect(() => { - const selected = activities.find((a) => a.id === ISselectedActivity); - setSelectedActivity(selected || null); - }, [ISselectedActivity]); + if( ISselectedActivity ){ + const selected = activities.find((a) => a.id === ISselectedActivity); + setSelectedActivity( selected || null ); + setActivityUnit(selected?.unitOfMeasurement) + } + }, [ ISselectedActivity,activities] ); + + return (
@@ -258,7 +263,7 @@ const EditActivityModal = ({ {activity.activityName} ))} - {!loading && activityData.length === 0 && ( + {!loading && activities.length === 0 && ( )} @@ -321,7 +326,7 @@ const EditActivityModal = ({ {/* )} */}
-
} + + {showModal2 &&
+ {/* */} +
} @@ -164,7 +262,7 @@ const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => { aria-label="Delete" type="button" className="btn p-0 dropdown-toggle hide-arrow" - onClick={showModal1} + onClick={showModalDelete} > { + const selectRef = useSelect({ minimumResultsForSearch: 5 }); + + return ( +
+ + + {error &&

{error.message}

} +
+ ); +}; + +export default ActivityDropdown; diff --git a/src/components/common/ConfirmModal.jsx b/src/components/common/ConfirmModal.jsx new file mode 100644 index 00000000..0a26ece8 --- /dev/null +++ b/src/components/common/ConfirmModal.jsx @@ -0,0 +1,64 @@ +import React, { useState } from 'react'; + +const ConfirmModal = ({ type, onSubmit, onClose, message, loading }) => { + + const TypeofIcon = (type) => { + switch (type) { + case "delete": + return ; + default: + return null; + } + }; + + const TypeofModal = (type) => { + switch (type) { + case "delete": + return "sm"; + case "other": + return "md"; + default: + return "sm"; // Return a default modal size + } + }; + + return ( +
+
+
+
+
+ + +
+
+
+
+
+
+
+ ); +}; + +export default ConfirmModal; diff --git a/src/components/common/GlobalModal/CommentEditor.css b/src/components/common/GlobalModal/CommentEditor.css new file mode 100644 index 00000000..9bc05902 --- /dev/null +++ b/src/components/common/GlobalModal/CommentEditor.css @@ -0,0 +1,42 @@ +.marco-quill-wrapper { + border: 1px solid #dcdfe4; + border-radius: 6px; + background: #fff; + padding: 4px; + font-family: "Segoe UI", sans-serif; + position: absolute; + bottom: 0; + } + + /* Style the toolbar */ + .marco-quill-wrapper .ql-toolbar { + border: none; + padding: 4px 8px; + background: #f4f5f7; + border-bottom: 1px solid #dcdfe4; + border-radius: 6px 6px 0 0; + } + + /* Style the editor */ + .marco-quill-wrapper .ql-container { + border: none; + } + + .jira-quill-wrapper .ql-editor { + min-height: 100px; + padding: 8px; + font-size: 14px; + line-height: 1.6; + } + + /* Optional: Customize hover/focus */ + .marco-quill-wrapper .ql-toolbar button:hover { + background-color: #ebecf0; + } + + .marco-quill-wrapper .ql-toolbar button.ql-active { + background-color: #d2e0f7; + } + .marco-quill-wrapper .quill{ + padding: 0px; + } \ No newline at end of file diff --git a/src/components/common/GlobalModal/CommentEditor.jsx b/src/components/common/GlobalModal/CommentEditor.jsx new file mode 100644 index 00000000..68d4e353 --- /dev/null +++ b/src/components/common/GlobalModal/CommentEditor.jsx @@ -0,0 +1,54 @@ +// src/components/CommentEditor.jsx +import React, { useState } from "react"; +import ReactQuill from "react-quill"; +import "react-quill/dist/quill.snow.css"; // Core styling +import "./CommentEditor.css"; // Custom styles + +const modules = { + toolbar: [ + [{ header: [1, 2, false] }], + ["bold", "italic", "underline"], + [{ list: "ordered" }, { list: "bullet" }], + ["link"], + ["clean"], + ], +}; + +const formats = [ + "header", + "bold", + "italic", + "underline", + "list", + "bullet", + "link", +]; + +const CommentEditor = () => { + const [value, setValue] = useState(""); + + const handleSubmit = () => { + console.log("Comment:", value); + // Submit or handle content + }; + + return ( +
+ +
+ +
+
+ ); +}; + +export default CommentEditor; diff --git a/src/components/common/GlobalModal/CreateIssue.jsx b/src/components/common/GlobalModal/CreateIssue.jsx new file mode 100644 index 00000000..9d090df8 --- /dev/null +++ b/src/components/common/GlobalModal/CreateIssue.jsx @@ -0,0 +1,174 @@ +import React,{useState} from "react"; +import CommentEditor from "./CommentEditor"; +import ReactQuill from "react-quill"; +import "react-quill/dist/quill.snow.css"; +import "./CommentEditor.css"; + +const jiraModules = { + toolbar: [ + ["bold", "italic", "underline", "strike"], + ["link", "code"], + [{ list: "bullet" }], + ], + }; + + const jiraFormats = [ + "bold", + "italic", + "underline", + "strike", + "link", + "code", + "list", + ]; + +const CreateIssue = () => +{ + const [value, setValue] = useState(""); + return ( + +
+
+
+ + +
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+ +
+
+ + +
+ ); +}; + +export default CreateIssue; diff --git a/src/components/common/useSelect.js b/src/components/common/useSelect.js new file mode 100644 index 00000000..6b40b2e4 --- /dev/null +++ b/src/components/common/useSelect.js @@ -0,0 +1,32 @@ +import { useEffect, useRef } from "react"; + +const useSelect= (selector, options = {}) => { + const selectRef = useRef(null); + + useEffect(() => { + const $ = window.$; + const node = selectRef.current; + + if (!node || !$.fn.select2) return; + + const $select = $(node); + + if (!$select.hasClass("select2-hidden-accessible")) { + $select.select2({ + width: "100%", + dropdownAutoWidth: true, + ...options, + }); + } + + return () => { + if ($select.hasClass("select2-hidden-accessible")) { + $select.select2("destroy"); + } + }; + }, [options]); + + return selectRef; +}; + +export default useSelect; diff --git a/src/repositories/ProjectRepository.jsx b/src/repositories/ProjectRepository.jsx index 90ee336e..3425d2b0 100644 --- a/src/repositories/ProjectRepository.jsx +++ b/src/repositories/ProjectRepository.jsx @@ -16,7 +16,8 @@ const ProjectRepository = { manageProjectAllocation: ( data ) => api.post( "/api/project/allocation", data ), manageProjectInfra: (data) => api.post("/api/project/manage-infra", data), - manageProjectTasks: (data) => api.post("/api/project/task", data), + manageProjectTasks: ( data ) => api.post( "/api/project/task", data ), + deleteProjectTask:(id)=> api.delete(`/api/project/task/${id}`), updateProject: (id, data) => api.put(`/api/project/update/${id}`, data), deleteProject: (id) => api.delete(`/projects/${id}`),