v1.7.2: Zeiteingabe – Startzeit leer, Endzeit vorbelegt und fokussiert

- Startzeit startet leer (manuelle Eingabe erforderlich)
- Endzeit startet mit aktueller Uhrzeit auf 5 Minuten aufgerundet
- Endzeit erhält Autofokus beim Laden des Formulars
- Startzeit synct Endzeit nicht mehr automatisch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 21:01:09 +02:00
parent cf038ad3be
commit 1a34fccc35
4 changed files with 29 additions and 18 deletions
+23 -14
View File
@@ -20,10 +20,18 @@ function toLocalDatetimeValue(isoOrDatetime: string): string {
return isoOrDatetime.slice(0, 16); return isoOrDatetime.slice(0, 16);
} }
function nowLocalDatetime(): string { function todayDate(): string {
const now = new Date(); const now = new Date();
const pad = (n: number) => String(n).padStart(2, '0'); const pad = (n: number) => String(n).padStart(2, '0');
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}T${pad(now.getHours())}:${pad(now.getMinutes())}`; return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
}
function nowRounded5(): string {
const now = new Date();
const pad = (n: number) => String(n).padStart(2, '0');
const total = now.getHours() * 60 + now.getMinutes();
const rounded = Math.ceil(total / 5) * 5;
return `${pad(Math.floor(rounded / 60) % 24)}:${pad(rounded % 60)}`;
} }
const NO_OBJEKTE_ARTEN: ArtFuehrung[] = ['BEOS', 'TD']; const NO_OBJEKTE_ARTEN: ArtFuehrung[] = ['BEOS', 'TD'];
@@ -31,8 +39,8 @@ const SONNE_ART: ArtFuehrung = 'SonF';
export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved }: Props) { export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved }: Props) {
const [artFuehrung, setArtFuehrung] = useState<ArtFuehrung>('RF'); const [artFuehrung, setArtFuehrung] = useState<ArtFuehrung>('RF');
const [beginn, setBeginn] = useState(nowLocalDatetime()); const [beginn, setBeginn] = useState(todayDate());
const [ende, setEnde] = useState(nowLocalDatetime()); const [ende, setEnde] = useState(todayDate() + 'T' + nowRounded5());
const [besucher, setBesucher] = useState<number | ''>(''); const [besucher, setBesucher] = useState<number | ''>('');
const [beos, setBeos] = useState<BeoOption[]>([currentUserBeo]); const [beos, setBeos] = useState<BeoOption[]>([currentUserBeo]);
const [objekte, setObjekte] = useState<SelectedObjekt[]>([]); const [objekte, setObjekte] = useState<SelectedObjekt[]>([]);
@@ -90,8 +98,8 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
} }
} else { } else {
setArtFuehrung('RF'); setArtFuehrung('RF');
setBeginn(nowLocalDatetime()); setBeginn(todayDate());
setEnde(nowLocalDatetime()); setEnde(todayDate() + 'T' + nowRounded5());
setBesucher(0); setBesucher(0);
setBeos([currentUserBeo]); setBeos([currentUserBeo]);
setObjekte([]); setObjekte([]);
@@ -144,8 +152,12 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
setError('Bitte Besucherzahl eingeben.'); setError('Bitte Besucherzahl eingeben.');
return; return;
} }
if (!beginn.slice(11, 16)) {
setError('Bitte Startzeit eingeben.');
return;
}
if (beginn === ende) { if (beginn === ende) {
setError('Die Zeite wurden nicht eingegeben'); setError('Start- und Endzeit sind identisch.');
return; return;
} }
@@ -177,8 +189,8 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
setSuccess(true); setSuccess(true);
setTimeout(() => setSuccess(false), 5000); setTimeout(() => setSuccess(false), 5000);
if (!editEntry) { if (!editEntry) {
setBeginn(nowLocalDatetime()); setBeginn(todayDate());
setEnde(nowLocalDatetime()); setEnde(todayDate() + 'T' + nowRounded5());
setBesucher(0); setBesucher(0);
setBeos([currentUserBeo]); setBeos([currentUserBeo]);
setObjekte([]); setObjekte([]);
@@ -238,10 +250,7 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
<label className={labelCls}>Startzeit</label> <label className={labelCls}>Startzeit</label>
<TimeInput <TimeInput
value={beginn.slice(11, 16)} value={beginn.slice(11, 16)}
onChange={(t) => { onChange={(t) => setBeginn(beginn.slice(0, 10) + 'T' + t)}
setBeginn(beginn.slice(0, 10) + 'T' + t);
setEnde(ende.slice(0, 10) + 'T' + t);
}}
className="w-24" className="w-24"
/> />
</div> </div>
@@ -250,7 +259,7 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
<TimeInput <TimeInput
value={ende.slice(11, 16)} value={ende.slice(11, 16)}
onChange={(t) => setEnde(ende.slice(0, 10) + 'T' + t)} onChange={(t) => setEnde(ende.slice(0, 10) + 'T' + t)}
clearOnFocus autoFocus
className="w-24" className="w-24"
/> />
</div> </div>
+3 -1
View File
@@ -7,6 +7,7 @@ interface Props {
onChange: (value: string) => void; onChange: (value: string) => void;
className?: string; className?: string;
clearOnFocus?: boolean; clearOnFocus?: boolean;
autoFocus?: boolean;
} }
function isValid(t: string): boolean { function isValid(t: string): boolean {
@@ -20,7 +21,7 @@ function normalize(t: string): string {
return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`; return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;
} }
export default function TimeInput({ value, onChange, className = '', clearOnFocus = false }: Props) { export default function TimeInput({ value, onChange, className = '', clearOnFocus = false, autoFocus = false }: Props) {
const [local, setLocal] = useState(value); const [local, setLocal] = useState(value);
const [error, setError] = useState(false); const [error, setError] = useState(false);
@@ -71,6 +72,7 @@ export default function TimeInput({ value, onChange, className = '', clearOnFocu
onChange={(e) => handleChange(e.target.value)} onChange={(e) => handleChange(e.target.value)}
onFocus={handleFocus} onFocus={handleFocus}
onBlur={handleBlur} onBlur={handleBlur}
autoFocus={autoFocus}
placeholder="HH:MM" placeholder="HH:MM"
maxLength={5} maxLength={5}
className={`w-full px-2 py-1 border-2 rounded-lg bg-white text-sm text-gray-900 font-mono text-center focus:outline-none ${ className={`w-full px-2 py-1 border-2 rounded-lg bg-white text-sm text-gray-900 font-mono text-center focus:outline-none ${
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "logbuch", "name": "logbuch",
"version": "1.7.1", "version": "1.7.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "logbuch", "name": "logbuch",
"version": "1.7.1", "version": "1.7.2",
"dependencies": { "dependencies": {
"bcryptjs": "^3.0.3", "bcryptjs": "^3.0.3",
"jose": "^6.2.2", "jose": "^6.2.2",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "logbuch", "name": "logbuch",
"version": "1.7.1", "version": "1.7.2",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",