Cloudtopiaa_Reseller_Frontend/src/components/VendorDetailsModal.tsx
2025-08-11 00:47:45 +05:30

358 lines
14 KiB
TypeScript

import React from 'react';
import { X, Building, Mail, Phone, MapPin, Globe, FileText, DollarSign, Users, Calendar } from 'lucide-react';
import { VendorModalProps } from '../types/vendor';
const VendorDetailsModal: React.FC<VendorModalProps> = ({
vendor,
isOpen,
onClose,
onApprove,
onReject
}) => {
console.log('VendorDetailsModal props:', { isOpen, vendor: vendor?.id, vendorName: vendor ? `${vendor.firstName} ${vendor.lastName}` : null });
if (!isOpen || !vendor) return null;
const formatRoleName = (role: string) => {
if (role.startsWith('channel_partner_')) {
return 'Vendor';
} else if (role.startsWith('reseller_')) {
return 'Reseller';
} else if (role.startsWith('system_')) {
return 'System Admin';
}
return role.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
};
const formatUserType = (userType: string) => {
if (userType === 'channel_partner') {
return 'Vendor';
} else if (userType === 'reseller') {
return 'Reseller';
}
return userType.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
};
const formatCurrency = (amount: number) => {
return new Intl.NumberFormat('en-IN', {
style: 'currency',
currency: 'INR',
minimumFractionDigits: 0,
maximumFractionDigits: 0
}).format(amount);
};
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-[9999] p-4" style={{ backdropFilter: 'blur(4px)' }}>
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-2xl max-w-2xl w-full max-h-[90vh] overflow-y-auto">
{/* Header */}
<div className="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700">
<div className="flex items-center space-x-3">
<Building className="w-6 h-6 text-blue-600" />
<h2 className="text-xl font-semibold text-gray-900 dark:text-white">
Vendor Details
</h2>
</div>
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
>
<X className="w-5 h-5" />
</button>
</div>
{/* Content */}
<div className="p-6 space-y-6">
{/* Basic Information */}
<div className="space-y-4">
<h3 className="text-lg font-medium text-gray-900 dark:text-white border-b border-gray-200 dark:border-gray-700 pb-2">
Basic Information
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Full Name
</label>
<p className="text-gray-900 dark:text-white">
{vendor.firstName} {vendor.lastName}
</p>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Email
</label>
<p className="text-gray-900 dark:text-white flex items-center">
<Mail className="w-4 h-4 mr-2" />
{vendor.email}
</p>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Phone
</label>
<p className="text-gray-900 dark:text-white flex items-center">
<Phone className="w-4 h-4 mr-2" />
{vendor.phone || 'N/A'}
</p>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Company
</label>
<p className="text-gray-900 dark:text-white flex items-center">
<Building className="w-4 h-4 mr-2" />
{vendor.company}
</p>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Role
</label>
<p className="text-gray-900 dark:text-white">
{formatRoleName(vendor.role)}
</p>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
User Type
</label>
<p className="text-gray-900 dark:text-white">
{formatUserType(vendor.userType)}
</p>
</div>
</div>
</div>
{/* Business Information */}
{(vendor.companyType || vendor.registrationNumber || vendor.gstNumber || vendor.panNumber) && (
<div className="space-y-4">
<h3 className="text-lg font-medium text-gray-900 dark:text-white border-b border-gray-200 dark:border-gray-700 pb-2">
Business Information
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{vendor.companyType && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Company Type
</label>
<p className="text-gray-900 dark:text-white">
{vendor.companyType.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
</p>
</div>
)}
{vendor.registrationNumber && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Registration Number
</label>
<p className="text-gray-900 dark:text-white">
{vendor.registrationNumber}
</p>
</div>
)}
{vendor.gstNumber && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
GST Number
</label>
<p className="text-gray-900 dark:text-white">
{vendor.gstNumber}
</p>
</div>
)}
{vendor.panNumber && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
PAN Number
</label>
<p className="text-gray-900 dark:text-white">
{vendor.panNumber}
</p>
</div>
)}
</div>
</div>
)}
{/* Financial Information */}
{(vendor.annualRevenue || vendor.employeeCount || vendor.yearsInBusiness) && (
<div className="space-y-4">
<h3 className="text-lg font-medium text-gray-900 dark:text-white border-b border-gray-200 dark:border-gray-700 pb-2">
Financial Information
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{vendor.annualRevenue && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Annual Revenue
</label>
<p className="text-gray-900 dark:text-white flex items-center">
<DollarSign className="w-4 h-4 mr-2" />
{formatCurrency(vendor.annualRevenue)}
</p>
</div>
)}
{vendor.employeeCount && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Employee Count
</label>
<p className="text-gray-900 dark:text-white flex items-center">
<Users className="w-4 h-4 mr-2" />
{vendor.employeeCount} employees
</p>
</div>
)}
{vendor.yearsInBusiness && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Years in Business
</label>
<p className="text-gray-900 dark:text-white flex items-center">
<Calendar className="w-4 h-4 mr-2" />
{vendor.yearsInBusiness} years
</p>
</div>
)}
</div>
</div>
)}
{/* Address Information */}
{vendor.address && (
<div className="space-y-4">
<h3 className="text-lg font-medium text-gray-900 dark:text-white border-b border-gray-200 dark:border-gray-700 pb-2">
Address Information
</h3>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Address
</label>
<p className="text-gray-900 dark:text-white flex items-start">
<MapPin className="w-4 h-4 mr-2 mt-0.5 flex-shrink-0" />
{vendor.address}
</p>
</div>
</div>
)}
{/* Additional Information */}
{(vendor.website || vendor.businessLicense || vendor.taxId || vendor.industry) && (
<div className="space-y-4">
<h3 className="text-lg font-medium text-gray-900 dark:text-white border-b border-gray-200 dark:border-gray-700 pb-2">
Additional Information
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{vendor.website && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Website
</label>
<p className="text-gray-900 dark:text-white flex items-center">
<Globe className="w-4 h-4 mr-2" />
<a href={vendor.website} target="_blank" rel="noopener noreferrer" className="text-blue-600 hover:text-blue-800">
{vendor.website}
</a>
</p>
</div>
)}
{vendor.businessLicense && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Business License
</label>
<p className="text-gray-900 dark:text-white flex items-center">
<FileText className="w-4 h-4 mr-2" />
{vendor.businessLicense}
</p>
</div>
)}
{vendor.taxId && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Tax ID
</label>
<p className="text-gray-900 dark:text-white">
{vendor.taxId}
</p>
</div>
)}
{vendor.industry && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Industry
</label>
<p className="text-gray-900 dark:text-white">
{vendor.industry}
</p>
</div>
)}
</div>
</div>
)}
{/* Rejection Information */}
{vendor.rejectionReason && (
<div className="space-y-4">
<h3 className="text-lg font-medium text-gray-900 dark:text-white border-b border-gray-200 dark:border-gray-700 pb-2">
Rejection Information
</h3>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Rejection Reason
</label>
<p className="text-gray-900 dark:text-white bg-red-50 dark:bg-red-900/20 p-3 rounded-lg">
{vendor.rejectionReason}
</p>
</div>
</div>
)}
{/* Timestamp */}
<div className="space-y-4">
<h3 className="text-lg font-medium text-gray-900 dark:text-white border-b border-gray-200 dark:border-gray-700 pb-2">
Timestamp
</h3>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Created At
</label>
<p className="text-gray-900 dark:text-white flex items-center">
<Calendar className="w-4 h-4 mr-2" />
{new Date(vendor.createdAt).toLocaleString()}
</p>
</div>
</div>
</div>
{/* Footer */}
<div className="flex items-center justify-end space-x-3 p-6 border-t border-gray-200 dark:border-gray-700">
<button
onClick={onClose}
className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-600 dark:hover:bg-gray-600"
>
Close
</button>
{vendor.status === 'pending' && (
<>
<button
onClick={() => onReject(vendor.id, '')}
className="px-4 py-2 text-sm font-medium text-white bg-red-600 border border-transparent rounded-md hover:bg-red-700"
>
Reject
</button>
<button
onClick={() => onApprove(vendor.id)}
className="px-4 py-2 text-sm font-medium text-white bg-green-600 border border-transparent rounded-md hover:bg-green-700"
>
Approve
</button>
</>
)}
</div>
</div>
</div>
);
};
export default VendorDetailsModal;