Commit Graph

12 Commits

Author SHA1 Message Date
schalli 8532b63097 feat(web): Design Mosaik Runde 3 - Reiter in der Seitenleiste, lebendigere Kacheln
- Dashboard-Reiter stehen in der aufgeklappten Seitenleiste als Liste
  unter "Dashboard" (Ziehen sortiert senkrecht, Umbenennen/Loeschen/Neu
  im Bearbeitungsmodus); eingeklappt und auf dem Handy wie bisher in der
  Kopfzeile. Die Kopfzeile zeigt sonst den Namen des Dashboards.
- Begruessung einzeilig auf Hoehe der Befehlsleiste.
- Kachel-Groesse: kollidiert die gezogene Groesse mit einem Nachbarn, wird
  nur die freie Achse uebernommen - vorher verwarf react-grid-layout mit
  preventCollision die ganze Aenderung, sobald die Maus eine Zeile nach
  unten wackelte (Favoriten liessen sich deshalb oft nicht schmaler ziehen).
- Ansicht: belegte Spalten mittig, Begruessung/Befehlsleiste ruecken mit.
- Kalender: einzeilige Terminliste mit "Heute"/"Morgen" in Akzentfarbe,
  Ort im Tooltip, Standardhoehe 16 statt 12.
- Hintergrund "Bluete" im Dunkelmodus weggelassen (Farbstufen), Ersatz Nebel.
- Kacheln: Symbol-Chip in der Akzentfarbe, leichtes Anheben beim Zeigen,
  gestaffeltes Einblenden beim Laden (ohne bei reduzierter Bewegung).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 15:58:01 +02:00
schalli b06a2d1066 feat(web): Dashboard mit Begruessung, Befehlsleiste und ruhigeren Kacheln
Begruessung nach Tageszeit mit Datum, Befehlsleiste oben rechts statt
schwebendem Knopf, einheitliche Kachel-Kopfzeilen mit Symbol, Kalender
mit Pfeilknoepfen, runden Tagen und Terminpunkten, Favoriten als
36-px-Zeilen bzw. App-Starter-Kacheln, Notiz-Kaestchen im Akzent,
leerer Zustand mit drei Vorschlaegen.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 13:09:05 +02:00
schalli 219038b3ee feat(web): Dashboard-Kacheln im Fluent-Stil und waehlbarer Hintergrund
Einheitliche Kachel-Kopfzeile, ruhigere Notiz-/Kalender-/Favoriten-
Darstellung, 12 px Raster-Abstand, gestrichelte Kontur und Griff im
Bearbeitungsmodus. Neuer Knopf Hintergrund: Keiner, fuenf eingebaute
(Nebel, Salbei, Bluete, Duenen, Mosaik) oder eigenes Bild aus den
Bilderrahmen-Bildern; Prototyp speichert im localStorage je Benutzer.
Mit Hintergrund werden Kacheln Mica-artig durchscheinend (Kontrast
>= 4,5:1 auch im schlechtesten Fall).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 14:49:01 +02:00
schalli f471b785db fix(quick-260921-jt4): verschwendete Kalender-Abrufe abgestellt, t-Identitaet gemessen statt behauptet
Restposten 3a (doppeltes Ladefenster): lastFetchWindowRef merkt sich das
zuletzt TATSAECHLICH geholte from/to-Paar; ein Monatswechsel, dessen
berechnetes Fenster damit uebereinstimmt, ueberspringt fetchEvents. Der
5-Minuten-Auffrischer (force=true) umgeht den Sperrgriff immer, sonst
friert die Anzeige ein. computeFetchWindow und die Tagesgrenzen-Rundung
bleiben unangetastet.

Restposten 3b (Quellenliste je Monatswechsel): hasSourcesRef merkt sich
das Ergebnis; fetchSources laeuft nur beim Aufbau (Merkung leer) oder
erzwungen (Auffrischer) — eine neu eingerichtete Quelle wird weiterhin
binnen fuenf Minuten bemerkt.

