erp-platform/ui/src/views/hr/components/EmployeeCards.tsx

183 lines
7 KiB
TypeScript
Raw Normal View History

2025-09-15 19:46:52 +00:00
import React, { useState } from 'react'
2025-09-15 09:31:47 +00:00
import {
FaUser,
FaEnvelope,
FaPhone,
FaCalendar,
FaCertificate,
FaEdit,
FaEye,
FaTrash,
FaPlus,
2025-09-15 19:46:52 +00:00
} from 'react-icons/fa'
2025-10-29 10:20:21 +00:00
import { EmployeeDto, EmployeeStatusEnum } from '../../../types/hr'
2025-09-15 19:46:52 +00:00
import { mockEmployees } from '../../../mocks/mockEmployees'
import { getEmployeeStatusColor, getEmployeeStatusText } from '../../../utils/erp'
import { Container } from '@/components/shared'
2025-09-15 09:31:47 +00:00
const EmployeeCards: React.FC = () => {
2025-10-29 10:20:21 +00:00
const [employees] = useState<EmployeeDto[]>(mockEmployees)
2025-09-15 19:46:52 +00:00
const [selectedDepartment, setSelectedDepartment] = useState<string>('all')
const [selectedStatus, setSelectedStatus] = useState<string>('all')
2025-09-15 09:31:47 +00:00
2025-10-29 10:20:21 +00:00
const handleEdit = (employee: EmployeeDto) => {
2025-09-15 19:46:52 +00:00
console.log('Edit employee:', employee)
2025-09-15 09:31:47 +00:00
// Implement edit functionality
2025-09-15 19:46:52 +00:00
}
2025-09-15 09:31:47 +00:00
2025-10-29 10:20:21 +00:00
const handleView = (employee: EmployeeDto) => {
2025-09-15 19:46:52 +00:00
console.log('View employee:', employee)
2025-09-15 09:31:47 +00:00
// Implement view functionality
2025-09-15 19:46:52 +00:00
}
2025-09-15 09:31:47 +00:00
const handleDelete = (id: string) => {
2025-09-15 19:46:52 +00:00
console.log('Delete employee:', id)
2025-09-15 09:31:47 +00:00
// Implement delete functionality
2025-09-15 19:46:52 +00:00
}
2025-09-15 09:31:47 +00:00
const handleAdd = () => {
2025-09-15 19:46:52 +00:00
console.log('Add new employee')
2025-09-15 09:31:47 +00:00
// Implement add functionality
2025-09-15 19:46:52 +00:00
}
2025-09-15 09:31:47 +00:00
const filteredEmployees = employees.filter((employee) => {
2025-09-15 19:46:52 +00:00
if (selectedDepartment !== 'all' && employee.department?.id !== selectedDepartment) {
return false
2025-09-15 09:31:47 +00:00
}
2025-09-15 19:46:52 +00:00
if (selectedStatus !== 'all' && employee.employeeStatus !== selectedStatus) {
return false
2025-09-15 09:31:47 +00:00
}
2025-09-15 19:46:52 +00:00
return true
})
2025-09-15 09:31:47 +00:00
return (
2025-09-15 19:46:52 +00:00
<Container>
<div className="space-y-2">
{/* Header with Add Button */}
<div className="flex justify-between items-center">
<h2 className="text-xl font-bold text-gray-900">Personel Kartları</h2>
<button
onClick={handleAdd}
className="px-2 py-1.5 text-sm bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors flex items-center gap-2"
>
<FaPlus className="w-4 h-4" />
Yeni Personel
</button>
</div>
2025-09-15 09:31:47 +00:00
2025-09-15 19:46:52 +00:00
{/* Filters */}
<div className="flex gap-3 mb-4">
<select
value={selectedDepartment}
onChange={(e) => setSelectedDepartment(e.target.value)}
className="px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="all">Tüm Departmanlar</option>
{/* Department options would be populated from departments list */}
</select>
2025-09-15 09:31:47 +00:00
2025-09-15 19:46:52 +00:00
<select
value={selectedStatus}
onChange={(e) => setSelectedStatus(e.target.value)}
className="px-2 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
2025-09-15 09:31:47 +00:00
>
2025-09-15 19:46:52 +00:00
<option value="all">Tüm Durumlar</option>
2025-09-17 09:46:58 +00:00
{Object.values(EmployeeStatusEnum).map((status) => (
<option key={status} value={status}>
{getEmployeeStatusText(status)}
</option>
))}
2025-09-15 19:46:52 +00:00
</select>
</div>
2025-09-15 09:31:47 +00:00
2025-09-15 19:46:52 +00:00
{/* Employee Cards Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
{filteredEmployees.map((employee) => (
<div
key={employee.id}
className="bg-white rounded-lg shadow-sm p-3 hover:shadow-md transition-shadow border"
>
{/* Header */}
<div className="flex items-center justify-between mb-3">
<div className="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center">
<FaUser className="w-6 h-6 text-blue-600" />
</div>
<span
className={`px-2 py-1 text-xs font-medium rounded-full ${getEmployeeStatusColor(
employee.employeeStatus,
)}`}
>
{getEmployeeStatusText(employee.employeeStatus)}
</span>
</div>
2025-09-15 09:31:47 +00:00
2025-09-15 19:46:52 +00:00
{/* Employee Info */}
<div className="space-y-1 mb-3">
<h3 className="font-semibold text-sm text-gray-900">{employee.fullName}</h3>
<p className="text-xs text-gray-600">{employee.jobPosition?.name}</p>
<p className="text-sm text-gray-500">{employee.department?.name}</p>
2025-09-15 09:31:47 +00:00
</div>
2025-09-15 19:46:52 +00:00
{/* Contact Info */}
<div className="space-y-1.5 mb-3">
2025-09-15 09:31:47 +00:00
<div className="flex items-center text-xs text-gray-600">
2025-09-15 19:46:52 +00:00
<FaEnvelope className="w-4 h-4 mr-2" />
<span className="truncate">{employee.email}</span>
</div>
{employee.phone && (
<div className="flex items-center text-xs text-gray-600">
<FaPhone className="w-4 h-4 mr-2" />
<span>{employee.phone}</span>
</div>
)}
<div className="flex items-center text-xs text-gray-600">
<FaCalendar className="w-4 h-4 mr-2" />
<span>{new Date(employee.hireDate).toLocaleDateString('tr-TR')}</span>
</div>
<div className="flex items-center text-xs text-gray-600">
<FaCertificate className="w-4 h-4 mr-2" />
<span>{employee.code}</span>
2025-09-15 09:31:47 +00:00
</div>
</div>
2025-09-15 19:46:52 +00:00
{/* Actions */}
<div className="flex gap-2 pt-3 border-t">
<button
onClick={() => handleView(employee)}
className="flex-1 px-2 py-1 text-xs bg-blue-50 text-blue-600 rounded-md hover:bg-blue-100 transition-colors flex items-center justify-center gap-1"
>
<FaEye className="w-4 h-4" />
Görüntüle
</button>
<button
onClick={() => handleEdit(employee)}
className="flex-1 px-2 py-1 text-xs bg-green-50 text-green-600 rounded-md hover:bg-green-100 transition-colors flex items-center justify-center gap-1"
>
<FaEdit className="w-4 h-4" />
Düzenle
</button>
<button
onClick={() => handleDelete(employee.id)}
className="px-2 py-1 text-xs bg-red-50 text-red-600 rounded-md hover:bg-red-100 transition-colors flex items-center justify-center"
>
<FaTrash className="w-4 h-4" />
</button>
2025-09-15 09:31:47 +00:00
</div>
</div>
2025-09-15 19:46:52 +00:00
))}
</div>
2025-09-15 09:31:47 +00:00
2025-09-15 19:46:52 +00:00
{filteredEmployees.length === 0 && (
<div className="text-center py-12">
<FaUser className="w-10 h-10 text-gray-400 mx-auto mb-3" />
<h3 className="text-base font-medium text-gray-900 mb-2">Personel bulunamadı</h3>
<p className="text-gray-500">Seçilen kriterlere uygun personel bulunmamaktadır.</p>
2025-09-15 09:31:47 +00:00
</div>
2025-09-15 19:46:52 +00:00
)}
2025-09-15 09:31:47 +00:00
</div>
2025-09-15 19:46:52 +00:00
</Container>
)
}
2025-09-15 09:31:47 +00:00
2025-09-15 19:46:52 +00:00
export default EmployeeCards