import React, { useState } from 'react' import { FaUsers, FaEye, FaEdit, FaPlus, FaChartBar, FaTimes, FaSave, FaPlay, FaPoll, } from 'react-icons/fa' import { HrEvaluation360, CampaignStatusEnum, AssessorTypeEnum, ParticipantStatusEnum, QuestionTypeEnum, ResultStatusEnum, HrEvaluation360Result, HrGroupScore, HrAssessorTypeScore, } from '../../../types/hr' import DataTable, { Column } from '../../../components/common/DataTable' import { mockEvaluation360 } from '../../../mocks/mockEvaluation360' import { mockEvaluation360Results } from '../../../mocks/mockEvaluation360Results' import { mockEmployees } from '../../../mocks/mockEmployees' import { mockDepartments } from '../../../mocks/mockDepartments' import { mockEvaluation360Templates } from '../../../mocks/mockEvaluation360Templates' import { mockBusinessParties } from '../../../mocks/mockBusinessParties' import Widget from '../../../components/common/Widget' import { getAssessorTypeDescription, getAssessorTypeText, getParticipantStatusColor, getParticipantStatusText, getCampaignStatusColor, getCampaignStatusText, } from '../../../utils/erp' import { Container } from '@/components/shared' const Degree360Evaluation: React.FC = () => { const [activeTab, setActiveTab] = useState<'campaigns' | 'results'>('campaigns') const [selectedStatus, setSelectedStatus] = useState('all') const [selectedEmployee, setSelectedEmployee] = useState('all') const [selectedDepartment, setSelectedDepartment] = useState('all') // Results tab filters const [selectedResultsStatus, setSelectedResultsStatus] = useState('all') const [selectedResultsEmployee, setSelectedResultsEmployee] = useState('all') const [selectedResultsDepartment, setSelectedResultsDepartment] = useState('all') const [selectedResultsCampaign, setSelectedResultsCampaign] = useState('all') // Modal states const [showCampaignModal, setShowCampaignModal] = useState(false) const [showViewModal, setShowViewModal] = useState(false) const [showEvaluationModal, setShowEvaluationModal] = useState(false) const [showResultDetailModal, setShowResultDetailModal] = useState(false) const [showResultEditModal, setShowResultEditModal] = useState(false) const [selectedCampaign, setSelectedCampaign] = useState(null) const [selectedResult, setSelectedResult] = useState<{ resultId: string evaluatedEmployeeName: string evaluatorName: string campaignName: string overallScore: number scorePercentage: number evaluatedEmployeeId: string evaluatorId: string campaignId: string evaluatorType: AssessorTypeEnum status: ParticipantStatusEnum completedDate?: Date } | null>(null) // Evaluation states const [evaluationTarget, setEvaluationTarget] = useState('') const [evaluationEvaluator, setEvaluationEvaluator] = useState('') const [selectedAssessorType, setSelectedAssessorType] = useState(null) const [externalEvaluatorName, setExternalEvaluatorName] = useState('') const [externalEvaluatorEmail, setExternalEvaluatorEmail] = useState('') const [selectedCustomerId, setSelectedCustomerId] = useState('') const [evaluatorSearchTerm, setEvaluatorSearchTerm] = useState('') const [currentCampaignForEvaluation, setCurrentCampaignForEvaluation] = useState(null) // Evaluation responses state const [evaluationResponses, setEvaluationResponses] = useState>( {}, ) // Edit modal states const [editResponses, setEditResponses] = useState>({}) const [editManagerComments, setEditManagerComments] = useState('') const [editHrComments, setEditHrComments] = useState('') const [editResultStatus, setEditResultStatus] = useState('PENDING') // Form states const [campaignFormData, setCampaignFormData] = useState({ name: '', description: '', templateId: '', departmentId: '', targetEmployees: [] as string[], startDate: '', endDate: '', }) // Event handlers const handleCloseModal = () => { setShowCampaignModal(false) setShowViewModal(false) setShowEvaluationModal(false) setShowResultDetailModal(false) setShowResultEditModal(false) setSelectedCampaign(null) setSelectedResult(null) setEvaluationTarget('') setEvaluationEvaluator('') setSelectedAssessorType(null) setExternalEvaluatorName('') setExternalEvaluatorEmail('') setSelectedCustomerId('') setEvaluatorSearchTerm('') setCurrentCampaignForEvaluation(null) setEvaluationResponses({}) setEditResponses({}) setEditManagerComments('') setEditHrComments('') setEditResultStatus('PENDING') setCampaignFormData({ name: '', description: '', templateId: '', departmentId: '', targetEmployees: [], startDate: '', endDate: '', }) } // Response handling functions const handleResponseChange = (questionId: string, value: string | number) => { setEvaluationResponses((prev) => ({ ...prev, [questionId]: value, })) } // Edit response handling function const handleEditResponseChange = (questionId: string, value: string | number) => { setEditResponses((prev) => ({ ...prev, [questionId]: value, })) } // Evaluation kaydetme fonksiyonu const handleSaveEvaluation = () => { if (!currentCampaignForEvaluation || !evaluationTarget || !evaluationEvaluator) { alert('Tüm alanları doldurun!') return } const template = mockEvaluation360Templates.find( (t) => t.id === currentCampaignForEvaluation.templateId, ) if (!template) { alert('Template bulunamadı!') return } // Responses oluştur const responses = Object.entries(evaluationResponses).map(([questionId, responseValue]) => { const question = template.questionGroups .flatMap((g) => g.questions) .find((q) => q.id === questionId) let score = 0 if (question) { if (question.questionType === QuestionTypeEnum.Rating) { score = Number(responseValue) } else if (question.questionType === QuestionTypeEnum.YesNo) { score = responseValue === 'yes' ? question.maxRating || 5 : question.minRating || 1 } else if (question.questionType === QuestionTypeEnum.MultipleChoice) { const option = question.options?.find((o) => o.value === Number(responseValue)) score = option?.value || 0 } } return { id: `response-${Date.now()}-${Math.random()}`, participantId: `participant-${Date.now()}`, questionId, question, responseValue, responseText: typeof responseValue === 'string' ? responseValue : undefined, score, submittedDate: new Date(), } }) // Puanları hesapla const totalScore = responses.reduce((sum, response) => sum + response.score, 0) const maxScore = template.questionGroups .flatMap((g) => g.questions) .reduce((sum, q) => sum + (q.maxRating || 5), 0) const scorePercentage = maxScore > 0 ? (totalScore / maxScore) * 100 : 0 // Grup skorlarını hesapla const groupScores: HrGroupScore[] = template.questionGroups.map((group) => { const groupResponses = responses.filter((r) => group.questions.some((q) => q.id === r.questionId), ) const groupScore = groupResponses.reduce((sum, r) => sum + r.score, 0) const groupMaxScore = group.questions.reduce((sum, q) => sum + (q.maxRating || 5), 0) return { groupId: group.id, groupName: group.groupName, score: groupScore, maxScore: groupMaxScore, percentage: groupMaxScore > 0 ? (groupScore / groupMaxScore) * 100 : 0, responseCount: groupResponses.length, } }) // Assessor type skorlarını hesapla const assessorTypeScores: HrAssessorTypeScore[] = [ { assessorType: selectedAssessorType!, assessorCount: 1, averageScore: totalScore, maxScore: maxScore, percentage: scorePercentage, }, ] // Evaluation360Result oluştur const evaluationResult: HrEvaluation360Result = { id: `result-${Date.now()}`, campaignId: currentCampaignForEvaluation.id, employeeId: evaluationTarget, employee: mockEmployees.find((e) => e.id === evaluationTarget), participants: [ { id: `participant-${Date.now()}`, campaignId: currentCampaignForEvaluation.id, evaluatedEmployeeId: evaluationTarget, evaluatedEmployee: mockEmployees.find((e) => e.id === evaluationTarget), evaluatorId: evaluationEvaluator, evaluator: selectedAssessorType === AssessorTypeEnum.External || selectedAssessorType === AssessorTypeEnum.Customer ? undefined // External ve Customer için Employee bilgisi yok : mockEmployees.find((e) => e.id === evaluationEvaluator), evaluatorType: selectedAssessorType!, status: ParticipantStatusEnum.Completed, invitedDate: new Date(), startedDate: new Date(), completedDate: new Date(), responses, overallScore: totalScore, notes: '', }, ], overallScore: totalScore, maxPossibleScore: maxScore, scorePercentage, groupScores, assessorTypeScores, strengths: ['Güçlü iletişim', 'Takım çalışması'], // Örnek veriler developmentAreas: ['Zaman yönetimi', 'Teknik beceriler'], // Örnek veriler actionPlan: ['Zaman yönetimi kursu alma', 'Teknik eğitimlere katılma'], // Örnek veriler managerComments: '', hrComments: '', status: ResultStatusEnum.Pending, generatedDate: new Date(), approvedBy: undefined, approvedDate: undefined, } // Console'a yazdır console.log('Evaluation360Result:', evaluationResult) alert('Değerlendirme başarıyla kaydedildi! Sonuç konsola yazdırıldı.') handleCloseModal() } const handleNewCampaign = () => { setSelectedCampaign(null) setShowCampaignModal(true) } const handleEditCampaign = (campaign: HrEvaluation360 | null) => { if (campaign) { setSelectedCampaign(campaign) setCampaignFormData({ name: campaign.name, description: campaign.description, templateId: campaign.templateId, departmentId: campaign.departmentId || '', targetEmployees: campaign.targetEmployees, startDate: campaign.startDate.toISOString().split('T')[0], endDate: campaign.endDate.toISOString().split('T')[0], }) setShowCampaignModal(true) } } const handleViewCampaign = (campaign: HrEvaluation360) => { setSelectedCampaign(campaign) setShowViewModal(true) } const handleSaveCampaign = () => { console.log('Değerlendirme kaydediliyor:', campaignFormData) handleCloseModal() } const handleDepartmentChange = (departmentId: string) => { setSelectedDepartment(departmentId) setCampaignFormData({ ...campaignFormData, departmentId, targetEmployees: [], }) } // Değerlendirme yapma handler'ı const handleStartEvaluation = () => { setCurrentCampaignForEvaluation(null) setEvaluationTarget('') setEvaluationEvaluator('') setShowEvaluationModal(true) } // Otomatik değerlendirici belirleme fonksiyonu (360° metodolojisi) const getEvaluatorsByType = (targetEmployeeId: string, assessorType: AssessorTypeEnum) => { const targetEmployee = mockEmployees.find((emp) => emp.id === targetEmployeeId) if (!targetEmployee) return [] switch (assessorType) { case AssessorTypeEnum.Self: { return [ { id: targetEmployee.id, name: targetEmployee.fullName, title: targetEmployee.jobPosition?.name, department: mockDepartments.find((d) => d.id === targetEmployee.departmantId)?.name || '', type: 'employee', }, ] } case AssessorTypeEnum.Manager: { const managers = mockEmployees.filter( (emp) => emp.departmantId === targetEmployee.departmantId && (typeof emp.jobPosition?.level === 'number' && typeof targetEmployee.jobPosition?.level === 'number' ? emp.jobPosition?.level > targetEmployee.jobPosition?.level : emp.jobPosition?.name.includes('Müdür') || emp.jobPosition?.name.includes('Manager')), ) return managers.map((emp) => ({ id: emp.id, name: emp.fullName, title: emp.jobPosition?.name, department: mockDepartments.find((d) => d.id === emp.departmantId)?.name || '', type: 'employee', })) } case AssessorTypeEnum.Peer: { const peers = mockEmployees.filter( (emp) => emp.id !== targetEmployeeId && emp.departmantId === targetEmployee.departmantId && emp.jobPosition?.level === targetEmployee.jobPosition?.level, ) return peers.map((emp) => ({ id: emp.id, name: emp.fullName, title: emp.jobPosition?.name, department: mockDepartments.find((d) => d.id === emp.departmantId)?.name || '', type: 'employee', })) } case AssessorTypeEnum.Subordinate: { const subordinates = mockEmployees.filter( (emp) => emp.departmantId === targetEmployee.departmantId && (typeof emp.jobPosition?.level === 'number' && typeof targetEmployee.jobPosition?.level === 'number' ? emp.jobPosition?.level < targetEmployee.jobPosition?.level : !emp.jobPosition?.name.includes('Müdür') && !emp.jobPosition?.name.includes('Manager')), ) return subordinates.map((emp) => ({ id: emp.id, name: emp.fullName, title: emp.jobPosition?.name, department: mockDepartments.find((d) => d.id === emp.departmantId)?.name || '', type: 'employee', })) } case AssessorTypeEnum.Customer: { return mockBusinessParties.map((customer) => ({ id: customer.id, name: customer.name, title: 'Müşteri Temsilcisi', department: 'Müşteri', type: 'customer', })) } case AssessorTypeEnum.External: { return [ { id: 'external', name: 'Dış Değerlendirici', title: 'Harici', department: 'Dış Paydaş', type: 'external', }, ] } case AssessorTypeEnum.HRUpperManagement: { const hrEmployees = mockEmployees.filter( (emp) => emp.id !== targetEmployeeId && (emp.departmantId === 'hr' || emp.departmantId === '3'), // HR departmanı ) return hrEmployees.map((emp) => ({ id: emp.id, name: emp.fullName, title: emp.jobPosition?.name, department: mockDepartments.find((d) => d.id === emp.departmantId)?.name || '', type: 'employee', })) } case AssessorTypeEnum.OtherDepartment: { const otherDepartmentEmployees = mockEmployees.filter( (emp) => emp.id !== targetEmployeeId && emp.departmantId !== targetEmployee.departmantId, ) return otherDepartmentEmployees.map((emp) => ({ id: emp.id, name: emp.fullName, title: emp.jobPosition?.name, department: mockDepartments.find((d) => d.id === emp.departmantId)?.name || '', type: 'employee', })) } default: return [] } } // Değerlendiren bilgisini getiren fonksiyon const getEvaluatorInfo = () => { if (evaluationEvaluator === 'external') { return externalEvaluatorName } if (selectedAssessorType === AssessorTypeEnum.Customer) { const customer = mockBusinessParties.find((c) => c.id === selectedCustomerId) return customer ? customer.name : 'Müşteri Bulunamadı' } const employee = mockEmployees.find((e) => e.id === evaluationEvaluator) return employee ? employee.fullName : 'Çalışan Bulunamadı' } // Template'deki izin verilen assessor tiplerini getir const getAllowedAssessorTypes = () => { if (!currentCampaignForEvaluation) return [] const template = mockEvaluation360Templates.find( (t) => t.id === currentCampaignForEvaluation.templateId, ) return template?.assessorTypes || [] } // Helper function to get participants for a campaign from results const getCampaignParticipants = (campaignId: string) => { return mockEvaluation360Results .filter((result) => result.campaignId === campaignId) .flatMap((result) => result.participants) } // Filtered data const filteredCampaigns = mockEvaluation360.filter((campaign) => { if (selectedStatus !== 'all' && campaign.status !== selectedStatus) return false if (selectedDepartment !== 'all' && campaign.departmentId !== selectedDepartment) return false if (selectedEmployee !== 'all') { const participants = getCampaignParticipants(campaign.id) const hasEmployee = participants.some( (p) => p.evaluatedEmployeeId === selectedEmployee || p.evaluatorId === selectedEmployee, ) if (!hasEmployee) return false } return true }) const filteredEmployeesByDepartment = mockEmployees.filter( (emp) => selectedDepartment === 'all' || emp.departmantId === selectedDepartment, ) // Statistics const totalActiveCampaigns = mockEvaluation360.filter( (c) => c.status === CampaignStatusEnum.Active, ).length const allParticipants = mockEvaluation360Results.flatMap((result) => result.participants) const totalCompletedEvaluations = allParticipants.filter( (p) => p.status === ParticipantStatusEnum.Completed, ).length const totalPendingEvaluations = allParticipants.filter( (p) => p.status === ParticipantStatusEnum.Invited || p.status === ParticipantStatusEnum.Started, ).length const totalParticipants = allParticipants.length // Results helper functions // Participant evaluation helper functions const handleViewEvaluationDetail = (result: { resultId: string evaluatedEmployeeName: string evaluatorName: string campaignName: string overallScore: number scorePercentage: number evaluatedEmployeeId: string evaluatorId: string campaignId: string evaluatorType: AssessorTypeEnum status: ParticipantStatusEnum completedDate?: Date }) => { // Değerlendirme detaylarını görüntüle console.log('Viewing evaluation detail:', result) setSelectedResult(result) setShowResultDetailModal(true) } const handleEditEvaluationDetail = (result: { resultId: string evaluatedEmployeeName: string evaluatorName: string campaignName: string overallScore: number scorePercentage: number evaluatedEmployeeId: string evaluatorId: string campaignId: string evaluatorType: AssessorTypeEnum status: ParticipantStatusEnum completedDate?: Date }) => { // Değerlendirme detaylarını düzenle console.log('Editing evaluation detail:', result) // Mevcut evaluation result'ını bul const evaluationResult = mockEvaluation360Results.find((r) => r.id === result.resultId) if (evaluationResult) { // Mevcut cevapları yükle const currentResponses: Record = {} evaluationResult.participants.forEach((participant) => { participant.responses.forEach((response) => { currentResponses[response.questionId] = response.responseValue }) }) setEditResponses(currentResponses) setEditManagerComments(evaluationResult.managerComments || '') setEditHrComments(evaluationResult.hrComments || '') setEditResultStatus(evaluationResult.status) } setSelectedResult(result) setShowResultEditModal(true) } const getAssessorTypeLabel = (assessorType: AssessorTypeEnum): string => { return getAssessorTypeText(assessorType) } const getAllEvaluationParticipants = () => { // Tüm sonuçlardan participant verilerini al const allParticipants = mockEvaluation360Results.flatMap((result) => result.participants.map((participant) => ({ ...participant, resultId: result.id, evaluatedEmployeeName: mockEmployees.find((e) => e.id === participant.evaluatedEmployeeId)?.fullName || 'Bilinmiyor', evaluatorName: mockEmployees.find((e) => e.id === participant.evaluatorId)?.fullName || 'Bilinmiyor', campaignName: mockEvaluation360.find((c) => c.id === participant.campaignId)?.name || 'Bilinmiyor', overallScore: result.overallScore, scorePercentage: result.scorePercentage, result: result, })), ) // Filtreleme işlemi return allParticipants.filter((participant) => { // Durum filtresi if (selectedResultsStatus !== 'all' && participant.status !== selectedResultsStatus) { return false } // Kampanya filtresi if (selectedResultsCampaign !== 'all' && participant.campaignId !== selectedResultsCampaign) { return false } // Değerlendirilecek kişi filtresi if ( selectedResultsEmployee !== 'all' && participant.evaluatedEmployeeId !== selectedResultsEmployee ) { return false } // Departman filtresi if (selectedResultsDepartment !== 'all') { const evaluatedEmployee = mockEmployees.find( (e) => e.id === participant.evaluatedEmployeeId, ) if (!evaluatedEmployee || evaluatedEmployee.departmantId !== selectedResultsDepartment) { return false } } return true }) } // Columns for campaigns table const campaignColumns: Column[] = [ { key: 'name', header: 'Değerlendirme Adı', sortable: true, }, { key: 'departmentId', header: 'Departman', render: (item: HrEvaluation360) => { const department = mockDepartments.find((d) => d.id === item.departmentId) return department?.name || 'Tüm Departmanlar' }, }, { key: 'templateId', header: 'Şablon', render: (item: HrEvaluation360) => { const template = mockEvaluation360Templates.find((t) => t.id === item.templateId) return template?.name || 'Bilinmiyor' }, }, { key: 'status', header: 'Durum', render: (item: HrEvaluation360) => ( {getCampaignStatusText(item.status)} ), }, { key: 'startDate', header: 'Başlangıç', render: (item: HrEvaluation360) => item.startDate.toLocaleDateString('tr-TR'), }, { key: 'endDate', header: 'Bitiş', render: (item: HrEvaluation360) => item.endDate.toLocaleDateString('tr-TR'), }, { key: 'participants', header: 'Katılımcı', render: (item: HrEvaluation360) => { const participants = getCampaignParticipants(item.id) return `${participants.length} kişi` }, }, { key: 'id', header: 'İşlemler', render: (item: HrEvaluation360) => (
), }, ] return (
{/* Header */}

360° Değerlendirme Sistemi

Çok yönlü performans değerlendirme sistemi

{/* Statistics Cards */}
{/* Tabs */}
{activeTab === 'campaigns' && (
{/* Filters and Actions */}
{/* Campaigns Table */}
)} {activeTab === 'results' && (
{/* Results Filters */}
{/* Results Summary */}
{getAllEvaluationParticipants().map((result) => ( ))}
Değerlendirme Adı Değerlendirilecek Kişi Değerlendiren Toplam İlerleme Değerlendirme Durumu Toplam Puan Puan Yüzdesi İşlemler
{result.campaignName} {result.completedDate ? new Date(result.completedDate).toLocaleDateString('tr-TR') : '-'}
{result.evaluatedEmployeeName}
{result.evaluatorName} {getAssessorTypeLabel(result.evaluatorType)}
{result.status === ParticipantStatusEnum.Completed ? 100 : 50}%
{getParticipantStatusText(result.status)} {result.overallScore}/100 %{result.scorePercentage}
)}
{/* Campaign Modal */} {showCampaignModal && (

{selectedCampaign ? 'Değerlendirme Düzenle' : 'Yeni Değerlendirme'}

setCampaignFormData({ ...campaignFormData, name: e.target.value, }) } className="w-full border border-gray-300 rounded-md px-2 py-1 text-sm" />