diff --git a/src/components/Expenses/ExpenseSchema.js b/src/components/Expenses/ExpenseSchema.js index ad22e67a..90a48483 100644 --- a/src/components/Expenses/ExpenseSchema.js +++ b/src/components/Expenses/ExpenseSchema.js @@ -169,7 +169,7 @@ export const defaultActionValues = { reimburseById: null, tdsPercentage: 0, baseAmount:null, - taxAmount: 0, + taxAmount: null, }; export const SearchSchema = z.object({ diff --git a/src/components/Expenses/ExpenseStatusLogs.jsx b/src/components/Expenses/ExpenseStatusLogs.jsx index c7be711b..e6540a87 100644 --- a/src/components/Expenses/ExpenseStatusLogs.jsx +++ b/src/components/Expenses/ExpenseStatusLogs.jsx @@ -18,7 +18,7 @@ const ExpenseStatusLogs = ({ data }) => { () => sortedLogs.slice(0, visibleCount), [sortedLogs, visibleCount] ); - +console.log(logsToShow) const timelineData = useMemo(() => { return logsToShow.map((log, index) => ({ diff --git a/src/components/Expenses/Filelist.jsx b/src/components/Expenses/Filelist.jsx index 15fe9fc3..96ae7901 100644 --- a/src/components/Expenses/Filelist.jsx +++ b/src/components/Expenses/Filelist.jsx @@ -1,54 +1,96 @@ import React from "react"; import { formatFileSize, getIconByFileType } from "../../utils/appUtils"; +import Tooltip from "../common/Tooltip"; const Filelist = ({ files, removeFile, expenseToEdit }) => { return ( -
- {files - .filter((file) => { - if (expenseToEdit) { - return file.isActive; - } - return true; - }) - .map((file, idx) => ( -
-
- {/* File icon and info */} -
- +
+ {files + .filter((file) => { + if (expenseToEdit) { + return file.isActive; + } + return true; + }) + .map((file, idx) => ( +
+
+ {/* File icon and info */} +
+ -
- - {file.fileName} - - - {file.fileSize ? formatFileSize(file.fileSize) : ""} - -
-
- - {/* Delete icon */} - - { - e.preventDefault(); - removeFile(expenseToEdit ? file.documentId : idx); - }} - > - +
+ + {file.fileName} + + + {file.fileSize ? formatFileSize(file.fileSize) : ""} +
- ))} -
+ + {/* Delete icon */} + + { + e.preventDefault(); + removeFile(expenseToEdit ? file.documentId : idx); + }} + > + +
+
+ ))} +
+ ); }; export default Filelist; +export const FilelistView = ({ files, viewFile }) => { + console.log( files) + return ( +
+ {files?.map((file, idx) => ( +
+
+ {/* File icon and info */} +
+ + +
{ + e.preventDefault(); + viewFile({ + IsOpen: true, + Image: file.preSignedUrl, + }); + }} + > + + {file.fileName} + + + + {" "} + {file.fileSize ? formatFileSize(file.fileSize) : ""} + + +
+
+
+
+ ))} +
+ ); +}; \ No newline at end of file diff --git a/src/components/Expenses/ManageExpense.jsx b/src/components/Expenses/ManageExpense.jsx index ce392463..b7bd01bd 100644 --- a/src/components/Expenses/ManageExpense.jsx +++ b/src/components/Expenses/ManageExpense.jsx @@ -134,7 +134,6 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { reader.onerror = (error) => reject(error); }); const removeFile = (index) => { - documentId; if (expenseToEdit) { const newFiles = files.map((file, i) => { if (file.documentId !== index) return file; diff --git a/src/components/Expenses/ViewExpense.jsx b/src/components/Expenses/ViewExpense.jsx index b6c5f311..0c9168cd 100644 --- a/src/components/Expenses/ViewExpense.jsx +++ b/src/components/Expenses/ViewExpense.jsx @@ -109,6 +109,7 @@ const ViewExpense = ({ ExpenseId }) => { const handleImageLoad = (id) => { setImageLoaded((prev) => ({ ...prev, [id]: true })); }; + console.log(errors) return (
diff --git a/src/components/PaymentRequest/ManagePaymentRequest.jsx b/src/components/PaymentRequest/ManagePaymentRequest.jsx index 8232d3aa..8365a66d 100644 --- a/src/components/PaymentRequest/ManagePaymentRequest.jsx +++ b/src/components/PaymentRequest/ManagePaymentRequest.jsx @@ -392,10 +392,7 @@ function ManagePaymentRequest({ closeModal, requestToEdit = null }) { error={errors.payee?.message} /> - {errors.payee && ( - {errors.payee.message} - )} - + {/* Checkbox below input */}
{ }), billAttachments: z - .array( - z.object({ - fileName: z.string().min(1, { message: "Filename is required" }), - base64Data: z.string().nullable(), - contentType: z - .string() - .refine((val) => ALLOWED_TYPES.includes(val), { - message: "Only PDF, PNG, JPG, or JPEG files are allowed", - }), - documentId: z.string().optional(), - fileSize: z.number().max(MAX_FILE_SIZE, { - message: "File size must be less than or equal to 5MB", - }), - description: z.string().optional(), - isActive: z.boolean().default(true), - }) - ).refine((data)=>{ - if(isItself){ - payee.z.string().optional(); - } - }), + .array( + z.object({ + fileName: z.string().min(1, { message: "Filename is required" }), + base64Data: z.string().nullable(), + contentType: z + .string() + .refine((val) => ALLOWED_TYPES.includes(val), { + message: "Only PDF, PNG, JPG, or JPEG files are allowed", + }), + documentId: z.string().optional(), + fileSize: z.number().max(MAX_FILE_SIZE, { + message: "File size must be less than or equal to 5MB", + }), + description: z.string().optional(), + isActive: z.boolean().default(true), + }) + ) + , }) }; diff --git a/src/components/PaymentRequest/PaymentStatusLogs.jsx b/src/components/PaymentRequest/PaymentStatusLogs.jsx new file mode 100644 index 00000000..9abb3fa5 --- /dev/null +++ b/src/components/PaymentRequest/PaymentStatusLogs.jsx @@ -0,0 +1,93 @@ +import { useState, useMemo } from "react"; +import Avatar from "../common/Avatar"; +import { formatUTCToLocalTime } from "../../utils/dateUtils"; +import Timeline from "../common/TimeLine"; +import moment from "moment"; +import { getColorNameFromHex } from "../../utils/appUtils"; +const PaymentStatusLogs = ({ data }) => { + const [visibleCount, setVisibleCount] = useState(4); + + const sortedLogs = useMemo(() => { + if (!data?.updateLogs) return []; + return [...data.updateLogs].sort( + (a, b) => new Date(b.updatedAt) - new Date(a.updatedAt) + ); + }, [data?.updateLogs]); + + const logsToShow = useMemo( + () => sortedLogs.slice(0, visibleCount), + [sortedLogs, visibleCount] + ); + + const timelineData = useMemo(() => { + return logsToShow.map((log, index) => ({ + id: index + 1, + title: log.nextStatus?.name || "Status Updated", + description: log.nextStatus?.description || "", + timeAgo: log.updatedAt, + color: getColorNameFromHex(log.nextStatus?.color) || "primary", + users: log.updatedBy + ? [ + { + firstName: log.updatedBy.firstName || "", + lastName: log?.updatedBy?.lastName || "", + role: log.updatedBy.jobRoleName || "", + avatar: log.updatedBy.photo, + }, + ] + : [], + })); + }, [logsToShow]); + + const handleShowMore = () => { + setVisibleCount((prev) => prev + 4); + }; + + return ( +
+ {/*
+ {logsToShow.map((log) => ( +
+ + +
+
+
+ {`${log.updatedBy.firstName} ${log.updatedBy.lastName}`} + + {log.action} + + + {formatUTCToLocalTime(log.updateAt, true)} + +
+
+ {log.comment} +
+
+
+
+ ))} +
+ + {sortedLogs.length > visibleCount && ( +
+ +
+ )} */} + + +
+ ); +}; + +export default PaymentStatusLogs; diff --git a/src/components/PaymentRequest/ViewPaymentRequest.jsx b/src/components/PaymentRequest/ViewPaymentRequest.jsx index 27447d0a..85b0e8f9 100644 --- a/src/components/PaymentRequest/ViewPaymentRequest.jsx +++ b/src/components/PaymentRequest/ViewPaymentRequest.jsx @@ -34,6 +34,8 @@ import { REVIEW_EXPENSE, } from "../../utils/constants"; import Label from "../common/Label"; +import { FilelistView } from "../Expenses/Filelist"; +import PaymentStatusLogs from "./PaymentStatusLogs"; const ViewPaymentRequest = ({ requestId }) => { const { data, isLoading, isError, error, isFetching } = @@ -125,7 +127,7 @@ const ViewPaymentRequest = ({ requestId }) => {
-
+
{data?.paymentRequestUID} @@ -537,7 +539,7 @@ const ViewPaymentRequest = ({ requestId }) => { {" "}

TimeLine

- +
diff --git a/src/components/common/TimeLine.jsx b/src/components/common/TimeLine.jsx index 43d32873..a43d632a 100644 --- a/src/components/common/TimeLine.jsx +++ b/src/components/common/TimeLine.jsx @@ -1,5 +1,8 @@ import React from "react"; import Avatar from "./Avatar"; +import Tooltip from "./Tooltip"; +import { formatUTCToLocalTime } from "../../utils/dateUtils"; +import moment from "moment"; const Timeline = ({ items = [], transparent = true }) => { return ( @@ -24,7 +27,7 @@ const Timeline = ({ items = [], transparent = true }) => {
{item.title}
- {item.timeAgo} + {moment(item.timeAgo).fromNow()}
{item.description &&

{item.description}

} diff --git a/src/pages/Expense/ExpensePage.jsx b/src/pages/Expense/ExpensePage.jsx index f5c3ea5d..c55b7706 100644 --- a/src/pages/Expense/ExpensePage.jsx +++ b/src/pages/Expense/ExpensePage.jsx @@ -190,7 +190,7 @@ const ExpensePage = () => { {viewExpense.view && ( setViewExpense({ expenseId: null, view: false })} >