chore: fix/art-reset → main (Version 1.16.1)
This commit is contained in:
@@ -28,7 +28,7 @@ Next.js 16 App Router application. All pages are server components; interactive
|
|||||||
|
|
||||||
- **`CustomSelect`**: replaces native `<select>` everywhere — iOS/Android native popups ignore CSS sizing. Supports `keepOpen` prop for multi-select use cases (BEOs, Objekte).
|
- **`CustomSelect`**: replaces native `<select>` everywhere — iOS/Android native popups ignore CSS sizing. Supports `keepOpen` prop for multi-select use cases (BEOs, Objekte).
|
||||||
- **`TimePicker5`**: custom time picker, no native `<input type="time">`. Shows HH:MM with ▲/▼ buttons, 5-minute steps, auto-repeat on hold (400 ms delay → 1-hour steps at 350 ms). Keyboard: ↑/↓.
|
- **`TimePicker5`**: custom time picker, no native `<input type="time">`. Shows HH:MM with ▲/▼ buttons, 5-minute steps, auto-repeat on hold (400 ms delay → 1-hour steps at 350 ms). Keyboard: ↑/↓.
|
||||||
- **`LogbuchForm`**: Beginn/Ende stored as `"YYYY-MM-DDTHH:MM"` strings. Date and time are split into separate `<input type="date">` + `<TimeInput>`. The single date field is the **Beginn** date; Ende's date is derived, never entered. Rule for sessions crossing midnight: **start time-of-day later than end time-of-day ⇒ Beginn is the previous day**, anchored on Ende (the moment the form is filled in, hence the reliable one) — `beginnAusEnde()` / `endeAusBeginn()`. So typing a start time can move the visible date back a day; a grey line below the row explains it. A duration over 12 h shows a soft hint but never blocks saving. Entries created before 1.16.0 may have `Beginn > Ende`; `migrate_zeiten.sql` fixes them.
|
- **`LogbuchForm`**: Beginn/Ende stored as `"YYYY-MM-DDTHH:MM"` strings. Date and time are split into separate `<input type="date">` + `<TimeInput>`. The single date field is the **Beginn** date; Ende's date is derived, never entered. Rule for sessions crossing midnight: **start time-of-day later than end time-of-day ⇒ Beginn is the previous day**, anchored on Ende (the moment the form is filled in, hence the reliable one) — `beginnAusEnde()` / `endeAusBeginn()`. So typing a start time can move the visible date back a day; a grey line below the row explains it. A duration over 12 h shows a soft hint but never blocks saving. Entries created before 1.16.0 may have `Beginn > Ende`; `migrate_zeiten.sql` fixes them. Changing ArtFuehrung only clears what no longer fits — Objekte just when the category flips (`SonF` ↔ rest), never BEOs. The `currentUserBeo` prop must be referentially stable (it is `useMemo`'d in `MainClient`): it sits in the prefill effect's deps, so a fresh object on every parent render would wipe the form mid-entry.
|
||||||
- **`LogbuchList`**: accepts `compact` and `limit` props. Compact mode used for the 5-entry preview below the form on desktop (`hidden lg:block`).
|
- **`LogbuchList`**: accepts `compact` and `limit` props. Compact mode used for the 5-entry preview below the form on desktop (`hidden lg:block`).
|
||||||
|
|
||||||
## Data model
|
## Data model
|
||||||
|
|||||||
+7
-2
@@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { KUPPELN } from '@/types/logbuch';
|
import { KUPPELN } from '@/types/logbuch';
|
||||||
import type { Kuppel, LogbuchEintrag, SofueStatus } from '@/types/logbuch';
|
import type { Kuppel, LogbuchEintrag, SofueStatus } from '@/types/logbuch';
|
||||||
import LogbuchForm from '@/components/LogbuchForm';
|
import LogbuchForm from '@/components/LogbuchForm';
|
||||||
@@ -50,7 +50,12 @@ export default function MainClient({ kuerzel, beoId, beoName, role }: Props) {
|
|||||||
process.env.NEXT_PUBLIC_BUILD_DATE ||
|
process.env.NEXT_PUBLIC_BUILD_DATE ||
|
||||||
new Date().toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });
|
new Date().toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });
|
||||||
|
|
||||||
const currentUserBeo = { ID: beoId, Kuerzel: kuerzel, Name: beoName };
|
// Muss stabil bleiben: LogbuchForm setzt bei jeder Änderung dieses Objekts das
|
||||||
|
// Formular zurück. Frisch erzeugt würde jedes Rendern hier die Eingaben löschen.
|
||||||
|
const currentUserBeo = useMemo(
|
||||||
|
() => ({ ID: beoId, Kuerzel: kuerzel, Name: beoName }),
|
||||||
|
[beoId, kuerzel, beoName]
|
||||||
|
);
|
||||||
|
|
||||||
function handleSaved(sofue?: SofueStatus | null) {
|
function handleSaved(sofue?: SofueStatus | null) {
|
||||||
setRefreshKey((k) => k + 1);
|
setRefreshKey((k) => k + 1);
|
||||||
|
|||||||
@@ -175,6 +175,8 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
|
|||||||
return () => { verworfen = true; };
|
return () => { verworfen = true; };
|
||||||
}, [ende]);
|
}, [ende]);
|
||||||
|
|
||||||
|
// Vorbelegen beim Bearbeiten, sonst leeres Formular. currentUserBeo muss vom
|
||||||
|
// Aufrufer stabil gehalten werden, sonst setzt jedes Rendern die Eingaben zurück.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editEntry) {
|
if (editEntry) {
|
||||||
setArtFuehrung(editEntry.ArtFuehrung);
|
setArtFuehrung(editEntry.ArtFuehrung);
|
||||||
@@ -233,17 +235,23 @@ export default function LogbuchForm({ kuppel, currentUserBeo, editEntry, onSaved
|
|||||||
}
|
}
|
||||||
}, [editEntry]);
|
}, [editEntry]);
|
||||||
|
|
||||||
// Objekte, Besucher und Spende zurücksetzen beim Wechsel der Art der Führung
|
// Beim Wechsel der Art der Führung nur das zurücksetzen, was zur neuen Art nicht
|
||||||
|
// mehr passt. Der erste Lauf bleibt außen vor: dort steht noch der Startwert 'RF',
|
||||||
|
// während die Vorbelegung aus editEntry gerade erst gesetzt wird.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const vorherigeArt = prevArtRef.current;
|
const vorherigeArt = prevArtRef.current;
|
||||||
prevArtRef.current = artFuehrung;
|
prevArtRef.current = artFuehrung;
|
||||||
|
if (vorherigeArt === null) return;
|
||||||
|
|
||||||
|
// Objekte nur leeren, wenn die Kategorie wechselt (Sonne ↔ Sterne) — sonst gingen
|
||||||
|
// bereits eingetragene Objekte verloren, wenn die Art erst danach gewählt wird.
|
||||||
|
if ((vorherigeArt === SONNE_ART) !== (artFuehrung === SONNE_ART)) {
|
||||||
setObjekte([]);
|
setObjekte([]);
|
||||||
|
}
|
||||||
if (NO_OBJEKTE_ARTEN.includes(artFuehrung)) {
|
if (NO_OBJEKTE_ARTEN.includes(artFuehrung)) {
|
||||||
setBesucher('');
|
setBesucher('');
|
||||||
}
|
}
|
||||||
// Nicht beim ersten Lauf leeren — sonst überschreibt der Start-Wert 'RF'
|
if (artFuehrung !== 'SF') {
|
||||||
// die aus editEntry vorbelegte Spende.
|
|
||||||
if (vorherigeArt !== null && artFuehrung !== 'SF') {
|
|
||||||
setSpende('');
|
setSpende('');
|
||||||
setSpendeBetragRaw('');
|
setSpendeBetragRaw('');
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "logbuch",
|
"name": "logbuch",
|
||||||
"version": "1.16.0",
|
"version": "1.16.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|||||||
Reference in New Issue
Block a user