Restposten 4 (t-Identitaet): neue translations-identity.test.tsx rendert
eine Testkomponente unter dem ECHTEN NextIntlClientProvider und beweist
per Referenzgleichheit, dass t bei einem lokalen Zustandswechsel
dasselbe Funktionsobjekt bleibt — bestaetigt durch den use-intl-4.13.0-
Quelltext (translate entsteht in einem useMemo, dessen Abhaengigkeiten
ausschliesslich aus dem root-staendigen Intl-Kontext stammen). Die
Faustregel aus 260921-gof ("t gehoert in keine Abhaengigkeitsliste")
bleibt als Konvention in Ordnung; die zugrunde liegende Annahme ("t ist
bei jedem Render frisch") ist damit ausdruecklich WIDERLEGT statt ein
drittes Mal weitergetragen. Die vier verbliebenen Stellen
(marketplace/page.tsx, admin/users/page.tsx,
calendar-settings-panel.tsx, calendar-source-form.tsx) bleiben deshalb
unveraendert.

Vier neue zaehlende Testfaelle in calendar-widget.test.tsx (Aufbau je 1,
abweichendes Fenster +1/+0, identisches Fenster +0/+0, erzwungener Lauf
+1/+1) plus ein Test, dass ein uebersprungener Lauf den Ladezustand
sauber beendet und geladene Termine nicht leert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
2026-09-21 15:10:10 +02:00
schalli e651c24647 fix(quick-260921-jt4): Kalender-Tageszelle wird echte Schaltflaeche fuer Tage mit Terminen
- Zelle rendert als <button type="button"> NUR wenn hasEvents gilt,
  sonst unveraendert als <div> ohne Handler (D-01) — 42 neue Tab-Stopps
  waeren eine Verschlechterung
- onFocus/onBlur mit demselben Rumpf wie onMouseEnter/onMouseLeave,
  damit die Termin-Einblendung auch per Tastatur erscheint/verschwindet
- cellClass unveraendert uebernommen, nur w-full text-left ergaenzt
  (D-04, kein optischer Unterschied); widgetNoDrag bleibt erhalten
- aria-label nennt Datum und Terminzahl ueber neue Katalogschluessel
  widgets.calendar.dayEventsOne/dayEventsMany (Mehrzahl-Konvention wie
  configMaxEventsOne/Many, D-05)
- Neue Tests: Tag mit Terminen ist <button> und reagiert auf
  Fokus/Weggehen wie auf Maus-Hover; Tag ohne Termine bleibt <div>;
  Einzahl-/Mehrzahl-Beschriftung; echter Tab-Stopp nachgewiesen

Nach diesem Umbau: klick-regeln 5 (nur die vier <img onError> +
Taschenrechner-Rahmen), semantic 0, a11y gesamt 14, errors 0 — Aufgabe
1 des Plans vollstaendig.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
2026-09-21 14:51:41 +02:00
schalli b3f0e3cdcd fix(web): Kalender-Ladeeffekt an monthDate statt getTime(), Stoppuhr-Takt liest nur noch Einzelwerte
Befunde 1-6 der Biome-Regel useExhaustiveDependencies (quick-260921-gof):

- calendar-widget.tsx: useMemo um resolveCalendarConfig() entfernt
  (reine Funktion, spart nichts). showToday setzt monthDate jetzt
  identitaetserhaltend, wenn der aktuelle Monat schon angezeigt wird -
  erst danach durfte der Ladeeffekt von monthDate.getTime() auf
  monthDate umgestellt werden, sonst haette jeder Druck auf den
  Monatsknopf im laufenden Monat einen Termin-Abruf bis zum
  Exchange-Server ausgeloest (D-04).
- stopwatch-widget.tsx: neue reine Hilfsfunktion computeElapsedFrom()
  fuer den Takt-Effekt, der jetzt nur noch drei Einzelwerte statt des
  ganzen sw-Objekts liest - eine sw-Abhaengigkeit haette den 100-ms-Takt
  bei jeder aufgezeichneten Runde ab- und wiederaufgebaut.
- Testerweiterungen als Rueckfallsicherungen: 2x weiterblaettern -> 3
  Abrufe, 3x Monatsknopf im laufenden Monat -> kein Zusatzabruf; Runde
  waehrend die Stoppuhr laeuft unterbricht den Takt nicht, genau 1 PATCH
  je Klick.
- Wirkungslose eslint-disable-Zeilen fuer diese Regel entfallen (kein
  ESLint mehr im Projekt).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
2026-09-21 12:23:35 +02:00
schalli 7429c5bd8d feat(web): Kalender-Widget zeigt je Kalender einen kleinen Kreis am Tag; Changelog
- Plaketten-Wrapper calendar-day-badges rendert buildDayBadges(day.events) statt der alten Einzel-Plakette
- Ein Kalender: unveraendert eine Plakette in Kalenderfarbe/Akzentfarbe (Tests 3/3b/3c bleiben gruen)
- Zwei/drei Kalender: je ein kleiner Kreis pro Kalender in Startreihenfolge (Test 3d)
- Vier oder mehr Kalender: zwei Kreise plus grauer Restkreis bg-muted-foreground/text-background mit Summe (Test 3e)
- CHANGELOG-Stichpunkt erweitert (mehrere Kalender am selben Tag)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 14:37:01 +02:00
schalli 1e4ec30190 feat(web): Kalender-Plakette in der Farbe des Kalenders, Farbpunkt je Tooltip-Zeile
- groupEventsByDate sortiert jede Tagesgruppe jetzt nach Start aufsteigend
- Zaehl-Plakette im Monatsraster traegt die Farbe des Kalenders des fruehesten Termins (weisse Schrift), ohne Farbe unveraendert bg-primary
- Tooltip-Zeilen bekommen denselben Farbpunkt wie die Liste "Naechste Termine" (Rueckfall var(--muted-foreground))
- 3 neue Tests: calendar-month Test 2b, calendar-widget Test 3b/3c

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 14:25:21 +02:00
schalli b16e4b8e67 fix(web): Kalender-Tooltip bricht lange Termintitel um (Breite/Klemmung aus einer Konstante)
- Titel-Span im Tooltip: min-w-0 break-words statt truncate
- Breite (288px) und Rand-Klemmung aus TOOLTIP_WIDTH_PX/TOOLTIP_EDGE_PX
- Test 4c: belegt Klassen und Tooltip-Breite

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 13:54:34 +02:00
schalli 61996dceef feat(web): Kalender-Widget neu gebaut mit Monatsraster + Naechste Termine, Mindestgroesse 6x8
- calendar-widget.tsx komplett neu: Monatsraster (Nav-Zeile, Wochentagskopf, 42 Zellen, heutiger Tag, Zaehl-Plakette, Portal-Tooltip) + Block "Naechste Termine"; fetchEvents bekommt immer zwei Tagesgrenzen-ISO-Strings ueber computeFetchWindow
- Komponententest komplett neu geschrieben (9 Tests: Laden/Quellen, Raster, Plakette, Tooltip inkl. 5+-Kuerzung, Naechste-Termine-Filter, showMonth/maxEvents=0, Ladefenster, Blaettern)
- WIDGET_CONSTRAINTS.calendar auf { minW: 6, minH: 8, defaultW: 8, defaultH: 12 } angehoben (quick-260916-htc), Registry-Test A mitgezogen

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 13:10:33 +02:00
schalli a175c00c18 feat(quick-260916-bwo): Abstaende halbiert — Seitenrahmen p-3 (alle Seiten), Dashboard p-2, Grid 8 px, Widget-Innenabstaende
- app-shell.tsx: main p-3 (12 px statt 24) — gilt fuer alle Seiten, Nachtrag des Users
- page.tsx: Container relative p-2, Umschalter right-2 top-2; mt-8 bleibt (Umschalter 36 px hoch, sonst Ueberlappung)
- link/favorites p-1, calendar p-1.5 (Zustandsansichten p-2), search px-1.5, note-Kopfzeile px-1.5
- Grid-Abstand 8 px bereits in Task 1, Uhr/Stoppuhr/Rechner-Innenabstaende bereits in 2a

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018N9CD3ebPKm1b32bPpBknY
2026-09-16 09:13:23 +02:00
schalli c0f2f4ca51 feat(05-04): calendar API client, calendar widget, registry wiring
- calendar-api.ts: fetchSources/addSource/updateSource/deleteSource/testSource/fetchEvents with credentials:'include'
- calendar-widget.tsx: upcoming-events list with source color dots, three empty states (no sources/no events/loading)
- widget-registry.tsx: wireCalendarWidget() replaces placeholder with real CalendarWidget
- page.tsx: wires CalendarWidget into registry on mount
- i18n: added calendar.loading key to de.json and en.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 15:23:27 +02:00