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

203 lines
7.1 KiB
TypeScript
Raw Normal View History

2025-09-15 09:31:47 +00:00
import React, { useState } from "react";
import {
FaUser,
FaEnvelope,
FaPhone,
FaCalendar,
FaCertificate,
FaEdit,
FaEye,
FaTrash,
FaPlus,
} from "react-icons/fa";
import { HrEmployee, EmployeeStatusEnum } from "../../../types/hr";
import { mockEmployees } from "../../../mocks/mockEmployees";
import {
getEmployeeStatusColor,
getEmployeeStatusText,
} from "../../../utils/erp";
const EmployeeCards: React.FC = () => {
const [employees] = useState<HrEmployee[]>(mockEmployees);
const [selectedDepartment, setSelectedDepartment] = useState<string>("all");
const [selectedStatus, setSelectedStatus] = useState<string>("all");
const handleEdit = (employee: HrEmployee) => {
console.log("Edit employee:", employee);
// Implement edit functionality
};
const handleView = (employee: HrEmployee) => {
console.log("View employee:", employee);
// Implement view functionality
};
const handleDelete = (id: string) => {
console.log("Delete employee:", id);
// Implement delete functionality
};
const handleAdd = () => {
console.log("Add new employee");
// Implement add functionality
};
const filteredEmployees = employees.filter((employee) => {
if (
selectedDepartment !== "all" &&
employee.department?.id !== selectedDepartment
) {
return false;
}
if (
selectedStatus !== "all" &&
employee.employeeStatus !== selectedStatus
) {
return false;
}
return true;
});
return (
<div className="space-y-4 pt-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>
{/* 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>
<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"
>
<option value="all">Tüm Durumlar</option>
<option value={EmployeeStatusEnum.Active}>Aktif</option>
<option value={EmployeeStatusEnum.Inactive}>Pasif</option>
<option value={EmployeeStatusEnum.OnLeave}>İzinli</option>
<option value={EmployeeStatusEnum.Suspended}>Askıda</option>
<option value={EmployeeStatusEnum.Terminated}>
İşten Çıkarılmış
</option>
</select>
</div>
{/* 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>
{/* 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>
</div>
{/* Contact Info */}
<div className="space-y-1.5 mb-3">
<div className="flex items-center text-xs text-gray-600">
<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>
</div>
</div>
{/* 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>
</div>
</div>
))}
</div>
{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>
</div>
)}
</div>
);
};
export default EmployeeCards;