From 59c46f7f3b04899f0747a7e342abf09b9da816f1 Mon Sep 17 00:00:00 2001 From: Kartik Sharma Date: Mon, 3 Nov 2025 14:46:20 +0530 Subject: [PATCH] Calling API for Get payment Request. --- .../PaymentRequest/PaymentRequestList.jsx | 290 ++++++++++++++---- .../PaymentRequest/PaymentRequestPage.jsx | 161 ++++++---- 2 files changed, 322 insertions(+), 129 deletions(-) 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 + +
    +

    No Expense 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 */} +
    + +
    -
    + ); };