497 lines
21 KiB
TypeScript
497 lines
21 KiB
TypeScript
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";
|
||
import { HrEmployee } from "../../../types/hr";
|
||
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;
|
||
|
||
const formatDate = (date: Date | string): string => {
|
||
return new Date(date).toLocaleDateString("tr-TR");
|
||
};
|
||
|
||
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`;
|
||
};
|
||
|
||
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>
|
||
</div>
|
||
|
||
{/* 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>
|
||
);
|
||
};
|
||
|
||
export default EmployeeViewModal;
|