import React, { useState, useEffect } from 'react'; import { formatCurrency, formatNumber, formatDate } from '../../utils/format'; import Modal from '../../components/Modal'; import DetailView from '../../components/DetailView'; import toast from 'react-hot-toast'; import { Search, Filter, MoreVertical, Eye, Edit, CheckCircle, XCircle, Clock, TrendingUp, Users, DollarSign, Calendar, Handshake, AlertCircle, Download, Mail, MapPin, Building2, User, Phone } from 'lucide-react'; import { cn } from '../../utils/cn'; interface Reseller { id: string; firstName: string; lastName: string; email: string; phone?: string; status: string; tier?: string; totalRevenue?: number; lastActive?: string; customers?: number; commissionRate?: number; region?: string; avatar?: string; company?: string; createdAt?: string; } const ApprovedResellersPage: React.FC = () => { const [searchTerm, setSearchTerm] = useState(''); const [statusFilter, setStatusFilter] = useState('active'); const [tierFilter, setTierFilter] = useState('all'); const [isDetailModalOpen, setIsDetailModalOpen] = useState(false); const [selectedReseller, setSelectedReseller] = useState(null); const [resellers, setResellers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // Set page title useEffect(() => { document.title = 'All Resellers - Cloudtopiaa'; }, []); // Fetch approved resellers from API useEffect(() => { fetchApprovedResellers(); }, []); const fetchApprovedResellers = async () => { try { setLoading(true); setError(null); const token = localStorage.getItem('accessToken'); if (!token) { setError('Authentication required. Please log in again.'); return; } // Fetch all resellers (not just active ones) const response = await fetch(`${process.env.REACT_APP_API_URL || 'http://localhost:5000/api'}/vendors/resellers`, { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }); if (!response.ok) { throw new Error('Failed to fetch resellers'); } const data = await response.json(); if (data.success) { // Filter out pending resellers - only show non-pending ones const nonPendingResellers = (data.data.resellers || []).filter( (reseller: Reseller) => reseller.status !== 'pending' ); setResellers(nonPendingResellers); } else { const errorMsg = data.message || 'Failed to fetch resellers'; setError(errorMsg); } } catch (error: any) { console.error('Error fetching approved resellers:', error); const errorMsg = error.message || 'Failed to fetch approved resellers'; setError(errorMsg); } finally { setLoading(false); } }; // Filter resellers (all non-pending ones) const filteredResellers = resellers.filter(reseller => { const fullName = `${reseller.firstName} ${reseller.lastName}`.toLowerCase(); const matchesSearch = fullName.includes(searchTerm.toLowerCase()) || reseller.email.toLowerCase().includes(searchTerm.toLowerCase()) || (reseller.company && reseller.company.toLowerCase().includes(searchTerm.toLowerCase())); const matchesStatus = statusFilter === 'all' || reseller.status === statusFilter; const matchesTier = tierFilter === 'all' || reseller.tier === tierFilter; return matchesSearch && matchesStatus && matchesTier; }); const getStatusColor = (status: string) => { switch (status) { case 'active': return 'bg-success-100 text-success-800 dark:bg-success-900 dark:text-success-300'; case 'pending': return 'bg-warning-100 text-warning-800 dark:bg-warning-900 dark:text-warning-300'; case 'suspended': return 'bg-danger-100 text-danger-800 dark:bg-danger-900 dark:text-danger-300'; default: return 'bg-secondary-100 text-secondary-800 dark:bg-secondary-900 dark:text-secondary-300'; } }; const getTierColor = (tier: string) => { switch (tier) { case 'platinum': return 'bg-gradient-to-r from-yellow-400 to-yellow-600 text-white'; case 'gold': return 'bg-gradient-to-r from-yellow-500 to-yellow-700 text-white'; case 'silver': return 'bg-gradient-to-r from-gray-400 to-gray-600 text-white'; default: return 'bg-secondary-100 text-secondary-800 dark:bg-secondary-900 dark:text-secondary-300'; } }; const handleViewReseller = (reseller: Reseller) => { setSelectedReseller(reseller); setIsDetailModalOpen(true); }; const handleEditReseller = (reseller: Reseller) => { toast(`Edit functionality for ${reseller.firstName} ${reseller.lastName} - This would open an edit form`); }; const handleMailReseller = (reseller: Reseller) => { const mailtoLink = `mailto:${reseller.email}?subject=Cloudtopiaa Partnership Update`; window.open(mailtoLink, '_blank'); toast.success(`Opening email client for ${reseller.firstName} ${reseller.lastName}`); }; const handleMoreOptions = (reseller: Reseller) => { const options = [ 'View Performance', 'Download Report', 'Send Notification', 'Change Terms', 'Suspend Partnership' ]; const selectedOption = prompt(`Select an option for ${reseller.firstName} ${reseller.lastName}:\n${options.join('\n')}`); if (selectedOption) { toast.success(`Selected: ${selectedOption} for ${reseller.firstName} ${reseller.lastName}`); } }; if (loading) { return
Loading...
; } if (error) { return (

{error}

); } return (
{/* Header */}

All Resellers

Manage all reseller partnerships (active, inactive, rejected, etc.)

{/* Action Buttons */}
{/* Stats Cards */}

Total Resellers

{resellers.length}

Platinum Tier

{resellers.filter(r => r.tier === 'platinum').length}

Total Customers

{resellers.reduce((sum, r) => sum + (r.customers || 0), 0)}

Total Revenue

{formatCurrency(resellers.reduce((sum, r) => sum + (r.totalRevenue || 0), 0))}

{/* Filters */}
{/* Search */}
setSearchTerm(e.target.value)} className="w-full pl-12 pr-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all" />
{/* Status Filter */}
{/* Tier Filter Row */}
{/* Content Area */} {loading ? (

Loading resellers...

) : resellers.length === 0 ? (

No resellers found

You don't have any reseller partnerships yet.

To get started:

  • • Approve qualified reseller applications
) : (

Reseller List ({resellers.length})

{/* Resellers Table */}
{resellers.map((reseller) => ( ))}
Reseller Contact Tier Status Performance Actions
{reseller.avatar ? ( {`${reseller.firstName} ) : ( )}
{reseller.firstName} {reseller.lastName}
{reseller.company || 'No company'}
{reseller.email}
{reseller.phone && (
{reseller.phone}
)}
{reseller.tier ? reseller.tier.charAt(0).toUpperCase() + reseller.tier.slice(1) : 'Standard'} {reseller.status.charAt(0).toUpperCase() + reseller.status.slice(1)}
Customers: {reseller.customers || 0}
Revenue: {formatCurrency(reseller.totalRevenue || 0)}
)} {/* Reseller Detail Modal */} setIsDetailModalOpen(false)} title="Reseller Details" size="lg" > {selectedReseller && ( )}
); }; export default ApprovedResellersPage;