package templates import "fmt" // CalendarSummary is one calendar (own or shared) shown in the combined // month view's legend. type CalendarSummary struct { Ref string // path-safe reference: "name" or "owner~name" Name string Owner string // owner's username Color string // hex color like "#3b82f6", "" if unset Shared bool // true if owned by someone other than the viewer Writable bool Virtual bool // true for computed calendars (e.g. birthdays) with no import/export } // EventSummary is a single event shown inside a month-view day cell. type EventSummary struct { ID string CalRef string Color string Summary string TimeText string // e.g. "14:00" or "" for all-day events AllDay bool // LinkURL overrides the default "/web/calendar/{CalRef}/{ID}/edit" // link target, used by virtual/read-only calendars (e.g. birthdays) // that don't have an editable event object of their own. LinkURL string } // MonthDay is one day cell in the month grid. type MonthDay struct { Date string // "YYYY-MM-DD", used for links and the "new event" date Day int // day-of-month number shown in the cell InMonth bool // false for the leading/trailing days of neighboring months IsToday bool Events []EventSummary } // MonthViewData is everything the combined month grid template needs to // render one month across every calendar (own + shared) visible to the // viewer. type MonthViewData struct { Calendars []CalendarSummary HasWritable bool // true if the viewer can create events in at least one calendar MonthLabel string // e.g. "August 2026" Weeks [][]MonthDay PrevMonthURL string NextMonthURL string TodayURL string } // CalendarOption is one entry in the "new event" calendar } } templ monthDayCell(day MonthDay) {
{ fmt.Sprint(day.Day) }
for _, ev := range day.Events { if !ev.AllDay && ev.TimeText != "" { { ev.TimeText } } { " " + ev.Summary } }
} func eventLinkURL(ev EventSummary) string { if ev.LinkURL != "" { return ev.LinkURL } return "/web/calendar/" + ev.CalRef + "/" + ev.ID + "/edit" } templ EventForm(username string, data EventFormData, errMsg string) { @Layout("Calendar", username) { ← Calendar

if data.ID == "" { New event } else { Edit event }

if errMsg != "" {

{ errMsg }

} if data.ID != "" && !data.Writable {

This calendar was shared with you as read-only — you can view this event but not change it.

}
if data.ID == "" { } else {

{ data.CalendarLabel }

}
if data.ID == "" || data.Writable { } if data.ID != "" && data.Writable { } if data.ID != "" { Export .ics }
} } func eventFormAction(data EventFormData) templ.SafeURL { if data.ID == "" { return templ.URL("/web/calendar/new") } return templ.URL("/web/calendar/" + data.CalRef + "/" + data.ID + "/edit") } func weekdayLabels() []string { return []string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"} }