added view deatils of purchases
This commit is contained in:
parent
909022b034
commit
528255c2bd
@ -2,22 +2,130 @@ import React, { useState } from "react";
|
||||
import { usePurchasesList } from "../../hooks/usePurchase";
|
||||
import { ITEMS_PER_PAGE } from "../../utils/constants";
|
||||
import Pagination from "../common/Pagination";
|
||||
import { PurchaseColumn } from "./Purchasetable";
|
||||
import { SpinnerLoader } from "../common/Loader";
|
||||
import { useDebounce } from "../../utils/appUtils";
|
||||
import { usePurchaseContext } from "../../pages/purchase/PurchasePage";
|
||||
|
||||
const PurchaseList = () => {
|
||||
const PurchaseList = ({ searchString }) => {
|
||||
const { setViewPurchase } = usePurchaseContext();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const { data, isLoading, isError, error } = usePurchasesList(
|
||||
const debounceSearch = useDebounce(searchString, 300);
|
||||
const { data, isLoading } = usePurchasesList(
|
||||
ITEMS_PER_PAGE,
|
||||
currentPage,
|
||||
true,
|
||||
{}
|
||||
{},
|
||||
debounceSearch
|
||||
);
|
||||
|
||||
const paginate = (page) => {
|
||||
if (page >= 1 && page <= (data?.totalPages ?? 1)) {
|
||||
setCurrentPage(page);
|
||||
}
|
||||
};
|
||||
|
||||
const visibleColumns = PurchaseColumn.filter((col) => !col.hidden);
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="card mt-2">
|
||||
<div className="table-responsive px-3">
|
||||
<table className="datatables-users table border-top text-nowrap">
|
||||
<thead>
|
||||
<tr>
|
||||
{visibleColumns.map((col) => (
|
||||
<th key={col.key} colSpan={col.colSpan || 1}>
|
||||
<div className={col.className || ""}>{col.label}</div>
|
||||
</th>
|
||||
))}
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{/* LOADING */}
|
||||
{isLoading && (
|
||||
<tr>
|
||||
<td colSpan={3} colSpan={visibleColumns.length}>
|
||||
<div className="py-6 py-12">
|
||||
<SpinnerLoader />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{!isLoading && data?.data?.length === 0 && (
|
||||
<tr>
|
||||
<td
|
||||
colSpan={visibleColumns.length}
|
||||
className="text-center py-4"
|
||||
colSpan={4}
|
||||
>
|
||||
No Data Found
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
|
||||
{!isLoading &&
|
||||
data?.data?.map((item, index) => (
|
||||
<tr key={item?.id || index}>
|
||||
{visibleColumns.map((col) => (
|
||||
<td key={col.key} className={col.className || ""}>
|
||||
{col.render ? col.render(item) : item[col.key] || "NA"}
|
||||
</td>
|
||||
))}
|
||||
<td>
|
||||
<div className="dropdown z-2">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-icon btn-text-secondary rounded-pill dropdown-toggle hide-arrow p-0"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<i
|
||||
className="bx bx-dots-vertical-rounded bx-sm text-muted"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-offset="0,8"
|
||||
data-bs-placement="top"
|
||||
data-bs-custom-class="tooltip-dark"
|
||||
title="More Action"
|
||||
></i>
|
||||
</button>
|
||||
<ul className="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a
|
||||
className="dropdown-item cursor-pointer"
|
||||
onClick={() =>
|
||||
setViewPurchase({
|
||||
isOpen: true,
|
||||
purchaseId: item.id,
|
||||
})
|
||||
}
|
||||
>
|
||||
<i className="bx bx-eye me-2"></i>
|
||||
<span className="align-left">view</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a className="dropdown-item cursor-pointer">
|
||||
<i className="bx bx-trash me-2"></i>
|
||||
<span className="align-left">Add</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a className="dropdown-item cursor-pointer">
|
||||
<i className="bx bx-trash me-2"></i>
|
||||
<span className="align-left">Delete</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{data?.data?.length > 0 && (
|
||||
<Pagination
|
||||
currentPage={currentPage}
|
||||
@ -30,4 +138,3 @@ const PurchaseList = () => {
|
||||
};
|
||||
|
||||
export default PurchaseList;
|
||||
``;
|
||||
|
||||
60
src/components/purchase/Purchasetable.jsx
Normal file
60
src/components/purchase/Purchasetable.jsx
Normal file
@ -0,0 +1,60 @@
|
||||
import { formatFigure, getColorNameFromHex } from "../../utils/appUtils";
|
||||
|
||||
export const PurchaseColumn = [
|
||||
{
|
||||
key: "purchaseInvoiceUId",
|
||||
label: "Invoice Id",
|
||||
|
||||
className: "text-start",
|
||||
render: (item) => (
|
||||
<div className="d-flex justify-content-start align-items-center p-1">
|
||||
<span className="fw-normal">{item?.purchaseInvoiceUId || "NA"}</span>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "title",
|
||||
label: "Title",
|
||||
|
||||
className: "text-start",
|
||||
render: (item) => (
|
||||
<div className="d-flex justify-content-start align-items-center">
|
||||
<span className="fw-normal">{item?.title || "NA"}</span>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "project",
|
||||
label: "Project",
|
||||
className: "text-start d-none d-sm-table-cell",
|
||||
render: (item) => <span>{item?.project?.name || "NA"}</span>,
|
||||
},
|
||||
{
|
||||
key: "supplier",
|
||||
label: "Supplier",
|
||||
className: "text-start d-none d-sm-table-cell",
|
||||
render: (item) => <span>{item?.supplier?.name || "NA"}</span>,
|
||||
},
|
||||
{
|
||||
key: "status",
|
||||
label: "Status",
|
||||
className: "text-start",
|
||||
render: (item) => {
|
||||
let color = getColorNameFromHex(item.status?.color);
|
||||
return (
|
||||
<span className={`badge rounded-pill bg-label-${color}`}>
|
||||
<span className={`badge badge-dot bg-${color} me-1`}></span>
|
||||
{item?.status.displayName || "NA"}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "totalAmount",
|
||||
label: "Total Amount",
|
||||
className: " text-end w-min",
|
||||
render: (item) => (
|
||||
<span>{formatFigure(item?.totalAmount, { type: "currency" })}</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
227
src/components/purchase/ViewPurchase.jsx
Normal file
227
src/components/purchase/ViewPurchase.jsx
Normal file
@ -0,0 +1,227 @@
|
||||
import React from "react";
|
||||
import { usePurchase } from "../../hooks/usePurchase";
|
||||
import { SpinnerLoader } from "../common/Loader";
|
||||
import { formatUTCToLocalTime } from "../../utils/dateUtils";
|
||||
import { getColorNameFromHex } from "../../utils/appUtils";
|
||||
|
||||
const ViewPurchase = ({ purchaseId }) => {
|
||||
const { data, isLoading, isError, error } = usePurchase(purchaseId);
|
||||
|
||||
if (isLoading) return <SpinnerLoader />;
|
||||
if (isError) return <Error error={error} />;
|
||||
|
||||
return (
|
||||
<div className="row g-3">
|
||||
<div className="col-12 text-start">
|
||||
<div className=" ">
|
||||
<p className="fs-6 mb-3">Purchase Details</p>
|
||||
<div className="row">
|
||||
<div className="col-md-4">
|
||||
<small className="text-secondary">Purchase No:</small>
|
||||
<p className="fw-light mb-1">{data?.purchaseInvoiceUId}</p>
|
||||
</div>
|
||||
|
||||
<div className="col-md-4">
|
||||
<small className="text-secondary">Title:</small>
|
||||
<p className="fw-light mb-1">{data?.title}</p>
|
||||
</div>
|
||||
|
||||
<div className="col-md-4">
|
||||
<small className="fw-light me-3">Status:</small>
|
||||
|
||||
<span className={`badge rounded-pill bg-label-${getColorNameFromHex(data?.status?.color)}`}>
|
||||
{data?.status.displayName || "NA"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="col-12 ">
|
||||
<small className="text-secondary">Description:</small>
|
||||
<p className="fw-light mb-1">{data?.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-md-6">
|
||||
<div className="text-start h-auto">
|
||||
<p className="text-muted mb-2">Project</p>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">Name:</small>
|
||||
<p className="fw-light mb-1">{data?.project?.name}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">Organization</small>{" "}
|
||||
<p className="fw-light mb-1"> {data?.organization?.name}</p>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-column flex-md-row gap-3 my-1">
|
||||
<div>
|
||||
<small className="text-secondary">Email:</small>
|
||||
<p className="fw-light mb-0">{data?.organization?.email}</p>
|
||||
</div>
|
||||
<div>
|
||||
<small className="text-secondary">Contact:</small>{" "}
|
||||
<p className="fw-light mb-0">
|
||||
{data?.organization?.contactNumber}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<small className="text-secondary">Address:</small>{" "}
|
||||
<p className="fw-light">{data?.organization?.address}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-md-6">
|
||||
<div className="text-start h-auto">
|
||||
<p className="text-muted mb-2">Supplier</p>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">Name:</small>
|
||||
<p className="fw-light mb-1">{data?.supplier?.name}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">Contact Person:</small>
|
||||
<p className="fw-light mb-1">{data?.supplier?.contactPerson}</p>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-column flex-md-row gap-3 my-1">
|
||||
<div>
|
||||
<small className="text-secondary">Email:</small>
|
||||
<p className="fw-light mb-0">{data?.supplier?.email}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">Contact:</small>
|
||||
<p className="fw-light mb-0">{data?.supplier?.contactNumber}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">Address:</small>
|
||||
<p className="fw-light">{data?.supplier?.address}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<div className="text-start h-auto">
|
||||
<p className="text-muted mb-2">Invoice Details</p>
|
||||
|
||||
<div className="row g-3">
|
||||
{/* Left column */}
|
||||
<div className="col-12 col-sm-6">
|
||||
<div>
|
||||
<small className="text-secondary">Invoice No:</small>
|
||||
<p className="fw-light mb-1">{data?.invoiceNumber}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">Proforma No:</small>
|
||||
<p className="fw-light mb-1">{data?.proformaInvoiceNumber}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">E-Way Bill:</small>
|
||||
<p className="fw-light mb-1">{data?.eWayBillNumber}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">PO No:</small>
|
||||
<p className="fw-light mb-1">{data?.purchaseOrderNumber}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right column */}
|
||||
<div className="col-12 col-sm-6">
|
||||
<div>
|
||||
<small className="text-secondary">Invoice Date:</small>
|
||||
<p className="fw-light mb-1">
|
||||
{formatUTCToLocalTime(data?.invoiceDate)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">Proforma Date:</small>
|
||||
<p className="fw-light mb-1">
|
||||
{formatUTCToLocalTime(data?.proformaInvoiceDate)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">E-Way Date:</small>
|
||||
<p className="fw-light mb-1">
|
||||
{formatUTCToLocalTime(data?.eWayBillDate)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<small className="text-secondary">PO Date:</small>
|
||||
<p className="fw-light">
|
||||
{formatUTCToLocalTime(data?.purchaseOrderDate)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-md-6">
|
||||
<div className="text-start h-auto">
|
||||
<p className="text-muted mb-2">Amount Summary</p>
|
||||
|
||||
<div className="d-flex justify-content-between">
|
||||
<small className="text-secondary">Base Amount</small>
|
||||
<p className="fw-light mb-1">₹ {data?.baseAmount}</p>
|
||||
</div>
|
||||
|
||||
<div className="d-flex justify-content-between">
|
||||
<small className="text-secondary">Tax</small>
|
||||
<p className="fw-light mb-1">₹ {data?.taxAmount}</p>
|
||||
</div>
|
||||
|
||||
<div className="d-flex justify-content-between">
|
||||
<small className="text-secondary">Transport</small>
|
||||
<p className="fw-light mb-1">₹ {data?.transportCharges}</p>
|
||||
</div>
|
||||
|
||||
<hr className="my-2" />
|
||||
|
||||
<div className="d-flex justify-content-between fs-6 fs-medium">
|
||||
<span>Total</span>
|
||||
<span>₹ {data?.totalAmount}</span>
|
||||
</div>
|
||||
|
||||
<div className="mt-2">
|
||||
<small className="text-secondary">Due Date:</small>
|
||||
<p className="fw-light mb-0">
|
||||
{formatUTCToLocalTime(data?.paymentDueDate)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row mt-3 text-start">
|
||||
<div className="col-md-6 mb-3">
|
||||
<div className=" h-100">
|
||||
<p className="text-secondary mb-2">Billing Address</p>
|
||||
|
||||
<p className="mb-0 fw-light">{data?.billingAddress || "-"}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col-md-6 mb-3 text-start">
|
||||
<div className=" h-100">
|
||||
<p className="text-secondary mb-2">Shipping Address</p>
|
||||
<p className="mb-0 fw-light">{data?.shippingAddress || "-"}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ViewPurchase;
|
||||
@ -38,6 +38,7 @@ export const usePurchase = (id) => {
|
||||
const resp = await PurchaseRepository.GetPurchase(id);
|
||||
return resp.data;
|
||||
},
|
||||
enabled: !!id,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import showToast from "../../services/toastService";
|
||||
import GlobalModel from "../../components/common/GlobalModel";
|
||||
import ManagePurchase from "../../components/purchase/ManagePurchase";
|
||||
import PurchaseList from "../../components/purchase/PurchaseList";
|
||||
import ViewPurchase from "../../components/purchase/ViewPurchase";
|
||||
|
||||
export const PurchaseContext = createContext();
|
||||
export const usePurchaseContext = () => {
|
||||
@ -13,11 +14,20 @@ export const usePurchaseContext = () => {
|
||||
showToast("Please use Innne cntext", "warning");
|
||||
window.location = "/dashboard";
|
||||
}
|
||||
return context;
|
||||
};
|
||||
const PurchasePage = () => {
|
||||
const [searchText, setSearchText] = useState("");
|
||||
const [addePurchase, setAddedPurchase] = useState(false);
|
||||
const [viewPurchaseState, setViewPurchase] = useState({
|
||||
isOpen: false,
|
||||
purchaseId: null,
|
||||
});
|
||||
|
||||
const contextValue = {};
|
||||
const contextValue = {
|
||||
setViewPurchase,
|
||||
};
|
||||
console.log(ViewPurchase);
|
||||
return (
|
||||
<PurchaseContext.Provider value={contextValue}>
|
||||
<div className="container-fluid">
|
||||
@ -30,7 +40,20 @@ const PurchasePage = () => {
|
||||
/>
|
||||
<div className="card">
|
||||
<div className="row p-2">
|
||||
<di className="col-12 text-end">
|
||||
<div className="col-12 col-md-6 text-start">
|
||||
{" "}
|
||||
<label className="mb-0">
|
||||
<input
|
||||
type="search"
|
||||
value={searchText}
|
||||
onChange={(e) => setSearchText(e.target.value)}
|
||||
className="form-control form-control-sm"
|
||||
placeholder="Search Purchase"
|
||||
aria-controls="DataTables_Table_0"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<di className="col-6 text-end">
|
||||
<button
|
||||
className="btn btn-sm btn-primary"
|
||||
onClick={() => setAddedPurchase(true)}
|
||||
@ -41,8 +64,8 @@ const PurchasePage = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PurchaseList />
|
||||
|
||||
<PurchaseList searchString={searchText} />
|
||||
{addePurchase && (
|
||||
<GlobalModel
|
||||
isOpen={addePurchase}
|
||||
size="lg"
|
||||
@ -50,6 +73,19 @@ const PurchasePage = () => {
|
||||
>
|
||||
<ManagePurchase onClose={() => setAddedPurchase(false)} />
|
||||
</GlobalModel>
|
||||
)}
|
||||
|
||||
{viewPurchaseState.isOpen && (
|
||||
<GlobalModel
|
||||
isOpen={viewPurchaseState.isOpen}
|
||||
size="lg"
|
||||
closeModal={() =>
|
||||
setViewPurchase({ isOpen: false, purchaseId: null })
|
||||
}
|
||||
>
|
||||
<ViewPurchase purchaseId={viewPurchaseState.purchaseId} />
|
||||
</GlobalModel>
|
||||
)}
|
||||
</div>
|
||||
</PurchaseContext.Provider>
|
||||
);
|
||||
|
||||
@ -7,7 +7,9 @@ export const PurchaseRepository = {
|
||||
`/api/PurchaseInvoice/list?pageSize=${pageSize}&pageNumber=${pageNumber}&isActive=${isActive}&filter=${filter}&searchString=${searchString}`
|
||||
),
|
||||
|
||||
GetPurchase:(id)=>api.get(`/api/PurchaseInvoice/details/${id}`)
|
||||
GetPurchase: (id) => api.get(`/api/PurchaseInvoice/details/${id}`),
|
||||
UpdatePurchase: (id, data) =>
|
||||
api.patch(`/api/PurchaseInvoice/edit/${id}`, data),
|
||||
};
|
||||
|
||||
// const filterPayload = JSON.stringify({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user