marco.pms.web/src/pages/collections/CollectionPage.jsx

245 lines
8.2 KiB
JavaScript

import React, { createContext, useContext, useState } from "react";
import moment from "moment";
import Breadcrumb from "../../components/common/Breadcrumb";
import CollectionList from "../../components/collections/CollectionList";
import { useModal } from "../../hooks/useAuth";
import { FormProvider, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { DateRangePicker1 } from "../../components/common/DateRangePicker";
import { isPending } from "@reduxjs/toolkit";
import ConfirmModal from "../../components/common/ConfirmModal";
import showToast from "../../services/toastService";
import { useMarkedPaymentReceived } from "../../hooks/useCollections";
import GlobalModel from "../../components/common/GlobalModel";
import AddPayment from "../../components/collections/AddPayment";
import ViewCollection from "../../components/collections/ViewCollection";
import ManageCollection from "../../components/collections/ManageCollection";
import PreviewDocument from "../../components/Expenses/PreviewDocument";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import {
ADDPAYMENT_COLLECTION,
ADMIN_COLLECTION,
CREATE_COLLECTION,
EDIT_COLLECTION,
VIEW_COLLECTION,
} from "../../utils/constants";
import AccessDenied from "../../components/common/AccessDenied";
const CollectionContext = createContext();
export const useCollectionContext = () => {
const context = useContext(CollectionContext);
if (!context) {
window.location = "/dashboard";
showToast("Out of Context Happend inside Collection Context", "warning");
}
return context;
};
const CollectionPage = () => {
const [viewCollection, setViewCollection] = useState(null);
const [makeCollection, setCollection] = useState({
isOpen: false,
invoiceId: null,
});
const [ViewDocument, setDocumentView] = useState({
IsOpen: false,
Image: null,
});
const [processedPayment, setProcessedPayment] = useState(null);
const [addPayment, setAddPayment] = useState({
isOpen: false,
invoiceId: null,
});
const [showPending, setShowPending] = useState(false);
const [searchText, setSearchText] = useState("");
const isAdmin = useHasUserPermission(ADMIN_COLLECTION);
const canViewCollection = useHasUserPermission(VIEW_COLLECTION);
const canCreate = useHasUserPermission(CREATE_COLLECTION);
const canEditCollection = useHasUserPermission(EDIT_COLLECTION);
const canAddPayment = useHasUserPermission(ADDPAYMENT_COLLECTION);
const methods = useForm({
defaultValues: {
fromDate: moment().subtract(180, "days").format("DD-MM-YYYY"),
toDate: moment().format("DD-MM-YYYY"),
},
});
const { watch } = methods;
const [fromDate, toDate] = watch(["fromDate", "toDate"]);
const handleToggleActive = (e) => setShowPending(e.target.checked);
const contextMassager = {
setProcessedPayment,
setCollection,
setAddPayment,
addPayment,
setViewCollection,
viewCollection,
setDocumentView,
};
const { mutate: MarkedReceived, isPending } = useMarkedPaymentReceived(() => {
setProcessedPayment(null);
});
const handleMarkedPayment = (payload) => {
MarkedReceived(payload);
};
if (
isAdmin === undefined ||
canAddPayment === undefined ||
canEditCollection === undefined ||
canViewCollection === undefined ||
canCreate === undefined
) {
return <div className="text-center py-5">Checking access...</div>;
}
if (
!isAdmin &&
!canAddPayment &&
!canEditCollection &&
!canViewCollection &&
!canCreate
) {
return (
<AccessDenied
data={[{ label: "Home", link: "/dashboard" }, { label: "Collection" }]}
/>
);
}
return (
<CollectionContext.Provider value={contextMassager}>
<div className="container-fluid">
<Breadcrumb
data={[
{ label: "Home", link: "/dashboard" },
{ label: "Collection" },
]}
/>
<div className="card my-3 py-2 px-sm-4 px-2">
<div className="row align-items-center gap-sm-2 gap-md-0 mx-0">
<div className="col-12 col-md-4 d-flex flex-column flex-md-row flex-wrap align-items-start">
<div className="d-inline-flex border rounded-pill overflow-hidden shadow-none">
<button
type="button"
className={`btn px-2 py-1 rounded-0 text-tiny ${
!showPending ? "btn-primary text-white" : ""
}`}
onClick={() => setShowPending(false)}
>
Show All
</button>
<button
type="button"
className={`btn px-2 py-1 rounded-0 text-tiny ${
showPending ? "btn-primary text-white" : ""
}`}
onClick={() => setShowPending(true)}
>
Pending
</button>
</div>
</div>
<div className="col-12 col-sm-8 d-block d-sm-flex justify-content-end ga-2 align-items-center gap-2">
<input
type="search"
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
placeholder="Search Collection"
className="form-control form-control-sm mt-2 mt-sm-0"
/>
<div className="d-flex justify-content-between justify-content-sm-between mt-2 mt-sm-0">
<FormProvider {...methods} className="me-3">
<DateRangePicker1
howManyDay={180}
startField="fromDate"
endField="toDate"
/>
</FormProvider>
{(canCreate || isAdmin) && (
<button
className="btn btn-sm btn-primary ms-sm-2"
type="button"
onClick={() =>
setCollection({ isOpen: true, invoiceId: null })
}
>
<i className="bx bx-plus-circle me-2"></i>
<span className="d-none d-md-inline-block">Collection</span>
</button>
)}
</div>
</div>
</div>
</div>
<CollectionList
fromDate={fromDate}
toDate={toDate}
isPending={showPending}
searchString={searchText}
/>
{makeCollection.isOpen && (
<GlobalModel
isOpen={makeCollection.isOpen}
size="lg"
closeModal={() => setCollection({ isOpen: false, invoiceId: null })}
>
<ManageCollection
collectionId={makeCollection?.invoiceId ?? null}
onClose={() => setCollection({ isOpen: false, invoiceId: null })}
/>
</GlobalModel>
)}
{addPayment.isOpen && (
<GlobalModel
size="lg"
isOpen={addPayment.isOpen}
closeModal={() => setAddPayment({ isOpen: false, invoiceId: null })}
>
<AddPayment
onClose={() => setAddPayment({ isOpen: false, invoiceId: null })}
/>
</GlobalModel>
)}
{viewCollection && (
<GlobalModel
size="lg"
isOpen={viewCollection}
closeModal={() => setViewCollection(null)}
>
<ViewCollection onClose={() => setViewCollection(null)} />
</GlobalModel>
)}
{ViewDocument.IsOpen && (
<GlobalModel
isOpen
size="md"
key={ViewDocument.Image ?? "doc"}
closeModal={() => setDocumentView({ IsOpen: false, Image: null })}
>
<PreviewDocument imageUrl={ViewDocument.Image} />
</GlobalModel>
)}
<ConfirmModal
type="success"
header="Payment Successful Received"
message="Payment has been recored successfully."
isOpen={processedPayment?.isOpen}
loading={isPending}
onSubmit={() => handleMarkedPayment(processedPayment?.invoiceId)}
onClose={() => setProcessedPayment(null)}
/>
</div>
</CollectionContext.Provider>
);
};
export default CollectionPage;