Inventory
This commit is contained in:
parent
d0b9aa60e9
commit
3ada9ea922
@ -8,8 +8,7 @@ import debounce from "lodash.debounce";
|
|||||||
const Inventory = () => {
|
const Inventory = () => {
|
||||||
const token = isAutheticated();
|
const token = isAutheticated();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
// const [inventoryData, setInventoryData] = useState([]);
|
const [inventoryData, setInventoryData] = useState([]);
|
||||||
const [filteredData, setFilteredData] = useState([]);
|
|
||||||
|
|
||||||
const nameRef = useRef();
|
const nameRef = useRef();
|
||||||
const startDateRef = useRef();
|
const startDateRef = useRef();
|
||||||
@ -31,12 +30,14 @@ const Inventory = () => {
|
|||||||
show: itemPerPage,
|
show: itemPerPage,
|
||||||
startDate: startDateRef.current?.value || "",
|
startDate: startDateRef.current?.value || "",
|
||||||
endDate: endDateRef.current?.value || "",
|
endDate: endDateRef.current?.value || "",
|
||||||
|
name: nameRef.current?.value || "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const transformedData =
|
const transformedData =
|
||||||
response.data?.inventories?.map((entry) => ({
|
response.data?.inventories?.map((entry) => ({
|
||||||
id: entry._id,
|
id: entry._id,
|
||||||
|
uniqueId: entry.uniqueId,
|
||||||
tradeName:
|
tradeName:
|
||||||
entry.addedForData?.shippingAddress?.tradeName ||
|
entry.addedForData?.shippingAddress?.tradeName ||
|
||||||
entry.addedForData?.trade_name ||
|
entry.addedForData?.trade_name ||
|
||||||
@ -51,13 +52,9 @@ const Inventory = () => {
|
|||||||
createdAt: entry.createdAt,
|
createdAt: entry.createdAt,
|
||||||
updatedAt: entry.updatedAt,
|
updatedAt: entry.updatedAt,
|
||||||
})) || [];
|
})) || [];
|
||||||
|
|
||||||
// setInventoryData(transformedData);
|
setInventoryData(transformedData);
|
||||||
setTotalData(response.data?.total_data || 0);
|
setTotalData(response.data?.total_data || 0);
|
||||||
|
|
||||||
// Apply the filter after data is fetched
|
|
||||||
filterData(transformedData);
|
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const msg = err?.response?.data?.msg || "Something went wrong!";
|
const msg = err?.response?.data?.msg || "Something went wrong!";
|
||||||
swal({
|
swal({
|
||||||
@ -72,14 +69,6 @@ const Inventory = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const filterData = (data) => {
|
|
||||||
const tradeName = nameRef.current?.value || "";
|
|
||||||
const filtered = data.filter((entry) =>
|
|
||||||
entry.tradeName.toLowerCase().includes(tradeName.toLowerCase())
|
|
||||||
);
|
|
||||||
setFilteredData(filtered);
|
|
||||||
};
|
|
||||||
|
|
||||||
const debouncedSearch = useCallback(
|
const debouncedSearch = useCallback(
|
||||||
debounce(() => {
|
debounce(() => {
|
||||||
setCurrentPage(1);
|
setCurrentPage(1);
|
||||||
@ -177,7 +166,7 @@ const Inventory = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="table-responsive table-shoot mt-3">
|
<div className="table-responsive table-shoot mt-3">
|
||||||
<table
|
{/* <table
|
||||||
className="table table-centered table-nowrap"
|
className="table table-centered table-nowrap"
|
||||||
style={{ border: "1px solid" }}
|
style={{ border: "1px solid" }}
|
||||||
>
|
>
|
||||||
@ -206,11 +195,11 @@ const Inventory = () => {
|
|||||||
Loading...
|
Loading...
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
) : filteredData.length > 0 ? (
|
) : inventoryData.length > 0 ? (
|
||||||
filteredData.map((entry, i) =>
|
inventoryData.map((entry, i) =>
|
||||||
entry.products.map((product, j) => (
|
entry.products.map((product, j) => (
|
||||||
<tr key={`${i}-${j}`}>
|
<tr key={`${i}-${j}`}>
|
||||||
<td className="text-start">{entry.id}</td>
|
<td className="text-start">{entry.uniqueId}</td>
|
||||||
<td className="text-start">
|
<td className="text-start">
|
||||||
{new Date(entry.createdAt).toLocaleString(
|
{new Date(entry.createdAt).toLocaleString(
|
||||||
"en-IN",
|
"en-IN",
|
||||||
@ -282,9 +271,215 @@ const Inventory = () => {
|
|||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table> */}
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<table
|
||||||
|
className="table table-centered table-nowrap"
|
||||||
|
style={{
|
||||||
|
border: "1px solid",
|
||||||
|
borderCollapse: "collapse",
|
||||||
|
}} // Ensure borders collapse for clean lines
|
||||||
|
>
|
||||||
|
<thead
|
||||||
|
className="thead-light"
|
||||||
|
style={{ background: "#ecdddd" }}
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
ID
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Date
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Time
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Trade Name
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
PD/RD
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Product SKU
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Product Name
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Sale
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Inventory
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Actions
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
{loading ? (
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
className="text-center"
|
||||||
|
colSpan="10"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
Loading...
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : inventoryData.length > 0 ? (
|
||||||
|
inventoryData.map((entry, i) =>
|
||||||
|
entry.products.map((product, j) => (
|
||||||
|
<tr key={`${i}-${j}`}>
|
||||||
|
{/* Only show ID, Date, Time, Trade Name, PD/RD, and Actions on the first row of each entry */}
|
||||||
|
{j === 0 && (
|
||||||
|
<>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{entry.uniqueId}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{new Date(entry.createdAt).toLocaleString(
|
||||||
|
"en-IN",
|
||||||
|
{
|
||||||
|
month: "short",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{new Date(entry.createdAt).toLocaleString(
|
||||||
|
"en-IN",
|
||||||
|
{
|
||||||
|
hour: "numeric",
|
||||||
|
minute: "numeric",
|
||||||
|
hour12: true,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{entry.tradeName}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{entry.designation}
|
||||||
|
</td>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{/* Product details */}
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{product.SKU}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{product.ProductName}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{product.Sale}
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
{product.Inventory}
|
||||||
|
</td>
|
||||||
|
{/* Actions: only show on the first row of each entry */}
|
||||||
|
{j === 0 && (
|
||||||
|
<td
|
||||||
|
className="text-start"
|
||||||
|
rowSpan={entry.products.length}
|
||||||
|
style={{ border: "1px solid" }}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
to={`/inventory/view/${entry.id}`}
|
||||||
|
state={{ product }}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
color: "white",
|
||||||
|
marginRight: "1rem",
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary btn-sm waves-effect waves-light btn-table mx-1 mt-1"
|
||||||
|
>
|
||||||
|
View
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
|
</tr>
|
||||||
|
))
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<tr className="text-center">
|
||||||
|
<td colSpan="10" style={{ border: "1px solid" }}>
|
||||||
|
<h5>No Data Available...</h5>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
<div className="row mt-20">
|
<div className="row mt-20">
|
||||||
<div className="col-sm-12 col-md-6 mb-20">
|
<div className="col-sm-12 col-md-6 mb-20">
|
||||||
<div
|
<div
|
||||||
@ -293,65 +488,92 @@ const Inventory = () => {
|
|||||||
role="status"
|
role="status"
|
||||||
aria-live="polite"
|
aria-live="polite"
|
||||||
>
|
>
|
||||||
Showing {Math.min(itemPerPage * currentPage, totalData)} of {totalData} entries
|
Showing {currentPage * itemPerPage - itemPerPage + 1} to{" "}
|
||||||
|
{Math.min(currentPage * itemPerPage, totalData)} of{" "}
|
||||||
|
{totalData} entries
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-sm-12 col-md-6 text-md-end">
|
|
||||||
<div
|
<div className="col-sm-12 col-md-6">
|
||||||
className="dataTables_paginate paging_simple_numbers"
|
<div className="d-flex">
|
||||||
id="datatable_paginate"
|
<ul className="pagination ms-auto">
|
||||||
>
|
|
||||||
<ul className="pagination pagination-rounded">
|
|
||||||
<li
|
<li
|
||||||
className={`paginate_button page-item previous ${currentPage === 1 ? "disabled" : ""
|
className={
|
||||||
}`}
|
currentPage === 1
|
||||||
|
? "paginate_button page-item previous disabled"
|
||||||
|
: "paginate_button page-item previous"
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<a
|
<span
|
||||||
href="#"
|
|
||||||
className="page-link"
|
className="page-link"
|
||||||
onClick={() => {
|
style={{ cursor: "pointer" }}
|
||||||
if (currentPage > 1) {
|
onClick={() => setCurrentPage((prev) => prev - 1)}
|
||||||
setCurrentPage((prev) => prev - 1);
|
disabled={loading}
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Previous
|
Previous
|
||||||
</a>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{[...Array(Math.ceil(totalData / itemPerPage))].map(
|
{!(currentPage - 1 < 1) && (
|
||||||
(_, index) => (
|
<li className="paginate_button page-item">
|
||||||
<li
|
<span
|
||||||
key={index}
|
className="page-link"
|
||||||
className={`paginate_button page-item ${index + 1 === currentPage ? "active" : ""
|
style={{ cursor: "pointer" }}
|
||||||
}`}
|
onClick={(e) =>
|
||||||
|
setCurrentPage((prev) => prev - 1)
|
||||||
|
}
|
||||||
|
disabled={loading}
|
||||||
>
|
>
|
||||||
<a
|
{currentPage - 1}
|
||||||
href="#"
|
</span>
|
||||||
className="page-link"
|
</li>
|
||||||
onClick={() => setCurrentPage(index + 1)}
|
)}
|
||||||
>
|
|
||||||
{index + 1}
|
<li className="paginate_button page-item active">
|
||||||
</a>
|
<span
|
||||||
</li>
|
className="page-link"
|
||||||
)
|
style={{ cursor: "pointer" }}
|
||||||
|
>
|
||||||
|
{currentPage}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
totalData - 1
|
||||||
|
) && (
|
||||||
|
<li className="paginate_button page-item ">
|
||||||
|
<span
|
||||||
|
className="page-link"
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentPage((prev) => prev + 1);
|
||||||
|
}}
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
{currentPage + 1}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<li
|
<li
|
||||||
className={`paginate_button page-item next ${currentPage === Math.ceil(totalData / itemPerPage) ? "disabled" : ""
|
className={
|
||||||
}`}
|
!(
|
||||||
|
(currentPage + 1) * itemPerPage - itemPerPage >
|
||||||
|
totalData - 1
|
||||||
|
)
|
||||||
|
? "paginate_button page-item next"
|
||||||
|
: "paginate_button page-item next disabled"
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<a
|
<span
|
||||||
href="#"
|
|
||||||
className="page-link"
|
className="page-link"
|
||||||
onClick={() => {
|
style={{ cursor: "pointer" }}
|
||||||
if (currentPage < Math.ceil(totalData / itemPerPage)) {
|
onClick={() => setCurrentPage((prev) => prev + 1)}
|
||||||
setCurrentPage((prev) => prev + 1);
|
disabled={loading}
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Next
|
Next
|
||||||
</a>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user