Rewrite the calendar frontend in Next.js
Replaces the Angular 18 app with Next.js 16 / React 19 / Tailwind 4 / shadcn, the same stack and design system as nachklang-feedback, planned in docs/rewrite-plan.md. - Admin: all calendars in one mobile-friendly list (month groups, calendar chips, Kommend/Vergangen/Alle, search, sort, filters in the URL), an edit sheet for create/edit/duplicate/delete, publish confirmation, and an "Abonnieren" dialog with subscription links for every calendar. - Public landing page: subscribe links from env instead of hardcoded, plus the next public events, server-rendered and revalidated every 5 minutes. - All times handled explicitly as Europe/Berlin; whole-day events stored as 00:00-23:59. Fixes carried over from the Angular app: the move dialog leaking a cancelled calendar change, saves that looked saved when they failed, in-place Date mutation, and duplicated calendar-id mappings. - Same shared-session auth as before (proxy.ts gate, /admin/me, 401 vs 403). - 112 Vitest tests over lib/; docs in docs/ (architecture, features, gotchas, API wish list, deployment). Needs the API branch feature/calendar-ical-escaping-subscriptions deployed first (GET /calendar/events/subscriptions). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
138 files changed
+15942
-24010
No files matched your search
@@ -0,0 +1,49 @@
|
||||
# Features
|
||||
|
||||
What the calendar app does, as of the Next.js rewrite (September 2026).
|
||||
|
||||
## Public page (`/`)
|
||||
|
||||
- Subscribe to the public calendar: Apple Kalender (`webcal://`), Google Kalender (deep link), or
|
||||
copy the iCal URL (shows the URL if the clipboard isn't available).
|
||||
- "Nächste Termine": the next four public events with date, time and place; an event with a web
|
||||
link opens it. Refreshed every five minutes; hidden if the API can't be reached.
|
||||
- Link to the Verwaltung (`/admin`).
|
||||
|
||||
## Verwaltung (`/admin`)
|
||||
|
||||
Sign-in happens in the admin app (one account for all Nachklang apps). Accounts need the calendar
|
||||
permission; without it the page says so instead of redirecting.
|
||||
|
||||
**List**
|
||||
- All calendars in one list, grouped by month, colour-coded per calendar.
|
||||
- Calendar chips toggle calendars on and off, with a count each; Geburtstage is off by default.
|
||||
- Kommend / Vergangen / Alle. "Vergangen" shows the newest first; "Alle" scrolls to a "Heute" marker.
|
||||
- Search over title and location.
|
||||
- Sort by start or by creation date (the latter as a flat list).
|
||||
- The view is in the URL, so a link reproduces it.
|
||||
- Drafts show an "Entwurf" badge and a "Veröffentlichen" button, which asks for confirmation and
|
||||
says who will see the event.
|
||||
- Repeating events (birthdays) show a "jährlich" badge and appear at their next occurrence.
|
||||
- Failed calendars are marked on their chip with a retry banner; the rest of the list stays usable.
|
||||
|
||||
**Edit sheet** (bottom sheet on phones, side panel on larger screens)
|
||||
- Create ("Neuer Termin" in the header, "+" button on phones), edit, duplicate, delete.
|
||||
- Fields: Kalender, Titel, Ganztägig, Beginn, Ende, Ort, Link, Beschreibung (multi-line), Status
|
||||
(Entwurf / Veröffentlicht; "Privat" is kept but not selectable).
|
||||
- Moving the start moves the end with it. Whole-day events take dates only.
|
||||
- A link without `https://` is completed; anything that isn't a web address is flagged.
|
||||
- Moving an event into Geburtstage makes it yearly; moving it out removes that again.
|
||||
- Errors appear next to their field; a failed save keeps the edits and says why.
|
||||
- Closing with unsaved changes asks first; so does leaving the page.
|
||||
- Shows who created and last changed the event.
|
||||
|
||||
**Abonnieren** (header)
|
||||
- Subscription links for every calendar, including the internal ones with their password: Apple,
|
||||
Google, or copy. Chor and Geburtstage share a password.
|
||||
|
||||
## Not (yet) possible
|
||||
|
||||
- Restoring deleted events and editing recurrence need API work first - see
|
||||
[api-wishlist.md](api-wishlist.md).
|
||||
- A month-grid view was deferred (decision Q6); the agenda list came first.
|
||||
Reference in new issue
Block a user