added expense status logs

This commit is contained in:
pramod mahajan 2025-08-04 12:37:18 +05:30
parent 1e26b1261c
commit 68bd0d6bb5
4 changed files with 129 additions and 25 deletions

View File

@ -20473,7 +20473,10 @@ li:not(:first-child) .dropdown-item,
word-wrap: break-word !important; word-wrap: break-word !important;
word-break: break-word !important; word-break: break-word !important;
} }
/* text-size */
.text-tiny{
font-size: 13px;
}
/* rtl:end:remove */ /* rtl:end:remove */
.text-primary { .text-primary {
--bs-text-opacity: 1; --bs-text-opacity: 1;

View File

@ -0,0 +1,63 @@
import { useState } from "react";
import Avatar from "../common/Avatar";
const ExpenseStatusLogs = ({ data }) => {
const [visibleCount, setVisibleCount] = useState(4);
const logsToShow = data?.expenseLogs?.slice(0, visibleCount) || [];
const handleShowMore = () => {
setVisibleCount((prev) => prev + 4);
};
return (
<>
<div className="row g-2">
{logsToShow.map((log, index) => (
<div
key={log.id}
className="col-12 d-flex align-items-start mb-2"
>
<Avatar
size="xs"
firstName={log.updatedBy.firstName}
lastName={log.updatedBy.lastName}
/>
<div className="flex-grow-1">
<div className="d-flex justify-content-start">
<div className="text-start">
<div >
<div className="flex">
<span>{`${log.updatedBy.firstName} ${log.updatedBy.lastName}`}</span>
<small className="text-secondary text-tiny ms-2">
<em>{log.action}</em>
</small>
<span className="text-tiny text-secondary d-block small">{log?.updateAt ?? "14-Aug-2025"}</span>
</div>
</div>
<div className="d-flex align-items-center text-muted small mt-1">
<span className="small">{log.comment}</span>
</div>
</div>
</div>
</div>
</div>
))}
</div>
{data?.expenseLogs?.length > visibleCount && (
<div className="text-center my-1">
<button
className="btn btn-xs btn-outline-primary"
onClick={handleShowMore}
>
Show More
</button>
</div>
)}
</>
);
};
export default ExpenseStatusLogs;

View File

@ -27,6 +27,7 @@ import { useEmployeeRoles, useEmployeesName } from "../../hooks/useEmployees";
import EmployeeSearchInput from "../common/EmployeeSearchInput"; import EmployeeSearchInput from "../common/EmployeeSearchInput";
import { z } from "zod"; import { z } from "zod";
import moment from "moment"; import moment from "moment";
import ExpenseStatusLogs from "./ExpenseStatusLogs";
const ViewExpense = ({ ExpenseId }) => { const ViewExpense = ({ ExpenseId }) => {
const { data, isLoading, isError, error } = useExpense(ExpenseId); const { data, isLoading, isError, error } = useExpense(ExpenseId);
@ -111,7 +112,12 @@ const ViewExpense = ({ ExpenseId }) => {
<h5 className="fw-semibold">Expense Details</h5> <h5 className="fw-semibold">Expense Details</h5>
<hr /> <hr />
</div> </div>
<div className="text-start mb-2">
{/* <label className="form-label me-2 mb-0 fw-semibold">
Description :
</label> */}
<div className="text-muted">{data?.description}</div>
</div>
{/* Row 1 */} {/* Row 1 */}
<div className="col-md-6 mb-3"> <div className="col-md-6 mb-3">
<div className="d-flex"> <div className="d-flex">
@ -270,7 +276,7 @@ const ViewExpense = ({ ExpenseId }) => {
</div> </div>
)} )}
{data.reviewedBy && ( {/* {data.reviewedBy && (
<div className="col-md-6 mb-3 text-start"> <div className="col-md-6 mb-3 text-start">
<div className="d-flex align-items-center"> <div className="d-flex align-items-center">
<label <label
@ -345,17 +351,17 @@ const ViewExpense = ({ ExpenseId }) => {
</div> </div>
</div> </div>
</div> </div>
)} )} */}
</div> </div>
{data.expensesReimburse && ( {data.expensesReimburse && (
<div className="row text-start"> <div className="row text-start">
<div className="col-md-6 mb-3"> <div className="col-md-6 ">
<label className="form-label me-2 mb-0 fw-semibold"> <label className="form-label me-2 mb-0 fw-semibold">
Transaction ID : Transaction ID :
</label> </label>
{data.expensesReimburse.reimburseTransactionId || "N/A"} {data.expensesReimburse.reimburseTransactionId || "N/A"}
</div> </div>
<div className="col-md-6 mb-3"> <div className="col-md-6 ">
<label className="form-label me-2 mb-0 fw-semibold"> <label className="form-label me-2 mb-0 fw-semibold">
Reimburse Date : Reimburse Date :
</label> </label>
@ -364,7 +370,7 @@ const ViewExpense = ({ ExpenseId }) => {
{data.expensesReimburse && ( {data.expensesReimburse && (
<> <>
<div className="col-md-6 mb-3 d-flex align-items-center"> <div className="col-md-6 d-flex align-items-center">
<label className="form-label me-2 mb-0 fw-semibold"> <label className="form-label me-2 mb-0 fw-semibold">
Reimburse By : Reimburse By :
</label> </label>
@ -380,20 +386,15 @@ const ViewExpense = ({ ExpenseId }) => {
</div> </div>
</> </>
)} )}
<div className="col-md-6 mb-3">
<label className="form-label me-2 mb-0 fw-semibold"> Note :</label>{" "}
{data.expensesReimburse.reimburseNote}
</div>
</div> </div>
)} )}
<div className="text-start"> {/* <div className="text-start">
<label className="form-label me-2 mb-0 fw-semibold"> <label className="form-label me-2 mb-0 fw-semibold">
Description : Description :
</label> </label>
<div className="text-muted">{data?.description}</div> <div className="text-muted">{data?.description}</div>
</div> </div> */}
<div className="col-12 my-2 text-start"> <div className="col-12 my-2 text-start">
<label className="form-label me-2 mb-0 fw-semibold">Attachment :</label> <label className="form-label me-2 mb-0 fw-semibold">Attachment :</label>
@ -488,7 +489,7 @@ const ViewExpense = ({ ExpenseId }) => {
)} )}
</div> </div>
<div className="col-12 col-md-6 text-start"> <div className="col-12 col-md-6 text-start">
<label className="form-label">Reimburse By </label> <label className="form-label">Reimburse By </label>
<EmployeeSearchInput <EmployeeSearchInput
control={control} control={control}
name="reimburseById" name="reimburseById"
@ -540,7 +541,12 @@ const ViewExpense = ({ ExpenseId }) => {
</div> </div>
</> </>
)} )}
<ExpenseStatusLogs data={data}/>
</form> </form>
); );
}; };

