erp-platform/ui/src/views/maintenance/components/MaintenancePlanModal.tsx
2025-09-16 00:29:07 +03:00

214 lines
7.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from 'react'
import { FaTimes, FaSave, FaPlus } from 'react-icons/fa'
import {
PmWorkCenter,
MaintenancePlanTypeEnum,
FrequencyUnitEnum,
PmMaintenancePlan,
} from '../../../types/pm'
import { PriorityEnum } from '../../../types/common'
interface MaintenancePlanModalProps {
isOpen: boolean
onClose: () => void
onSave: (planData: PmMaintenancePlan[]) => void
selectedWorkCenters: PmWorkCenter[]
}
const MaintenancePlanModal: React.FC<MaintenancePlanModalProps> = ({
isOpen,
onClose,
onSave,
selectedWorkCenters,
}) => {
const [planData, setPlanData] = useState({
planType: MaintenancePlanTypeEnum.Preventive,
description: '',
frequency: 1,
frequencyUnit: FrequencyUnitEnum.Months,
estimatedDuration: 60,
priority: PriorityEnum.Normal,
instructions: '',
requiredSkills: [] as string[],
nextDue: new Date(),
})
const [newSkill, setNewSkill] = useState('')
if (!isOpen) return null
const handleInputChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>,
) => {
const { name, value, type } = e.target
setPlanData((prev) => ({
...prev,
[name]: type === 'date' ? new Date(value) : type === 'number' ? Number(value) : value,
}))
}
const addSkill = () => {
if (newSkill.trim() && !planData.requiredSkills.includes(newSkill.trim())) {
setPlanData((prev) => ({
...prev,
requiredSkills: [...prev.requiredSkills, newSkill.trim()],
}))
setNewSkill('')
}
}
const removeSkill = (skillToRemove: string) => {
setPlanData((prev) => ({
...prev,
requiredSkills: prev.requiredSkills.filter((skill) => skill !== skillToRemove),
}))
}
const handleSave = () => {
const plansToCreate = selectedWorkCenters.map((workCenter) => ({
id: `MP${Date.now()}-${workCenter.id}`,
planCode: `MP-${workCenter.code}-${Date.now()}`,
workCenterId: workCenter.id,
workCenter: workCenter,
...planData,
requiredMaterials: [],
isActive: true,
creationTime: new Date(),
lastModificationTime: new Date(),
}))
onSave(plansToCreate)
onClose()
}
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg w-full max-w-2xl mx-4 max-h-[90vh] overflow-y-auto">
{/* Header */}
<div className="flex items-center justify-between p-4 border-b border-gray-200">
<h2 className="text-lg font-semibold text-gray-900">
Bakım Planı Oluştur ({selectedWorkCenters.length} merkezi)
</h2>
<button onClick={onClose} className="p-2 hover:bg-gray-100 rounded-lg transition-colors">
<FaTimes className="w-5 h-5 text-gray-500" />
</button>
</div>
{/* Content */}
<div className="p-4 space-y-4">
{/* Selected Work Center List */}
<div>
<h3 className="text-sm font-medium text-gray-900 mb-2">Seçili İş Merkezleri</h3>
<div className="max-h-28 overflow-y-auto bg-gray-50 rounded-lg p-2">
{selectedWorkCenters.map((workCenter) => (
<div key={workCenter.id} className="flex items-center justify-between py-0.5">
<span className="text-sm text-gray-700">
{workCenter.code} - {workCenter.name}
</span>
<span className="text-xs text-gray-500">{workCenter.location}</span>
</div>
))}
</div>
</div>
{/* Plan Details */}
<div>
<h3 className="text-sm font-medium text-gray-900 mb-2">Plan Detayları</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Plan Tipi</label>
<select
name="planType"
value={planData.planType}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={MaintenancePlanTypeEnum.Preventive}>Önleyici Bakım</option>
<option value={MaintenancePlanTypeEnum.Predictive}>Kestirimci Bakım</option>
<option value={MaintenancePlanTypeEnum.Corrective}>Düzeltici Bakım</option>
<option value={MaintenancePlanTypeEnum.Condition}>Durum Bazlı Bakım</option>
</select>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Öncelik</label>
<select
name="priority"
value={planData.priority}
onChange={handleInputChange}
className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
<option value={PriorityEnum.Low}>Düşük</option>
<option value={PriorityEnum.Normal}>Normal</option>
<option value={PriorityEnum.High}>Yüksek</option>
<option value={PriorityEnum.Urgent}>Acil</option>
</select>
</div>
</div>
</div>
{/* Required Skills */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Gerekli Yetenekler
</label>
<div className="flex space-x-2 mb-2">
<input
type="text"
value={newSkill}
onChange={(e) => setNewSkill(e.target.value)}
placeholder="Yetenek ekle..."
className="flex-1 px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
onKeyPress={(e) => e.key === 'Enter' && addSkill()}
/>
<button
type="button"
onClick={addSkill}
className="px-3 py-1.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
>
<FaPlus className="w-4 h-4" />
</button>
</div>
<div className="flex flex-wrap gap-2">
{planData.requiredSkills.map((skill, index) => (
<span
key={index}
className="inline-flex items-center px-2 py-1 bg-blue-100 text-blue-800 rounded-full text-xs"
>
{skill}
<button
type="button"
onClick={() => removeSkill(skill)}
className="ml-2 text-blue-600 hover:text-blue-800"
>
×
</button>
</span>
))}
</div>
</div>
</div>
{/* Footer */}
<div className="flex items-center justify-end space-x-3 p-4 border-t border-gray-200">
<button
type="button"
onClick={onClose}
className="px-3 py-1.5 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
>
İptal
</button>
<button
type="button"
onClick={handleSave}
className="flex items-center space-x-2 px-3 py-1.5 text-sm bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors"
>
<FaSave className="w-4 h-4" />
<span>Bakım Planı Oluştur</span>
</button>
</div>
</div>
</div>
)
}
export default MaintenancePlanModal