marco.pms.web/src/components/Directory/NotesCardViewDirectory.jsx

183 lines
6.3 KiB
JavaScript

import React, { useEffect, useState, useMemo } from "react";
import { DirectoryRepository } from "../../repositories/DirectoryRepository";
import NoteCardDirectoryEditable from "./NoteCardDirectoryEditable";
const NotesCardViewDirectory = ({ notes, setNotes, searchText, selectedNoteNames }) => { // ✅ Changed to array
const [allNotes, setAllNotes] = useState([]);
const [filteredNotes, setFilteredNotes] = useState([]);
const [loading, setLoading] = useState(true);
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(1);
const pageSize = 20;
const fetchNotes = async () => {
setLoading(true);
try {
const response = await DirectoryRepository.GetNotes(1000, 1);
const fetchedNotes = response.data?.data || [];
setAllNotes(fetchedNotes);
} catch (error) {
console.error("Failed to fetch notes:", error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchNotes();
}, []);
// useEffect(() => {
// const lowerSearch = searchText?.toLowerCase() || "";
// const filtered = allNotes.filter((noteItem) => {
// const plainNote = noteItem?.note?.replace(/<[^>]+>/g, "").toLowerCase();
// const fullName = `${noteItem?.createdBy?.firstName || ""} ${noteItem?.createdBy?.lastName || ""}`.trim(); // Get full name
// const lowerFullName = fullName.toLowerCase(); // Convert to lowercase for comparison
// const createdDate = new Date(noteItem?.createdAt).toLocaleDateString("en-IN").toLowerCase();
// const matchesSearch =
// plainNote.includes(lowerSearch) ||
// lowerFullName.includes(lowerSearch) ||
// createdDate.includes(lowerSearch);
// // ✅ Filter logic for multiple selected names
// const matchesNameFilter =
// selectedNoteNames.length === 0 || // If no names are selected, all notes pass this filter
// selectedNoteNames.includes(fullName); // Check if the note's creator is in the selected names array
// return matchesSearch && matchesNameFilter;
// });
// setFilteredNotes(filtered);
// setNotes(filtered);
// setCurrentPage(1);
// setTotalPages(Math.ceil(filtered.length / pageSize));
// }, [searchText, allNotes, selectedNoteNames]); // ✅ Add selectedNoteNames to dependencies
useEffect(() => {
const lowerSearch = searchText?.toLowerCase() || "";
const filtered = allNotes.filter((noteItem) => {
const plainNote = noteItem?.note?.replace(/<[^>]+>/g, "").toLowerCase();
const fullName = `${noteItem?.createdBy?.firstName || ""} ${noteItem?.createdBy?.lastName || ""}`.trim();
const lowerFullName = fullName.toLowerCase();
const createdDate = new Date(noteItem?.createdAt).toLocaleDateString("en-IN").toLowerCase();
// ✅ Collect all string values in the note object to search through
const stringValues = [];
const extractStrings = (obj) => {
for (const key in obj) {
if (!obj.hasOwnProperty(key)) continue;
const value = obj[key];
if (typeof value === "string") {
stringValues.push(value.toLowerCase());
} else if (typeof value === "object" && value !== null) {
extractStrings(value); // Recursively extract from nested objects
}
}
};
extractStrings(noteItem);
// Add manually stripped note, full name, date, etc.
stringValues.push(plainNote, lowerFullName, createdDate);
const matchesSearch = stringValues.some((val) => val.includes(lowerSearch));
const matchesNameFilter =
selectedNoteNames.length === 0 || selectedNoteNames.includes(fullName);
return matchesSearch && matchesNameFilter;
});
setFilteredNotes(filtered);
setNotes(filtered);
setCurrentPage(1);
setTotalPages(Math.ceil(filtered.length / pageSize));
}, [searchText, allNotes, selectedNoteNames]);
const currentItems = useMemo(() => {
const startIndex = (currentPage - 1) * pageSize;
return filteredNotes.slice(startIndex, startIndex + pageSize);
}, [filteredNotes, currentPage]);
const handlePageClick = (page) => {
if (page !== currentPage) {
setCurrentPage(page);
}
};
if (loading) {
return <p className="mt-10 text-center">Loading notes...</p>;
}
if (!filteredNotes.length) {
return <p className="mt-10 text-center">No matching notes found</p>;
}
return (
<div
className="w-100 h-100"
>
<div className="d-flex flex-column text-start mt-4" style={{ gap: "0rem", minHeight: "100%" }}>
{currentItems.map((noteItem) => (
<NoteCardDirectoryEditable
key={noteItem.id}
noteItem={noteItem}
contactId={noteItem.contactId}
onNoteUpdate={(updatedNote) => {
setAllNotes((prevNotes) =>
prevNotes.map((n) => (n.id === updatedNote.id ? updatedNote : n))
);
}}
onNoteDelete={() => {
fetchNotes();
}}
/>
))}
</div>
{totalPages > 1 && (
<div className="d-flex justify-content-end mt-3 me-3">
<div className="d-flex align-items-center gap-2">
<button
className="btn btn-sm rounded-circle border"
onClick={() => handlePageClick(Math.max(1, currentPage - 1))}
disabled={currentPage === 1}
title="Previous"
>
«
</button>
{[...Array(totalPages)].map((_, i) => {
const page = i + 1;
return (
<button
key={page}
className={`btn btn-sm rounded-circle border ${page === currentPage ? "btn-primary text-white" : "btn-outline-primary"}`}
style={{ width: "32px", height: "32px", padding: 0 }}
onClick={() => handlePageClick(page)}
>
{page}
</button>
);
})}
<button
className="btn btn-sm rounded-circle border"
onClick={() => handlePageClick(Math.min(totalPages, currentPage + 1))}
disabled={currentPage === totalPages}
title="Next"
>
»
</button>
</div>
</div>
)}
</div>
);
};
export default NotesCardViewDirectory;