import React, { useState, useMemo, useCallback, useEffect } from 'react';
import {
Search,
ChevronUp,
ChevronDown,
Filter,
Eye,
Edit,
Trash2,
User,
Mail,
Phone,
Settings,
Download,
Plus,
X,
Check,
Star,
ArrowUpDown,
MoreHorizontal,
Calendar,
Building,
Shield,
Activity,
TrendingUp,
Zap
} from 'lucide-react';
const PremiumTable = () => {
// Enhanced sample data with more fields
const [data] = useState([
{
id: 1,
name: 'Alexandra Chen',
email: 'alex.chen@company.com',
role: 'Senior Engineer',
status: 'Active',
age: 28,
department: 'Engineering',
salary: 125000,
joinDate: '2023-01-15',
performance: 95,
projects: 12,
avatar: 'AC',
phone: '+1 (555) 123-4567',
location: 'San Francisco, CA'
},
{
id: 2,
name: 'Marcus Rodriguez',
email: 'marcus.r@company.com',
role: 'Product Manager',
status: 'Active',
age: 32,
department: 'Product',
salary: 135000,
joinDate: '2022-08-20',
performance: 88,
projects: 8,
avatar: 'MR',
phone: '+1 (555) 987-6543',
location: 'New York, NY'
},
{
id: 3,
name: 'Sarah Kim',
email: 'sarah.kim@company.com',
role: 'Design Lead',
status: 'Active',
age: 29,
department: 'Design',
salary: 118000,
joinDate: '2023-03-10',
performance: 92,
projects: 15,
avatar: 'SK',
phone: '+1 (555) 456-7890',
location: 'Austin, TX'
},
{
id: 4,
name: 'David Thompson',
email: 'david.t@company.com',
role: 'Data Scientist',
status: 'Inactive',
age: 35,
department: 'Analytics',
salary: 140000,
joinDate: '2021-11-05',
performance: 78,
projects: 6,
avatar: 'DT',
phone: '+1 (555) 321-0987',
location: 'Seattle, WA'
},
{
id: 5,
name: 'Emily Watson',
email: 'emily.watson@company.com',
role: 'Marketing Director',
status: 'Active',
age: 38,
department: 'Marketing',
salary: 145000,
joinDate: '2020-06-12',
performance: 91,
projects: 20,
avatar: 'EW',
phone: '+1 (555) 654-3210',
location: 'Los Angeles, CA'
},
{
id: 6,
name: 'James Wilson',
email: 'james.wilson@company.com',
role: 'DevOps Engineer',
status: 'Active',
age: 31,
department: 'Engineering',
salary: 128000,
joinDate: '2022-12-01',
performance: 89,
projects: 9,
avatar: 'JW',
phone: '+1 (555) 789-0123',
location: 'Denver, CO'
}
]);
const [searchTerm, setSearchTerm] = useState('');
const [sortConfig, setSortConfig] = useState({ key: 'performance', direction: 'desc' });
const [selectedRows, setSelectedRows] = useState(new Set());
const [viewMode, setViewMode] = useState('table'); // table, grid, compact
const [showAdvancedFilters, setShowAdvancedFilters] = useState(false);
const [animateRows, setAnimateRows] = useState(false);
const [filters, setFilters] = useState({
role: '',
status: '',
department: '',
salaryMin: '',
salaryMax: '',
performanceMin: 0,
joinDateFrom: '',
joinDateTo: ''
});
useEffect(() => {
setAnimateRows(true);
const timer = setTimeout(() => setAnimateRows(false), 300);
return () => clearTimeout(timer);
}, [sortConfig, filters, searchTerm]);
// Enhanced column configuration
const columns = [
{
key: 'select',
header: '',
width: '60px',
render: (item) => (
<div className="flex items-center justify-center">
<input
type="checkbox"
checked={selectedRows.has(item.id)}
onChange={(e) => handleRowSelect(item.id, e.target.checked)}
className="w-4 h-4 text-indigo-600 bg-gray-100 border-2 border-gray-300 rounded-md focus:ring-indigo-500 focus:ring-2 transition-all duration-200"
/>
</div>
),
sortable: false
},
{
key: 'name',
header: 'Employee',
sortable: true,
render: (item) => (
<div className="flex items-center space-x-4 group cursor-pointer">
<div className="relative">
<div className="w-12 h-12 bg-gradient-to-br from-indigo-400 to-purple-600 rounded-xl flex items-center justify-center text-white font-bold text-sm shadow-lg group-hover:shadow-xl transition-all duration-300 group-hover:scale-105">
{item.avatar}
</div>
<div className={`absolute -bottom-1 -right-1 w-4 h-4 rounded-full border-2 border-white ${
item.status === 'Active' ? 'bg-emerald-400' : 'bg-gray-400'
}`}></div>
</div>
<div className="flex-1">
<div className="font-semibold text-gray-900 group-hover:text-indigo-600 transition-colors duration-200">
{item.name}
</div>
<div className="text-sm text-gray-500 flex items-center space-x-2">
<span>{item.location}</span>
<span>โข</span>
<span>ID: {item.id}</span>
</div>
</div>
</div>
),
onClick: (item) => handleEmployeeClick(item)
},
{
key: 'role',
header: 'Role & Department',
sortable: true,
render: (item) => (
<div className="space-y-1">
<div className="font-medium text-gray-900">{item.role}</div>
<div className="flex items-center space-x-1">
<Building className="w-3 h-3 text-gray-400" />
<span className="text-sm text-gray-600">{item.department}</span>
</div>
</div>
)
},
{
key: 'performance',
header: 'Performance',
sortable: true,
render: (item) => (
<div className="space-y-2">
<div className="flex items-center justify-between">
<span className="text-sm font-medium text-gray-900">{item.performance}%</span>
<div className="flex items-center space-x-1">
{item.performance >= 90 ? (
<Star className="w-4 h-4 text-yellow-500 fill-current" />
) : item.performance >= 80 ? (
<TrendingUp className="w-4 h-4 text-green-500" />
) : (
<Activity className="w-4 h-4 text-orange-500" />
)}
</div>
</div>
<div className="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
<div
className={`h-2 rounded-full transition-all duration-500 ${
item.performance >= 90 ? 'bg-gradient-to-r from-green-400 to-emerald-500' :
item.performance >= 80 ? 'bg-gradient-to-r from-blue-400 to-indigo-500' :
item.performance >= 70 ? 'bg-gradient-to-r from-yellow-400 to-orange-500' :
'bg-gradient-to-r from-red-400 to-pink-500'
}`}
style={{ width: `${item.performance}%` }}
></div>
</div>
</div>
)
},
{
key: 'salary',
header: 'Compensation',
sortable: true,
render: (item) => (
<div className="space-y-1">
<div className="font-bold text-gray-900">
${item.salary.toLocaleString()}
</div>
<div className="text-xs text-gray-500">Annual</div>
<div className="text-xs text-gray-400">{item.projects} projects</div>
</div>
)
},
{
key: 'contact',
header: 'Contact',
sortable: false,
render: (item) => (
<div className="space-y-2">
<div
className="flex items-center space-x-2 cursor-pointer text-indigo-600 hover:text-indigo-800 transition-colors"
onClick={(e) => {e.stopPropagation(); handleEmailClick(item);}}
>
<Mail className="w-4 h-4" />
<span className="text-sm truncate max-w-32">{item.email}</span>
</div>
<div
className="flex items-center space-x-2 cursor-pointer text-gray-600 hover:text-gray-800 transition-colors"
onClick={(e) => {e.stopPropagation(); handlePhoneClick(item);}}
>
<Phone className="w-4 h-4" />
<span className="text-sm">{item.phone}</span>
</div>
</div>
)
},
{
key: 'joinDate',
header: 'Join Date',
sortable: true,
render: (item) => (
<div className="space-y-1">
<div className="flex items-center space-x-2">
<Calendar className="w-4 h-4 text-gray-400" />
<span className="text-sm text-gray-900">
{new Date(item.joinDate).toLocaleDateString()}
</span>
</div>
<div className="text-xs text-gray-500">
{Math.floor((new Date() - new Date(item.joinDate)) / (1000 * 60 * 60 * 24 * 365))} years
</div>
</div>
)
},
{
key: 'status',
header: 'Status',
sortable: true,
render: (item) => (
<div className="flex flex-col items-center space-y-2">
<span className={`px-3 py-1 text-xs font-bold rounded-full shadow-sm ${
item.status === 'Active'
? 'bg-emerald-100 text-emerald-800 border border-emerald-200'
: 'bg-gray-100 text-gray-800 border border-gray-200'
}`}>
{item.status}
</span>
{item.status === 'Active' && (
<Zap className="w-4 h-4 text-emerald-500 animate-pulse" />
)}
</div>
)
},
{
key: 'actions',
header: 'Actions',
width: '140px',
render: (item) => (
<div className="flex items-center space-x-1">
<button
onClick={(e) => {e.stopPropagation(); handleView(item);}}
className="p-2 text-blue-600 hover:text-blue-800 hover:bg-blue-50 rounded-lg transition-all duration-200 group"
title="View Details"
>
<Eye className="w-4 h-4 group-hover:scale-110 transition-transform" />
</button>
<button
onClick={(e) => {e.stopPropagation(); handleEdit(item);}}
className="p-2 text-emerald-600 hover:text-emerald-800 hover:bg-emerald-50 rounded-lg transition-all duration-200 group"
title="Edit Employee"
>
<Edit className="w-4 h-4 group-hover:scale-110 transition-transform" />
</button>
<button
onClick={(e) => {e.stopPropagation(); handleDelete(item);}}
className="p-2 text-red-600 hover:text-red-800 hover:bg-red-50 rounded-lg transition-all duration-200 group"
title="Delete Employee"
>
<Trash2 className="w-4 h-4 group-hover:scale-110 transition-transform" />
</button>
<div className="relative group">
<button className="p-2 text-gray-600 hover:text-gray-800 hover:bg-gray-50 rounded-lg transition-all duration-200">
<MoreHorizontal className="w-4 h-4" />
</button>
</div>
</div>
),
sortable: false
}
];
// Enhanced click handlers
const handleEmployeeClick = (item) => {
alert(`๐ค Employee Profile: ${item.name}\n๐ง ${item.email}\n๐ข ${item.role} at ${item.department}\n๐ Performance: ${item.performance}%`);
};
const handleEmailClick = (item) => {
window.open(`mailto:${item.email}?subject=Hello ${item.name}`, '_blank');
};
const handlePhoneClick = (item) => {
navigator.clipboard.writeText(item.phone);
alert(`๐ Phone number copied: ${item.phone}`);
};
const handleView = (item) => {
alert(`๐๏ธ Viewing detailed profile for ${item.name}`);
};
const handleEdit = (item) => {
alert(`โ๏ธ Opening edit form for ${item.name}`);
};
const handleDelete = (item) => {
if (window.confirm(`๐๏ธ Are you sure you want to delete ${item.name}?`)) {
alert(`โ ${item.name} has been deleted`);
}
};
// Enhanced selection handlers
const handleRowSelect = (id, checked) => {
const newSelected = new Set(selectedRows);
if (checked) {
newSelected.add(id);
} else {
newSelected.delete(id);
}
setSelectedRows(newSelected);
};
const handleSelectAll = (checked) => {
if (checked) {
setSelectedRows(new Set(filteredAndSortedData.map(item => item.id)));
} else {
setSelectedRows(new Set());
}
};
// Enhanced sorting with animation
const handleSort = useCallback((key) => {
setSortConfig(prevConfig => ({
key,
direction: prevConfig.key === key && prevConfig.direction === 'asc' ? 'desc' : 'asc'
}));
}, []);
// Advanced filtering and sorting
const filteredAndSortedData = useMemo(() => {
let result = [...data];
// Global search
if (searchTerm) {
result = result.filter(item =>
Object.values(item).some(value =>
value.toString().toLowerCase().includes(searchTerm.toLowerCase())
)
);
}
// Advanced filters
if (filters.role) {
result = result.filter(item =>
item.role.toLowerCase().includes(filters.role.toLowerCase())
);
}
if (filters.status) {
result = result.filter(item => item.status === filters.status);
}
if (filters.department) {
result = result.filter(item => item.department === filters.department);
}
if (filters.salaryMin) {
result = result.filter(item => item.salary >= parseInt(filters.salaryMin));
}
if (filters.salaryMax) {
result = result.filter(item => item.salary <= parseInt(filters.salaryMax));
}
if (filters.performanceMin > 0) {
result = result.filter(item => item.performance >= filters.performanceMin);
}
if (filters.joinDateFrom) {
result = result.filter(item => new Date(item.joinDate) >= new Date(filters.joinDateFrom));
}
if (filters.joinDateTo) {
result = result.filter(item => new Date(item.joinDate) <= new Date(filters.joinDateTo));
}
// Enhanced sorting
if (sortConfig.key) {
result.sort((a, b) => {
let aValue = a[sortConfig.key];
let bValue = b[sortConfig.key];
if (sortConfig.key === 'joinDate') {
aValue = new Date(aValue);
bValue = new Date(bValue);
}
if (aValue < bValue) return sortConfig.direction === 'asc' ? -1 : 1;
if (aValue > bValue) return sortConfig.direction === 'asc' ? 1 : -1;
return 0;
});
}
return result;
}, [data, searchTerm, filters, sortConfig]);
const getUniqueValues = (key) => {
return [...new Set(data.map(item => item[key]))].sort();
};
const clearFilters = () => {
setFilters({
role: '',
status: '',
department: '',
salaryMin: '',
salaryMax: '',
performanceMin: 0,
joinDateFrom: '',
joinDateTo: ''
});
setSearchTerm('');
};
return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-50 p-6">
<div className="max-w-7xl mx-auto">
{/* Premium Header */}
<div className="bg-white rounded-2xl shadow-xl border border-gray-100 mb-6 overflow-hidden">
<div className="bg-gradient-to-r from-indigo-600 via-purple-600 to-indigo-800 px-8 py-6">
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold text-white mb-2">Employee Directory</h1>
<p className="text-indigo-200">
{filteredAndSortedData.length} of {data.length} employees
{selectedRows.size > 0 && (
<span className="ml-2 px-3 py-1 bg-white/20 rounded-full text-sm">
{selectedRows.size} selected
</span>
)}
</p>
</div>
<div className="flex items-center space-x-4">
<button className="px-6 py-3 bg-white/20 hover:bg-white/30 text-white rounded-xl font-semibold transition-all duration-200 flex items-center space-x-2">
<Plus className="w-5 h-5" />
<span>Add Employee</span>
</button>
<button className="p-3 bg-white/20 hover:bg-white/30 text-white rounded-xl transition-all duration-200">
<Settings className="w-5 h-5" />
</button>
</div>
</div>
</div>
{/* Enhanced Controls */}
<div className="p-6 bg-gradient-to-r from-gray-50 to-white">
<div className="flex flex-wrap gap-4 items-center justify-between mb-4">
{/* Search with enhanced styling */}
<div className="relative flex-1 max-w-md">
<Search className="absolute left-4 top-1/2 transform -translate-y-1/2 text-gray-400 w-5 h-5" />
<input
type="text"
placeholder="Search employees, roles, departments..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="w-full pl-12 pr-4 py-3 bg-white border-2 border-gray-200 rounded-xl focus:ring-4 focus:ring-indigo-100 focus:border-indigo-500 transition-all duration-200 shadow-sm"
/>
</div>
{/* Filter Controls */}
<div className="flex items-center space-x-3">
<button
onClick={() => setShowAdvancedFilters(!showAdvancedFilters)}
className={`px-4 py-2 rounded-lg font-medium transition-all duration-200 flex items-center space-x-2 ${
showAdvancedFilters
? 'bg-indigo-100 text-indigo-700 border-2 border-indigo-200'
: 'bg-gray-100 text-gray-700 border-2 border-gray-200 hover:bg-gray-200'
}`}
>
<Filter className="w-4 h-4" />
<span>Advanced Filters</span>
</button>
{selectedRows.size > 0 && (
<div className="flex space-x-2 animate-in slide-in-from-right duration-300">
<button className="px-4 py-2 bg-emerald-600 hover:bg-emerald-700 text-white rounded-lg font-medium transition-all duration-200 flex items-center space-x-2">
<Download className="w-4 h-4" />
<span>Export</span>
</button>
<button className="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg font-medium transition-all duration-200">
<Trash2 className="w-4 h-4" />
</button>
</div>
)}
</div>
</div>
{/* Advanced Filters Panel */}
{showAdvancedFilters && (
<div className="bg-white rounded-xl border-2 border-gray-100 p-6 animate-in slide-in-from-top duration-300">
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold text-gray-900">Advanced Filters</h3>
<button
onClick={clearFilters}
className="text-sm text-indigo-600 hover:text-indigo-800 font-medium"
>
Clear All
</button>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Role</label>
<select
value={filters.role}
onChange={(e) => setFilters(prev => ({ ...prev, role: e.target.value }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
>
<option value="">All Roles</option>
{getUniqueValues('role').map(role => (
<option key={role} value={role}>{role}</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Department</label>
<select
value={filters.department}
onChange={(e) => setFilters(prev => ({ ...prev, department: e.target.value }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
>
<option value="">All Departments</option>
{getUniqueValues('department').map(dept => (
<option key={dept} value={dept}>{dept}</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Status</label>
<select
value={filters.status}
onChange={(e) => setFilters(prev => ({ ...prev, status: e.target.value }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
>
<option value="">All Status</option>
{getUniqueValues('status').map(status => (
<option key={status} value={status}>{status}</option>
))}
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Min Performance</label>
<input
type="range"
min="0"
max="100"
value={filters.performanceMin}
onChange={(e) => setFilters(prev => ({ ...prev, performanceMin: parseInt(e.target.value) }))}
className="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer"
/>
<div className="text-sm text-gray-600 mt-1">{filters.performanceMin}%+</div>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mt-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Min Salary</label>
<input
type="number"
placeholder="50000"
value={filters.salaryMin}
onChange={(e) => setFilters(prev => ({ ...prev, salaryMin: e.target.value }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Max Salary</label>
<input
type="number"
placeholder="200000"
value={filters.salaryMax}
onChange={(e) => setFilters(prev => ({ ...prev, salaryMax: e.target.value }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Join Date From</label>
<input
type="date"
value={filters.joinDateFrom}
onChange={(e) => setFilters(prev => ({ ...prev, joinDateFrom: e.target.value }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Join Date To</label>
<input
type="date"
value={filters.joinDateTo}
onChange={(e) => setFilters(prev => ({ ...prev, joinDateTo: e.target.value }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
/>
</div>
</div>
</div>
)}
</div>
</div>
{/* Premium Table */}
<div className="bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden">
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="bg-gradient-to-r from-gray-50 to-gray-100 border-b border-gray-200">
<th className="px-6 py-4">
<input
type="checkbox"
checked={selectedRows.size === filteredAndSortedData.length && filteredAndSortedData.length > 0}
onChange={(e) => handleSelectAll(e.target.checked)}
className="w-4 h-4 text-indigo-600 bg-gray-100 border-2 border-gray-300 rounded-md focus:ring-indigo-500 focus:ring-2"
/>
</th>
{columns.slice(1).map((column) => (
<th
key={column.key}
className={`px-6 py-4 text-left text-sm font-bold text-gray-700 uppercase tracking-wider ${
column.sortable ? 'cursor-pointer hover:bg-gray-200 transition-colors duration-200 select-none' : ''
}`}
style={{ width: column.width }}
onClick={() => column.sortable && handleSort(column.key)}
>
<div className="flex items-center space-x-2 group">
<span className="group-hover:text-indigo-600 transition-colors">{column.header}</span>
{column.sortable && (
<div className="flex flex-col opacity-50 group-hover:opacity-100 transition-opacity">
{sortConfig.key === column.key ? (
sortConfig.direction === 'asc' ? (
<ChevronUp className="w-4 h-4 text-indigo-600" />
) : (
<ChevronDown className="w-4 h-4 text-indigo-600" />
)
) : (
<ArrowUpDown className="w-4 h-4 text-gray-400 group-hover:text-indigo-500" />
)}
</div>
)}
</div>
</th>
))}
</tr>
</thead>
<tbody className="divide-y divide-gray-100">
{filteredAndSortedData.map((item, index) => (
<tr
key={item.id}
className={`
hover:bg-gradient-to-r hover:from-indigo-50 hover:to-purple-50
transition-all duration-300 cursor-pointer group
${selectedRows.has(item.id) ? 'bg-indigo-50 border-l-4 border-indigo-500' : ''}
${animateRows ? 'animate-pulse' : ''}
`}
style={{
animationDelay: animateRows ? `${index * 50}ms` : '0ms'
}}
>
{columns.map((column) => (
<td
key={column.key}
className={`px-6 py-6 whitespace-nowrap transition-all duration-200 ${
column.onClick ? 'cursor-pointer' : ''
}`}
onClick={() => column.onClick && column.onClick(item)}
>
{column.render ? column.render(item) : item[column.key]}
</td>
))}
</tr>
))}
</tbody>
</table>
{/* Empty State */}
{filteredAndSortedData.length === 0 && (
<div className="text-center py-16">
<div className="w-24 h-24 mx-auto mb-4 bg-gradient-to-br from-gray-100 to-gray-200 rounded-full flex items-center justify-center">
<Search className="w-12 h-12 text-gray-400" />
</div>
<h3 className="text-xl font-semibold text-gray-900 mb-2">No employees found</h3>
<p className="text-gray-500 mb-6">Try adjusting your search criteria or filters</p>
<button
onClick={clearFilters}
className="px-6 py-3 bg-indigo-600 hover:bg-indigo-700 text-white rounded-xl font-semibold transition-all duration-200"
>
Clear all filters
</button>
</div>
)}
</div>
{/* Premium Footer with Analytics */}
<div className="bg-gradient-to-r from-gray-50 to-white border-t border-gray-200 px-8 py-6">
<div className="flex flex-wrap items-center justify-between gap-4">
<div className="flex items-center space-x-8">
<div className="text-sm text-gray-600">
<span className="font-semibold text-gray-900">
{filteredAndSortedData.length}
</span> of <span className="font-semibold">{data.length}</span> employees
</div>
<div className="flex items-center space-x-6 text-sm text-gray-600">
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-emerald-400 rounded-full"></div>
<span>Active: {data.filter(item => item.status === 'Active').length}</span>
</div>
<div className="flex items-center space-x-2">
<div className="w-3 h-3 bg-gray-400 rounded-full"></div>
<span>Inactive: {data.filter(item => item.status === 'Inactive').length}</span>
</div>
</div>
</div>
<div className="flex items-center space-x-6">
<div className="text-sm text-gray-600">
<span className="font-semibold">Avg Performance:</span>
<span className="ml-1 text-indigo-600 font-bold">
{Math.round(data.reduce((sum, item) => sum + item.performance, 0) / data.length)}%
</span>
</div>
<div className="text-sm text-gray-600">
<span className="font-semibold">Total Projects:</span>
<span className="ml-1 text-purple-600 font-bold">
{data.reduce((sum, item) => sum + item.projects, 0)}
</span>
</div>
<div className="text-xs text-gray-500 bg-gray-100 px-3 py-2 rounded-full">
Built with React & Premium UI
</div>
</div>
</div>
</div>
</div>
{/* Floating Action Button */}
<div className="fixed bottom-8 right-8">
<button className="w-16 h-16 bg-gradient-to-r from-indigo-600 to-purple-600 hover:from-indigo-700 hover:to-purple-700 text-white rounded-full shadow-2xl hover:shadow-3xl transition-all duration-300 flex items-center justify-center group hover:scale-110">
<Plus className="w-8 h-8 group-hover:rotate-90 transition-transform duration-300" />
</button>
</div>
{/* Selection Info Toast */}
{selectedRows.size > 0 && (
<div className="fixed bottom-8 left-8 bg-white rounded-2xl shadow-2xl border border-gray-200 p-6 animate-in slide-in-from-left duration-300">
<div className="flex items-center space-x-4">
<div className="w-12 h-12 bg-indigo-100 rounded-xl flex items-center justify-center">
<Check className="w-6 h-6 text-indigo-600" />
</div>
<div>
<div className="font-semibold text-gray-900">
{selectedRows.size} employee{selectedRows.size > 1 ? 's' : ''} selected
</div>
<div className="text-sm text-gray-500">
Ready for bulk actions
</div>
</div>
<button
onClick={() => setSelectedRows(new Set())}
className="p-2 text-gray-400 hover:text-gray-600 transition-colors"
>
<X className="w-5 h-5" />
</button>
</div>
</div>
)}
</div>
</div>
);
};
export default PremiumTable;
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)