diff --git a/src/pages/PaymentRequest/PaymentRequestList.jsx b/src/pages/PaymentRequest/PaymentRequestList.jsx
index 528086db..d6ac73a9 100644
--- a/src/pages/PaymentRequest/PaymentRequestList.jsx
+++ b/src/pages/PaymentRequest/PaymentRequestList.jsx
@@ -1,17 +1,103 @@
import React, { useState } from "react";
-import { ITEMS_PER_PAGE } from "../../utils/constants";
-import { useDebounce } from "../../utils/appUtils";
+import { EXPENSE_DRAFT, ITEMS_PER_PAGE } from "../../utils/constants";
+import { formatCurrency, getColorNameFromHex, useDebounce } from "../../utils/appUtils";
import { usePaymentRequestList } from "../../hooks/useExpense";
-import { formatDate } from "../../utils/dateUtils";
+import { formatDate, formatUTCToLocalTime } from "../../utils/dateUtils";
+import Avatar from "../../components/common/Avatar";
+import { usePaymentRequestContext } from "./PaymentRequestPage";
+
+const PaymentRequestList = ({ groupBy = "transactionDate", search }) => {
+
+ const { setManagePaymentRequestModal } = usePaymentRequestContext();
+ const groupByField = (items, field) => {
+ return items.reduce((acc, item) => {
+ let key;
+ let displayField;
+
+ switch (field) {
+ case "transactionDate":
+ key = item?.transactionDate?.split("T")[0];
+ displayField = "Transaction Date";
+ break;
+ case "status":
+ key = item?.status?.displayName || "Unknown";
+ displayField = "Status";
+ break;
+ case "submittedBy":
+ key = `${item?.createdBy?.firstName ?? ""} ${item.createdBy?.lastName ?? ""
+ }`.trim();
+ displayField = "Submitted By";
+ break;
+ case "project":
+ key = item?.project?.name || "Unknown Project";
+ displayField = "Project";
+ break;
+ case "paymentMode":
+ key = item?.paymentMode?.name || "Unknown Mode";
+ displayField = "Payment Mode";
+ break;
+ case "expensesType":
+ key = item?.expensesType?.name || "Unknown Type";
+ displayField = "Expense Category";
+ break;
+ case "createdAt":
+ key = item?.createdAt?.split("T")[0] || "Unknown Date";
+ displayField = "Created Date";
+ break;
+ default:
+ key = "Others";
+ displayField = "Others";
+ }
+
+ const groupKey = `${field}_${key}`; // unique key for object property
+ if (!acc[groupKey]) {
+ acc[groupKey] = { key, displayField, items: [] };
+ }
+
+ acc[groupKey].items.push(item);
+ return acc;
+ }, {});
+ };
-const PaymentRequestList = ({ setManagePaymentRequestModal, search }) => {
const paymentRequestColumns = [
- { key: "paymentRequestUID", label: "Request ID", align: "text-start mx-2" },
- { key: "title", label: "Request Title", align: "text-start" },
- { key: "payee", label: "Payee", align: "text-start" },
- { key: "createdAt", label: "Submitted On", align: "text-start" },
- { key: "amount", label: "Amount", align: "text-start" },
- { key: "expenseStatus", label: "Status", align: "text-start" },
+ { key: "paymentRequestUID", label: "Request ID", align: "text-start mx-2", getValue: (e) => e.paymentRequestUID || "N/A" },
+ { key: "title", label: "Request Title", align: "text-start", getValue: (e) => e.title || "N/A" },
+ // { key: "payee", label: "Payee", align: "text-start" },
+ {
+ key: "SubmittedBy",
+ label: "Submitted By",
+ align: "text-start",
+ getValue: (e) =>
+ `${e.createdBy?.firstName ?? ""} ${e.createdBy?.lastName ?? ""
+ }`.trim() || "N/A",
+ customRender: (e) => (
+
navigate(`/employee/${e.createdBy?.id}`)}>
+
+
+ {`${e.createdBy?.firstName ?? ""} ${e.createdBy?.lastName ?? ""
+ }`.trim() || "N/A"}
+
+
+ ),
+ },
+ { key: "createdAt", label: "Submitted On", align: "text-start", getValue: (e) => formatUTCToLocalTime(e?.createdAt) },
+ { key: "amount", label: "Amount", align: "text-start", getValue: (e) => <>{formatCurrency(e?.amount)}>, },
+ {
+ key: "expenseStatus", label: "Status", align: "text-start", getValue: (e) => (
+
+ {e?.expenseStatus?.name || "Unknown"}
+
+ ),
+ },
];
const [currentPage, setCurrentPage] = useState(1);
@@ -37,6 +123,27 @@ const PaymentRequestList = ({ setManagePaymentRequestModal, search }) => {
);
}
+ const grouped = groupBy
+ ? groupByField(data?.data ?? [], groupBy)
+ : { All: data?.data ?? [] };
+ const IsGroupedByDate = [
+ { key: "transactionDate", displayField: "Transaction Date" },
+ { key: "createdAt", displayField: "created Date" },
+ ]?.includes(groupBy);
+
+ const canEditExpense = (paymentRequest) => {
+ return (
+ (paymentRequest?.status?.id === EXPENSE_DRAFT ||
+ EXPENSE_REJECTEDBY.includes(paymentRequest?.status?.id)) &&
+ paymentRequest?.createdBy?.id === SelfId
+ );
+ };
+ const canDetetExpense = (expense) => {
+ return (
+ expense?.status?.id === EXPENSE_DRAFT && expense?.createdBy?.id === SelfId
+ );
+ };
+
return (
@@ -53,67 +160,116 @@ const PaymentRequestList = ({ setManagePaymentRequestModal, search }) => {
- {isLoading || isFetching ? (
-
- |
- Loading Payment Requests...
- |
-
- ) : paymentRequestData.length > 0 ? (
- paymentRequestData.map((row) => (
-
- | {row.paymentRequestUID} |
- {row.title} |
- {row.payee} |
- {formatDate(row.createdAt)} |
-
- {row.currency?.symbol}
- {row.amount}
- |
-
-
- {row.expenseStatus?.displayName || "Unknown"}
-
- |
-
-
-
- console.log("View clicked for:", row.paymentRequestUID)
- }
- >
+ {Object.keys(grouped).length > 0 ? (
+ Object.values(grouped).map(({ key, displayField, items }) => (
+
+
+ |
+
+ {" "}
+
+ {displayField} :{" "}
+ {" "}
+
+ {IsGroupedByDate
+ ? formatUTCToLocalTime(key)
+ : key}
+
+
+ |
+
+ {items?.map((paymentRequest) => (
+
+ {paymentRequestColumns.map(
+ (col) =>
+ (col.isAlwaysVisible || groupBy !== col.key) && (
+ |
+ {col?.customRender
+ ? col?.customRender(paymentRequest)
+ : col?.getValue(paymentRequest)}
+ |
+ )
+ )}
+
+
+
+ setViewExpense({
+ expenseId: paymentRequest.id,
+ view: true,
+ })
+ }
+ >
+
+
+
+
+
+ -
+ setManagePaymentRequestModal({
+ IsOpen: true,
+ expenseId: paymentRequest.id,
+ })
+ }
+ >
+
+
+
+ Modify
+
+
+
+
-
- setManagePaymentRequestModal({
- IsOpen: true,
- expenseId: row.id, // Pass ID for editing
- })
- }
- >
-
- |
-
+
+ {
+ setIsDeleteModalOpen(true);
+ setDeletingId(paymentRequest.id);
+ }}
+ >
+
+
+
+ Delete
+
+
+
+
+
+
+
+
+ |
+
+ ))}
+
))
) : (
- |
- No Payment Requests Found
+ |
+
|
)}
diff --git a/src/pages/PaymentRequest/PaymentRequestPage.jsx b/src/pages/PaymentRequest/PaymentRequestPage.jsx
index 92dc36bd..5c5b2b5a 100644
--- a/src/pages/PaymentRequest/PaymentRequestPage.jsx
+++ b/src/pages/PaymentRequest/PaymentRequestPage.jsx
@@ -1,90 +1,127 @@
-import React, { useState } from "react";
+import React, { createContext, useState,useEffect, useContext } from "react";
import Breadcrumb from "../../components/common/Breadcrumb";
import GlobalModel from "../../components/common/GlobalModel";
import ManagePaymentRequest from "../../components/PaymentRequest/ManagePaymentRequest";
import PaymentRequestList from "./PaymentRequestList";
+import ExpenseFilterPanel from "../../components/Expenses/ExpenseFilterPanel";
+import { useFab } from "../../Context/FabContext";
+export const PaymentRequestContext = createContext();
+export const usePaymentRequestContext = () => {
+ const context = useContext(PaymentRequestContext);
+ if (!context) {
+ throw new Error("usePaymentRequestContext must be used within an ExpenseProvider");
+ }
+ return context;
+};
const PaymentRequestPage = () => {
const [ManagePaymentRequestModal, setManagePaymentRequestModal] = useState({
IsOpen: null,
expenseId: null,
});
+ const { setOffcanvasContent, setShowTrigger } = useFab();
const [search, setSearch] = useState("");
- return (
-
- {/* Breadcrumb */}
-
{
+
+ setShowTrigger(true);
+ setOffcanvasContent(
+ "Expense Filters",
+
+ );
- {/* Top Bar */}
-
-
-
-
- setSearch(e.target.value)}
- />
-
+ return () => {
+ setShowTrigger(false);
+ setOffcanvasContent("", null);
+ };
+ },[]);
-
-
+ return (
+
+
+ {/* Breadcrumb */}
+
+
+ {/* Top Bar */}
+
+
+
+
+ setSearch(e.target.value)}
+ />
+
+
+
+
+
-
- {/* Add/Edit Modal */}
- {ManagePaymentRequestModal.IsOpen && (
-
- setManagePaymentRequestModal({ IsOpen: null, expenseId: null })
- }
- >
-
setManagePaymentRequestModal({ IsOpen: null, expenseId: null })
}
- />
-
- )}
+ >
+
+ setManagePaymentRequestModal({ IsOpen: null, expenseId: null })
+ }
+ />
+
+ )}
- {/* Payment Request List */}
-
-
+ {/* Payment Request List */}
+
-
+
);
};