Arbeitszeit nur in 15-Minuten-Schritten, berechnete Zeit wird aufgerundet
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
32bc3d7c3d
commit
3535f18a2b
5 files changed
+70
-37
No files matched your search
@@ -1,7 +1,8 @@
|
||||
import { useState } from 'react'
|
||||
import { FaTimes } from 'react-icons/fa'
|
||||
import { isoToGermanDate, timeToWoms, germanDateToIso, womsTimeToInput, minutesBetween, isGitWorksheet, needsTimeEntry } from '../lib/ticketForm'
|
||||
import { DateTimeInput } from './ui'
|
||||
import { DateTimeInput, DurationSelect } from './ui'
|
||||
import { roundUpToStep, isValidStep } from '../lib/timeSteps'
|
||||
|
||||
// Gespeichert ist dd.mm.yyyy / hhmm, die Kalender-Felder brauchen yyyy-mm-dd / hh:mm
|
||||
const formFromWorksheet = (worksheet) => ({
|
||||
@@ -18,16 +19,20 @@ const formFromWorksheet = (worksheet) => ({
|
||||
export default function WorksheetTimesModal({ worksheet, onClose, onSave }) {
|
||||
const isGit = isGitWorksheet(worksheet)
|
||||
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.
|
||||
// null = die Arbeitszeit folgt Beginn und Ende (aufgerundet auf 15 Minuten). Passte sie
|
||||
// schon vorher nicht dazu, wurde sie von Hand gewaehlt (z.B. ohne Pause) und bleibt stehen.
|
||||
// Alte Zeiten ausserhalb des Rasters (z.B. 70) werden auf den naechsten Schritt aufgerundet.
|
||||
const [manualTotal, setManualTotal] = useState(() => {
|
||||
const stored = Number(worksheet.totalTime) || 0
|
||||
return !stored || stored === minutesBetween(formData.startTime, formData.endTime) ? null : stored
|
||||
const calculated = minutesBetween(formData.startTime, formData.endTime)
|
||||
if (!stored || (calculated !== null && stored === roundUpToStep(calculated))) return null
|
||||
return isValidStep(stored) ? stored : roundUpToStep(stored)
|
||||
})
|
||||
const [saving, setSaving] = useState(false)
|
||||
const [error, setError] = useState('')
|
||||
|
||||
const calculatedTotal = minutesBetween(formData.startTime, formData.endTime)
|
||||
const calculatedMinutes = minutesBetween(formData.startTime, formData.endTime)
|
||||
const calculatedTotal = calculatedMinutes === null ? null : roundUpToStep(calculatedMinutes)
|
||||
const totalTime = manualTotal ?? calculatedTotal ?? 0
|
||||
|
||||
const handleChange = (field, value) => {
|
||||
@@ -45,6 +50,10 @@ export default function WorksheetTimesModal({ worksheet, onClose, onSave }) {
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault()
|
||||
if (!isValidStep(totalTime)) {
|
||||
setError('Bitte die Arbeitszeit auswählen.')
|
||||
return
|
||||
}
|
||||
setSaving(true)
|
||||
setError('')
|
||||
try {
|
||||
@@ -53,7 +62,7 @@ export default function WorksheetTimesModal({ worksheet, onClose, onSave }) {
|
||||
startTime: timeToWoms(formData.startTime),
|
||||
endDate: isoToGermanDate(formData.endDate),
|
||||
endTime: timeToWoms(formData.endTime),
|
||||
totalTime: parseInt(totalTime, 10) || 0
|
||||
totalTime: Number(totalTime)
|
||||
})
|
||||
if (result?.success) {
|
||||
onClose()
|
||||
@@ -115,21 +124,16 @@ export default function WorksheetTimesModal({ worksheet, onClose, onSave }) {
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label" htmlFor="worksheet-times-total">Arbeitszeit (Minuten)</label>
|
||||
<input
|
||||
<label className="form-label" htmlFor="worksheet-times-total">Arbeitszeit</label>
|
||||
<DurationSelect
|
||||
id="worksheet-times-total"
|
||||
type="number"
|
||||
className="form-control"
|
||||
min="0"
|
||||
step="1"
|
||||
value={totalTime}
|
||||
onChange={(e) => setManualTotal(e.target.value)}
|
||||
placeholder="0"
|
||||
onChange={(value) => setManualTotal(value)}
|
||||
/>
|
||||
<small style={{ color: '#a0aec0', fontSize: '12px' }}>
|
||||
{manualTotal === null && calculatedTotal !== null
|
||||
? '✓ Automatisch berechnet'
|
||||
: 'Manuell eingeben'}
|
||||
? '✓ Aus Beginn und Ende berechnet, aufgerundet auf 15 Minuten'
|
||||
: 'Von Hand gewählt'}
|
||||
</small>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in new issue
Block a user