Files
shop-admin/src/components/ShipmentManagementModal.tsx
T
2025-12-02 16:54:18 +03:30

186 lines
8.6 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react';
import DefaulModal from '@/components/DefaulModal';
import Button from '@/components/Button';
import Select from '@/components/Select';
import { type Shipper, type ShipmentMethod } from '@/pages/shipment/types/Types';
import { useGetShipment, useGetAdminShop, useAddShipmentToAdmin, useRemoveShipmentFromAdmin } from '@/pages/shipment/hooks/useShipmentData';
import { toast } from 'react-toastify';
import { extractErrorMessage } from '@/helpers/utils';
interface ShipmentManagementModalProps {
isManagementModalOpen: boolean;
setIsManagementModalOpen: (open: boolean) => void;
}
export const ShipmentManagementModal = ({
isManagementModalOpen,
setIsManagementModalOpen,
}: ShipmentManagementModalProps) => {
const [selectedShipment, setSelectedShipment] = useState('');
const { data: shipmentData } = useGetShipment(1);
const { data: adminShopData, refetch: refetchAdminShop } = useGetAdminShop();
const addShipmentToAdminMutation = useAddShipmentToAdmin();
const removeShipmentFromAdminMutation = useRemoveShipmentFromAdmin();
const shipments = shipmentData?.results?.shipper || [];
const adminShipments: ShipmentMethod[] = adminShopData?.results?.data?.shipmentMethod || (adminShopData?.results as { shop?: { shipmentMethod?: ShipmentMethod[] } })?.shop?.shipmentMethod || [];
// لیست روش‌های ارسال که هنوز به ادمین اضافه نشده‌اند
const availableShipments = shipments.filter((shipment: Shipper) => {
// اگر adminShipments خالی باشد، همه shipments را نشان بده
if (adminShipments.length === 0) {
return true;
}
// اگر shipment._id وجود داشته باشد، از _id برای مقایسه استفاده کن
if (shipment._id != null) {
return !adminShipments.some((adminShipment: ShipmentMethod) =>
adminShipment._id != null && adminShipment._id === shipment._id
);
}
// اگر _id وجود نداشته باشد، از name برای مقایسه استفاده کن
return !adminShipments.some((adminShipment: ShipmentMethod) =>
adminShipment.name === shipment.name
);
});
const handleAddShipmentToAdmin = async () => {
if (!selectedShipment) return;
// اگر value با "index-" شروع شود، یعنی _id وجود ندارد
if (selectedShipment.startsWith('index-')) {
const index = parseInt(selectedShipment.replace('index-', ''));
const shipment = availableShipments[index];
if (!shipment || shipment._id == null) {
toast.error('شناسه روش ارسال یافت نشد. لطفاً صفحه را رفرش کنید.');
return;
}
await addShipmentToAdminMutation.mutateAsync(Number(shipment._id), {
onError: (error) => {
toast.error(extractErrorMessage(error));
},
onSuccess: () => {
refetchAdminShop();
setSelectedShipment('');
toast.success('روش ارسال با موفقیت اضافه شد');
}
});
return;
}
const shipmentId = Number(selectedShipment);
if (isNaN(shipmentId)) {
toast.error('شناسه روش ارسال نامعتبر است');
return;
}
await addShipmentToAdminMutation.mutateAsync(shipmentId, {
onError: (error) => {
toast.error(extractErrorMessage(error));
},
onSuccess: () => {
refetchAdminShop();
setSelectedShipment('');
toast.success('روش ارسال با موفقیت اضافه شد');
}
});
};
const handleRemoveShipmentFromAdmin = async (shipmentId: string) => {
await removeShipmentFromAdminMutation.mutateAsync(Number(shipmentId), {
onError: (error) => {
toast.error(extractErrorMessage(error));
},
onSuccess: () => {
refetchAdminShop();
toast.success('روش ارسال با موفقیت حذف شد');
}
});
};
const getDeliveryTypeText = (type: string) => {
switch (type) {
case 'Standard':
return 'معمولی';
case 'SameDay':
return 'همان روز';
case 'Express':
return 'اکسپرس';
default:
return type;
}
};
return (
<DefaulModal
open={isManagementModalOpen}
close={() => setIsManagementModalOpen(false)}
title_header="مدیریت روش‌های ارسال ادمین"
isHeader={true}
width={800}
>
<div className="space-y-6 w-[400px] mt-5">
{/* بخش اضافه کردن روش ارسال جدید */}
<div className="border-b pb-4">
<h3 className="mb-3">اضافه کردن روش ارسال جدید</h3>
<div className="flex gap-3">
<Select
className="flex-1"
placeholder="انتخاب روش ارسال"
value={selectedShipment}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setSelectedShipment(e.target.value)}
items={availableShipments.map((shipment: Shipper, index: number) => {
// اگر _id وجود داشته باشد، از آن استفاده کن، در غیر این صورت از index
const value = shipment._id != null ? String(shipment._id) : `index-${index}`;
return {
value,
label: shipment.name
};
})}
/>
<Button
label="اضافه کردن"
onClick={handleAddShipmentToAdmin}
isLoading={addShipmentToAdminMutation.isPending}
disabled={!selectedShipment}
className="w-fit whitespace-nowrap"
/>
</div>
</div>
{/* بخش روش‌های ارسال فعال ادمین */}
<div>
<h3 className="mb-3">روشهای ارسال فعال ادمین</h3>
{adminShipments.length === 0 ? (
<p className="text-gray-500 text-center py-8">هیچ روش ارسالی فعالی وجود ندارد</p>
) : (
<div className="space-y-3">
{adminShipments
.filter((shipment: ShipmentMethod) => shipment._id != null)
.map((shipment: ShipmentMethod) => (
<div key={shipment._id} className="flex items-center justify-between p-4 bg-gray-50 rounded-xl">
<div>
<h4 className="font-medium">{shipment.name}</h4>
<p className="text-sm text-gray-600">{shipment.description}</p>
<p className="text-xs text-gray-500 mt-1">
نوع ارسال: {getDeliveryTypeText(shipment.deliveryType)} |
زمان ارسال: {shipment.deliveryTime} روز
</p>
</div>
<Button
variant="danger"
size="sm"
label="حذف"
onClick={() => handleRemoveShipmentFromAdmin(String(shipment._id))}
isLoading={removeShipmentFromAdminMutation.isPending}
className="w-fit"
/>
</div>
))}
</div>
)}
</div>
</div>
</DefaulModal>
);
};