Untitled
unknown
plain_text
2 years ago
14 kB
12
Indexable
import { SendOutlined } from "@ant-design/icons";
import {
Button,
Form,
Input,
Select,
Table,
Tooltip,
Typography,
message,
} from "antd";
import { useEffect, useState } from "react";
import { NavLink } from "react-router-dom";
import StatusLabel from "../../statusLabel";
import {
getOrderByGatheringDep,
updateOrder,
} from "../../../repository/order/order";
import { useStoreState } from "../../../store/hook";
import { getDepartmentById } from "../../../repository/department/department";
const GatheringOrderTable = () => {
const [messageApi, contextHolder] = message.useMessage();
const [form] = Form.useForm();
const [isRowSelected, setIsRowSelected] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const currentUser = useStoreState((state) => state.currentUser);
const [allOrders, setAllOrders] = useState([]);
const [selectedRows, setSelectedRows] = useState([]);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const [searchValue, setSearchValue] = useState("");
const [filterValue, setFilterValue] = useState("incoming orders");
const [ordersData, setOrdersData] = useState([]);
const [isOrderUpdated, setIsOrderUpdated] = useState(false);
const [currentDepInfo, setCurrentDepInfo] = useState({});
const [description, setDescription] = useState("");
useEffect(() => {
const fetchCurrentDepInfo = async () => {
const res = await getDepartmentById(currentUser.workDepartment._id);
if (res?.status === 200) {
setCurrentDepInfo(res.data.data.gatherPoint);
}
};
fetchCurrentDepInfo();
}, []);
console.log("selectedRows: ", selectedRows);
// Handle format selected orders to send to server
const handleFormatConfirmOrders = (selectedRows) => {
const formattedOrders = selectedRows.map((order) => {
if (
order.status === "processing" &&
order.next_department._id === currentUser.workDepartment._id
) {
return {
orderId: order._id,
current_department: currentUser.workDepartment._id,
description: `Đơn hàng đã đến ${currentUser.workDepartment.name}`,
};
}
});
return {
type: "confirm",
orders: [...formattedOrders],
};
};
const handleFormatTransferOrders = (selectedRows) => {
const formattedOrders = selectedRows.map((order) => {
if (
order.status === "accepted" &&
order.current_department._id === currentUser.workDepartment._id
) {
return {
orderId: order._id,
next_department: order.next_department,
description: `Đơn hàng đang đến ${order.description}`,
};
}
});
return {
type: "transfer",
orders: [...formattedOrders],
};
};
// Handle when user clicks confirm button
const handleOnConfirm = async () => {
// setIsLoading(true);
if (filterValue === "incoming orders") {
const ordersData = handleFormatConfirmOrders(selectedRows);
setOrdersData(ordersData.orders);
console.log(ordersData);
if (ordersData.orders.length > 0 && ordersData.type === "confirm") {
const res = await updateOrder(ordersData);
console.log("update order: ", res);
if (res.status === 200) {
messageApi.success("Xác nhận đơn hàng thành công");
setIsLoading(false);
setIsOrderUpdated(!isOrderUpdated);
} else {
messageApi.error("Xác nhận đơn hàng thất bại");
setIsLoading(false);
}
}
} else if (filterValue === "outgoing orders") {
const ordersData = handleFormatTransferOrders(selectedRows);
setOrdersData(ordersData.orders);
console.log(ordersData);
}
};
// Fetch all orders by department id that have current department as this department
useEffect(() => {
const fetchOrderByGatheringDep = async (data) => {
setIsLoading(true);
const res = await getOrderByGatheringDep(data);
if (res?.status === 200) {
setIsLoading(false);
setAllOrders(res.data.orders);
setIsRowSelected(false);
setSelectedRows([]);
setSelectedRowKeys([]);
} else {
setIsLoading(false);
messageApi.error("Lấy danh sách đơn hàng thất bại");
}
};
if (filterValue === "incoming orders") {
const data = {
condition: {
next_department: currentUser.workDepartment._id,
status: "processing",
},
};
fetchOrderByGatheringDep(data);
} else if (filterValue === "outgoing orders") {
const data = {
condition: {
current_department: currentUser.workDepartment._id,
},
};
fetchOrderByGatheringDep(data);
}
}, [currentUser.workDepartment._id, messageApi, isOrderUpdated, filterValue]);
const columns = [
{
title: "Mã đơn hàng",
dataIndex: "_id",
key: "orderCode",
render: (value, record) => {
return (
<NavLink to={`/employee/order-detail/${record._id}`}>{value}</NavLink>
);
},
},
{
title: "Người gửi",
dataIndex: "sender",
key: "senderName",
width: "14%",
filteredValue: [searchValue],
onFilter: (value, record) =>
String(record.sender).toLowerCase().includes(value.toLowerCase()) ||
String(record.receiver).toLowerCase().includes(value.toLowerCase()) ||
String(record._id).toLowerCase().includes(value.toLowerCase()),
},
{
title: "Người nhận",
dataIndex: "receiver",
key: "receiverName",
width: "14%",
},
{
title: "Trạng thái",
dataIndex: "status",
key: "status",
render: (value) => {
return <StatusLabel status={value} />;
},
width: "14%",
},
{
title: "Ngày gửi hàng",
dataIndex: "createdAt",
key: "createdAt",
render: (value) => {
return <div>{new Date(value).toLocaleDateString("vi-VN")}</div>;
},
width: "16%",
},
{
key: "action",
render: (value, record) => (
<div
className={`flex items-center ${
record.status === "rejected" ? "justify-between" : "justify-center"
}`}
>
{record?.status === "rejected" && (
<Tooltip
title={<span className="text-lg text-black">Gửi lại</span>}
color="white"
>
<span className="text-lg cursor-pointer hover:text-[#1e91cf]">
<SendOutlined />
</span>
</Tooltip>
)}
</div>
),
width: "3%",
fixed: "right",
},
];
// Handle format linked departments so they don't include send department of order
const linkedDepOptions = (sendDepId) => {
const res = currentDepInfo.linkDepartments
?.filter((item) => item.departmentId !== sendDepId)
.map((dep) => {
return {
value: dep.departmentId,
label: dep.name,
};
});
return res;
};
if (filterValue === "outgoing orders") {
columns.splice(1, 0, {
title: "Điểm đến tiếp theo",
dataIndex: "newData",
key: "nextDepartment",
width: "16%",
render: (value, record) => {
return (
<Form>
<Form.Item>
<Select
disabled={
!selectedRows.map((order) => order._id).includes(record._id)
}
onSelect={(selectedNextDep) => {
console.log(selectedNextDep);
const tmp = linkedDepOptions(record.send_department._id);
const des = tmp.find((item) => item.value === selectedNextDep).label;
// Add next department to each order when user selects from input
setSelectedRows((prevSelectedRows) => {
console.log(prevSelectedRows);
return prevSelectedRows.map((order) =>
order._id === record._id
? { ...order, next_department: selectedNextDep, description: des }
: order
);
});
// const tmp = linkedDepOptions(record.send_department._id);
// const des = tmp.find((item) => item.value === selectedNextDep).label;
// console.log(des);
// setDescription(des.label);
}}
size="large"
options={linkedDepOptions(record.send_department._id)}
placeholder={
record.next_department?.name || "Chọn điểm chuyển tiếp"
}
/>
</Form.Item>
</Form>
);
},
});
}
// Handle select rows of orders in table
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
// New selected rows after onChange event
const newSelectedRows = selectedRows;
console.log("fafef", selectedRows);
setSelectedRows((prevSelectedRows) => {
// Find the rows that were not previously selected
const addedRows = newSelectedRows.filter(
(newRow) =>
!prevSelectedRows.some((oldRow) => oldRow._id === newRow._id)
);
// Find the rows that were previously selected but are not selected now
const removedRows = prevSelectedRows.filter(
(oldRow) =>
!newSelectedRows.some((newRow) => oldRow._id === newRow._id)
);
// Return the new selected rows, excluding the removed rows
return prevSelectedRows
.concat(addedRows)
.filter((row) => !removedRows.includes(row));
});
setSelectedRowKeys(selectedRowKeys);
if (selectedRows.length > 0) {
setIsRowSelected(true);
// setSelectedRows(selectedRows);
} else {
setIsRowSelected(false);
setSelectedRows([]);
setSelectedRowKeys([]);
}
},
getCheckboxProps: (record) => ({
// Disable check box when order is processing and being transported to another department
disabled:
record.status === "processing" &&
record.next_department !== currentUser.workDepartment._id,
// || record.next_department === null,
// &&
// record.next_department !== currentUser.workDepartment._id,
// Column configuration not to be checked
status: record.status,
}),
};
return (
<>
{contextHolder}
<div className="w-full h-full">
<div className="w-full p-3 flex items-center">
<div className="w-full flex items-center gap-x-3">
<p className="font-semibold text-xl text-[#266191]">Bộ lọc</p>
<Form
form={form}
initialValues={{
filterValue: "incoming orders",
}}
>
<Form.Item noStyle className="w-full" name="filterValue">
<Select
onChange={(value) => setFilterValue(value)}
placeholder="Chọn trạng thái"
size="large"
options={[
{
value: "incoming orders",
label: "Chờ xác nhận",
},
{
value: "outgoing orders",
label: "Đơn chuyển tiếp",
},
]}
/>
</Form.Item>
</Form>
</div>
<Input.Search
className="max-w-[42%] w-full"
size="large"
placeholder="Nhập mã đơn hàng, tên người gửi, người nhận"
onSearch={(value) => setSearchValue(value)}
onChange={(e) => setSearchValue(e.target.value)}
/>
</div>
<Table
loading={isLoading}
rowSelection={{
...rowSelection,
selectedRowKeys,
}}
rowKey={(row) => row._id}
columns={columns}
dataSource={allOrders}
bordered
scroll={{ x: 1600 }}
pagination={{ pageSize: 10, position: ["bottomCenter"] }}
title={() => (
<div className="flex items-center justify-between">
<Typography.Title className="mb-0" level={3}>
Danh sách đơn hàng
</Typography.Title>
</div>
)}
/>
<div className="w-full flex items-center justify-between my-6">
<p className="font-semibold text-xl text-[#266191] bg-neutral-300 p-2 rounded-lg">
Đã chọn:{" "}
<span className="text-orange-600">
{selectedRows.length}/{allOrders.length}
</span>
</p>
<Button
loading={isLoading}
onClick={handleOnConfirm}
htmlType="submit"
className="float-right"
type="primary"
disabled={
!isRowSelected ||
selectedRows.map((item) => item?.next_department).includes(null)
}
size="large"
>
Xác nhận
</Button>
</div>
</div>
</>
);
};
export default GatheringOrderTable;
Editor is loading...
Leave a Comment