// Code generated by templ - DO NOT EDIT. // templ: version: v0.3.1020 package templates //lint:file-ignore SA4006 This context is only used if a nested component is present. import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" import "fmt" import "strconv" import "strings" import "time" // 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}" (detail // view) 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 WeekURL string // link to switch to the week view } // WeekDay is one day column in the week grid. type WeekDay struct { Date string // "YYYY-MM-DD", used for links and the "new event" date Weekday string // full weekday name, e.g. "Monday" Day int // day-of-month number shown in the column header Month string // short month abbreviation, e.g. "Aug" (for cross-month weeks) IsToday bool Events []EventSummary } // WeekViewData is everything the week grid template needs to render one // 7-day week across every calendar (own + shared) visible to the viewer. type WeekViewData struct { Calendars []CalendarSummary HasWritable bool RangeLabel string // e.g. "Aug 18 – 24, 2026" Days []WeekDay PrevWeekURL string NextWeekURL string TodayURL string MonthURL string // link to switch to the month view } // CalendarOption is one entry in the "new event" calendar ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } func monthDayCell(day MonthDay) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var21 := templ.GetChildren(ctx) if templ_7745c5c3_Var21 == nil { templ_7745c5c3_Var21 = templ.NopComponent } ctx = templ.ClearChildren(ctx) var templ_7745c5c3_Var22 = []any{"bg-white min-h-[4.5rem] sm:min-h-[6rem] p-1 sm:p-1.5 flex flex-col gap-1", templ.KV("bg-gray-50 text-gray-400", !day.InMonth)} templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var24 = []any{"text-xs font-medium rounded-full w-5 h-5 flex items-center justify-center", templ.KV("bg-indigo-600 text-white", day.IsToday), templ.KV("hover:bg-gray-100", !day.IsToday)} templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var24...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var27 string templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(day.Day)) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 210, Col: 25} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, ev := range day.Events { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if !ev.AllDay && ev.TimeText != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var32 string templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(ev.TimeText) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 222, Col: 44} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } var templ_7745c5c3_Var33 string templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(" " + ev.Summary) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 224, Col: 22} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // WeekView renders a single 7-day week across every calendar (own + // shared) visible to the viewer, one column per day. func WeekView(username string, data WeekViewData) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var34 := templ.GetChildren(ctx) if templ_7745c5c3_Var34 == nil { templ_7745c5c3_Var34 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var35 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "

Calendar

