marco.pms.web/src/pages/Directory/ContactsPage.jsx

133 lines
4.1 KiB
JavaScript

import React, { useEffect, useState } from "react";
import { useFab } from "../../Context/FabContext";
import { useContactList } from "../../hooks/useDirectory";
import { useDirectoryContext } from "./DirectoryPage";
import CardViewContact from "../../components/Directory/CardViewContact";
import { ITEMS_PER_PAGE } from "../../utils/constants";
import ContactFilterPanel from "./ContactFilterPanel";
import { defaultContactFilter } from "../../components/Directory/DirectorySchema";
import { useDebounce } from "../../utils/appUtils";
import Pagination from "../../components/common/Pagination";
import ListViewContact from "../../components/Directory/ListViewContact";
import {
CardViewContactSkeleton,
ListViewContactSkeleton,
} from "../../components/Directory/DirectoryPageSkeleton";
import Loader from "../../components/common/Loader";
// Utility function to format contacts for CSV export
const formatExportData = (contacts) => {
return contacts.map((contact) => ({
Email: contact.contactEmails?.map((e) => e.emailAddress).join(", ") || "",
Phone: contact.contactPhones?.map((p) => p.phoneNumber).join(", ") || "",
Created: contact.createdAt
? new Date(contact.createdAt).toLocaleString()
: "",
Location: contact.address || "",
Organization: contact.organization || "",
Category: contact.contactCategory?.name || "",
Tags: contact.tags?.map((t) => t.name).join(", ") || "",
Buckets: contact.bucketIds?.join(", ") || "",
}));
};
const ContactsPage = ({ projectId, searchText, onExport }) => {
const [currentPage, setCurrentPage] = useState(1);
const [filters, setFilter] = useState(defaultContactFilter);
const debouncedSearch = useDebounce(searchText, 500);
const { showActive, gridView } = useDirectoryContext();
const { data, isError, isLoading, error } = useContactList(
showActive,
projectId,
ITEMS_PER_PAGE,
currentPage,
filters,
debouncedSearch
);
const { setOffcanvasContent, setShowTrigger } = useFab();
const clearFilter = () => setFilter(defaultContactFilter);
useEffect(() => {
setShowTrigger(true);
setOffcanvasContent(
"Contacts Filters",
<ContactFilterPanel onApply={setFilter} clearFilter={clearFilter} />
);
return () => {
setShowTrigger(false);
setOffcanvasContent("", null);
};
}, []);
// 🔹 Format contacts for export
useEffect(() => {
if (data?.data && onExport) {
onExport(formatExportData(data.data));
}
}, [data?.data]);
const paginate = (page) => {
if (page >= 1 && page <= (data?.totalPages ?? 1)) {
setCurrentPage(page);
}
};
if (isError) return <div>{error.message}</div>;
// if (isLoading) return gridView ? <CardViewContactSkeleton /> : <ListViewContactSkeleton />;
return (
<div className="row mt-5">
{gridView ? (
<>
{isLoading && (
<div>
<Loader />
</div>
)}
{data?.data?.length === 0 && (<div className="py-12 ">
{searchText ? `No contact found for "${searchText}"`:"No contacts found" }
</div>)}
{data?.data?.map((contact) => (
<div
key={contact.id}
className="col-12 col-sm-6 col-md-4 col-lg-4 mb-4"
>
<CardViewContact IsActive={showActive} contact={contact} />
</div>
))}
{data?.data?.length > 0 && (
<div className="col-12 d-flex justify-content-start mt-3">
<Pagination
currentPage={currentPage}
totalPages={data.totalPages}
onPageChange={paginate}
/>
</div>
)}
</>
) : (
<div className="col-12">
<ListViewContact
data={data?.data}
isLoading={isLoading}
Pagination={
<Pagination
currentPage={currentPage}
totalPages={data?.totalPages}
onPageChange={paginate}
/>
}
/>
</div>
)}
</div>
);
};
export default ContactsPage;