update status
deploy to danak / build_and_deploy (push) Has been cancelled

This commit is contained in:
2026-07-08 19:40:44 +03:30
parent 311f7f55e5
commit 9684b78b9f
5 changed files with 143 additions and 6 deletions
+34 -4
View File
@@ -15,13 +15,17 @@ import DesignerSearch from "../designer/DesignerSearch";
import CategoriesSelect from "../product/components/CategoriesSelect";
import { orderListTabs } from "./constants/orderStatus";
import { getOrderListColumns } from "./components/OrderListColumns";
import { useDeleteOrder, useGetOrders } from "./hooks/useOrderData";
import {
useDeleteOrder,
useGetOrders,
useUpdateOrderStatus,
} from "./hooks/useOrderData";
import {
ORDER_LIST_FILTER_FIELDS,
useOrderListParams,
} from "./hooks/useOrderListParams";
import type { OrderListItemType } from "./types/Types";
import { TabOrderListEnum } from "./enum/OrderEnum";
import { OrderStatusEnum, TabOrderListEnum } from "./enum/OrderEnum";
const countActiveFilters = (params: {
search?: string;
@@ -48,6 +52,8 @@ const OrdersList: FC = () => {
const { data, refetch, isFetching } = useGetOrders(queryParams);
const { mutate: deleteOrder, isPending: isDeleting } = useDeleteOrder();
const { mutate: updateOrderStatus, isPending: isUpdatingStatus } =
useUpdateOrderStatus();
const activeFilterCount = useMemo(() => countActiveFilters(params), [params]);
const hasActiveFilters = activeFilterCount > 0;
@@ -66,9 +72,33 @@ const OrdersList: FC = () => {
[deleteOrder, refetch],
);
const handleUpdateStatus = useCallback(
(id: string, status: OrderStatusEnum) => {
updateOrderStatus(
{ orderId: id, status },
{
onSuccess: () => {
refetch();
toast.success("وضعیت سفارش با موفقیت به‌روزرسانی شد");
},
onError: (error) => {
toast.error(extractErrorMessage(error));
},
},
);
},
[refetch, updateOrderStatus],
);
const columns = useMemo(
() => getOrderListColumns({ onDelete: handleDelete, isDeleting }),
[handleDelete, isDeleting],
() =>
getOrderListColumns({
onDelete: handleDelete,
onUpdateStatus: handleUpdateStatus,
isDeleting,
isUpdatingStatus,
}),
[handleDelete, handleUpdateStatus, isDeleting, isUpdatingStatus],
);
return (
@@ -1,19 +1,54 @@
import { type FC } from "react";
import { type FC, useMemo, useState } from "react";
import { Link } from "react-router-dom";
import { DocumentText, Edit2, Eye, Printer, Receipt21 } from "iconsax-react";
import TrashWithConfrim from "@/components/TrashWithConfrim";
import DefaulModal from "@/components/DefaulModal";
import Select from "@/components/Select";
import Button from "@/components/Button";
import { Paths } from "@/config/Paths";
import { getOrderInvoiceItemRef } from "../utils/orderListUtils";
import type { OrderListItemType } from "../types/Types";
import { OrderStatusEnum } from "../enum/OrderEnum";
import { getOrderStatusLabel } from "../constants/orderStatus";
type Props = {
item: OrderListItemType;
onDelete: (id: string) => void;
onUpdateStatus: (id: string, status: OrderStatusEnum) => void;
isDeleting?: boolean;
isUpdatingStatus?: boolean;
};
const OrderListActions: FC<Props> = ({ item, onDelete, isDeleting }) => {
const OrderListActions: FC<Props> = ({
item,
onDelete,
onUpdateStatus,
isDeleting,
isUpdatingStatus,
}) => {
const [isStatusModalOpen, setIsStatusModalOpen] = useState(false);
const [selectedStatus, setSelectedStatus] = useState<OrderStatusEnum>(
item.status as OrderStatusEnum,
);
const invoiceRef = getOrderInvoiceItemRef(item);
const statusOptions = useMemo(
() =>
Object.values(OrderStatusEnum).map((status) => ({
value: status,
label: getOrderStatusLabel(status),
})),
[],
);
const handleOpenStatusModal = () => {
setSelectedStatus(item.status as OrderStatusEnum);
setIsStatusModalOpen(true);
};
const handleSubmitStatus = () => {
onUpdateStatus(item.id, selectedStatus);
setIsStatusModalOpen(false);
};
return (
<div className="flex items-center gap-2">
@@ -40,11 +75,48 @@ const OrderListActions: FC<Props> = ({ item, onDelete, isDeleting }) => {
<Edit2 size={20} color="#0037FF" />
</Link>
<button
type="button"
title="تغییر وضعیت سفارش"
onClick={handleOpenStatusModal}
className="inline-flex"
>
<Receipt21 size={20} color="#8C90A3" />
</button>
<TrashWithConfrim
onDelete={() => onDelete(item.id)}
isloading={isDeleting}
colorIcon="red"
/>
<DefaulModal
open={isStatusModalOpen}
close={() => setIsStatusModalOpen(false)}
title_header="تغییر وضعیت سفارش"
isHeader
>
<div className="mt-6 space-y-6">
<Select
label="وضعیت سفارش"
value={selectedStatus}
onChange={(e) => setSelectedStatus(e.target.value as OrderStatusEnum)}
items={statusOptions}
/>
<div className="flex justify-center gap-3">
<Button
label="ثبت"
onClick={handleSubmitStatus}
isLoading={isUpdatingStatus}
/>
<Button
label="لغو"
className="border border-primary bg-transparent text-black"
onClick={() => setIsStatusModalOpen(false)}
/>
</div>
</div>
</DefaulModal>
</div>
);
};
@@ -6,6 +6,7 @@ import {
} from "../constants/orderStatus";
import OrderListActions from "./OrderListActions";
import type { OrderListItemType } from "../types/Types";
import type { OrderStatusEnum } from "../enum/OrderEnum";
const getCustomerName = (item: OrderListItemType) => {
const user = item.user;
@@ -27,12 +28,16 @@ const getDesignerName = (item: OrderListItemType) => {
type OrderListColumnsOptions = {
onDelete: (id: string) => void;
onUpdateStatus: (id: string, status: OrderStatusEnum) => void;
isDeleting?: boolean;
isUpdatingStatus?: boolean;
};
export const getOrderListColumns = ({
onDelete,
onUpdateStatus,
isDeleting,
isUpdatingStatus,
}: OrderListColumnsOptions): ColumnType<OrderListItemType>[] => [
{
key: "orderNumber",
@@ -85,7 +90,9 @@ export const getOrderListColumns = ({
<OrderListActions
item={item}
onDelete={onDelete}
onUpdateStatus={onUpdateStatus}
isDeleting={isDeleting}
isUpdatingStatus={isUpdatingStatus}
/>
),
},
+18
View File
@@ -5,6 +5,7 @@ import type {
OrderPrintFormType,
UpdateOrderType,
} from "../types/Types";
import type { OrderStatusEnum } from "../enum/OrderEnum";
export const useGetOrders = (params?: api.GetOrdersParams) => {
return useQuery({
@@ -132,3 +133,20 @@ export const useDeleteOrder = () => {
},
});
};
export const useUpdateOrderStatus = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({
orderId,
status,
}: {
orderId: string;
status: OrderStatusEnum;
}) => api.updateOrderStatus(orderId, status),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["orders"] });
},
});
};
+10
View File
@@ -148,3 +148,13 @@ export const deleteOrder = async (orderId: string) => {
const { data } = await axios.delete(`/admin/orders/${orderId}`);
return data;
};
export const updateOrderStatus = async (
orderId: string,
status: OrderStatusEnum,
) => {
const { data } = await axios.post(`/admin/orders/${orderId}/status`, {
status,
});
return data;
};