PR-2 of t-paliad-115. The unified Fristen + Termine surface now lives at
/events. Old /deadlines and /appointments list URLs 301-redirect to
/events?type=deadline and /events?type=appointment so existing bookmarks
still land on the right view. Detail pages (/deadlines/{id},
/appointments/{id}) stay type-specific.
Backend (Go).
- New `GET /events` route → handleEventsListPage serves dist/events.html.
- `GET /deadlines` → handleDeadlinesListRedirect (301 → /events?type=deadline).
- `GET /appointments` → handleAppointmentsListRedirect (301 → /events?type=appointment).
- /deadlines/new, /deadlines/calendar, /deadlines/{id}, /appointments/new,
/appointments/calendar, /appointments/{id} unchanged — type-specific
detail / form / legacy-calendar surfaces stay where they are.
Frontend.
- build.ts now emits ONE events.html (not events-deadlines /
events-appointments) with defaultType="all" baked in. The page reads
?type=… and ?view=… on hydration, so /events?type=deadline lands on
the Fristen-only Cards view, /events?view=calendar opens the calendar,
and bare /events shows the Beides view.
- Sidebar Fristen / Termine entries point at /events?type=deadline and
/events?type=appointment. The SSR active-state matches exactly via
href === currentPath, so detail/new/calendar pages that pass
currentPath="/events?type=deadline" (resp. appointment) still
highlight the right entry.
- events.ts hydration adds applySidebarTypeHighlight(): on bare /events
the sidebar SSRs with neither entry lit, and we re-highlight the
matching entry whenever the in-page chip toggle changes the active
type. Sidebar stays in sync without a server round-trip.
- Updated every list-target reference: palette-actions.ts (Cmd-K
navigation), deadlines-detail.ts + appointments-detail.ts (post-delete
redirect), and the back-link / cancel hrefs in the *-new + *-detail +
*-calendar TSX templates. Detail-page Sidebar/BottomNav currentPath
also moved from "/deadlines" → "/events?type=deadline" so the new
highlight contract holds end-to-end.
Out of scope (per task brief).
- A third "Ereignisse / Alle Events" sidebar entry pointing at /events
bare. m's call: keep two entries; defer until signal.
- Removing /deadlines/calendar + /appointments/calendar standalone
pages. The new /events?view=calendar covers the same need but the
legacy URLs stay live for one cycle.
Build clean: `cd frontend && bun run build` + `go build/vet/test ./...`.
29 lines
1.1 KiB
Go
29 lines
1.1 KiB
Go
package handlers
|
|
|
|
import "net/http"
|
|
|
|
// Server-rendered page endpoints for the Phase E Deadlines UI.
|
|
// HTML is generated at build time by frontend/build.ts; the per-page
|
|
// client TS bundles call /api/deadlines* to populate the DOM and read
|
|
// id/project_id from window.location.
|
|
|
|
// handleDeadlinesListRedirect 301-redirects the legacy /deadlines list URL
|
|
// to the canonical /events?type=deadline (t-paliad-115). Detail page
|
|
// /deadlines/{id} stays type-specific. Drop this redirect once we're
|
|
// confident no caches / bookmarks / external links still hit the old URL.
|
|
func handleDeadlinesListRedirect(w http.ResponseWriter, r *http.Request) {
|
|
http.Redirect(w, r, "/events?type=deadline", http.StatusMovedPermanently)
|
|
}
|
|
|
|
func handleDeadlinesNewPage(w http.ResponseWriter, r *http.Request) {
|
|
http.ServeFile(w, r, "dist/deadlines-new.html")
|
|
}
|
|
|
|
func handleDeadlinesDetailPage(w http.ResponseWriter, r *http.Request) {
|
|
http.ServeFile(w, r, "dist/deadlines-detail.html")
|
|
}
|
|
|
|
func handleDeadlinesCalendarPage(w http.ResponseWriter, r *http.Request) {
|
|
http.ServeFile(w, r, "dist/deadlines-calendar.html")
|
|
}
|