package app import ( "context" "errors" "fmt" "log/slog" "net/http" "forge.capytal.company/capytalcode/project-comicverse/lib/middleware" "forge.capytal.company/capytalcode/project-comicverse/lib/router" "forge.capytal.company/capytalcode/project-comicverse/lib/router/rerrors" "github.com/minio/minio-go/v7" "keikos.work/assets" "keikos.work/configs" "keikos.work/handlers/pages" ) type App interface { Start() error Stop() error } type Options struct { Port uint Development bool Log *slog.Logger S3 *minio.Client Assets http.Handler } type app struct { log *slog.Logger s3 *minio.Client assets http.Handler server *http.Server } func (a *app) Start() error { if err := a.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { return err } return nil } func (a *app) Stop() error { if err := a.server.Shutdown(context.Background()); err != nil { return err } return nil } func NewWeb(opts Options) App { r := router.NewRouter() r.Use(middleware.NewLoggerMiddleware(opts.Log)) if opts.Development { configs.DEVELOPMENT = true r.Use(middleware.DevMiddleware) } else { r.Use(middleware.CacheMiddleware) } r.Use(rerrors.NewErrorMiddleware(pages.ErrorPage{}.Component, opts.Log)) r.Handle("/", &pages.Home{}) r.Handle("/eye", &pages.Eye{}) r.Handle("/assets/", opts.Assets) robots, err := assets.ASSETS.ReadFile("robots.txt") if err != nil { panic(err) } r.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) { if _, err := w.Write(robots); err != nil { rerrors.InternalError(err).ServeHTTP(w, r) } }) ai, err := assets.ASSETS.ReadFile("ai.txt") if err != nil { panic(err) } r.HandleFunc("/ai.txt", func(w http.ResponseWriter, r *http.Request) { if _, err := w.Write(ai); err != nil { rerrors.InternalError(err).ServeHTTP(w, r) } }) // imgs := &pages.Images{S3: opts.S3} // r.HandleFunc("GET /images", imgs.List) // r.HandleFunc("GET /images/{name}", imgs.Get) srv := http.Server{ Addr: fmt.Sprintf(":%d", opts.Port), Handler: r, } return &app{ log: opts.Log, s3: opts.S3, assets: opts.Assets, server: &srv, } } func NewAdmin(opts Options) App { r := router.NewRouter() r.Use(middleware.NewLoggerMiddleware(opts.Log)) if opts.Development { configs.DEVELOPMENT = true r.Use(middleware.DevMiddleware) } else { r.Use(middleware.CacheMiddleware) } r.Use(rerrors.NewErrorMiddleware(pages.ErrorPage{}.Component, opts.Log)) r.Handle("/", &pages.Dashboard{}) r.Handle("/assets/", opts.Assets) imgs := &pages.Images{S3: opts.S3} r.HandleFunc("GET /images", imgs.List) r.HandleFunc("GET /images/{name}", imgs.Get) r.HandleFunc("POST /images", imgs.Create) r.HandleFunc("PUT /images/{name}", imgs.Update) r.HandleFunc("DELETE /images/{name}", imgs.Delete) srv := http.Server{ Addr: fmt.Sprintf(":%d", opts.Port), Handler: r, } return &app{ log: opts.Log, s3: opts.S3, assets: opts.Assets, server: &srv, } }