import React, { useState, useMemo } from 'react'; import { ClayCard } from './ClayCard'; import { Button } from './Button'; import { ChevronUp, ChevronDown, Search, Filter, Bell, CheckCircle, XCircle, AlertTriangle, DollarSign, Users } from 'lucide-react'; export interface UserOnboardingRecord { id: string; firstName: string; lastName: string; email: string; brokerage: string; yearsInBusiness: string; gciLast12Months: string; currentCRM: string | null; goalsSelected: string[]; setupStatus: { smsConfigured: boolean; emailConfigured: boolean; contactsImported: boolean; campaignsSetup: boolean; }; createdAt: Date; } interface AdminViewProps { users: UserOnboardingRecord[]; onUserClick?: (userId: string) => void; onNotifyUser?: (userId: string) => void; } type SortField = 'name' | 'email' | 'brokerage' | 'yearsInBusiness' | 'gci' | 'createdAt' | 'setupCompletion'; type SortDirection = 'asc' | 'desc'; type FilterType = 'all' | 'highGCI' | 'incompleteSetup' | 'completeSetup'; const parseGCI = (gciString: string): number => { const cleaned = gciString.replace(/[$,]/g, ''); return parseFloat(cleaned) || 0; }; const getSetupCompletionCount = (status: UserOnboardingRecord['setupStatus']): number => { return [ status.smsConfigured, status.emailConfigured, status.contactsImported, status.campaignsSetup ].filter(Boolean).length; }; const isHighGCI = (gciString: string): boolean => { return parseGCI(gciString) >= 100000; }; const hasIncompleteSetup = (status: UserOnboardingRecord['setupStatus']): boolean => { return getSetupCompletionCount(status) < 4; }; export const AdminView: React.FC = ({ users, onUserClick, onNotifyUser }) => { const [searchQuery, setSearchQuery] = useState(''); const [sortField, setSortField] = useState('createdAt'); const [sortDirection, setSortDirection] = useState('desc'); const [filterType, setFilterType] = useState('all'); const handleSort = (field: SortField) => { if (sortField === field) { setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc'); } else { setSortField(field); setSortDirection('asc'); } }; const filteredAndSortedUsers = useMemo(() => { let result = [...users]; // Apply search filter if (searchQuery) { const query = searchQuery.toLowerCase(); result = result.filter(user => user.firstName.toLowerCase().includes(query) || user.lastName.toLowerCase().includes(query) || user.email.toLowerCase().includes(query) || user.brokerage.toLowerCase().includes(query) ); } // Apply type filter switch (filterType) { case 'highGCI': result = result.filter(user => isHighGCI(user.gciLast12Months)); break; case 'incompleteSetup': result = result.filter(user => hasIncompleteSetup(user.setupStatus)); break; case 'completeSetup': result = result.filter(user => !hasIncompleteSetup(user.setupStatus)); break; } // Apply sorting result.sort((a, b) => { let comparison = 0; switch (sortField) { case 'name': comparison = `${a.firstName} ${a.lastName}`.localeCompare(`${b.firstName} ${b.lastName}`); break; case 'email': comparison = a.email.localeCompare(b.email); break; case 'brokerage': comparison = a.brokerage.localeCompare(b.brokerage); break; case 'yearsInBusiness': comparison = parseFloat(a.yearsInBusiness) - parseFloat(b.yearsInBusiness); break; case 'gci': comparison = parseGCI(a.gciLast12Months) - parseGCI(b.gciLast12Months); break; case 'createdAt': comparison = new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime(); break; case 'setupCompletion': comparison = getSetupCompletionCount(a.setupStatus) - getSetupCompletionCount(b.setupStatus); break; } return sortDirection === 'asc' ? comparison : -comparison; }); return result; }, [users, searchQuery, sortField, sortDirection, filterType]); const SortIcon: React.FC<{ field: SortField }> = ({ field }) => { if (sortField !== field) return null; return sortDirection === 'asc' ? : ; }; const StatusBadge: React.FC<{ configured: boolean; label: string }> = ({ configured, label }) => ( {configured ? : } {label} ); const highGCICount = users.filter(u => isHighGCI(u.gciLast12Months)).length; const incompleteSetupCount = users.filter(u => hasIncompleteSetup(u.setupStatus)).length; return (
{/* Header */}

Admin Dashboard

Manage and monitor user onboarding progress

{/* Stats Cards */}

Total Users

{users.length}

High GCI Users ($100K+)

{highGCICount}

Incomplete Setup

{incompleteSetupCount}

{/* Filters and Search */}
{/* Search */}
setSearchQuery(e.target.value)} className="w-full pl-10 pr-4 py-3 rounded-xl bg-gray-50 border-none shadow-inner focus:ring-2 focus:ring-indigo-500 outline-none" />
{/* Filter Buttons */}
{/* Users Table */}
{filteredAndSortedUsers.map((user) => { const userIsHighGCI = isHighGCI(user.gciLast12Months); const userHasIncompleteSetup = hasIncompleteSetup(user.setupStatus); return ( ); })}
handleSort('name')} > Name handleSort('email')} > Email handleSort('brokerage')} > Brokerage handleSort('yearsInBusiness')} > Years handleSort('gci')} > GCI (12mo) CRM Goals handleSort('setupCompletion')} > Setup Status Actions
onUserClick?.(user.id)} > {user.firstName} {user.lastName} {userIsHighGCI && ( High GCI )}
{user.email} {user.brokerage} {user.yearsInBusiness} {user.gciLast12Months} {user.currentCRM || None}
{user.goalsSelected.length > 0 ? ( user.goalsSelected.map((goal, idx) => ( {goal} )) ) : ( No goals )}
{userHasIncompleteSetup && onNotifyUser && ( )}
{filteredAndSortedUsers.length === 0 && (

No users found

Try adjusting your search or filter criteria

)}
{/* Results Summary */}
Showing {filteredAndSortedUsers.length} of {users.length} users
); };