638 lines
26 KiB
TypeScript
638 lines
26 KiB
TypeScript
import React, { useState } from 'react'
|
||
import {
|
||
FaPlus,
|
||
FaSearch,
|
||
FaFilter,
|
||
FaFileAlt,
|
||
FaClock,
|
||
FaCheckCircle,
|
||
FaExclamationTriangle,
|
||
FaEdit,
|
||
FaTrash,
|
||
FaEye,
|
||
FaDollarSign,
|
||
} from 'react-icons/fa'
|
||
import { PmMaintenanceWorkOrder, WorkOrderStatusEnum, WorkOrderTypeEnum } from '../../../types/pm'
|
||
import { mockMaintenanceWorkOrders } from '../../../mocks/mockMaintenanceWorkOrders'
|
||
import NewWorkOrderModal from './NewWorkOrderModal'
|
||
import ViewWorkOrderModal from './ViewWorkOrderModal'
|
||
import EditWorkOrderModal from './EditWorkOrderModal'
|
||
import StartWorkOrderModal from './StartWorkOrderModal'
|
||
import AssignWorkOrdersModal from './AssignWorkOrdersModal'
|
||
import ChangeWorkOrderStatusModal from './ChangeWorkOrderStatusModal'
|
||
import Widget from '../../../components/common/Widget'
|
||
import {
|
||
getPriorityColor,
|
||
getPriorityText,
|
||
getWorkOrderStatusColor,
|
||
getWorkOrderStatusIcon,
|
||
getWorkOrderStatusText,
|
||
getWorkOrderTypeColor,
|
||
getWorkOrderTypeText,
|
||
} from '../../../utils/erp'
|
||
import { Container } from '@/components/shared'
|
||
|
||
const MaintenanceWorkOrders: React.FC = () => {
|
||
const [searchTerm, setSearchTerm] = useState('')
|
||
const [statusFilter, setStatusFilter] = useState<WorkOrderStatusEnum | 'all'>('all')
|
||
const [typeFilter, setTypeFilter] = useState<WorkOrderTypeEnum | 'all'>('all')
|
||
const [showModal, setShowModal] = useState(false)
|
||
const [editingWorkOrder, setEditingWorkOrder] = useState<PmMaintenanceWorkOrder | null>(null)
|
||
const [viewingWorkOrder, setViewingWorkOrder] = useState<PmMaintenanceWorkOrder | null>(null)
|
||
const [selectedWorkOrders, setSelectedWorkOrders] = useState<string[]>([])
|
||
const [showStartModal, setShowStartModal] = useState(false)
|
||
const [showAssignModal, setShowAssignModal] = useState(false)
|
||
const [showStatusChangeModal, setShowStatusChangeModal] = useState(false)
|
||
|
||
// Mock data - replace with actual API calls
|
||
const [workOrders, setWorkOrders] = useState<PmMaintenanceWorkOrder[]>(mockMaintenanceWorkOrders)
|
||
|
||
const filteredWorkOrders = workOrders.filter((workOrder) => {
|
||
const matchesSearch =
|
||
workOrder.workOrderNumber.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||
workOrder.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||
workOrder.assignedTo?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||
workOrder.reportedBy.toLowerCase().includes(searchTerm.toLowerCase())
|
||
const matchesStatus = statusFilter === 'all' || workOrder.status === statusFilter
|
||
const matchesType = typeFilter === 'all' || workOrder.orderType === typeFilter
|
||
return matchesSearch && matchesStatus && matchesType
|
||
})
|
||
|
||
const getTotalMaterialCost = (workOrder: PmMaintenanceWorkOrder) => {
|
||
return workOrder.materials.reduce((total, material) => total + material.totalCost, 0)
|
||
}
|
||
|
||
const getCompletionPercentage = (workOrder: PmMaintenanceWorkOrder) => {
|
||
const completedActivities = workOrder.activities.filter(
|
||
(activity) => activity.completedAt,
|
||
).length
|
||
const totalActivities = workOrder.activities.length
|
||
return totalActivities > 0 ? Math.round((completedActivities / totalActivities) * 100) : 0
|
||
}
|
||
|
||
const isOverdue = (workOrder: PmMaintenanceWorkOrder) => {
|
||
if (!workOrder.scheduledEnd) return false
|
||
const now = new Date()
|
||
return workOrder.scheduledEnd < now && workOrder.status !== WorkOrderStatusEnum.Completed
|
||
}
|
||
|
||
const handleAddWorkOrder = () => {
|
||
setEditingWorkOrder(null)
|
||
setShowModal(true)
|
||
}
|
||
|
||
const handleEdit = (workOrder: PmMaintenanceWorkOrder) => {
|
||
setEditingWorkOrder(workOrder)
|
||
setShowModal(true)
|
||
}
|
||
|
||
const handleView = (workOrder: PmMaintenanceWorkOrder) => {
|
||
setViewingWorkOrder(workOrder)
|
||
}
|
||
|
||
const handleSelectWorkOrder = (workOrderId: string) => {
|
||
setSelectedWorkOrders((prev) =>
|
||
prev.includes(workOrderId) ? prev.filter((id) => id !== workOrderId) : [...prev, workOrderId],
|
||
)
|
||
}
|
||
|
||
const handleSaveWorkOrder = (
|
||
workOrderData: Omit<PmMaintenanceWorkOrder, 'id' | 'creationTime' | 'lastModificationTime'>,
|
||
) => {
|
||
const newWorkOrder: PmMaintenanceWorkOrder = {
|
||
...workOrderData,
|
||
id: `wo-${Date.now()}`,
|
||
creationTime: new Date(),
|
||
lastModificationTime: new Date(),
|
||
}
|
||
setWorkOrders([...workOrders, newWorkOrder])
|
||
}
|
||
|
||
const handleUpdateWorkOrder = (updatedWorkOrder: PmMaintenanceWorkOrder) => {
|
||
setWorkOrders(workOrders.map((wo) => (wo.id === updatedWorkOrder.id ? updatedWorkOrder : wo)))
|
||
}
|
||
|
||
const handleStartWorkOrders = (
|
||
selectedWorkOrders: PmMaintenanceWorkOrder[],
|
||
startData: {
|
||
actualStart: Date
|
||
assignedTo?: string
|
||
maintenanceTeamId?: string
|
||
notes?: string
|
||
},
|
||
) => {
|
||
const updatedWorkOrders = workOrders.map((wo) => {
|
||
if (selectedWorkOrders.some((swo) => swo.id === wo.id)) {
|
||
return {
|
||
...wo,
|
||
status: WorkOrderStatusEnum.InProgress,
|
||
actualStart: startData.actualStart,
|
||
assignedTo: startData.assignedTo || wo.assignedTo,
|
||
maintenanceTeamId: startData.maintenanceTeamId || wo.maintenanceTeamId,
|
||
notes: startData.notes
|
||
? `${wo.notes ? wo.notes + '\n' : ''}${startData.notes}`
|
||
: wo.notes,
|
||
lastModificationTime: new Date(),
|
||
}
|
||
}
|
||
return wo
|
||
})
|
||
setWorkOrders(updatedWorkOrders)
|
||
setSelectedWorkOrders([])
|
||
}
|
||
|
||
const handleAssignWorkOrders = (
|
||
selectedWorkOrders: PmMaintenanceWorkOrder[],
|
||
assignmentData: {
|
||
assignmentType: 'person' | 'team'
|
||
assignedTo?: string
|
||
maintenanceTeamId?: string
|
||
notes?: string
|
||
},
|
||
) => {
|
||
const updatedWorkOrders = workOrders.map((wo) => {
|
||
if (selectedWorkOrders.some((swo) => swo.id === wo.id)) {
|
||
return {
|
||
...wo,
|
||
assignedTo: assignmentData.assignedTo || wo.assignedTo,
|
||
maintenanceTeamId: assignmentData.maintenanceTeamId || wo.maintenanceTeamId,
|
||
notes: assignmentData.notes
|
||
? `${wo.notes ? wo.notes + '\n' : ''}${assignmentData.notes}`
|
||
: wo.notes,
|
||
lastModificationTime: new Date(),
|
||
}
|
||
}
|
||
return wo
|
||
})
|
||
setWorkOrders(updatedWorkOrders)
|
||
setSelectedWorkOrders([])
|
||
}
|
||
|
||
const handleChangeWorkOrderStatus = (
|
||
selectedWorkOrders: PmMaintenanceWorkOrder[],
|
||
statusData: {
|
||
newStatus: WorkOrderStatusEnum
|
||
notes?: string
|
||
completionNotes?: string
|
||
},
|
||
) => {
|
||
const updatedWorkOrders = workOrders.map((wo) => {
|
||
if (selectedWorkOrders.some((swo) => swo.id === wo.id)) {
|
||
const updates: Partial<PmMaintenanceWorkOrder> = {
|
||
status: statusData.newStatus,
|
||
lastModificationTime: new Date(),
|
||
}
|
||
|
||
if (statusData.notes) {
|
||
updates.notes = statusData.notes
|
||
}
|
||
|
||
if (statusData.completionNotes) {
|
||
updates.completionNotes = statusData.completionNotes
|
||
}
|
||
|
||
if (statusData.newStatus === WorkOrderStatusEnum.Completed) {
|
||
updates.actualEnd = new Date()
|
||
}
|
||
|
||
return { ...wo, ...updates }
|
||
}
|
||
return wo
|
||
})
|
||
setWorkOrders(updatedWorkOrders)
|
||
setSelectedWorkOrders([])
|
||
}
|
||
|
||
return (
|
||
<Container>
|
||
<div className="space-y-2">
|
||
{/* Header */}
|
||
<div className="flex items-center justify-between">
|
||
<div>
|
||
<h2 className="text-2xl font-bold text-gray-900">Bakım İş Emirleri</h2>
|
||
<p className="text-gray-600">Bakım iş emirlerini takip edin ve yönetin</p>
|
||
</div>
|
||
<button
|
||
onClick={handleAddWorkOrder}
|
||
className="bg-blue-600 text-white px-3 py-1.5 rounded-lg hover:bg-blue-700 flex items-center space-x-2 text-sm"
|
||
>
|
||
<FaPlus className="w-4 h-4" />
|
||
<span>Yeni İş Emri</span>
|
||
</button>
|
||
</div>
|
||
|
||
{/* Summary Cards */}
|
||
<div className="grid grid-cols-1 md:grid-cols-5 gap-6">
|
||
<Widget title="Toplam" value={workOrders.length} color="gray" icon="FaFileAlt" />
|
||
|
||
<Widget
|
||
title="Devam Ediyor"
|
||
value={workOrders.filter((wo) => wo.status === WorkOrderStatusEnum.InProgress).length}
|
||
color="orange"
|
||
icon="FaWrench"
|
||
/>
|
||
|
||
<Widget
|
||
title="Planlandı"
|
||
value={workOrders.filter((wo) => wo.status === WorkOrderStatusEnum.Planned).length}
|
||
color="blue"
|
||
icon="FaCalendar"
|
||
/>
|
||
|
||
<Widget
|
||
title="Tamamlandı"
|
||
value={workOrders.filter((wo) => wo.status === WorkOrderStatusEnum.Completed).length}
|
||
color="green"
|
||
icon="FaCheckCircle"
|
||
/>
|
||
|
||
<Widget
|
||
title="Geciken"
|
||
value={workOrders.filter((wo) => isOverdue(wo)).length}
|
||
color="red"
|
||
icon="FaExclamationTriangle"
|
||
/>
|
||
</div>
|
||
|
||
{/* Filters */}
|
||
<div className="flex space-x-3">
|
||
<div className="flex-1 relative">
|
||
<FaSearch className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" />
|
||
<input
|
||
type="text"
|
||
placeholder="İş emri ara..."
|
||
value={searchTerm}
|
||
onChange={(e) => setSearchTerm(e.target.value)}
|
||
className="w-full pl-9 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||
/>
|
||
</div>
|
||
<div className="relative">
|
||
<FaFilter className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-5 h-5" />
|
||
<select
|
||
value={statusFilter}
|
||
onChange={(e) => setStatusFilter(e.target.value as WorkOrderStatusEnum | 'all')}
|
||
className="pl-10 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||
>
|
||
<option value="all">Tüm Durumlar</option>
|
||
{Object.values(WorkOrderStatusEnum).map((status) => (
|
||
<option key={status} value={status}>
|
||
{getWorkOrderStatusText(status)}
|
||
</option>
|
||
))}
|
||
</select>
|
||
</div>
|
||
<div className="relative">
|
||
<select
|
||
value={typeFilter}
|
||
onChange={(e) => setTypeFilter(e.target.value as WorkOrderTypeEnum | 'all')}
|
||
className="pl-4 pr-4 py-1.5 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||
>
|
||
<option value="all">Tüm Tipler</option>
|
||
{Object.values(WorkOrderTypeEnum).map((type) => (
|
||
<option key={type} value={type}>
|
||
{getWorkOrderTypeText(type)}
|
||
</option>
|
||
))}
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Work Orders List */}
|
||
<div className="space-y-3 pt-2">
|
||
{filteredWorkOrders.map((workOrder) => {
|
||
const completionPercentage = getCompletionPercentage(workOrder)
|
||
const materialCost = getTotalMaterialCost(workOrder)
|
||
|
||
return (
|
||
<div
|
||
key={workOrder.id}
|
||
className="bg-white rounded-lg shadow-md border border-gray-200 p-4 hover:shadow-lg transition-shadow"
|
||
>
|
||
<div className="flex items-start justify-between">
|
||
<div className="flex items-start space-x-4 flex-1">
|
||
<input
|
||
type="checkbox"
|
||
checked={selectedWorkOrders.includes(workOrder.id)}
|
||
onChange={() => handleSelectWorkOrder(workOrder.id)}
|
||
className="mt-1 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
|
||
/>
|
||
|
||
<div className="flex-1">
|
||
<div className="flex items-center space-x-3 mb-2">
|
||
<h3 className="text-base font-semibold text-gray-900">
|
||
{workOrder.workOrderNumber}
|
||
</h3>
|
||
<span
|
||
className={`px-2 py-1 rounded-full text-xs font-medium flex items-center space-x-1 ${getWorkOrderStatusColor(
|
||
workOrder.status,
|
||
)}`}
|
||
>
|
||
{getWorkOrderStatusIcon(workOrder.status)}
|
||
<span>{getWorkOrderStatusText(workOrder.status)}</span>
|
||
</span>
|
||
<span
|
||
className={`px-2 py-1 rounded-full text-xs font-medium ${getWorkOrderTypeColor(
|
||
workOrder.orderType,
|
||
)}`}
|
||
>
|
||
{getWorkOrderTypeText(workOrder.orderType)}
|
||
</span>
|
||
<span
|
||
className={`px-2 py-1 rounded-full text-xs font-medium ${getPriorityColor(
|
||
workOrder.priority,
|
||
)}`}
|
||
>
|
||
{getPriorityText(workOrder.priority)}
|
||
</span>
|
||
{isOverdue(workOrder) && (
|
||
<span className="px-2 py-1 rounded-full text-xs font-medium bg-red-100 text-red-800 flex items-center space-x-1">
|
||
<FaExclamationTriangle className="w-3 h-3" />
|
||
<span>GECİKMİŞ</span>
|
||
</span>
|
||
)}
|
||
</div>
|
||
|
||
<h4 className="font-medium text-gray-800 mb-2 text-sm">
|
||
{workOrder.description}
|
||
</h4>
|
||
|
||
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 text-xs mb-3">
|
||
<div>
|
||
<span className="text-gray-500">Bildiren:</span>
|
||
<p className="font-medium text-gray-900">{workOrder.reportedBy}</p>
|
||
</div>
|
||
<div>
|
||
<span className="text-gray-500">Atanan:</span>
|
||
<p className="font-medium text-gray-900">
|
||
{workOrder.assignedTo || 'Atanmadı'}
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<span className="text-gray-500">Planlanan Süre:</span>
|
||
<p className="font-medium text-gray-900">
|
||
{workOrder.scheduledStart && workOrder.scheduledEnd ? (
|
||
<>
|
||
{workOrder.scheduledStart.toLocaleDateString('tr-TR')} -{' '}
|
||
{workOrder.scheduledEnd.toLocaleDateString('tr-TR')}
|
||
</>
|
||
) : (
|
||
'Belirsiz'
|
||
)}
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<span className="text-gray-500">Maliyet:</span>
|
||
<p className="font-medium text-gray-900 flex items-center">
|
||
<FaDollarSign className="w-3 h-3 mr-1" />₺
|
||
{workOrder.actualCost > 0
|
||
? workOrder.actualCost.toLocaleString('tr-TR')
|
||
: workOrder.estimatedCost.toLocaleString('tr-TR')}
|
||
{workOrder.actualCost === 0 && (
|
||
<span className="text-xs text-gray-500 ml-1">(tahmini)</span>
|
||
)}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Progress Bar */}
|
||
{workOrder.status === WorkOrderStatusEnum.InProgress && (
|
||
<div className="mb-3">
|
||
<div className="flex items-center justify-between text-sm text-gray-600 mb-1">
|
||
<span>İlerleme</span>
|
||
<span>{completionPercentage}%</span>
|
||
</div>
|
||
<div className="w-full bg-gray-200 rounded-full h-2">
|
||
<div
|
||
className="bg-blue-600 h-2 rounded-full transition-all duration-300"
|
||
style={{ width: `${completionPercentage}%` }}
|
||
></div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Materials Summary */}
|
||
{workOrder.materials.length > 0 && (
|
||
<div className="bg-blue-50 rounded-lg p-2 mb-2">
|
||
<div className="flex items-center justify-between text-sm">
|
||
<div className="flex items-center space-x-2">
|
||
<span className="text-gray-600">Malzemeler:</span>
|
||
<span className="font-medium text-gray-900">
|
||
{workOrder.materials.length} kalem
|
||
</span>
|
||
</div>
|
||
<span className="font-medium text-gray-900">
|
||
₺{materialCost.toLocaleString('tr-TR')}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Activities Summary */}
|
||
<div className="bg-gray-50 rounded-lg p-2 mb-2">
|
||
<div className="flex items-center justify-between text-sm">
|
||
<div className="flex items-center space-x-2">
|
||
<span className="text-gray-600">Aktiviteler:</span>
|
||
<span className="font-medium text-gray-900">
|
||
{workOrder.activities.filter((a) => a.completedAt).length} /{' '}
|
||
{workOrder.activities.length} tamamlandı
|
||
</span>
|
||
</div>
|
||
<div className="text-gray-600">
|
||
Toplam:{' '}
|
||
{workOrder.activities.reduce(
|
||
(total, activity) => total + activity.plannedDuration,
|
||
0,
|
||
)}{' '}
|
||
dk
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{workOrder.notes && (
|
||
<div className="bg-yellow-50 rounded-lg p-2 mb-2">
|
||
<div className="flex items-start space-x-2 text-sm">
|
||
<FaFileAlt className="w-4 h-4 text-yellow-600 mt-0.5" />
|
||
<div>
|
||
<span className="text-gray-600">Notlar:</span>
|
||
<p className="text-gray-900 mt-1">{workOrder.notes}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{workOrder.completionNotes && (
|
||
<div className="bg-green-50 rounded-lg p-2 mb-2">
|
||
<div className="flex items-start space-x-2 text-sm">
|
||
<FaCheckCircle className="w-4 h-4 text-green-600 mt-0.5" />
|
||
<div>
|
||
<span className="text-gray-600">Tamamlanma Notları:</span>
|
||
<p className="text-gray-900 mt-1">{workOrder.completionNotes}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
<div className="flex items-center justify-between text-xs text-gray-500">
|
||
<div className="flex items-center space-x-2">
|
||
<FaClock className="w-3 h-3" />
|
||
<span>
|
||
Oluşturuldu: {workOrder.creationTime.toLocaleDateString('tr-TR')}
|
||
</span>
|
||
</div>
|
||
<div className="flex items-center space-x-2">
|
||
<span>
|
||
Son Güncelleme:{' '}
|
||
{workOrder.lastModificationTime.toLocaleDateString('tr-TR')}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex space-x-1">
|
||
<button
|
||
onClick={() => handleView(workOrder)}
|
||
className="p-1.5 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-md transition-colors"
|
||
>
|
||
<FaEye className="w-4 h-4" />
|
||
</button>
|
||
<button
|
||
onClick={() => handleEdit(workOrder)}
|
||
className="p-1.5 text-gray-400 hover:text-green-600 hover:bg-green-50 rounded-md transition-colors"
|
||
>
|
||
<FaEdit className="w-4 h-4" />
|
||
</button>
|
||
<button className="p-1.5 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded-md transition-colors">
|
||
<FaTrash className="w-4 h-4" />
|
||
</button>
|
||
{workOrder.status === WorkOrderStatusEnum.InProgress && (
|
||
<button className="p-1.5 text-gray-400 hover:text-green-600 hover:bg-green-50 rounded-md transition-colors">
|
||
<FaCheckCircle className="w-4 h-4" />
|
||
</button>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
})}
|
||
</div>
|
||
|
||
{filteredWorkOrders.length === 0 && (
|
||
<div className="text-center py-12">
|
||
<FaFileAlt className="w-16 h-16 text-gray-400 mx-auto mb-4" />
|
||
<h3 className="text-lg font-medium text-gray-900 mb-2">İş emri bulunamadı</h3>
|
||
<p className="text-gray-500 mb-4">
|
||
Arama kriterlerinizi değiştirin veya yeni bir iş emri oluşturun.
|
||
</p>
|
||
<button
|
||
onClick={handleAddWorkOrder}
|
||
className="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700"
|
||
>
|
||
Yeni İş Emri Oluştur
|
||
</button>
|
||
</div>
|
||
)}
|
||
|
||
{/* Bulk Actions */}
|
||
{selectedWorkOrders.length > 0 && (
|
||
<div className="fixed bottom-6 left-1/2 transform -translate-x-1/2 bg-white rounded-lg shadow-lg border border-gray-200 p-4">
|
||
<div className="flex items-center space-x-4">
|
||
<span className="text-sm text-gray-600">
|
||
{selectedWorkOrders.length} iş emri seçildi
|
||
</span>
|
||
<div className="flex space-x-2">
|
||
<button
|
||
onClick={() => setShowStartModal(true)}
|
||
className="bg-green-600 text-white px-2.5 py-1.5 rounded text-sm hover:bg-green-700"
|
||
>
|
||
Başlat
|
||
</button>
|
||
<button
|
||
onClick={() => setShowAssignModal(true)}
|
||
className="bg-blue-600 text-white px-2.5 py-1.5 rounded text-sm hover:bg-blue-700"
|
||
>
|
||
Atama Yap
|
||
</button>
|
||
<button
|
||
onClick={() => setShowStatusChangeModal(true)}
|
||
className="bg-orange-600 text-white px-2.5 py-1.5 rounded text-sm hover:bg-orange-700"
|
||
>
|
||
Durum Değiştir
|
||
</button>
|
||
<button
|
||
onClick={() => setSelectedWorkOrders([])}
|
||
className="bg-gray-600 text-white px-2.5 py-1.5 rounded text-sm hover:bg-gray-700"
|
||
>
|
||
Temizle
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* Modals */}
|
||
{showModal && !editingWorkOrder && (
|
||
<NewWorkOrderModal
|
||
isOpen={showModal}
|
||
onClose={() => setShowModal(false)}
|
||
onSave={handleSaveWorkOrder}
|
||
/>
|
||
)}
|
||
|
||
{editingWorkOrder && (
|
||
<EditWorkOrderModal
|
||
isOpen={showModal}
|
||
onClose={() => {
|
||
setShowModal(false)
|
||
setEditingWorkOrder(null)
|
||
}}
|
||
onSave={handleUpdateWorkOrder}
|
||
workOrder={editingWorkOrder}
|
||
/>
|
||
)}
|
||
|
||
{viewingWorkOrder && (
|
||
<ViewWorkOrderModal
|
||
isOpen={!!viewingWorkOrder}
|
||
onClose={() => setViewingWorkOrder(null)}
|
||
onEdit={(workOrder) => {
|
||
setViewingWorkOrder(null)
|
||
setEditingWorkOrder(workOrder)
|
||
setShowModal(true)
|
||
}}
|
||
workOrder={viewingWorkOrder}
|
||
/>
|
||
)}
|
||
|
||
{showStartModal && selectedWorkOrders.length > 0 && (
|
||
<StartWorkOrderModal
|
||
isOpen={showStartModal}
|
||
onClose={() => setShowStartModal(false)}
|
||
onStart={handleStartWorkOrders}
|
||
workOrders={workOrders.filter((wo) => selectedWorkOrders.includes(wo.id))}
|
||
/>
|
||
)}
|
||
|
||
{showAssignModal && selectedWorkOrders.length > 0 && (
|
||
<AssignWorkOrdersModal
|
||
isOpen={showAssignModal}
|
||
onClose={() => setShowAssignModal(false)}
|
||
onAssign={handleAssignWorkOrders}
|
||
workOrders={workOrders.filter((wo) => selectedWorkOrders.includes(wo.id))}
|
||
/>
|
||
)}
|
||
|
||
{showStatusChangeModal && selectedWorkOrders.length > 0 && (
|
||
<ChangeWorkOrderStatusModal
|
||
isOpen={showStatusChangeModal}
|
||
onClose={() => setShowStatusChangeModal(false)}
|
||
onStatusChange={handleChangeWorkOrderStatus}
|
||
workOrders={workOrders.filter((wo) => selectedWorkOrders.includes(wo.id))}
|
||
/>
|
||
)}
|
||
</Container>
|
||
)
|
||
}
|
||
|
||
export default MaintenanceWorkOrders
|