Add "not working" day option with UI updates and logic adjustments for overtime calculations

This commit is contained in:
T.Landgraf committed 2026-08-31 13:15:22 +02:00
1 parent 17936615e2
commit 3cb3306a79
1 file changed
+60 -11
+60 -11
View File
@@ -10,6 +10,7 @@ interface DayRecord {
breakMins: number;
workedHrs: number;
overtimeMinutes: number;
notWorking?: boolean;
}
type Records = Partial<Record<Workday, DayRecord>>;
@@ -17,7 +18,7 @@ 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 };
const DEFAULT_RECORD: DayRecord = { start: '', end: '', breakMins: 0, workedHrs: 0, overtimeMinutes: 0, notWorking: false };
const WEEKDAYS: Workday[] = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag'];
@@ -81,11 +82,16 @@ function App() {
}
const getWeeklyBalance = () => {
const days: Workday[] = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag'];
return days.reduce((sum, day) => sum + (records[day]?.overtimeMinutes ?? 0), 0) + carryoverMinutes;
const days: Workday[] = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag'];
return days.reduce((sum, day) => {
const r = records[day];
if (!r || r.notWorking) return sum;
return sum + (r.overtimeMinutes ?? 0);
}, 0) + carryoverMinutes;
}
const getWorkEndTime = () => {
if (record.notWorking) return '-';
const start = toMinutes(record.start);
if (start === null) return '-';
const balance = selectedDay === 'Freitag' ? getWeeklyBalance() : 0;
@@ -93,16 +99,25 @@ function App() {
}
const handleSave = () => {
if (record.notWorking) {
updateRecord({ workedHrs: 0, overtimeMinutes: 0 });
return;
}
const hours = getHourDiff();
updateRecord({ workedHrs: hours, overtimeMinutes: Math.round((hours - 8) * 60) });
}
const handleResetWorkdays = () => {
const totalOvertime = WEEKDAYS.reduce((sum, day) => sum + (records[day]?.overtimeMinutes ?? 0), 0) + carryoverMinutes;
const totalOvertime = WEEKDAYS.reduce((sum, day) => {
const r = records[day];
if (!r || r.notWorking) return sum;
return sum + (r.overtimeMinutes ?? 0);
}, 0) + carryoverMinutes;
setCarryoverMinutes(totalOvertime);
setRecords({});
}
const handleResetOvertime = () => {
setCarryoverMinutes(0);
}
@@ -111,16 +126,42 @@ function App() {
<Center className={"my-auto"}>
<Stack>
<SegmentedControl
data={['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag']}
data={WEEKDAYS.map((day) => ({
value: day,
label: (
<span
style={records[day]?.notWorking ? { color: 'var(--mantine-color-grape-4)' } : undefined}
>
{day}
</span>
),
}))}
value={selectedDay}
onChange={(value) => setSelectedDay(value as Workday)}
className={"mt-2"}
/>
<Button
variant={"outline"}
color={record.notWorking ? "grape" : "gray"}
onClick={() => {
const nowWorking = !record.notWorking;
if (nowWorking) {
updateRecord({ notWorking: true, start: '', end: '', breakMins: 0, workedHrs: 0, overtimeMinutes: 0 });
} else {
updateRecord({ notWorking: false });
}
}}
fullWidth
>
{record.notWorking ? "✓ Als Arbeitstag markieren" : "Nicht gearbeitet"}
</Button>
<TimePicker
value={record.start}
label={"Arbeitsbeginn"}
onChange={(value) => updateRecord({ start: value })}
format="24h"
clearable
disabled={record.notWorking}
/>
<TimePicker
value={record.end}
@@ -128,6 +169,7 @@ function App() {
onChange={(value) => updateRecord({ end: value })}
format="24h"
clearable
disabled={record.notWorking}
/>
<NumberInput
label={"Pause in Minuten"}
@@ -136,27 +178,34 @@ function App() {
onKeyDown={(event) => {
if (event.key === 'Enter') handleSave();
}}
disabled={record.notWorking}
/>
<Button onClick={handleSave}>
<Button onClick={handleSave} disabled={record.notWorking}>
Berechnen + Speichern
</Button>
<Text>Gearbeitete Stunden heute: {record.workedHrs.toFixed(2)}</Text>
{record.notWorking ? (
<Text c={"grape"}>Heute nicht gearbeitet</Text>
) : (
<Text>Gearbeitete Stunden heute: {record.workedHrs.toFixed(2)}</Text>
)}
{carryoverMinutes !== 0 && (
<Text c={"blue"}>Übernommene Überstunden aus Vorwoche: {carryoverMinutes} Minuten</Text>
)}
{selectedDay === 'Freitag' && (
<Text c={"green"}>Übertragen aus Montag bis Donnerstag (inkl. Vorwoche): {getWeeklyBalance()} Minuten</Text>
)}
<Text>Wann du gehen kannst für 8 Stunden: {getWorkEndTime()}</Text>
{record.start && record.end && record.overtimeMinutes === 0 && (
{!record.notWorking && (
<Text>Wann du gehen kannst für 8 Stunden: {getWorkEndTime()}</Text>
)}
{!record.notWorking && record.start && record.end && record.overtimeMinutes === 0 && (
<Text>Du hast genau 8 Stunden gearbeitet.</Text>
)}
{record.start && record.end && record.overtimeMinutes > 0 && (
{!record.notWorking && record.start && record.end && record.overtimeMinutes > 0 && (
<Text c="yellow">Überstunden: {record.overtimeMinutes} Minuten</Text>
)}
{record.start && record.end && record.overtimeMinutes < 0 && (
{!record.notWorking && record.start && record.end && record.overtimeMinutes < 0 && (
<Text c={"red"}>Fehlende Minuten für 8 Stunden: {-record.overtimeMinutes} Minuten</Text>
)}