diff --git a/src/pages/seller/List.tsx b/src/pages/seller/List.tsx index 1348a9b..c4ea15c 100644 --- a/src/pages/seller/List.tsx +++ b/src/pages/seller/List.tsx @@ -53,6 +53,7 @@ const SellerList: FC = () => { + diff --git a/src/pages/seller/components/DocumentsModal.tsx b/src/pages/seller/components/DocumentsModal.tsx new file mode 100644 index 0000000..c0c303a --- /dev/null +++ b/src/pages/seller/components/DocumentsModal.tsx @@ -0,0 +1,205 @@ +import { type FC, useState } from 'react' +import DefaulModal from '../../../components/DefaulModal' +import Button from '../../../components/Button' +import StatusWithText from '../../../components/StatusWithText' +import { type SellerDocument } from '../types/Types' +import { useChangeStatusDocument } from '../hooks/useSellerData' +import { Eye, Import, CloseCircle } from 'iconsax-react' + +interface Props { + open: boolean + close: () => void + documents: SellerDocument[] + sellerId: string +} + +const DocumentsModal: FC = ({ open, close, documents, sellerId }) => { + const [selectedImage, setSelectedImage] = useState(null) + const changeStatusMutation = useChangeStatusDocument() + + const getStatusVariant = (status: string) => { + switch (status) { + case 'Approved': return 'success' + case 'Pending': return 'warning' + default: return 'warning' + } + } + + const getStatusText = (status: string) => { + switch (status) { + case 'Approved': return 'تایید شده' + case 'Pending': return 'در انتظار' + default: return status + } + } + + const isImage = (url: string) => { + const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg'] + const lowerUrl = url.toLowerCase() + return imageExtensions.some(ext => lowerUrl.includes(ext)) + } + + const handleDownload = (url: string, fileName: string) => { + const link = document.createElement('a') + link.href = url + link.download = fileName + link.target = '_blank' + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + } + + const handleApprove = async (documentId: string) => { + try { + await changeStatusMutation.mutateAsync({ + sellerId, + params: { + docsId: documentId, + status: 'Approved' + } + }) + // Refresh documents or update local state + } catch (error) { + console.error('خطا در تایید مدرک:', error) + } + } + + const handleReject = async (documentId: string) => { + try { + await changeStatusMutation.mutateAsync({ + sellerId, + params: { + docsId: documentId, + status: 'REJECTED' + } + }) + // Refresh documents or update local state + } catch (error) { + console.error('خطا در رد مدرک:', error) + } + } + + return ( + +
+ {documents.length === 0 ? ( +
+ هیچ مدرکی یافت نشد +
+ ) : ( + documents.map((document) => ( +
+
+
+ {document.type} + +
+
+ {isImage(document.docsUrl) && ( + + )} + +
+
+ + {isImage(document.docsUrl) && ( +
+ {document.type} { + e.currentTarget.style.display = 'none' + }} + /> +
+ )} + + {document.comment && ( +
+ {document.comment} +
+ )} + +
+ ایجاد شده: {new Date(document.createdAt).toLocaleDateString('fa-IR')} +
+ + {document.status === 'Pending' && ( +
+ + +
+ )} +
+ )) + )} +
+ + {/* Image Preview Modal */} + {selectedImage && ( + setSelectedImage(null)} + width={800} + > +
+ + پیش‌نمایش مدرک +
+
+ )} +
+ ) +} + +export default DocumentsModal diff --git a/src/pages/seller/components/SellerTableRow.tsx b/src/pages/seller/components/SellerTableRow.tsx index f86c2f2..9b1b124 100644 --- a/src/pages/seller/components/SellerTableRow.tsx +++ b/src/pages/seller/components/SellerTableRow.tsx @@ -1,8 +1,9 @@ -import { type FC } from 'react' +import { type FC, useState } from 'react' import { type Seller } from '../types/Types' import StatusWithText from '../../../components/StatusWithText' import Td from '../../../components/Td' import SellerToggle from './SellerToggle' +import DocumentsModal from './DocumentsModal' import { Calendar, Call, Card, User as UserIcon, Shop, Eye } from 'iconsax-react' interface Props { @@ -11,6 +12,8 @@ interface Props { } const SellerTableRow: FC = ({ seller, onViewContract }) => { + const [documentsModalOpen, setDocumentsModalOpen] = useState(false) + const getStatusVariant = (status: string) => { switch (status) { case 'Approved': return 'success'; @@ -33,64 +36,81 @@ const SellerTableRow: FC = ({ seller, onViewContract }) => { }; return ( - - -
- - {seller.fullName || '-'} -
- - -
- - {seller.shop?.shopName || '-'} -
- - -
- - {seller.email || '-'} -
- - -
- - {seller.phoneNumber} -
- - - - - - -
- - {formatDate(seller.createdAt)} -
- - - {seller.contracts ? ( + <> + setDocumentsModalOpen(false)} + documents={seller.documents || []} + sellerId={seller._id} + /> + + +
+ + {seller.fullName || '-'} +
+ + +
+ + {seller.shop?.shopName || '-'} +
+ + +
+ + {seller.email || '-'} +
+ + +
+ + {seller.phoneNumber} +
+ + + + + + +
+ + {formatDate(seller.createdAt)} +
+ + + {seller.contracts ? ( + + ) : ( + - + )} + + - ) : ( - - - )} - - - - - + + + + + + ) } diff --git a/src/pages/seller/hooks/useSellerData.ts b/src/pages/seller/hooks/useSellerData.ts index b6470e0..f9f6ddd 100644 --- a/src/pages/seller/hooks/useSellerData.ts +++ b/src/pages/seller/hooks/useSellerData.ts @@ -1,6 +1,7 @@ import * as api from "../service/SellerService"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { + ChangeStatusDocumentType, CreateCategoryLearning, CreateLearningType, } from "../types/Types"; @@ -146,3 +147,19 @@ export const useUpdateContract = () => { mutationFn: api.updateContract, }); }; + +export const useChangeStatusDocument = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: ({ + sellerId, + params, + }: { + sellerId: string; + params: ChangeStatusDocumentType; + }) => api.changeStatusDocument(sellerId, params), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["sellers"] }); + }, + }); +}; diff --git a/src/pages/seller/service/SellerService.ts b/src/pages/seller/service/SellerService.ts index 5589b17..c8ce53b 100644 --- a/src/pages/seller/service/SellerService.ts +++ b/src/pages/seller/service/SellerService.ts @@ -12,6 +12,7 @@ import type { GetLearningResponse, CreateLearningType, UpdateContractType, + ChangeStatusDocumentType, } from "../types/Types"; export const getSellers = async ( @@ -158,3 +159,14 @@ export const updateContract = async (params: UpdateContractType) => { ); return data; }; + +export const changeStatusDocument = async ( + sellerId: string, + params: ChangeStatusDocumentType +) => { + const { data } = await axios.patch( + `/admin/sellers/document/${sellerId}`, + params + ); + return data; +}; diff --git a/src/pages/seller/types/Types.ts b/src/pages/seller/types/Types.ts index c41cceb..beb176c 100644 --- a/src/pages/seller/types/Types.ts +++ b/src/pages/seller/types/Types.ts @@ -380,3 +380,8 @@ export interface UpdateContractType { id: string; content: string; } + +export interface ChangeStatusDocumentType { + docsId: string; + status: "Approved" | "REJECTED"; +}