package api import ( "embed" "html/template" "net/http" "time" "reanimator/internal/domain" "reanimator/internal/repository/registry" "reanimator/internal/repository/tickets" "reanimator/internal/repository/timeline" ) //go:embed ui_assets.tmpl var uiTemplates embed.FS var assetTemplate = template.Must(template.New("asset").Funcs(template.FuncMap{ "formatTime": func(t time.Time) string { return t.UTC().Format("2006-01-02 15:04:05 UTC") }, "formatTimePtr": func(t *time.Time) string { if t == nil { return "—" } return t.UTC().Format("2006-01-02 15:04:05 UTC") }, }).ParseFS(uiTemplates, "ui_assets.tmpl")) type UIDependencies struct { Assets *registry.AssetRepository Installations *registry.InstallationRepository Timeline *timeline.EventRepository Tickets *tickets.TicketRepository } type uiHandlers struct { deps UIDependencies } func RegisterUIRoutes(mux *http.ServeMux, deps UIDependencies) { h := uiHandlers{deps: deps} mux.HandleFunc("/ui/assets/", h.handleAssetPage) } type assetPageData struct { Asset domain.Asset Components []domain.Component Events []domain.TimelineEvent Tickets []domain.Ticket } func (h uiHandlers) handleAssetPage(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { w.WriteHeader(http.StatusMethodNotAllowed) return } id, ok := parseID(r.URL.Path, "/ui/assets/") if !ok { w.WriteHeader(http.StatusNotFound) return } asset, err := h.deps.Assets.Get(r.Context(), id) if err != nil { w.WriteHeader(http.StatusNotFound) return } components := []domain.Component{} if h.deps.Installations != nil { components, err = h.deps.Installations.ListCurrentComponentsByAsset(r.Context(), id) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } } events := []domain.TimelineEvent{} if h.deps.Timeline != nil { items, _, err := h.deps.Timeline.List(r.Context(), "asset", id, 100, nil) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } events = items } tickets := []domain.Ticket{} if h.deps.Tickets != nil { items, err := h.deps.Tickets.ListByAsset(r.Context(), id) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } tickets = items } w.Header().Set("Content-Type", "text/html; charset=utf-8") if err := assetTemplate.Execute(w, assetPageData{ Asset: asset, Components: components, Events: events, Tickets: tickets, }); err != nil { w.WriteHeader(http.StatusInternalServerError) return } }