Today ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var39 string templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.JoinStringErrs(data.RangeLabel) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 240, Col: 60} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = viewSwitcher("week", data.MonthURL, "/web/calendar/week").Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if data.HasWritable { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "New event") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if len(data.Calendars) == 0 { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "

You don't have any calendars yet — create one from the dashboard first.

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, d := range data.Days { templ_7745c5c3_Err = weekDayHeaderCell(d).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } for _, d := range data.Days { templ_7745c5c3_Err = weekDayCell(d).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, c := range data.Calendars { templ_7745c5c3_Err = calendarLegendRow(c).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } return nil }) templ_7745c5c3_Err = Layout("Calendar", username).Render(templ.WithChildren(ctx, templ_7745c5c3_Var35), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } func weekDayHeaderCell(day WeekDay) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var40 := templ.GetChildren(ctx) if templ_7745c5c3_Var40 == nil { templ_7745c5c3_Var40 = templ.NopComponent } ctx = templ.ClearChildren(ctx) var templ_7745c5c3_Var41 = []any{"bg-gray-50 px-2 py-1.5 text-xs text-center", templ.KV("text-indigo-600 font-semibold", day.IsToday), templ.KV("text-gray-500 font-medium", !day.IsToday)} templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var41...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var43 string templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinStringErrs(day.Weekday) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 279, Col: 15} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var44 string templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(day.Month) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 279, Col: 57} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var45 string templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(day.Day)) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 279, Col: 88} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } func weekDayCell(day WeekDay) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var46 := templ.GetChildren(ctx) if templ_7745c5c3_Var46 == nil { templ_7745c5c3_Var46 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "
+ new ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, ev := range day.Events { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if !ev.AllDay && ev.TimeText != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var52 string templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs(ev.TimeText) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 301, Col: 44} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } var templ_7745c5c3_Var53 string templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs(" " + ev.Summary) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 303, Col: 22} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } func eventLinkURL(ev EventSummary) string { if ev.LinkURL != "" { return ev.LinkURL } return "/web/calendar/" + ev.CalRef + "/" + ev.ID } // eventTextColor returns a color derived from hex, darkened if needed so // it stays legible as text on monthDayCell's very light (~13% opacity) // tinted event background. Without this, a light calendar color like // white or pale yellow renders its own event text as invisible or // near-invisible, since the same color is used for both the tint and the // text. Colors that are already dark enough are returned unchanged. func eventTextColor(hex string) string { c := colorOrDefault(hex) r, g, b, ok := parseHexColor(c) if !ok { return c } // Perceived luminance (ITU-R BT.601). luminance := 0.299*float64(r) + 0.587*float64(g) + 0.114*float64(b) const maxReadableLuminance = 170 if luminance <= maxReadableLuminance { return c } // Scale each channel down so the color darkens towards black while // keeping its hue, ending up comfortably below the threshold. scale := maxReadableLuminance / luminance * 0.75 return fmt.Sprintf("#%02x%02x%02x", clampByte(float64(r)*scale), clampByte(float64(g)*scale), clampByte(float64(b)*scale)) } // parseHexColor parses a "#rrggbb" string into its red/green/blue // components. ok is false for anything else (including 3-digit shorthand // hex, which colorOrDefault/hexColorRe never produce). func parseHexColor(s string) (r, g, b int, ok bool) { s = strings.TrimPrefix(s, "#") if len(s) != 6 { return 0, 0, 0, false } v, err := strconv.ParseInt(s, 16, 32) if err != nil { return 0, 0, 0, false } return int(v >> 16 & 0xff), int(v >> 8 & 0xff), int(v & 0xff), true } func clampByte(v float64) int { if v < 0 { return 0 } if v > 255 { return 255 } return int(v) } // EventDetail is the read-only detail view for a single event, opened when // the user clicks an event in the month or week grid. It shows the // event's fields and, when the calendar is writable, offers an Edit link. func EventDetail(username string, data EventDetailData) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var54 := templ.GetChildren(ctx) if templ_7745c5c3_Var54 == nil { templ_7745c5c3_Var54 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var55 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "
← Calendar
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if data.Form.Writable { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "Edit ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "Export .ics

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var59 string templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.JoinStringErrs(data.Form.Summary) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 392, Col: 85} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var59)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var60 string templ_7745c5c3_Var60, templ_7745c5c3_Err = templ.JoinStringErrs(data.Form.CalendarLabel) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 393, Col: 68} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var60)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if !data.Form.Writable { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "

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

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "
When
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var61 string templ_7745c5c3_Var61, templ_7745c5c3_Err = templ.JoinStringErrs(eventRangeText(data.Form)) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 406, Col: 68} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var61)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if data.Form.Location != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "
Location
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var62 string templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(data.Form.Location) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 411, Col: 74} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if data.Form.Description != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "
Description
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var63 string templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(data.Form.Description) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 417, Col: 97} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) templ_7745c5c3_Err = Layout("Calendar", username).Render(templ.WithChildren(ctx, templ_7745c5c3_Var55), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } // eventRangeText renders a human-readable "when" string for an event: // a single timed event reads "Aug 5, 2026, 14:00 – 15:00"; a multi-day // range reads "Aug 5 – 7, 2026"; a single all-day date reads // "August 5, 2026". func eventRangeText(f EventFormData) string { if f.AllDay { if f.StartDate != f.EndDate { s, err := dateOnly(f.StartDate) if err != nil { return f.StartDate } e, err := dateOnly(f.EndDate) if err != nil { return f.EndDate } if s.Year() == e.Year() && s.Month() == e.Month() { return fmt.Sprintf("%s – %s, %d", s.Format("Jan 2"), e.Format("2"), s.Year()) } return fmt.Sprintf("%s – %s", s.Format("Jan 2, 2006"), e.Format("Jan 2, 2006")) } d, err := dateOnly(f.StartDate) if err != nil { return f.StartDate } return d.Format("January 2, 2006") } s, err := dateTime(f.StartDate, f.StartTime) if err != nil { return f.StartDate } e, err := dateTime(f.EndDate, f.EndTime) if err != nil { return s.Format("January 2, 2006, 15:04") } if s.Day() == e.Day() { return fmt.Sprintf("%s, %s – %s", s.Format("January 2, 2006"), s.Format("15:04"), e.Format("15:04")) } if s.Year() == e.Year() && s.Month() == e.Month() { return fmt.Sprintf("%s – %s, %d", s.Format("Jan 2, 15:04"), e.Format("15:04"), s.Year()) } return fmt.Sprintf("%s – %s", s.Format("Jan 2, 2006, 15:04"), e.Format("Jan 2, 2006, 15:04")) } func dateOnly(ds string) (time.Time, error) { return time.ParseInLocation("2006-01-02", ds, time.Local) } func dateTime(ds, ts string) (time.Time, error) { if ts == "" { return time.ParseInLocation("2006-01-02", ds, time.Local) } return time.ParseInLocation("2006-01-02T15:04", ds+"T"+ts, time.Local) } func EventForm(username string, data EventFormData, errMsg string) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var64 := templ.GetChildren(ctx) if templ_7745c5c3_Var64 == nil { templ_7745c5c3_Var64 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Var65 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "← Calendar

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if data.ID == "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "New event") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "Edit event") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if errMsg != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var66 string templ_7745c5c3_Var66, templ_7745c5c3_Err = templ.JoinStringErrs(errMsg) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 491, Col: 98} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var66)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if data.ID != "" && !data.Writable { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "

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

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if data.ID == "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var70 string templ_7745c5c3_Var70, templ_7745c5c3_Err = templ.JoinStringErrs(data.CalendarLabel) if templ_7745c5c3_Err != nil { return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/templates/calendar.templ`, Line: 513, Col: 63} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var70)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 111, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var73 = []any{templ.KV("hidden", data.AllDay)} templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var73...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 117, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var77 = []any{templ.KV("hidden", data.AllDay)} templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var77...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 121, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if data.ID == "" || data.Writable { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 126, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if data.ID != "" && data.Writable { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 127, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if data.ID != "" { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 129, "Export .ics") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 131, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) templ_7745c5c3_Err = Layout("Calendar", username).Render(templ.WithChildren(ctx, templ_7745c5c3_Var65), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } 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"} } var _ = templruntime.GeneratedTemplate