This commit is contained in:
@@ -15,13 +15,17 @@ import DesignerSearch from "../designer/DesignerSearch";
|
|||||||
import CategoriesSelect from "../product/components/CategoriesSelect";
|
import CategoriesSelect from "../product/components/CategoriesSelect";
|
||||||
import { orderListTabs } from "./constants/orderStatus";
|
import { orderListTabs } from "./constants/orderStatus";
|
||||||
import { getOrderListColumns } from "./components/OrderListColumns";
|
import { getOrderListColumns } from "./components/OrderListColumns";
|
||||||
import { useDeleteOrder, useGetOrders } from "./hooks/useOrderData";
|
import {
|
||||||
|
useDeleteOrder,
|
||||||
|
useGetOrders,
|
||||||
|
useUpdateOrderStatus,
|
||||||
|
} from "./hooks/useOrderData";
|
||||||
import {
|
import {
|
||||||
ORDER_LIST_FILTER_FIELDS,
|
ORDER_LIST_FILTER_FIELDS,
|
||||||
useOrderListParams,
|
useOrderListParams,
|
||||||
} from "./hooks/useOrderListParams";
|
} from "./hooks/useOrderListParams";
|
||||||
import type { OrderListItemType } from "./types/Types";
|
import type { OrderListItemType } from "./types/Types";
|
||||||
import { TabOrderListEnum } from "./enum/OrderEnum";
|
import { OrderStatusEnum, TabOrderListEnum } from "./enum/OrderEnum";
|
||||||
|
|
||||||
const countActiveFilters = (params: {
|
const countActiveFilters = (params: {
|
||||||
search?: string;
|
search?: string;
|
||||||
@@ -48,6 +52,8 @@ const OrdersList: FC = () => {
|
|||||||
|
|
||||||
const { data, refetch, isFetching } = useGetOrders(queryParams);
|
const { data, refetch, isFetching } = useGetOrders(queryParams);
|
||||||
const { mutate: deleteOrder, isPending: isDeleting } = useDeleteOrder();
|
const { mutate: deleteOrder, isPending: isDeleting } = useDeleteOrder();
|
||||||
|
const { mutate: updateOrderStatus, isPending: isUpdatingStatus } =
|
||||||
|
useUpdateOrderStatus();
|
||||||
const activeFilterCount = useMemo(() => countActiveFilters(params), [params]);
|
const activeFilterCount = useMemo(() => countActiveFilters(params), [params]);
|
||||||
const hasActiveFilters = activeFilterCount > 0;
|
const hasActiveFilters = activeFilterCount > 0;
|
||||||
|
|
||||||
@@ -66,9 +72,33 @@ const OrdersList: FC = () => {
|
|||||||
[deleteOrder, refetch],
|
[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(
|
const columns = useMemo(
|
||||||
() => getOrderListColumns({ onDelete: handleDelete, isDeleting }),
|
() =>
|
||||||
[handleDelete, isDeleting],
|
getOrderListColumns({
|
||||||
|
onDelete: handleDelete,
|
||||||
|
onUpdateStatus: handleUpdateStatus,
|
||||||
|
isDeleting,
|
||||||
|
isUpdatingStatus,
|
||||||
|
}),
|
||||||
|
[handleDelete, handleUpdateStatus, isDeleting, isUpdatingStatus],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,19 +1,54 @@
|
|||||||
import { type FC } from "react";
|
import { type FC, useMemo, useState } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { DocumentText, Edit2, Eye, Printer, Receipt21 } from "iconsax-react";
|
import { DocumentText, Edit2, Eye, Printer, Receipt21 } from "iconsax-react";
|
||||||
import TrashWithConfrim from "@/components/TrashWithConfrim";
|
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 { Paths } from "@/config/Paths";
|
||||||
import { getOrderInvoiceItemRef } from "../utils/orderListUtils";
|
import { getOrderInvoiceItemRef } from "../utils/orderListUtils";
|
||||||
import type { OrderListItemType } from "../types/Types";
|
import type { OrderListItemType } from "../types/Types";
|
||||||
|
import { OrderStatusEnum } from "../enum/OrderEnum";
|
||||||
|
import { getOrderStatusLabel } from "../constants/orderStatus";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
item: OrderListItemType;
|
item: OrderListItemType;
|
||||||
onDelete: (id: string) => void;
|
onDelete: (id: string) => void;
|
||||||
|
onUpdateStatus: (id: string, status: OrderStatusEnum) => void;
|
||||||
isDeleting?: boolean;
|
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 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 (
|
return (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@@ -40,11 +75,48 @@ const OrderListActions: FC<Props> = ({ item, onDelete, isDeleting }) => {
|
|||||||
<Edit2 size={20} color="#0037FF" />
|
<Edit2 size={20} color="#0037FF" />
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
title="تغییر وضعیت سفارش"
|
||||||
|
onClick={handleOpenStatusModal}
|
||||||
|
className="inline-flex"
|
||||||
|
>
|
||||||
|
<Receipt21 size={20} color="#8C90A3" />
|
||||||
|
</button>
|
||||||
|
|
||||||
<TrashWithConfrim
|
<TrashWithConfrim
|
||||||
onDelete={() => onDelete(item.id)}
|
onDelete={() => onDelete(item.id)}
|
||||||
isloading={isDeleting}
|
isloading={isDeleting}
|
||||||
colorIcon="red"
|
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>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
} from "../constants/orderStatus";
|
} from "../constants/orderStatus";
|
||||||
import OrderListActions from "./OrderListActions";
|
import OrderListActions from "./OrderListActions";
|
||||||
import type { OrderListItemType } from "../types/Types";
|
import type { OrderListItemType } from "../types/Types";
|
||||||
|
import type { OrderStatusEnum } from "../enum/OrderEnum";
|
||||||
|
|
||||||
const getCustomerName = (item: OrderListItemType) => {
|
const getCustomerName = (item: OrderListItemType) => {
|
||||||
const user = item.user;
|
const user = item.user;
|
||||||
@@ -27,12 +28,16 @@ const getDesignerName = (item: OrderListItemType) => {
|
|||||||
|
|
||||||
type OrderListColumnsOptions = {
|
type OrderListColumnsOptions = {
|
||||||
onDelete: (id: string) => void;
|
onDelete: (id: string) => void;
|
||||||
|
onUpdateStatus: (id: string, status: OrderStatusEnum) => void;
|
||||||
isDeleting?: boolean;
|
isDeleting?: boolean;
|
||||||
|
isUpdatingStatus?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getOrderListColumns = ({
|
export const getOrderListColumns = ({
|
||||||
onDelete,
|
onDelete,
|
||||||
|
onUpdateStatus,
|
||||||
isDeleting,
|
isDeleting,
|
||||||
|
isUpdatingStatus,
|
||||||
}: OrderListColumnsOptions): ColumnType<OrderListItemType>[] => [
|
}: OrderListColumnsOptions): ColumnType<OrderListItemType>[] => [
|
||||||
{
|
{
|
||||||
key: "orderNumber",
|
key: "orderNumber",
|
||||||
@@ -85,7 +90,9 @@ export const getOrderListColumns = ({
|
|||||||
<OrderListActions
|
<OrderListActions
|
||||||
item={item}
|
item={item}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
onUpdateStatus={onUpdateStatus}
|
||||||
isDeleting={isDeleting}
|
isDeleting={isDeleting}
|
||||||
|
isUpdatingStatus={isUpdatingStatus}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type {
|
|||||||
OrderPrintFormType,
|
OrderPrintFormType,
|
||||||
UpdateOrderType,
|
UpdateOrderType,
|
||||||
} from "../types/Types";
|
} from "../types/Types";
|
||||||
|
import type { OrderStatusEnum } from "../enum/OrderEnum";
|
||||||
|
|
||||||
export const useGetOrders = (params?: api.GetOrdersParams) => {
|
export const useGetOrders = (params?: api.GetOrdersParams) => {
|
||||||
return useQuery({
|
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"] });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -148,3 +148,13 @@ export const deleteOrder = async (orderId: string) => {
|
|||||||
const { data } = await axios.delete(`/admin/orders/${orderId}`);
|
const { data } = await axios.delete(`/admin/orders/${orderId}`);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateOrderStatus = async (
|
||||||
|
orderId: string,
|
||||||
|
status: OrderStatusEnum,
|
||||||
|
) => {
|
||||||
|
const { data } = await axios.post(`/admin/orders/${orderId}/status`, {
|
||||||
|
status,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user