Add more cosmatic changes for notes editor

This commit is contained in:
Vikas Nale 2025-06-12 18:48:30 +05:30
parent 3305c0b0d9
commit 6b9670b942
6 changed files with 142 additions and 116 deletions

View File

@ -128,9 +128,7 @@ const ManageBucket = () => {
setBucketList(updatedData); setBucketList(updatedData);
showToast("Bucket Updated Successfully", "success"); showToast("Bucket Updated Successfully", "success");
} } else {
else {
response = await DirectoryRepository.CreateBuckets(data); response = await DirectoryRepository.CreateBuckets(data);
const updatedBuckets = [...cache_buckets, response?.data]; const updatedBuckets = [...cache_buckets, response?.data];
@ -292,10 +290,13 @@ const ManageBucket = () => {
sortedBucktesList.map((bucket) => ( sortedBucktesList.map((bucket) => (
<div className="col" key={bucket.id}> <div className="col" key={bucket.id}>
<div className="card h-100"> <div className="card h-100">
<div className="card-body"> <div className="card-body p-4">
<h6 className="card-title d-flex justify-content-between align-items-center"> <h6 className="card-title d-flex justify-content-between align-items-center">
<span>{bucket.name}</span> <span>{bucket.name}</span>
{(DirManager || DirAdmin || bucket?.createdBy?.id === profile?.employeeInfo?.id) && ( {(DirManager ||
DirAdmin ||
bucket?.createdBy?.id ===
profile?.employeeInfo?.id) && (
<div className="d-flex gap-2"> <div className="d-flex gap-2">
<i <i
className="bx bx-edit bx-sm text-primary cursor-pointer" className="bx bx-edit bx-sm text-primary cursor-pointer"
@ -303,8 +304,12 @@ const ManageBucket = () => {
select_bucket(bucket); select_bucket(bucket);
setAction_bucket(true); setAction_bucket(true);
const initialSelectedEmployees = employeesList const initialSelectedEmployees = employeesList
.filter(emp => bucket.employeeIds?.includes(emp.employeeId)) .filter((emp) =>
.map(emp => ({ ...emp, isActive: true })); bucket.employeeIds?.includes(
emp.employeeId
)
)
.map((emp) => ({ ...emp, isActive: true }));
setSelectEmployee(initialSelectedEmployees); setSelectEmployee(initialSelectedEmployees);
}} }}
></i> ></i>
@ -315,10 +320,16 @@ const ManageBucket = () => {
</div> </div>
)} )}
</h6> </h6>
<h6 className="card-subtitle mb-2 text-muted"> <h6 className="card-subtitle mb-2 text-muted text-start">
Contacts: {bucket.numberOfContacts} Contacts:{" "}
{bucket.numberOfContacts
? bucket.numberOfContacts
: 0}
</h6> </h6>
<p className="card-text text-start" title={bucket.description}> <p
className="card-text text-start"
title={bucket.description}
>
{bucket.description || "No description available."} {bucket.description || "No description available."}
</p> </p>
</div> </div>
@ -330,7 +341,9 @@ const ManageBucket = () => {
<> <>
<form onSubmit={handleSubmit(onSubmit)} className="px-2 px-sm-0"> <form onSubmit={handleSubmit(onSubmit)} className="px-2 px-sm-0">
<div className="mb-3"> <div className="mb-3">
<label htmlFor="bucketName" className="form-label">Bucket Name</label> <label htmlFor="bucketName" className="form-label">
Bucket Name
</label>
<input <input
id="bucketName" id="bucketName"
className="form-control form-control-sm" className="form-control form-control-sm"
@ -341,7 +354,9 @@ const ManageBucket = () => {
)} )}
</div> </div>
<div className="mb-3"> <div className="mb-3">
<label htmlFor="bucketDescription" className="form-label">Bucket Description</label> <label htmlFor="bucketDescription" className="form-label">
Bucket Description
</label>
<textarea <textarea
id="bucketDescription" id="bucketDescription"
className="form-control form-control-sm" className="form-control form-control-sm"

View File

@ -132,17 +132,17 @@ const NoteCardDirectory = ({
<div className="d-flex align-items-center"> <div className="d-flex align-items-center">
<Avatar <Avatar
size="xs" size="xs"
firstName={noteItem.createdBy.firstName} firstName={noteItem?.createdBy?.firstName}
lastName={noteItem.createdBy.lastName} lastName={noteItem?.createdBy?.lastName}
className="m-0" className="m-0"
/> />
<div className="d-flex flex-column ms-2"> <div className="d-flex flex-column ms-2">
<span className="fw-semibold small"> <span className="fw-semibold small">
{noteItem.createdBy.firstName} {noteItem.createdBy.lastName} {noteItem?.createdBy?.firstName} {noteItem?.createdBy?.lastName}
</span> </span>
<span className="text-muted" style={{ fontSize: "10px" }}> <span className="text-muted" style={{ fontSize: "10px" }}>
{moment {moment
.utc(noteItem.createdAt) .utc(noteItem?.createdAt)
.add(5, "hours") .add(5, "hours")
.add(30, "minutes") .add(30, "minutes")
.format("MMMM DD, YYYY [at] hh:mm A")} .format("MMMM DD, YYYY [at] hh:mm A")}
@ -160,7 +160,7 @@ const NoteCardDirectory = ({
{!isDeleting ? ( {!isDeleting ? (
<i <i
className="bx bx-trash bx-sm me-1 text-secondary cursor-pointer" className="bx bx-trash bx-sm me-1 text-secondary cursor-pointer"
onClick={() => handleDeleteNote(!noteItem.isActive)} onClick={() => handleDeleteNote(!noteItem?.isActive)}
></i> ></i>
) : ( ) : (
<div <div
@ -176,7 +176,7 @@ const NoteCardDirectory = ({
) : ( ) : (
<i <i
className="bx bx-recycle me-1 text-primary cursor-pointer" className="bx bx-recycle me-1 text-primary cursor-pointer"
onClick={() => handleDeleteNote(!noteItem.isActive)} onClick={() => handleDeleteNote(!noteItem?.isActive)}
title="Restore" title="Restore"
></i> ></i>
)} )}

View File

@ -103,6 +103,7 @@ const NotesDirectory = ({
<p className="fw-semibold m-0">Notes :</p> <p className="fw-semibold m-0">Notes :</p>
</div> </div>
<div className="d-flex align-items-center justify-content-between mb-5"> <div className="d-flex align-items-center justify-content-between mb-5">
{contactNotes?.length > 0 && (
<div className="m-0 d-flex aligin-items-center"> <div className="m-0 d-flex aligin-items-center">
<label className="switch switch-primary"> <label className="switch switch-primary">
<input <input
@ -122,15 +123,24 @@ const NotesDirectory = ({
<span className="switch-label ">Include Deleted Notes</span> <span className="switch-label ">Include Deleted Notes</span>
</label> </label>
</div> </div>
)}
{!addNote && ( {!addNote && (
<div className="d-flex justify-content-center px-2"> <div
className={`
${
contactNotes?.length > 0
? "d-flex justify-content-center px-2"
: "d-flex justify-content-center px-2w-100"
}`}
>
<span <span
className={`btn btn-sm ${ className={`btn btn-sm ${
addNote ? "btn-danger" : "btn-primary" addNote ? "btn-danger" : "btn-primary"
}`} }`}
onClick={() => setAddNote(!addNote)} onClick={() => setAddNote(!addNote)}
> >
{addNote ? "Hide Editor" : "Add Note"} {addNote ? "Hide Editor" : "Add a Note"}
</span> </span>
</div> </div>
)} )}

View File

@ -88,8 +88,11 @@ const Header = () => {
if (projectNames && selectedProject !== " ") { if (projectNames && selectedProject !== " ") {
dispatch(setProjectId(projectNames[0]?.id)); dispatch(setProjectId(projectNames[0]?.id));
} }
}, [projectNames, ]); }, [projectNames]);
const isProjectPath = /^\/projectNames\/[a-f0-9-]{36}$/.test(location.pathname);
/** Check if current page id project details page */
const isProjectPath = /^\/projects\/[a-f0-9-]{36}$/.test(location.pathname);
return ( return (
<nav <nav
className="layout-navbar container-xxl navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme" className="layout-navbar container-xxl navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme"
@ -107,7 +110,8 @@ const Header = () => {
className="navbar-nav-right d-flex align-items-center justify-content-between" className="navbar-nav-right d-flex align-items-center justify-content-between"
id="navbar-collapse" id="navbar-collapse"
> >
{projectNames?.length > 0 && ( <div className=" align-items-center"> {projectNames?.length > 0 && (
<div className=" align-items-center">
{!isProjectPath && ( {!isProjectPath && (
<> <>
<i <i
@ -116,7 +120,9 @@ const Header = () => {
></i> ></i>
<div className="btn-group"> <div className="btn-group">
<button <button
className={`btn btn-sm-sm btn-xl ${projectNames?.length > 1 && "dropdown-toggle" } px-1`} className={`btn btn-sm-sm btn-xl ${
projectNames?.length > 1 && "dropdown-toggle"
} px-1`}
type="button" type="button"
data-bs-toggle="dropdown" data-bs-toggle="dropdown"
aria-expanded="false" aria-expanded="false"
@ -124,7 +130,8 @@ const Header = () => {
{displayText} {displayText}
</button> </button>
{projectNames?.length > 1 && ( <ul className="dropdown-menu"> {projectNames?.length > 1 && (
<ul className="dropdown-menu">
{projectNames?.map((project) => ( {projectNames?.map((project) => (
<li key={project?.id}> <li key={project?.id}>
<button <button
@ -135,11 +142,13 @@ const Header = () => {
</button> </button>
</li> </li>
))} ))}
</ul>)} </ul>
)}
</div> </div>
</> </>
)} )}
</div>)} </div>
)}
<ul className="navbar-nav flex-row align-items-center ms-md-auto"> <ul className="navbar-nav flex-row align-items-center ms-md-auto">
<li className="nav-item dropdown-shortcuts navbar-dropdown dropdown me-2 me-xl-0"> <li className="nav-item dropdown-shortcuts navbar-dropdown dropdown me-2 me-xl-0">

View File

@ -6,13 +6,13 @@
"text": "Dashboard", "text": "Dashboard",
"icon": "bx bx-home", "icon": "bx bx-home",
"available": true, "available": true,
"link": "/projects" "link": "/dashboard"
}, },
{ {
"text": "Projects", "text": "Projects",
"icon": "bx bx-building-house", "icon": "bx bx-building-house",
"available": true, "available": true,
"link": "/dashboard" "link": "/projects"
}, },
{ {
"text": "Employees", "text": "Employees",

View File

@ -7,8 +7,7 @@ import { setProjectId } from "../slices/localVariablesSlice";
import EmployeeList from "../components/Directory/EmployeeList"; import EmployeeList from "../components/Directory/EmployeeList";
export const useProjects = () => { export const useProjects = () => {
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
const loggedUser = useSelector( ( store ) => store.globalVariables.loginUser )
const [projects, setProjects] = useState([]); const [projects, setProjects] = useState([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState(""); const [error, setError] = useState("");
@ -129,39 +128,34 @@ export const useProjectDetails = (projectId) => {
} }
}, [projectId, profile]); }, [projectId, profile]);
return { projects_Details, loading, error, refetch: fetchData } return { projects_Details, loading, error, refetch: fetchData };
} };
export const useProjectsByEmployee = (employeeId) => {
export const useProjectsByEmployee = ( employeeId ) =>
{
const [projectList, setProjectList] = useState([]); const [projectList, setProjectList] = useState([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [error, setError] = useState(''); const [error, setError] = useState("");
const fetchProjects = async (id) => { const fetchProjects = async (id) => {
try { try {
setLoading(true); setLoading(true);
setError(''); // clear previous error setError(""); // clear previous error
const res = await ProjectRepository.getProjectsByEmployee(id); const res = await ProjectRepository.getProjectsByEmployee(id);
setProjectList(res.data); setProjectList(res.data);
cacheData( 'ProjectsByEmployee', {data: res.data, employeeId: id} ); cacheData("ProjectsByEmployee", { data: res.data, employeeId: id });
setLoading(false) setLoading(false);
} catch (err) { } catch (err) {
setError( err?.message || 'Failed to fetch projects' ); setError(err?.message || "Failed to fetch projects");
setLoading(false) setLoading(false);
} }
}; };
useEffect(() => { useEffect(() => {
if (!employeeId) return; if (!employeeId) return;
const cache_project = getCachedData('ProjectsByEmployee'); const cache_project = getCachedData("ProjectsByEmployee");
if ( if (!cache_project?.data || cache_project?.employeeId !== employeeId) {
!cache_project?.data ||
cache_project?.employeeId !== employeeId
) {
fetchProjects(employeeId); fetchProjects(employeeId);
} else { } else {
setProjectList(cache_project.data); setProjectList(cache_project.data);
@ -172,21 +166,20 @@ export const useProjectsByEmployee = ( employeeId ) =>
projectList, projectList,
loading, loading,
error, error,
refetch : fetchProjects refetch: fetchProjects,
} };
}; };
export const useProjectName = () => { export const useProjectName = () => {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [projectNames, setProjectName] = useState([]); const [projectNames, setProjectName] = useState([]);
const[Error,setError] = useState() const [Error, setError] = useState();
const fetchData = async () => { const fetchData = async () => {
try { try {
let response = await ProjectRepository.projectNameList(); let response = await ProjectRepository.projectNameList();
console.log(response)
setProjectName(response.data); setProjectName(response.data);
cacheData("basicProjectNameList",response.data); cacheData("basicProjectNameList", response.data);
setLoading(false); setLoading(false);
} catch (err) { } catch (err) {
setError("Failed to fetch data."); setError("Failed to fetch data.");
@ -199,4 +192,3 @@ export const useProjectName = () => {
return { projectNames, loading, Error }; return { projectNames, loading, Error };
}; };