diff --git a/src/data/mockPartnerData.ts b/src/data/mockPartnerData.ts index 5fe30e4..8641aa7 100644 --- a/src/data/mockPartnerData.ts +++ b/src/data/mockPartnerData.ts @@ -200,5 +200,35 @@ export const mockDocuments: PartnerDocument[] = [ status: 'Verified', uploadedBy: 'Alex Rivera', uploadedAt: subMonths(new Date(), 6).toISOString(), + }, + { + id: 'doc3', + partnerId: 'p5', + type: 'Compliance', + name: 'Company Registration (Pending)', + url: '#', + status: 'Pending', + uploadedBy: 'John Doe', + uploadedAt: subDays(new Date(), 1).toISOString(), + }, + { + id: 'doc4', + partnerId: 'p5', + type: 'Tax', + name: 'PAN Card Copy', + url: '#', + status: 'Pending', + uploadedBy: 'John Doe', + uploadedAt: subDays(new Date(), 1).toISOString(), + }, + { + id: 'doc5', + partnerId: 'p5', + type: 'Other', + name: 'Cancelled Cheque', + url: '#', + status: 'Pending', + uploadedBy: 'John Doe', + uploadedAt: subDays(new Date(), 1).toISOString(), } ]; diff --git a/src/features/partners/components/KYCReviewSheet.tsx b/src/features/partners/components/KYCReviewSheet.tsx new file mode 100644 index 0000000..33576aa --- /dev/null +++ b/src/features/partners/components/KYCReviewSheet.tsx @@ -0,0 +1,130 @@ + +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, + SheetFooter, +} from "@/components/ui/sheet"; +import { Button } from "@/components/ui/button"; +import { Partner, PartnerDocument } from "@/types/partner"; +import { mockDocuments } from "@/data/mockPartnerData"; +import { FileText, CheckCircle2, XCircle, Clock, Eye, Download } from "lucide-react"; +import { Badge } from "@/components/ui/badge"; +import { toast } from "sonner"; +import { useState } from "react"; + +interface KYCReviewSheetProps { + partner: Partner; + open: boolean; + onOpenChange: (open: boolean) => void; +} + +export function KYCReviewSheet({ partner, open, onOpenChange }: KYCReviewSheetProps) { + // Filter documents for this partner or use defaults if none found (for demo) + const partnerDocs = mockDocuments.filter(d => d.partnerId === partner.id); + const documentsToDisplay = partnerDocs.length > 0 ? partnerDocs : mockDocuments.slice(0, 3); + + const [status, setStatus] = useState<'pending' | 'approved' | 'rejected'>('pending'); + + const handleApprove = () => { + setStatus('approved'); + toast.success(`KYC documents for ${partner.name} verified successfully.`); + setTimeout(() => onOpenChange(false), 1500); + }; + + const handleReject = () => { + setStatus('rejected'); + toast.error(`KYC documents for ${partner.name} rejected. Partner notified.`); + setTimeout(() => onOpenChange(false), 1500); + }; + + const getStatusIcon = (status: PartnerDocument['status']) => { + switch (status) { + case 'Verified': return ; + case 'Rejected': return ; + case 'Signed': return ; + default: return ; + } + }; + + return ( + + + +
+
+ KYC +
+
+ Verification Review + Review submitted documents for {partner.name} +
+
+
+ +
+
+

Submitted Documents

+
+ {documentsToDisplay.map((doc) => ( +
+
+ +
+
+
+

{doc.name}

+ {getStatusIcon(doc.status)} +
+
+ {doc.type} • {new Date(doc.uploadedAt).toLocaleDateString()} + + {doc.status} + +
+
+
+ + +
+
+ ))} +
+
+ +
+

Verification Decision

+
+ + +
+

+ Actions are logged for audit purposes. +

+
+
+
+
+ ); +} diff --git a/src/features/partners/components/PartnerCard.tsx b/src/features/partners/components/PartnerCard.tsx index 18dba95..b58f6f3 100644 --- a/src/features/partners/components/PartnerCard.tsx +++ b/src/features/partners/components/PartnerCard.tsx @@ -9,6 +9,8 @@ import { DropdownMenuTrigger } from '@/components/ui/dropdown-menu'; import { useNavigate } from 'react-router-dom'; +import { useState } from 'react'; +import { KYCReviewSheet } from './KYCReviewSheet'; interface PartnerCardProps { partner: Partner; @@ -16,78 +18,94 @@ interface PartnerCardProps { export function PartnerCard({ partner }: PartnerCardProps) { const navigate = useNavigate(); + const [showKYCSheet, setShowKYCSheet] = useState(false); return ( -
navigate(`/partners/${partner.id}`)} - > -
-
-
- {partner.logo ? ( - {partner.name} - ) : ( - {partner.name.substring(0, 2)} - )} -
-
-

{partner.name}

-
- - + <> +
navigate(`/partners/${partner.id}`)} + > +
+
+
+ {partner.logo ? ( + {partner.name} + ) : ( + {partner.name.substring(0, 2)} + )} +
+
+

{partner.name}

+
+ + +
+ +
e.stopPropagation()}> + + + + + + navigate(`/partners/${partner.id}`)}>View Details + Assign to Event + {partner.status === 'Suspended' ? ( + Revoke Suspension + ) : ( + Suspend Partner + )} + + +
-
e.stopPropagation()}> - - - - - - navigate(`/partners/${partner.id}`)}>View Details - Assign to Event - {partner.status === 'Suspended' ? ( - Revoke Suspension - ) : ( - Suspend Partner - )} - - + {partner.verificationStatus === 'Pending' && ( +
e.stopPropagation()}> + KYC Verification Pending + +
+ )} + +
+
+

+ Active Deals +

+

{partner.metrics.activeDeals}

+
+
+

+ Open Balance +

+

₹{partner.metrics.openBalance.toLocaleString()}

+
+
+ +
+ {partner.primaryContact.name} + + View Portal +
- {partner.verificationStatus === 'Pending' && ( -
- KYC Verification Pending - -
- )} - -
-
-

- Active Deals -

-

{partner.metrics.activeDeals}

-
-
-

- Open Balance -

-

₹{partner.metrics.openBalance.toLocaleString()}

-
-
- -
- {partner.primaryContact.name} - - View Portal - -
-
+ + ); }