Add autofill for end time and break duration with labels indicating auto-filled values

This commit is contained in:
T.Landgraf committed 2026-09-15 14:28:00 +02:00
1 parent b91c9b1377
commit f8703963fd
1 file changed
+38 -7
+38 -7
View File
@@ -11,6 +11,8 @@ interface DayRecord {
workedHrs: number;
overtimeMinutes: number;
notWorking?: boolean;
endAutofilled?: boolean;
breakAutofilled?: boolean;
}
type Records = Partial<Record<Workday, DayRecord>>;
@@ -18,10 +20,13 @@ type Records = Partial<Record<Workday, DayRecord>>;
const STORAGE_KEY = 'workTrackerRecords';
const CARRYOVER_KEY = 'workTrackerCarryover';
const DEFAULT_RECORD: DayRecord = { start: '', end: '', breakMins: 0, workedHrs: 0, overtimeMinutes: 0, notWorking: false };
const DEFAULT_RECORD: DayRecord = { start: '', end: '', breakMins: 0, workedHrs: 0, overtimeMinutes: 0, notWorking: false, endAutofilled: false, breakAutofilled: false };
const WEEKDAYS: Workday[] = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag'];
const STANDARD_WORK_MINUTES = 8 * 60;
const STANDARD_BREAK_MINUTES = 60;
const loadRecords = (): Records => {
try {
const raw = localStorage.getItem(STORAGE_KEY);
@@ -100,6 +105,32 @@ function App() {
return fromMinutes(start + 8 * 60 - balance + record.breakMins);
}
const handleStartChange = (value: string) => {
const start = toMinutes(value);
if (start === null) {
updateRecord({ start: value, endAutofilled: false, breakAutofilled: false });
return;
}
updateRecord({
start: value,
breakMins: STANDARD_BREAK_MINUTES,
end: fromMinutes(start + STANDARD_WORK_MINUTES + STANDARD_BREAK_MINUTES),
endAutofilled: true,
breakAutofilled: true,
});
};
const autofillLabel = (label: string, autofilled?: boolean) => (
<span>
{label}
{autofilled && (
<Text component="span" size="xs" c="dimmed" fw={400}>
{' '}(automatisch ausgefüllt)
</Text>
)}
</span>
);
const handleSave = () => {
if (record.notWorking) {
updateRecord({ workedHrs: 0, overtimeMinutes: 0 });
@@ -148,7 +179,7 @@ function App() {
onClick={() => {
const nowWorking = !record.notWorking;
if (nowWorking) {
updateRecord({ notWorking: true, start: '', end: '', breakMins: 0, workedHrs: 0, overtimeMinutes: 0 });
updateRecord({ notWorking: true, start: '', end: '', breakMins: 0, workedHrs: 0, overtimeMinutes: 0, endAutofilled: false, breakAutofilled: false });
} else {
updateRecord({ notWorking: false });
}
@@ -160,23 +191,23 @@ function App() {
<TimePicker
value={record.start}
label={"Arbeitsbeginn"}
onChange={(value) => updateRecord({ start: value })}
onChange={handleStartChange}
format="24h"
clearable
disabled={record.notWorking}
/>
<TimePicker
value={record.end}
label={"Arbeitsende"}
onChange={(value) => updateRecord({ end: value })}
label={autofillLabel("Arbeitsende", record.endAutofilled)}
onChange={(value) => updateRecord({ end: value, endAutofilled: false })}
format="24h"
clearable
disabled={record.notWorking}
/>
<NumberInput
label={"Pause in Minuten"}
label={autofillLabel("Pause in Minuten", record.breakAutofilled)}
value={record.breakMins}
onChange={(val) => updateRecord({ breakMins: Number(val) })}
onChange={(val) => updateRecord({ breakMins: Number(val), breakAutofilled: false })}
onKeyDown={(event) => {
if (event.key === 'Enter') handleSave();
}}