Terminplaner: Portal-Ansicht – Nachbesserungen (2/2)

- Annehmen mit Rueckfrage in der Seite (schliesst den Vertrag, schickt G02)
- Offene Anfragen: alle bis Ende des Buchungszeitraums (Fenster zu je 62 Tagen,
  hoechstens 6 Aufrufe), passend zur Zahl auf Kachel und Banner
- Meldung ins Bild geholt, Fehler mit Fokus; einzige Live-Region
- Netzwerkfehler auf Deutsch; Antwort einer frueheren Website erscheint nie
  unter der neuen (Zaehler je Aufruf); Datumssprung nur mit echtem Tag
- Ende um Mitternacht als 24:00, Statusfilter nach Eintragen auf Alle,
  abgeschaltet ohne Einstellung mit Export-Link, dunkles Datumsfeld
- Playwright: Zeitzone New York/Berlin, ferne Anfragen, Projektwechsel,
  Meldung im Bild, Datumssprung, abgeschaltet ohne Einstellung

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-03 08:17:44 +00:00
1 parent 9c07f6a8c5
commit 650919b022
10 files changed
+410 -73

No files matched your search

+38 -7
View File
@@ -40,16 +40,45 @@ export function monatVon(tag) {
}
/**
* Zeitraum fuer die Abfrage der Buchungen. ansicht: 'tag' | 'woche' | 'monat' | 'anfragen' (ab heute, so weit die
* Schnittstelle reicht).
* Zeitraum der Liste. ansicht: 'tag' | 'woche' | 'monat' | 'anfragen' (ab heute bis zum Ende des Buchungszeitraums horizontTage
* der Einstellung, Vorgabe 60, hoechstens 365). Fuer 'anfragen' ist der Zeitraum laenger als ein Aufruf der Schnittstelle:
* fensterAufteilen macht daraus die einzelnen Abfragen.
*/
export function bereichFuer(ansicht, tag, heute) {
export function bereichFuer(ansicht, tag, heute, horizontTage) {
if (ansicht === 'woche') return wocheVon(tag)
if (ansicht === 'monat') return monatVon(tag)
if (ansicht === 'anfragen') return { von: heute, bis: tagPlus(heute, MAX_TAGE) }
if (ansicht === 'anfragen') {
const horizont = Number.isInteger(horizontTage) && horizontTage >= 1 ? Math.min(horizontTage, 365) : 60
return { von: heute, bis: tagPlus(heute, horizont) }
}
return { von: tag, bis: tag }
}
/**
* Zerlegt von..bis (beide Tage eingeschlossen) in lueckenlose Fenster, die die Schnittstelle einzeln annimmt:
* bis hoechstens 62 Tage nach von. 365 Tage ab heute sind sechs Aufrufe.
*/
export function fensterAufteilen(von, bis) {
const fenster = []
for (let anfang = von; anfang <= bis; anfang = tagPlus(fenster.at(-1).bis, 1)) {
const ende = tagPlus(anfang, MAX_TAGE)
fenster.push({ von: anfang, bis: ende < bis ? ende : bis })
}
return fenster
}
/** Ein echter Kalendertag 'JJJJ-MM-TT' aus den Jahren 2000 bis 2100 (ein Datumsfeld mit fuenfstelligem Jahr liefert anderes). */
export function istTag(text) {
const m = typeof text === 'string' ? TAG_RE.exec(text) : null
if (!m) return false
const jahr = Number(m[1])
const monat = Number(m[2])
const tag = Number(m[3])
if (jahr < 2000 || jahr > 2100) return false
const datum = new Date(Date.UTC(jahr, monat - 1, tag))
return datum.getUTCFullYear() === jahr && datum.getUTCMonth() === monat - 1 && datum.getUTCDate() === tag
}
/** Naechster (richtung 1) oder vorheriger (-1) Zeitraum: Tag +-1, Woche +-7, Monat auf den 1. des Nachbarmonats. */
export function verschiebeTag(ansicht, tag, richtung) {
if (ansicht === 'woche') return tagPlus(tag, 7 * richtung)
@@ -100,10 +129,12 @@ export function zeitraumTitel(ansicht, tag) {
const ENDE_FORMAT = new Intl.DateTimeFormat('de-DE', { timeZone: 'Europe/Berlin', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' })
/** Ende des Termins als Berliner Wanduhr 'HH:MM' (aus endsAt); '' wenn kein Zeitpunkt. */
/** Ende des Termins als Berliner Wanduhr 'HH:MM' (aus endsAt), Mitternacht als '24:00' (22:00–24:00); '' wenn kein Zeitpunkt. */
export function endeZeit(buchung) {
const ende = new Date(buchung?.endsAt)
return Number.isNaN(ende.getTime()) ? '' : ENDE_FORMAT.format(ende)
if (Number.isNaN(ende.getTime())) return ''
const zeit = ENDE_FORMAT.format(ende)
return zeit === '00:00' ? '24:00' : zeit
}
/* ------------------------------------------------------------- Uhrzeit --- */
@@ -182,7 +213,7 @@ export function filterStatus(key) {
return FILTER.find((f) => f.key === key)?.status?.join(',') ?? ''
}
/** „3 Anfragen warten“ / „1 Anfrage wartet“; bei 0 oder ohne Zahl ''. */
/** „3 Anfragen warten“ / „1 Anfrage wartet“; bei 0 oder ohne Zahl ''. Gleicher Text steht als anfragenText in funktionen.js (Kachel) – beide gemeinsam aendern. */
export function anfragenText(n) {
if (!Number.isInteger(n) || n < 1) return ''
return n === 1 ? '1 Anfrage wartet' : `${n} Anfragen warten`