Arbeitsblätter: Zeiten nachträglich bearbeiten, nur für den Ersteller
Eigene Arbeitsblätter (employeeId = angemeldeter Benutzer, kein reiner Kommentar) bekommen im Kopf den Button "Zeiten bearbeiten". Der Dialog ändert Beginn, Ende und Arbeitszeit; die Minuten rechnen wie beim Anlegen mit, von Hand eingetragene Minuten bleiben stehen. Gespeichert werden nur die fünf Zeitfelder, wieder als dd.mm.yyyy / hhmm. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e678899141
commit
149b38b94b
5 files changed
+219
-13
No files matched your search
@@ -0,0 +1,140 @@
|
||||
import { useState } from 'react'
|
||||
import { FaTimes } from 'react-icons/fa'
|
||||
import { isoToGermanDate, timeToWoms, germanDateToIso, womsTimeToInput, minutesBetween } from '../lib/ticketForm'
|
||||
import { DateTimeInput } from './ui'
|
||||
|
||||
// Gespeichert ist dd.mm.yyyy / hhmm, die Kalender-Felder brauchen yyyy-mm-dd / hh:mm
|
||||
const formFromWorksheet = (worksheet) => ({
|
||||
startDate: germanDateToIso(worksheet.startDate),
|
||||
startTime: womsTimeToInput(worksheet.startTime),
|
||||
endDate: germanDateToIso(worksheet.endDate || worksheet.startDate),
|
||||
endTime: womsTimeToInput(worksheet.endTime)
|
||||
})
|
||||
|
||||
/**
|
||||
* Beginn, Ende und Arbeitszeit eines Arbeitsblatts nachtraeglich aendern.
|
||||
* Wer das darf, entscheidet canEditWorksheetTimes (useWorksheets).
|
||||
*/
|
||||
export default function WorksheetTimesModal({ worksheet, onClose, onSave }) {
|
||||
const [formData, setFormData] = useState(() => formFromWorksheet(worksheet))
|
||||
// null = die Arbeitszeit folgt Beginn und Ende. Passte sie schon vorher nicht dazu,
|
||||
// wurde sie von Hand eingetragen (z.B. ohne Pause) und bleibt stehen.
|
||||
const [manualTotal, setManualTotal] = useState(() => {
|
||||
const stored = Number(worksheet.totalTime) || 0
|
||||
return !stored || stored === minutesBetween(formData.startTime, formData.endTime) ? null : stored
|
||||
})
|
||||
const [saving, setSaving] = useState(false)
|
||||
const [error, setError] = useState('')
|
||||
|
||||
const calculatedTotal = minutesBetween(formData.startTime, formData.endTime)
|
||||
const totalTime = manualTotal ?? calculatedTotal ?? 0
|
||||
|
||||
const handleChange = (field, value) => {
|
||||
setFormData(prev => ({ ...prev, [field]: value }))
|
||||
}
|
||||
|
||||
// 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()
|
||||
setSaving(true)
|
||||
setError('')
|
||||
try {
|
||||
const result = await onSave(worksheet, {
|
||||
startDate: isoToGermanDate(formData.startDate),
|
||||
startTime: timeToWoms(formData.startTime),
|
||||
endDate: isoToGermanDate(formData.endDate),
|
||||
endTime: timeToWoms(formData.endTime),
|
||||
totalTime: parseInt(totalTime, 10) || 0
|
||||
})
|
||||
if (result?.success) {
|
||||
onClose()
|
||||
return
|
||||
}
|
||||
setError(result?.error || 'Speichern fehlgeschlagen')
|
||||
} catch (err) {
|
||||
setError(err.message || 'Speichern fehlgeschlagen')
|
||||
}
|
||||
setSaving(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="overlay">
|
||||
<span className="overlay-close" onClick={onClose}>
|
||||
<FaTimes />
|
||||
</span>
|
||||
<div className="overlay-content" style={{ maxWidth: 560 }}>
|
||||
{/* Kurzer Titel: auf dem Handy laeuft ein langer unter das Schliessen-X */}
|
||||
<h2 className="mb-2">Zeiten bearbeiten</h2>
|
||||
<p className="text-grey" style={{ fontSize: '14px', marginBottom: '16px' }}>WSID {worksheet.wsid}</p>
|
||||
|
||||
{error && (
|
||||
<div className="bg-red text-white p-2 mb-2" style={{ borderRadius: '4px' }}>
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="form-group">
|
||||
<label className="form-label" htmlFor="worksheet-times-start">Beginn</label>
|
||||
<DateTimeInput
|
||||
id="worksheet-times-start"
|
||||
timeLabel="Uhrzeit Beginn"
|
||||
required
|
||||
date={formData.startDate}
|
||||
time={formData.startTime}
|
||||
onDateChange={handleStartDateChange}
|
||||
onTimeChange={(value) => handleChange('startTime', value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label" htmlFor="worksheet-times-end">Ende</label>
|
||||
<DateTimeInput
|
||||
id="worksheet-times-end"
|
||||
timeLabel="Uhrzeit Ende"
|
||||
required
|
||||
min={formData.startDate}
|
||||
date={formData.endDate}
|
||||
time={formData.endTime}
|
||||
onDateChange={(value) => handleChange('endDate', value)}
|
||||
onTimeChange={(value) => handleChange('endTime', value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label" htmlFor="worksheet-times-total">Arbeitszeit (Minuten)</label>
|
||||
<input
|
||||
id="worksheet-times-total"
|
||||
type="number"
|
||||
className="form-control"
|
||||
min="0"
|
||||
step="1"
|
||||
value={totalTime}
|
||||
onChange={(e) => setManualTotal(e.target.value)}
|
||||
placeholder="0"
|
||||
/>
|
||||
<small style={{ color: '#a0aec0', fontSize: '12px' }}>
|
||||
{manualTotal === null && calculatedTotal !== null
|
||||
? '✓ Automatisch berechnet'
|
||||
: 'Manuell eingeben'}
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div className="text-center mt-2">
|
||||
<button type="submit" className="btn btn-dark" disabled={saving}>
|
||||
{saving ? 'Speichert...' : 'Speichern'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user