View File

@ -1,24 +1,56 @@
import React from 'react'; import React from 'react';
import { useRouteError, isRouteErrorResponse } from 'react-router-dom'; import { useRouteError, isRouteErrorResponse } from 'react-router-dom';
const ErrorPage =() =>{ const ErrorPage = () => {
const error = useRouteError(); const error = useRouteError();
console.error(error); console.error('Route Error:', error);
if (isRouteErrorResponse(error)) { if (isRouteErrorResponse(error)) {
const { status, statusText, data } = error;
return ( return (
<div> <div className="container mt-5">
<h1>{error.status}</h1> <h1 className="text-danger">Oops! Something went wrong.</h1>
<p>{error.statusText}</p> <p className="lead">We couldnt load the page you requested.</p>
<hr />
<h4>Error Details</h4>
<ul>
<li><strong>Status:</strong> {status}</li>
<li><strong>Status Text:</strong> {statusText}</li>
{data && <li><strong>Message:</strong> {typeof data === 'string' ? data : JSON.stringify(data)}</li>}
</ul>
</div> </div>
); );
} }
const {
message = 'An unexpected error occurred.',
name,
stack,
} = error || {};
return ( return (
<div> <div className="container mt-5">
<h1>Something went wrong.</h1> <h1 className="text-danger">Something went wrong.</h1>
<p>{error?.message || 'Unknown error occurred'}</p> <p className="lead">Sorry, we couldnt complete your request.</p>
{message && (
<div className="alert alert-warning mt-4">
<strong>{name ? `${name}: ` : ''}</strong>
{message}
</div>
)}
{stack && (
<details className="mt-3 text-muted">
<summary>Developer Details (Stack Trace)</summary>
<pre>{stack}</pre>
</details>
)}
</div> </div>
); );
} };
export default ErrorPage
export default ErrorPage;