import { useState, useEffect, useRef } from 'react' import { useScrollIntoView } from '../hooks/useScrollIntoView' import { useAuth } from '../context/AuthContext' import { SERVICE_TYPES, todayIso, isoToGermanDate, timeToWoms, minutesBetween } from '../lib/ticketForm' import { TICKET_STATUSES, statusLabel } from '../lib/ticketStatus' import { Button, DateTimeInput, Dialog, DurationSelect, Field } from './ui' import { roundUpToStep, isValidStep } from '../lib/timeSteps' import { validateSupporters } from '../lib/support' import SupportersEditor from './SupportersEditor' // Akquise-Tickets: Ergebnis des Kundenkontakts (statt technischer Status) const ACQUISITION_STATUS = ['In Kontakt', 'Zugesagt', 'Abgesagt'] // Die sechs Status; ein alter Status (z. B. "Assigned") bleibt als aktuelle Auswahl sichtbar function statusOptionsFor(current) { if (!current || TICKET_STATUSES.some((s) => s.value === current)) return TICKET_STATUSES return [{ value: current, label: `${statusLabel(current)} (bisher)` }, ...TICKET_STATUSES] } // Datum als "yyyy-mm-dd", Uhrzeit als "hh:mm" (Werte der Kalender-Felder). // Die Service-Art kommt vom Ticket; das alte "Off Site" zaehlt als Fernwartung. const initialForm = (workorder, newStatus) => ({ serviceType: SERVICE_TYPES.some(t => t.value === workorder?.serviceType) ? workorder.serviceType : SERVICE_TYPES[0].value, newStatus, totalTime: 0, startDate: todayIso(), startTime: '', endDate: todayIso(), endTime: '', details: '', isComment: false, countsToPlan: false, supporters: [] }) // Mitarbeiterliste der Seite (useEmployees laeuft dort einmal); der Editor ruft den Hook nicht selbst auf const NO_EMPLOYEES_STATE = { employees: [], loading: false, error: null } export default function CreateWorksheetModal({ isOpen, onClose, workorder, onCreate, aboHoursAllowed = true, employeesState = NO_EMPLOYEES_STATE }) { const { user } = useAuth() const isAcquisition = workorder?.type === 'Akquise' const statusOptions = isAcquisition ? ACQUISITION_STATUS.map((s) => ({ value: s, label: s })) : statusOptionsFor(workorder?.status) const defaultStatus = isAcquisition ? (ACQUISITION_STATUS.includes(workorder?.status) ? workorder.status : 'In Kontakt') : (workorder?.status || 'Open') const [formData, setFormData] = useState(() => initialForm(workorder, defaultStatus)) const [loading, setLoading] = useState(false) const [error, setError] = useState('') const [autoCalculate, setAutoCalculate] = useState(true) const errorRef = useRef(null) useScrollIntoView(errorRef, error) // Reset form wenn Modal geöffnet wird useEffect(() => { if (isOpen && workorder) { setFormData(initialForm(workorder, defaultStatus)) setError('') setAutoCalculate(true) } }, [isOpen, workorder, defaultStatus]) // Automatische Zeitberechnung, aufgerundet auf 15 Minuten useEffect(() => { if (!autoCalculate || formData.isComment) return const minutes = minutesBetween(formData.startTime, formData.endTime) if (minutes !== null) { setFormData(prev => ({ ...prev, totalTime: roundUpToStep(minutes) })) } }, [formData.startTime, formData.endTime, formData.isComment, autoCalculate]) const handleChange = (field, value) => { setFormData(prev => ({ ...prev, [field]: value })) // Wenn totalTime manuell geändert wird, deaktiviere Auto-Berechnung if (field === 'totalTime') { setAutoCalculate(false) } } // Das Ende darf nicht vor dem Start liegen, deshalb rueckt es mit const handleStartDateChange = (value) => { setFormData(prev => ({ ...prev, startDate: value, endDate: value && prev.endDate && prev.endDate < value ? value : prev.endDate })) } const handleSubmit = async (e) => { e.preventDefault() setLoading(true) setError('') try { if (!formData.details.trim()) { setError('Bitte Details eingeben') setLoading(false) return } if (!formData.isComment && !isValidStep(formData.totalTime)) { setError('Bitte die Arbeitszeit auswählen.') setLoading(false) return } const supporters = formData.isComment ? [] : formData.supporters const supportError = validateSupporters(supporters, user?.$id) if (supportError) { setError(supportError) setLoading(false) return } const worksheetData = { woid: workorder.woid, workorderId: workorder.$id, serviceType: formData.serviceType, oldStatus: workorder.status, newStatus: formData.newStatus, totalTime: formData.isComment ? 0 : Number(formData.totalTime), startDate: isoToGermanDate(formData.startDate), startTime: timeToWoms(formData.startTime), endDate: isoToGermanDate(formData.endDate), endTime: timeToWoms(formData.endTime), details: formData.details, isComment: formData.isComment, countsToPlan: aboHoursAllowed && !formData.isComment && formData.countsToPlan, employeeShort: user?.prefs?.shortCode || '', // Aus User-Preferences supporters } const result = await onCreate(worksheetData, user) if (result.success) { onClose() } else { setError(result.error || 'Fehler beim Speichern des Arbeitsblatts') } } catch (err) { console.error('Error creating worksheet:', err) setError(err.message || 'Ein unerwarteter Fehler ist aufgetreten') } finally { setLoading(false) } } if (!isOpen || !workorder) return null return ( } > {error && (
{error}
)}
{aboHoursAllowed && ( )}
handleChange('startTime', value)} /> handleChange('endDate', value)} onTimeChange={(value) => handleChange('endTime', value)} />
handleChange('totalTime', value)} disabled={formData.isComment} /> {!formData.isComment && ( handleChange('supporters', list)} excludeUserId={user?.$id} minutes={formData.totalTime} employeesState={employeesState} /> )}