From 21ed1e77440e701b17972b2b39b3ee1db3bad847 Mon Sep 17 00:00:00 2001 From: "T.Landgraf" Date: Fri, 14 Aug 2026 08:41:42 +0200 Subject: [PATCH] Add persistent workday records with localStorage integration and reset functionality --- src/App.tsx | 106 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 29 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index cd3672b..40a3656 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,6 +4,29 @@ import * as React from 'react'; type Workday = 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday'; +interface DayRecord { + start: string; + end: string; + breakMins: number; + workedHrs: number; + overtimeMinutes: number; +} + +type Records = Partial>; + +const STORAGE_KEY = 'workTrackerRecords'; + +const DEFAULT_RECORD: DayRecord = { start: '', end: '', breakMins: 0, workedHrs: 0, overtimeMinutes: 0 }; + +const loadRecords = (): Records => { + try { + const raw = localStorage.getItem(STORAGE_KEY); + return raw ? JSON.parse(raw) : {}; + } catch { + return {}; + } +}; + const toMinutes = (time: string): number | null => { const match = /^(\d{2}):(\d{2})$/.exec(time); if (!match) return null; @@ -18,29 +41,48 @@ const fromMinutes = (mins: number): string => { function App() { const [selectedDay, setSelectedDay] = React.useState('Monday'); - const [workStart, setWorkStart] = React.useState(''); - const [workEnd, setWorkEnd] = React.useState(''); - const [breakMins, setBreakMins] = React.useState(0); - const [workedHrs, setWorkedHrs] = React.useState(0); - const [overtimeMinutes, setOvertimeMinutes] = React.useState(0); + const [records, setRecords] = React.useState(loadRecords); + + const record = records[selectedDay] ?? DEFAULT_RECORD; + + React.useEffect(() => { + localStorage.setItem(STORAGE_KEY, JSON.stringify(records)); + }, [records]); + + const updateRecord = (patch: Partial) => { + setRecords((prev) => ({ + ...prev, + [selectedDay]: { ...(prev[selectedDay] ?? DEFAULT_RECORD), ...patch }, + })); + }; const getHourDiff = () => { - const start = toMinutes(workStart); - const end = toMinutes(workEnd); + const start = toMinutes(record.start); + const end = toMinutes(record.end); if (start === null || end === null) return 0; - return (end - start) / 60 - breakMins / 60; + return (end - start) / 60 - record.breakMins / 60; + } + + const getWeeklyBalance = () => { + const days: Workday[] = ['Monday', 'Tuesday', 'Wednesday', 'Thursday']; + return days.reduce((sum, day) => sum + (records[day]?.overtimeMinutes ?? 0), 0); } const getWorkEndTime = () => { - const start = toMinutes(workStart); + const start = toMinutes(record.start); if (start === null) return '—'; - return fromMinutes(start + 8 * 60 + breakMins); + const balance = selectedDay === 'Friday' ? getWeeklyBalance() : 0; + return fromMinutes(start + 8 * 60 - balance + record.breakMins); } const handleSave = () => { const hours = getHourDiff(); - setWorkedHrs(hours); - setOvertimeMinutes(Math.round((hours - 8) * 60)); + updateRecord({ workedHrs: hours, overtimeMinutes: Math.round((hours - 8) * 60) }); + } + + const handleReset = () => { + localStorage.removeItem(STORAGE_KEY); + setRecords({}); } return ( @@ -48,48 +90,54 @@ function App() { { - setWorkStart(''); - setWorkEnd(''); - setSelectedDay(value as Workday); - }} + onChange={(value) => setSelectedDay(value as Workday)} className={"mt-2"} /> updateRecord({ start: value })} format="24h" clearable /> updateRecord({ end: value })} format="24h" clearable /> setBreakMins(Number(val))} + value={record.breakMins} + onChange={(val) => updateRecord({ breakMins: Number(val) })} + onKeyDown={(event) => { + if (event.key === 'Enter') handleSave(); + }} /> - Gearbeitete Stunden heute: {workedHrs.toFixed(2)} + Gearbeitete Stunden heute: {record.workedHrs.toFixed(2)} + {selectedDay === 'Friday' && ( + Übertragen aus Montag bis Donnerstag: {getWeeklyBalance()} Minuten + )} Wann du gehen kannst für 8 Stunden: {getWorkEndTime()} - {overtimeMinutes === 0 && ( + {record.overtimeMinutes === 0 && ( Du hast genau 8 Stunden gearbeitet. )} - {overtimeMinutes > 0 && ( - Überstunden: {overtimeMinutes} Minuten + {record.overtimeMinutes > 0 && ( + Überstunden: {record.overtimeMinutes} Minuten )} - {overtimeMinutes < 0 && ( - Fehlende Minuten für 8 Stunden: {-overtimeMinutes} Minuten + {record.overtimeMinutes < 0 && ( + Fehlende Minuten für 8 Stunden: {-record.overtimeMinutes} Minuten )} + + );