package blog import ( "arimelody-web/admin/core" "arimelody-web/admin/templates" "arimelody-web/controller" "arimelody-web/model" "fmt" "net/http" "os" "slices" ) func Handler(app *model.AppState) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { mux := http.NewServeMux() mux.Handle("/{id}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { blogID := r.PathValue("id") w.Write([]byte(blogID)) })) mux.Handle("/", handleBlogIndex(app)) mux.ServeHTTP(w, r) }) } type ( blogPost struct { *model.BlogPost Author *model.Account } blogPostGroup struct { Year int Posts []*blogPost } ) func handleBlogIndex(app *model.AppState) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { session, err := controller.GetSessionFromRequest(app, r) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve session: %v\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } posts, err := controller.GetBlogPosts(app.DB, false, -1, 0) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to fetch blog posts: %v\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } collections := []*blogPostGroup{} collectionPosts := []*blogPost{} collectionYear := -1 for i, post := range posts { author, err := controller.GetAccountByID(app.DB, post.AuthorID) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve author of blog %s: %v\n", post.ID, err) continue } if collectionYear == -1 { collectionYear = post.CreatedAt.Year() } authoredPost := blogPost{ BlogPost: post, Author: author, } if post.CreatedAt.Year() != collectionYear || i == len(posts) - 1 { if i == len(posts) - 1 { collectionPosts = append(collectionPosts, &authoredPost) } collections = append(collections, &blogPostGroup{ Year: collectionYear, Posts: slices.Clone(collectionPosts), }) collectionPosts = []*blogPost{} collectionYear = post.CreatedAt.Year() } collectionPosts = append(collectionPosts, &authoredPost) } type blogsData struct { core.AdminPageData TotalPosts int Collections []*blogPostGroup } err = templates.BlogsTemplate.Execute(w, blogsData{ AdminPageData: core.AdminPageData{ Session: session, }, TotalPosts: len(posts), Collections: collections, }) if err != nil { fmt.Fprintf(os.Stderr, "WARN: Error rendering admin blog index: %v\n", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } }) }