list of request create product
This commit is contained in:
@@ -199,5 +199,6 @@ export const Pages = {
|
|||||||
wholesaleRequests: "/sellers/wholesale-requests",
|
wholesaleRequests: "/sellers/wholesale-requests",
|
||||||
withdrawalRequests: "/sellers/withdrawal-requests",
|
withdrawalRequests: "/sellers/withdrawal-requests",
|
||||||
announcement: "/sellers/announcement",
|
announcement: "/sellers/announcement",
|
||||||
|
requestCreateProduct: "/sellers/request-create-product",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { type FC } from 'react'
|
||||||
|
|
||||||
|
const CategoryLearning = () => {
|
||||||
|
return (
|
||||||
|
<div>CategoryLearning</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CategoryLearning
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
import { type FC, useState } from 'react'
|
||||||
|
import { useGetRequestCreateProduct } from './hooks/useSellerData'
|
||||||
|
import { type ProductRequest } from './types/Types'
|
||||||
|
import PageLoading from '../../components/PageLoading'
|
||||||
|
import Error from '../../components/Error'
|
||||||
|
import PaginationUi from '../../components/PaginationUi'
|
||||||
|
import Td from '../../components/Td'
|
||||||
|
import ProductRequestTableRow from './components/ProductRequestTableRow'
|
||||||
|
import ProductRequestDetailModal from './components/ProductRequestDetailModal'
|
||||||
|
|
||||||
|
const RequestCreateProduct: FC = () => {
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [selectedRequest, setSelectedRequest] = useState<ProductRequest | null>(null);
|
||||||
|
const [isDetailModalOpen, setIsDetailModalOpen] = useState(false);
|
||||||
|
const { data, isLoading, error } = useGetRequestCreateProduct(currentPage);
|
||||||
|
|
||||||
|
const handleRowClick = (request: ProductRequest) => {
|
||||||
|
setSelectedRequest(request);
|
||||||
|
setIsDetailModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<div className="flex justify-center items-center min-h-[400px]">
|
||||||
|
<PageLoading />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<div className="flex justify-center items-center min-h-[400px]">
|
||||||
|
<Error errorText="خطا در بارگذاری درخواستهای ایجاد محصول" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const productRequests = data?.results?.productRequests || [];
|
||||||
|
const pager = data?.results?.pager;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className='relative overflow-x-auto rounded-3xl mt-5 w-full'>
|
||||||
|
<table className='w-full text-sm'>
|
||||||
|
<thead className='thead'>
|
||||||
|
<tr>
|
||||||
|
<Td text={'فروشنده'} />
|
||||||
|
<Td text={'فروشگاه'} />
|
||||||
|
<Td text={'نام محصول'} />
|
||||||
|
<Td text={'برند'} />
|
||||||
|
<Td text={'دستهبندی'} />
|
||||||
|
<Td text={'وضعیت'} />
|
||||||
|
<Td text={'تاریخ ایجاد'} />
|
||||||
|
<Td text={'خدمات درخواست شده'} />
|
||||||
|
<Td text={'عملیات'} />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{productRequests.length === 0 ? (
|
||||||
|
<tr className='tr'>
|
||||||
|
<td colSpan={9} className="text-center py-8 text-gray-500">
|
||||||
|
هیچ درخواست ایجاد محصولی یافت نشد
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : (
|
||||||
|
productRequests.map((request: ProductRequest) => (
|
||||||
|
<ProductRequestTableRow
|
||||||
|
key={request._id}
|
||||||
|
request={request}
|
||||||
|
onClick={() => handleRowClick(request)}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<PaginationUi
|
||||||
|
pager={pager}
|
||||||
|
onPageChange={(page) => {
|
||||||
|
setCurrentPage(page);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ProductRequestDetailModal
|
||||||
|
open={isDetailModalOpen}
|
||||||
|
close={() => setIsDetailModalOpen(false)}
|
||||||
|
request={selectedRequest}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RequestCreateProduct
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
import { type FC } from 'react'
|
||||||
|
import DefaulModal from '@/components/DefaulModal'
|
||||||
|
import { type ProductRequest } from '../types/Types'
|
||||||
|
import StatusWithText from '@/components/StatusWithText'
|
||||||
|
import { Calendar, User as UserIcon, Shop, Tag, Box, MessageSquare, Location, Money } from 'iconsax-react'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
open: boolean
|
||||||
|
close: () => void
|
||||||
|
request: ProductRequest | null
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProductRequestDetailModal: FC<Props> = ({ open, close, request }) => {
|
||||||
|
if (!request) return null
|
||||||
|
|
||||||
|
const getStatusVariant = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'Approved': return 'success'
|
||||||
|
case 'Rejected': return 'error'
|
||||||
|
case 'Pending': return 'warning'
|
||||||
|
case 'Draft': return 'warning'
|
||||||
|
default: return 'warning'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStatusText = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'Approved': return 'تایید شده'
|
||||||
|
case 'Rejected': return 'رد شده'
|
||||||
|
case 'Pending': return 'در انتظار'
|
||||||
|
case 'Draft': return 'پیشنویس'
|
||||||
|
default: return status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDate = (dateString: string) => {
|
||||||
|
if (!dateString) return '-'
|
||||||
|
return new Date(dateString).toLocaleDateString('fa-IR')
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DefaulModal
|
||||||
|
open={open}
|
||||||
|
close={close}
|
||||||
|
isHeader={true}
|
||||||
|
title_header="جزئیات درخواست ایجاد محصول"
|
||||||
|
width={800}
|
||||||
|
>
|
||||||
|
<div className="space-y-6 mt-4">
|
||||||
|
{/* وضعیت درخواست */}
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h3 className="text-lg font-semibold text-gray-900">وضعیت درخواست</h3>
|
||||||
|
<StatusWithText
|
||||||
|
variant={getStatusVariant(request.requestStatus)}
|
||||||
|
text={getStatusText(request.requestStatus)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* اطلاعات فروشنده */}
|
||||||
|
<div className="bg-gray-50 rounded-lg p-4">
|
||||||
|
<h4 className="text-md font-medium text-gray-900 mb-3 flex items-center gap-2">
|
||||||
|
<UserIcon size={20} color="#374151" />
|
||||||
|
اطلاعات فروشنده
|
||||||
|
</h4>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<UserIcon size={16} color="#6B7280" />
|
||||||
|
<span className="text-sm text-gray-600">نام:</span>
|
||||||
|
<span className="text-sm font-medium">{request.seller?.fullName || '-'}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Shop size={16} color="#6B7280" />
|
||||||
|
<span className="text-sm text-gray-600">فروشگاه:</span>
|
||||||
|
<span className="text-sm font-medium">{request.shop?.shopName || '-'}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Location size={16} color="#6B7280" />
|
||||||
|
<span className="text-sm text-gray-600">آدرس:</span>
|
||||||
|
<span className="text-sm font-medium">{request.shop?.address?.province?.name || '-'}، {request.shop?.address?.city?.name || '-'}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Tag size={16} color="#6B7280" />
|
||||||
|
<span className="text-sm text-gray-600">کد فروشگاه:</span>
|
||||||
|
<span className="text-sm font-medium">{request.shop?.shopCode || '-'}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* اطلاعات محصول */}
|
||||||
|
<div className="bg-blue-50 rounded-lg p-4">
|
||||||
|
<h4 className="text-md font-medium text-gray-900 mb-3 flex items-center gap-2">
|
||||||
|
<Box size={20} color="#1E40AF" />
|
||||||
|
اطلاعات محصول
|
||||||
|
</h4>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Box size={16} color="#6B7280" />
|
||||||
|
<span className="text-sm text-gray-600">نام محصول:</span>
|
||||||
|
<span className="text-sm font-medium">{request.productName}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Tag size={16} color="#6B7280" />
|
||||||
|
<span className="text-sm text-gray-600">برند:</span>
|
||||||
|
<span className="text-sm font-medium">{request.brand?.title_fa || '-'}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<MessageSquare size={16} color="#6B7280" />
|
||||||
|
<span className="text-sm text-gray-600">دستهبندی:</span>
|
||||||
|
<span className="text-sm font-medium">{request.category?.title_fa || '-'}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Tag size={16} color="#6B7280" />
|
||||||
|
<span className="text-sm text-gray-600">منبع:</span>
|
||||||
|
<span className="text-sm font-medium">{request.source || '-'}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* توضیحات */}
|
||||||
|
<div className="bg-green-50 rounded-lg p-4">
|
||||||
|
<h4 className="text-md font-medium text-gray-900 mb-3">توضیحات</h4>
|
||||||
|
<p className="text-sm text-gray-700 leading-relaxed">{String(request.description || 'توضیحاتی وارد نشده')}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* ابعاد و وزن */}
|
||||||
|
<div className="bg-yellow-50 rounded-lg p-4">
|
||||||
|
<h4 className="text-md font-medium text-gray-900 mb-3 flex items-center gap-2">
|
||||||
|
<Box size={20} color="#92400E" />
|
||||||
|
ابعاد و وزن
|
||||||
|
</h4>
|
||||||
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
|
<div className="text-center">
|
||||||
|
<div className="text-lg font-semibold text-gray-900">{request.dimensions?.package_weight || 0}</div>
|
||||||
|
<div className="text-xs text-gray-600">وزن (گرم)</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-center">
|
||||||
|
<div className="text-lg font-semibold text-gray-900">{request.dimensions?.package_length || 0}</div>
|
||||||
|
<div className="text-xs text-gray-600">طول (سانتیمتر)</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-center">
|
||||||
|
<div className="text-lg font-semibold text-gray-900">{request.dimensions?.package_width || 0}</div>
|
||||||
|
<div className="text-xs text-gray-600">عرض (سانتیمتر)</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-center">
|
||||||
|
<div className="text-lg font-semibold text-gray-900">{request.dimensions?.package_height || 0}</div>
|
||||||
|
<div className="text-xs text-gray-600">ارتفاع (سانتیمتر)</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* مزایا و معایب */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<div className="bg-green-50 rounded-lg p-4">
|
||||||
|
<h4 className="text-md font-medium text-green-900 mb-3">مزایا</h4>
|
||||||
|
{request.advantages && request.advantages.length > 0 ? (
|
||||||
|
<ul className="space-y-1">
|
||||||
|
{request.advantages.map((advantage, index) => (
|
||||||
|
<li key={index} className="text-sm text-green-800 flex items-center gap-2">
|
||||||
|
<span className="w-1.5 h-1.5 bg-green-600 rounded-full"></span>
|
||||||
|
{String(advantage)}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
) : (
|
||||||
|
<p className="text-sm text-gray-600">مزایایی وارد نشده</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-red-50 rounded-lg p-4">
|
||||||
|
<h4 className="text-md font-medium text-red-900 mb-3">معایب</h4>
|
||||||
|
{request.disAdvantages && request.disAdvantages.length > 0 ? (
|
||||||
|
<ul className="space-y-1">
|
||||||
|
{request.disAdvantages.map((disadvantage, index) => (
|
||||||
|
<li key={index} className="text-sm text-red-800 flex items-center gap-2">
|
||||||
|
<span className="w-1.5 h-1.5 bg-red-600 rounded-full"></span>
|
||||||
|
{String(disadvantage)}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
) : (
|
||||||
|
<p className="text-sm text-gray-600">معایبی وارد نشده</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* خدمات درخواست شده */}
|
||||||
|
<div className="bg-purple-50 rounded-lg p-4">
|
||||||
|
<h4 className="text-md font-medium text-gray-900 mb-3">خدمات درخواست شده</h4>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={request.requestPhotography}
|
||||||
|
readOnly
|
||||||
|
className="rounded border-gray-300"
|
||||||
|
/>
|
||||||
|
<span className="text-sm">📸 عکاسی محصول</span>
|
||||||
|
{request.requestPhotosCount && (
|
||||||
|
<span className="text-xs text-gray-600">({request.requestPhotosCount} عکس)</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={request.expertReview}
|
||||||
|
readOnly
|
||||||
|
className="rounded border-gray-300"
|
||||||
|
/>
|
||||||
|
<span className="text-sm">👨💼 بررسی تخصصی</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={request.unboxingVideo}
|
||||||
|
readOnly
|
||||||
|
className="rounded border-gray-300"
|
||||||
|
/>
|
||||||
|
<span className="text-sm">📦 ویدیو باز کردن بسته</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* اطلاعات پرداخت */}
|
||||||
|
{request.payment && (
|
||||||
|
<div className="bg-indigo-50 rounded-lg p-4">
|
||||||
|
<h4 className="text-md font-medium text-gray-900 mb-3 flex items-center gap-2">
|
||||||
|
<Money size={20} color="#312E81" />
|
||||||
|
اطلاعات پرداخت
|
||||||
|
</h4>
|
||||||
|
<div className="text-sm text-gray-700">
|
||||||
|
<pre className="whitespace-pre-wrap">{String(JSON.stringify(request.payment, null, 2))}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* تاریخ ایجاد */}
|
||||||
|
<div className="flex items-center justify-between text-sm text-gray-600 border-t pt-4">
|
||||||
|
<span>تاریخ ایجاد:</span>
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<Calendar size={16} color="#6B7280" />
|
||||||
|
<span>{formatDate(request._id ? new Date().toISOString() : '')}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DefaulModal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProductRequestDetailModal
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
import { type FC } from 'react'
|
||||||
|
import { type ProductRequest } from '../types/Types'
|
||||||
|
import StatusWithText from '../../../components/StatusWithText'
|
||||||
|
import Td from '../../../components/Td'
|
||||||
|
import { Calendar, User as UserIcon, Shop, Tag, Box, MessageSquare, Eye } from 'iconsax-react'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
request: ProductRequest
|
||||||
|
onClick?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProductRequestTableRow: FC<Props> = ({ request, onClick }) => {
|
||||||
|
const getStatusVariant = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'Approved': return 'success';
|
||||||
|
case 'Rejected': return 'error';
|
||||||
|
case 'Pending': return 'warning';
|
||||||
|
case 'Draft': return 'warning';
|
||||||
|
default: return 'warning';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStatusText = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'Approved': return 'تایید شده';
|
||||||
|
case 'Rejected': return 'رد شده';
|
||||||
|
case 'Pending': return 'در انتظار';
|
||||||
|
case 'Draft': return 'پیشنویس';
|
||||||
|
default: return status;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatDate = (dateString: string) => {
|
||||||
|
if (!dateString) return '-';
|
||||||
|
return new Date(dateString).toLocaleDateString('fa-IR');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr className='tr'>
|
||||||
|
<Td text="">
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<UserIcon size={16} color="#8C90A3" />
|
||||||
|
<span>{request.seller?.fullName || '-'}</span>
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
<Td text="">
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<Shop size={16} color="#8C90A3" />
|
||||||
|
<span>{request.shop?.shopName || '-'}</span>
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
<Td text="">
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<Box size={16} color="#8C90A3" />
|
||||||
|
<span>{request.productName}</span>
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
<Td text="">
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<Tag size={16} color="#8C90A3" />
|
||||||
|
<span>{request.brand?.title_fa || '-'}</span>
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
<Td text="">
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<MessageSquare size={16} color="#8C90A3" />
|
||||||
|
<span>{request.category?.title_fa || '-'}</span>
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
<Td text="">
|
||||||
|
<StatusWithText
|
||||||
|
variant={getStatusVariant(request.requestStatus)}
|
||||||
|
text={getStatusText(request.requestStatus)}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
<Td text="">
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<Calendar size={16} color="#8C90A3" />
|
||||||
|
<span>{formatDate(request._id ? new Date().toISOString() : '')}</span>
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
<Td text="">
|
||||||
|
<div className="flex flex-col gap-1 text-xs">
|
||||||
|
{request.requestPhotography && <span>📸 عکاسی</span>}
|
||||||
|
{request.expertReview && <span>👨💼 بررسی تخصصی</span>}
|
||||||
|
{request.unboxingVideo && <span>📦 ویدیو باز کردن بسته</span>}
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
<Td text="">
|
||||||
|
<Eye
|
||||||
|
size={16}
|
||||||
|
color="#8C90A3"
|
||||||
|
className="cursor-pointer hover:text-blue-500 transition-colors"
|
||||||
|
onClick={(e: React.MouseEvent) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onClick?.();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProductRequestTableRow
|
||||||
@@ -59,3 +59,10 @@ export const useCreateAnnouncementSpecificSeller = () => {
|
|||||||
mutationFn: api.createAnnouncementToSpecificSellers,
|
mutationFn: api.createAnnouncementToSpecificSellers,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useGetRequestCreateProduct = (page: number = 1) => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["request-create-product", page],
|
||||||
|
queryFn: () => api.getRequestCreateProduct(page),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import type {
|
|||||||
CreateAnnouncementSeller,
|
CreateAnnouncementSeller,
|
||||||
NotificationsResponse,
|
NotificationsResponse,
|
||||||
CreateAnnouncementSpecificSeller,
|
CreateAnnouncementSpecificSeller,
|
||||||
|
GetRequestCreateProductResponse,
|
||||||
} from "../types/Types";
|
} from "../types/Types";
|
||||||
|
|
||||||
export const getSellers = async (
|
export const getSellers = async (
|
||||||
@@ -77,3 +78,12 @@ export const createAnnouncementToSpecificSellers = async (
|
|||||||
);
|
);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getRequestCreateProduct = async (
|
||||||
|
page: number = 1
|
||||||
|
): Promise<GetRequestCreateProductResponse> => {
|
||||||
|
const { data } = await axios.get(
|
||||||
|
`/admin/products/requests/add-by-admin?page=${page}`
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|||||||
@@ -212,3 +212,109 @@ export interface NotificationsResponse {
|
|||||||
notifications: Notification[];
|
notifications: Notification[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CreateCategoryLearning {
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Product Request Types
|
||||||
|
export interface City {
|
||||||
|
_id: number;
|
||||||
|
name: string;
|
||||||
|
province: number;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Province {
|
||||||
|
_id: number;
|
||||||
|
name: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Address {
|
||||||
|
_id: string;
|
||||||
|
address: string;
|
||||||
|
city: City;
|
||||||
|
province: Province;
|
||||||
|
postalCode: string | null;
|
||||||
|
plaque: string | null;
|
||||||
|
lat: string;
|
||||||
|
lon: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProductRequestShop {
|
||||||
|
_id: string;
|
||||||
|
shopName: string;
|
||||||
|
address: Address;
|
||||||
|
shopCode: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Brand {
|
||||||
|
_id: string;
|
||||||
|
title_fa: string;
|
||||||
|
title_en: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Category {
|
||||||
|
_id: string;
|
||||||
|
title_fa: string;
|
||||||
|
title_en: string;
|
||||||
|
icon: string;
|
||||||
|
imageUrl: string;
|
||||||
|
description: string;
|
||||||
|
variants: string[];
|
||||||
|
hierarchy: string[];
|
||||||
|
leaf: boolean;
|
||||||
|
parent: string | null;
|
||||||
|
deleted: boolean;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
url: string;
|
||||||
|
children: Category[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Dimensions {
|
||||||
|
package_weight: number;
|
||||||
|
package_height: number;
|
||||||
|
package_length: number;
|
||||||
|
package_width: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProductRequestSeller {
|
||||||
|
_id: string;
|
||||||
|
fullName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProductRequest {
|
||||||
|
requestPhotography: boolean;
|
||||||
|
requestPhotosCount: number | null;
|
||||||
|
expertReview: boolean;
|
||||||
|
unboxingVideo: boolean;
|
||||||
|
payment: unknown | null;
|
||||||
|
requestStatus: string;
|
||||||
|
_id: string;
|
||||||
|
seller: ProductRequestSeller;
|
||||||
|
shop: ProductRequestShop;
|
||||||
|
brand: Brand;
|
||||||
|
category: Category;
|
||||||
|
source: string;
|
||||||
|
productName: string;
|
||||||
|
description: string;
|
||||||
|
dimensions: Dimensions;
|
||||||
|
advantages: string[];
|
||||||
|
disAdvantages: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetRequestCreateProductResponse {
|
||||||
|
status: number;
|
||||||
|
success: boolean;
|
||||||
|
results: {
|
||||||
|
productRequests: ProductRequest[];
|
||||||
|
pager: Pager;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ import SellerList from '@/pages/seller/List'
|
|||||||
import WholeSaleRequest from '@/pages/seller/WholeSaleRequest'
|
import WholeSaleRequest from '@/pages/seller/WholeSaleRequest'
|
||||||
import WithdrawalRequestPage from '@/pages/seller/WithdrawalRequest'
|
import WithdrawalRequestPage from '@/pages/seller/WithdrawalRequest'
|
||||||
import Annoncement from '@/pages/seller/Annoncement'
|
import Annoncement from '@/pages/seller/Annoncement'
|
||||||
|
import RequestCreateProduct from '@/pages/seller/RequestCreateProduct'
|
||||||
const MainRouter: FC = () => {
|
const MainRouter: FC = () => {
|
||||||
|
|
||||||
const { hasSubMenu } = useSharedStore()
|
const { hasSubMenu } = useSharedStore()
|
||||||
@@ -165,6 +166,7 @@ const MainRouter: FC = () => {
|
|||||||
<Route path={Pages.sellers.wholesaleRequests} element={<WholeSaleRequest />} />
|
<Route path={Pages.sellers.wholesaleRequests} element={<WholeSaleRequest />} />
|
||||||
<Route path={Pages.sellers.withdrawalRequests} element={<WithdrawalRequestPage />} />
|
<Route path={Pages.sellers.withdrawalRequests} element={<WithdrawalRequestPage />} />
|
||||||
<Route path={Pages.sellers.announcement} element={<Annoncement />} />
|
<Route path={Pages.sellers.announcement} element={<Annoncement />} />
|
||||||
|
<Route path={Pages.sellers.requestCreateProduct} element={<RequestCreateProduct />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -518,8 +518,8 @@ const SellersSubMenu: FC = () => {
|
|||||||
/>
|
/>
|
||||||
<SubMenuItem
|
<SubMenuItem
|
||||||
title={'درخواست های ثبت محصول'}
|
title={'درخواست های ثبت محصول'}
|
||||||
isActive={isActive('product-requests')}
|
isActive={isActive('request-create-product')}
|
||||||
link="/sellers/product-requests"
|
link={Pages.sellers.requestCreateProduct}
|
||||||
/>
|
/>
|
||||||
<SubMenuItem
|
<SubMenuItem
|
||||||
title={'قرار داد'}
|
title={'قرار داد'}
|
||||||
|
|||||||
Reference in New Issue
Block a user