183 lines
6.3 KiB
JavaScript
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; |