Calendar¶
An in-app, server-rendered calendar for the household — no Node build, no vendored calendar library. It shows manual events, projects todo due-dates, and (optionally) two-way-syncs with Google Calendar.
Views¶
Open /calendar. Three views are switched with ?view= and navigated with
?date= Turbo Frame links:
- Month — a 7-column CSS-grid grid. Each cell carries a stable
data-cal-day="YYYY-MM-DD"hook; events render as chips reusing the existing pill geometry (so they are dark-mode-correct for free). A day with more events than the chip cap shows a "+N weitere" overflow link; long titles ellipsis with the full text intitle=. - Agenda — a flat chronological list.
- Day — hour rows for a single day.
All times are stored in UTC and rendered in the household's timezone
(Household.current.timezone).
Events¶
- Create / edit events from the calendar. The editor opens in a
mobile-friendly modal (a native
<dialog>driven by a Turbo Frame) so you stay on the calendar instead of switching pages. - Todo due-dates project onto the grid read-only with a distinct accent and legend — they are driven by the existing todo table, so there is no duplication and no risk of an edit loop.
Suggestions from comments¶
When a todo comment mentions a German date — e.g.
"Termin am 5. Mai um 14 Uhr" — Homestead runs a deterministic
GermanDateExtractor after the comment is saved and surfaces a standalone chip
beneath it: "Termin erkannt … In Kalender übernehmen?".
- Nothing is ever created silently. A human click on the chip creates the
CalendarEvent(source: "comment_extraction"), resolved in the household timezone and stored UTC. - Negative or ambiguous phrases ("5 Äpfel", "Seite 14", a bare "14 Uhr" with no day) produce no chip — the parser favours precision over recall.
- Dismissing a chip persists the decision (
SuggestionDismissal), so it never re-nags; editing the comment only re-offers genuinely changed dates.
The reverse direction also exists: a manually-created event whose text looks task-like offers an "Aufgabe anlegen?" action that creates a linked todo. To keep the loop closed, an event that was itself generated from a comment is never re-scanned and never offers that action.