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

498 lines
21 KiB
TypeScript
Raw Normal View History

2025-09-15 19:46:52 +00:00
import React from "react";
import {
FaTimes,
FaUser,
FaIdCard,
FaEnvelope,
FaPhone,
FaCalendar,
FaBuilding,
FaBriefcase,
FaDollarSign,
FaMapMarkerAlt,
FaUserShield,
FaHeartbeat,
FaEdit,
FaClock,
FaBirthdayCake,
FaGraduationCap,
FaAward,
FaHistory,
} from "react-icons/fa";
2025-09-15 09:31:47 +00:00
import { HrEmployee } from "../../../types/hr";
2025-09-15 19:46:52 +00:00
import {
getEmployeeStatusColor,
getEmployeeStatusIcon,
getEmployeeStatusText,
} from "../../../utils/erp";
interface EmployeeViewModalProps {
isOpen: boolean;
onClose: () => void;
employee: HrEmployee | null;
onEdit?: (employee: HrEmployee) => void;
}
const EmployeeViewModal: React.FC<EmployeeViewModalProps> = ({
isOpen,
onClose,
employee,
onEdit,
}) => {
if (!isOpen || !employee) return null;
2025-09-15 09:31:47 +00:00
2025-09-15 19:46:52 +00:00
const formatDate = (date: Date | string): string => {
return new Date(date).toLocaleDateString("tr-TR");
2025-09-15 09:31:47 +00:00
};
2025-09-15 19:46:52 +00:00
const calculateWorkDuration = (hireDate: Date): string => {
const now = new Date();
const hire = new Date(hireDate);
const diffTime = Math.abs(now.getTime() - hire.getTime());
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
const years = Math.floor(diffDays / 365);
const months = Math.floor((diffDays % 365) / 30);
if (years > 0) {
return `${years} yıl ${months} ay`;
}
return `${months} ay`;
2025-09-15 09:31:47 +00:00
};
2025-09-15 19:46:52 +00:00
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-lg shadow-2xl w-full max-w-4xl max-h-[95vh] overflow-hidden flex flex-col">
{/* Header */}
<div className="bg-gradient-to-r from-blue-600 to-indigo-700 text-white p-3 flex-shrink-0">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-3">
<div className="w-10 h-10 bg-white bg-opacity-20 rounded-full flex items-center justify-center">
<FaUser className="w-5 h-5 text-white" />
</div>
<div>
<h2 className="text-lg font-bold">{employee.fullName}</h2>
<p className="text-blue-100 text-sm">
{employee.jobPosition?.name || "Pozisyon Belirtilmemiş"}
</p>
<p className="text-blue-200 text-xs">{employee.code}</p>
</div>
</div>
<div className="flex items-center space-x-2">
<div
className={`px-2 py-0.5 rounded-full border flex items-center space-x-1.5 text-xs ${getEmployeeStatusColor(
employee.employeeStatus
)} bg-opacity-90`}
>
{getEmployeeStatusIcon(employee.employeeStatus)}
<span className="font-medium text-xs">
{getEmployeeStatusText(employee.employeeStatus)}
</span>
</div>
{onEdit && (
<button
onClick={() => onEdit(employee)}
className="bg-white bg-opacity-20 hover:bg-opacity-30 text-white px-2 py-1 text-xs rounded-md flex items-center space-x-1.5 transition-all"
>
<FaEdit className="w-3 h-3" />
<span>Düzenle</span>
</button>
)}
<button
onClick={onClose}
className="text-white hover:bg-white hover:bg-opacity-20 p-1 rounded-lg transition-all"
>
<FaTimes className="w-5 h-5" />
</button>
</div>
</div>
2025-09-15 09:31:47 +00:00
</div>
2025-09-15 19:46:52 +00:00
{/* Content */}
<div className="p-3 overflow-y-auto flex-grow">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-3">
{/* Left Column - Personal Info */}
<div className="space-y-3">
{/* Kişisel Bilgiler */}
<div className="bg-gray-50 rounded-lg p-3 border border-gray-100">
<h3 className="text-sm font-semibold text-gray-900 mb-2 flex items-center">
<FaIdCard className="w-4 h-4 text-blue-600 mr-2" />
Kişisel Bilgiler
</h3>
<div className="space-y-2">
<div className="flex items-center space-x-2">
<FaBirthdayCake className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">Doğum Tarihi</p>
<p className="font-medium text-sm">
{formatDate(employee.birthDate)}
</p>
</div>
</div>
<div className="flex items-center space-x-2">
<FaUser className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">Cinsiyet</p>
<p className="font-medium text-sm">{employee.gender}</p>
</div>
</div>
<div className="flex items-center space-x-2">
<FaHeartbeat className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">Medeni Durum</p>
<p className="font-medium text-sm">
{employee.maritalStatus}
</p>
</div>
</div>
<div className="flex items-center space-x-2">
<FaIdCard className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">TC Kimlik No</p>
<p className="font-medium text-sm">
{employee.nationalId}
</p>
</div>
</div>
</div>
</div>
{/* İletişim Bilgileri */}
<div className="bg-gray-50 rounded-lg p-3 border border-gray-100">
<h3 className="text-sm font-semibold text-gray-900 mb-2 flex items-center">
<FaPhone className="w-4 h-4 text-green-600 mr-2" />
İletişim Bilgileri
</h3>
<div className="space-y-2">
<div className="flex items-center space-x-2">
<FaEnvelope className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">E-posta</p>
<p className="font-medium text-sm text-blue-600">
{employee.email}
</p>
</div>
</div>
{employee.phone && (
<div className="flex items-center space-x-2">
<FaPhone className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">İş Telefonu</p>
<p className="font-medium text-sm">{employee.phone}</p>
</div>
</div>
)}
{employee.personalPhone && (
<div className="flex items-center space-x-2">
<FaPhone className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">Kişisel Telefon</p>
<p className="font-medium text-sm">
{employee.personalPhone}
</p>
</div>
</div>
)}
{employee.address && (
<div className="flex items-start space-x-2">
<FaMapMarkerAlt className="w-3 h-3 text-gray-500 mt-0.5" />
<div>
<p className="text-xs text-gray-600">Adres</p>
<p className="font-medium text-sm">
{employee.address.street}
<br />
{employee.address.city}, {employee.address.state}
<br />
{employee.address.postalCode},{" "}
{employee.address.country}
</p>
</div>
</div>
)}
</div>
</div>
{/* Acil Durum İletişim */}
{employee.emergencyContact && (
<div className="bg-gray-50 rounded-lg p-3 border border-gray-100">
<h3 className="text-sm font-semibold text-gray-900 mb-2 flex items-center">
<FaUserShield className="w-4 h-4 text-red-600 mr-2" />
Acil Durum İletişim
</h3>
<div className="space-y-2">
<div>
<p className="text-xs text-gray-600">İsim</p>
<p className="font-medium text-sm">
{employee.emergencyContact.name}
</p>
</div>
<div>
<p className="text-xs text-gray-600">Telefon</p>
<p className="font-medium text-sm">
{employee.emergencyContact.phone}
</p>
</div>
<div>
<p className="text-xs text-gray-600">Yakınlık</p>
<p className="font-medium text-sm">
{employee.emergencyContact.relationship}
</p>
</div>
</div>
</div>
)}
</div>
{/* Middle Column - Work Info */}
<div className="space-y-3">
{/* İş Bilgileri */}
<div className="bg-gray-50 rounded-lg p-3 border border-gray-100">
<h3 className="text-sm font-semibold text-gray-900 mb-2 flex items-center">
<FaBriefcase className="w-4 h-4 text-purple-600 mr-2" />
İş Bilgileri
</h3>
<div className="space-y-2">
<div className="flex items-center space-x-2">
<FaBuilding className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">Departman</p>
<p className="font-medium text-sm">
{employee.department?.name || "Belirtilmemiş"}
</p>
</div>
</div>
<div className="flex items-center space-x-2">
<FaGraduationCap className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">Pozisyon</p>
<p className="font-medium text-sm">
{employee.jobPosition?.name || "Belirtilmemiş"}
</p>
</div>
</div>
<div className="flex items-center space-x-2">
<FaCalendar className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">
İşe Başlama Tarihi
</p>
<p className="font-medium text-sm">
{formatDate(employee.hireDate)}
</p>
</div>
</div>
<div className="flex items-center space-x-2">
<FaHistory className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">Çalışma Süresi</p>
<p className="font-medium text-sm">
{calculateWorkDuration(employee.hireDate)}
</p>
</div>
</div>
<div className="flex items-center space-x-2">
<FaBriefcase className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">Çalışma Türü</p>
<p className="font-medium text-sm">
{employee.employmentType}
</p>
</div>
</div>
{employee.workLocation && (
<div className="flex items-center space-x-2">
<FaMapMarkerAlt className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">
Çalışma Lokasyonu
</p>
<p className="font-medium text-sm">
{employee.workLocation}
</p>
</div>
</div>
)}
{employee.badgeNumber && (
<div className="flex items-center space-x-2">
<FaIdCard className="w-3 h-3 text-gray-500" />
<div>
<p className="text-xs text-gray-600">Rozet Numarası</p>
<p className="font-medium text-sm">
{employee.badgeNumber}
</p>
</div>
</div>
)}
</div>
</div>
{/* Yönetici Bilgileri */}
{employee.manager && (
<div className="bg-gray-50 rounded-lg p-3 border border-gray-100">
<h3 className="text-sm font-semibold text-gray-900 mb-2 flex items-center">
<FaUserShield className="w-4 h-4 text-indigo-600 mr-2" />
Yönetici
</h3>
<div className="flex items-center space-x-2">
<div className="w-10 h-10 bg-indigo-100 rounded-full flex items-center justify-center">
<FaUser className="w-5 h-5 text-indigo-600" />
</div>
<div>
<p className="font-medium text-sm text-gray-900">
{employee.manager.fullName}
</p>
<p className="text-xs text-gray-600">
{employee.manager.jobPosition?.name}
</p>
<p className="text-sm text-gray-600">
{employee.manager.email}
</p>
</div>
</div>
</div>
)}
{/* Performans ve Eğitimler */}
<div className="bg-gray-50 rounded-lg p-3 border border-gray-100">
<h3 className="text-sm font-semibold text-gray-900 mb-2 flex items-center">
<FaAward className="w-4 h-4 text-amber-600 mr-2" />
Performans & Gelişim
</h3>
<div className="grid grid-cols-2 gap-3">
<div className="text-center p-1.5 bg-white rounded-md">
<p className="text-xl font-bold text-amber-600">
{employee.evaluations?.length || 0}
</p>
<p className="text-xs text-gray-600">Değerlendirme</p>
</div>
<div className="text-center p-1.5 bg-white rounded-md">
<p className="text-xl font-bold text-emerald-600">
{employee.trainings?.length || 0}
</p>
<p className="text-xs text-gray-600">Eğitim</p>
</div>
</div>
</div>
</div>
{/* Right Column - Financial & Additional Info */}
<div className="space-y-3">
{/* Maaş Bilgileri */}
<div className="bg-gray-50 rounded-lg p-3 border border-gray-100">
<h3 className="text-sm font-semibold text-gray-900 mb-2 flex items-center">
<FaDollarSign className="w-4 h-4 text-emerald-600 mr-2" />
Maaş Bilgileri
</h3>
<div className="space-y-2">
<div>
<p className="text-xs text-gray-600">Temel Maaş</p>
<p className="text-xl font-bold text-emerald-600">
{employee.baseSalary?.toLocaleString()}{" "}
{employee.currency || "TRY"}
</p>
</div>
{employee.payrollGroup && (
<div>
<p className="text-xs text-gray-600">Bordro Grubu</p>
<p className="font-medium text-sm">
{employee.payrollGroup}
</p>
</div>
)}
</div>
</div>
{/* Banka Bilgileri */}
{employee.bankAccount && (
<div className="bg-gray-50 rounded-lg p-3 border border-gray-100">
<h3 className="text-sm font-semibold text-gray-900 mb-2 flex items-center">
<FaDollarSign className="w-4 h-4 text-slate-600 mr-2" />
Banka Bilgileri
</h3>
<div className="space-y-2">
<div>
<p className="text-xs text-gray-600">Banka Adı</p>
<p className="font-medium text-sm">
{employee.bankAccount.bankName}
</p>
</div>
<div>
<p className="text-xs text-gray-600">Hesap Numarası</p>
<p className="font-mono text-xs">
{employee.bankAccount.accountNumber}
</p>
</div>
<div>
<p className="text-xs text-gray-600">IBAN</p>
<p className="font-mono text-xs">
{employee.bankAccount.iban}
</p>
</div>
</div>
</div>
)}
{/* İzin Durumu */}
<div className="bg-gray-50 rounded-lg p-3 border border-gray-100">
<h3 className="text-sm font-semibold text-gray-900 mb-2 flex items-center">
<FaCalendar className="w-4 h-4 text-sky-600 mr-2" />
İzin Durumu
</h3>
<div className="grid grid-cols-1 gap-2">
<div className="bg-white p-1.5 rounded-md flex justify-between items-center">
<span className="text-xs text-gray-600">Toplam İzin</span>
<span className="font-bold text-sm text-sky-600">
{employee.leaves?.length || 0}
</span>
</div>
<div className="bg-white p-1.5 rounded-md flex justify-between items-center">
<span className="text-xs text-gray-600">Kalan İzin</span>
<span className="font-bold text-sm text-emerald-600">
15 gün
</span>
</div>
</div>
</div>
{/* Sistem Bilgileri */}
<div className="bg-gray-50 rounded-lg p-3 border border-gray-100">
<h3 className="text-sm font-semibold text-gray-900 mb-2 flex items-center">
<FaClock className="w-4 h-4 text-gray-600 mr-2" />
Sistem Bilgileri
</h3>
<div className="space-y-2 text-xs">
<div>
<p className="text-gray-600">Oluşturulma Tarihi</p>
<p className="font-medium text-gray-800">
{formatDate(employee.creationTime)}
</p>
</div>
<div>
<p className="text-gray-600">Son Güncelleme</p>
<p className="font-medium text-gray-800">
{formatDate(employee.lastModificationTime)}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
{/* Footer */}
<div className="bg-gray-50 px-3 py-2 border-t flex-shrink-0">
<div className="flex justify-end">
<button
onClick={onClose}
className="px-3 py-1 text-sm bg-gray-600 text-white rounded-md hover:bg-gray-700 transition-colors"
>
Kapat
</button>
</div>
</div>
</div>
</div>
2025-09-15 09:31:47 +00:00
);
};
2025-09-15 19:46:52 +00:00
export default EmployeeViewModal;