133 lines
4.1 KiB
JavaScript
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;
|