woms 3.0
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
import { useState } from 'react'
|
||||
import { FaLock, FaLockOpen, FaPlay, FaStop, FaTruck, FaSackDollar, FaUserGear } from 'react-icons/fa6'
|
||||
import { FaLock, FaLockOpen, FaPlay, FaStop, FaTruck, FaSackDollar, FaUserGear, FaPlus } from 'react-icons/fa6'
|
||||
import { formatDistanceToNow, format } from 'date-fns'
|
||||
import { de } from 'date-fns/locale'
|
||||
import StatusDropdown from './StatusDropdown'
|
||||
import PriorityDropdown from './PriorityDropdown'
|
||||
import EditorDropdown from './EditorDropdown'
|
||||
import ResponseDropdown from './ResponseDropdown'
|
||||
import CreateWorksheetModal from './CreateWorksheetModal'
|
||||
import WorksheetList from './WorksheetList'
|
||||
import WorksheetStats from './WorksheetStats'
|
||||
import { useWorksheets } from '../hooks/useWorksheets'
|
||||
|
||||
const PRIORITY_CLASSES = {
|
||||
0: 'priority-none',
|
||||
@@ -41,6 +45,15 @@ const APPROVAL_ICONS = {
|
||||
export default function TicketRow({ ticket, onUpdate, onExpand }) {
|
||||
const [expanded, setExpanded] = useState(false)
|
||||
const [locked, setLocked] = useState(true)
|
||||
const [showCreateWorksheet, setShowCreateWorksheet] = useState(false)
|
||||
|
||||
// Worksheets für dieses Ticket laden (nur wenn expanded)
|
||||
const {
|
||||
worksheets,
|
||||
loading: worksheetsLoading,
|
||||
createWorksheet,
|
||||
getTotalTime
|
||||
} = useWorksheets(expanded ? ticket.woid : null)
|
||||
|
||||
const createdAt = new Date(ticket.$createdAt || ticket.createdAt)
|
||||
const elapsed = formatDistanceToNow(createdAt, { locale: de })
|
||||
@@ -71,13 +84,27 @@ export default function TicketRow({ ticket, onUpdate, onExpand }) {
|
||||
setLocked(!locked)
|
||||
}
|
||||
|
||||
const handleCreateWorksheet = async (worksheetData, currentUser) => {
|
||||
const result = await createWorksheet(worksheetData, currentUser)
|
||||
|
||||
// Wenn Status geändert wurde, aktualisiere Work Order
|
||||
if (result.success && worksheetData.newStatus !== ticket.status) {
|
||||
await onUpdate(ticket.$id, {
|
||||
status: worksheetData.newStatus,
|
||||
responseLevel: worksheetData.newResponseLevel || ticket.responseLevel
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
const ApprovalIcon = APPROVAL_ICONS[ticket.approvalStatus] || FaUserGear
|
||||
|
||||
return (
|
||||
<>
|
||||
<tr className="ticket-row">
|
||||
<td className="ticket-id" rowSpan={2}>
|
||||
<div>{ticket.woid || ticket.$id?.slice(-5)}</div>
|
||||
<div><strong>WOID:</strong> {ticket.woid || ticket.$id?.slice(-5)}</div>
|
||||
<div className="ticket-time">{elapsed}</div>
|
||||
</td>
|
||||
<td className="ticket-info" rowSpan={2}>
|
||||
@@ -153,16 +180,82 @@ export default function TicketRow({ ticket, onUpdate, onExpand }) {
|
||||
<tr>
|
||||
<td colSpan={10} className="p-2">
|
||||
<div className="card">
|
||||
<div className="card-header">Details - WOID {ticket.woid || ticket.$id}</div>
|
||||
<div className="card-header d-flex justify-content-between align-items-center" style={{
|
||||
background: 'linear-gradient(135deg, #2d3748 0%, #1a202c 100%)',
|
||||
color: 'white',
|
||||
padding: '1rem 1.5rem'
|
||||
}}>
|
||||
<span className="fs-5 fw-bold">Details - WOID {ticket.woid || ticket.$id}</span>
|
||||
<button
|
||||
className="btn btn-sm px-4 py-2 border-0 fw-bold"
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, #10b981 0%, #059669 100%)',
|
||||
color: 'white',
|
||||
transition: 'all 0.2s ease'
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.transform = 'translateY(-2px)'
|
||||
e.currentTarget.style.boxShadow = '0 4px 12px rgba(16, 185, 129, 0.4)'
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.transform = 'translateY(0)'
|
||||
e.currentTarget.style.boxShadow = 'none'
|
||||
}}
|
||||
onClick={() => setShowCreateWorksheet(true)}
|
||||
>
|
||||
<FaPlus className="me-2" /> Add Worksheet
|
||||
</button>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<p><strong>Beschreibung:</strong></p>
|
||||
<p>{ticket.details || 'Keine Details vorhanden.'}</p>
|
||||
<div className="mb-4 p-4 rounded-3 shadow-sm" style={{
|
||||
background: 'linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%)',
|
||||
border: '2px solid #10b981'
|
||||
}}>
|
||||
<h5 className="mb-3" style={{ color: '#1a202c', fontWeight: 'bold' }}>
|
||||
📋 Ticket-Beschreibung
|
||||
</h5>
|
||||
<p style={{
|
||||
fontSize: '1.1rem',
|
||||
lineHeight: '1.8',
|
||||
color: '#1f2937',
|
||||
whiteSpace: 'pre-wrap',
|
||||
margin: 0
|
||||
}}>
|
||||
{ticket.details || 'Keine Details vorhanden.'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<h5 className="mt-4 mb-3">Worksheets (Arbeitsschritte)</h5>
|
||||
|
||||
{/* Statistiken */}
|
||||
{worksheets.length > 0 && (
|
||||
<>
|
||||
<WorksheetStats worksheets={worksheets} />
|
||||
<hr />
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Worksheet-Liste */}
|
||||
<WorksheetList
|
||||
worksheets={worksheets}
|
||||
totalTime={getTotalTime()}
|
||||
loading={worksheetsLoading}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</>
|
||||
)}
|
||||
|
||||
<CreateWorksheetModal
|
||||
isOpen={showCreateWorksheet}
|
||||
onClose={() => setShowCreateWorksheet(false)}
|
||||
workorder={ticket}
|
||||
onCreate={handleCreateWorksheet}
|
||||
/>
|
||||
<tr className="spacer">
|
||||
<td colSpan={10} style={{ height: '8px', background: '#fff' }}></td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user