package handlers import ( "context" "fmt" "net/http" "strconv" "git.haelnorr.com/h/golib/hws" "git.haelnorr.com/h/oslstats/internal/db" "git.haelnorr.com/h/oslstats/internal/respond" "git.haelnorr.com/h/oslstats/internal/throw" "git.haelnorr.com/h/oslstats/internal/view/seasonsview" "github.com/pkg/errors" "github.com/uptrace/bun" ) // SeriesDetailPage redirects to the default tab (overview) func SeriesDetailPage( s *hws.Server, conn *db.DB, ) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { seriesID, err := strconv.Atoi(r.PathValue("series_id")) if err != nil { throw.BadRequest(s, w, r, "Invalid series ID", err) return } http.Redirect(w, r, fmt.Sprintf("/series/%d/overview", seriesID), http.StatusSeeOther) }) } // SeriesDetailOverviewPage renders the overview tab of the series detail page func SeriesDetailOverviewPage( s *hws.Server, conn *db.DB, ) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { seriesID, err := strconv.Atoi(r.PathValue("series_id")) if err != nil { throw.BadRequest(s, w, r, "Invalid series ID", err) return } var series *db.PlayoffSeries var currentSchedule *db.PlayoffSeriesSchedule var canSchedule bool var userTeamID int var rosters map[string][]*db.PlayerWithPlayStatus if ok := conn.WithReadTx(s, w, r, func(ctx context.Context, tx bun.Tx) (bool, error) { var err error series, err = db.GetPlayoffSeriesByID(ctx, tx, seriesID) if err != nil { return false, errors.Wrap(err, "db.GetPlayoffSeriesByID") } if series == nil { throw.NotFound(s, w, r, r.URL.Path) return false, nil } currentSchedule, err = db.GetCurrentSeriesSchedule(ctx, tx, seriesID) if err != nil { return false, errors.Wrap(err, "db.GetCurrentSeriesSchedule") } user := db.CurrentUser(ctx) canSchedule, userTeamID, err = db.CanScheduleSeries(ctx, tx, series, user) if err != nil { return false, errors.Wrap(err, "db.CanScheduleSeries") } rosters, err = db.GetSeriesTeamRosters(ctx, tx, series) if err != nil { return false, errors.Wrap(err, "db.GetSeriesTeamRosters") } return true, nil }); !ok { return } if r.Method == "GET" { renderSafely(seasonsview.SeriesDetailOverviewPage( series, currentSchedule, canSchedule, userTeamID, rosters, ), s, r, w) } else { renderSafely(seasonsview.SeriesDetailOverviewContent( series, currentSchedule, canSchedule, userTeamID, rosters, ), s, r, w) } }) } // SeriesDetailPreviewPage renders the match preview tab of the series detail page func SeriesDetailPreviewPage( s *hws.Server, conn *db.DB, ) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { seriesID, err := strconv.Atoi(r.PathValue("series_id")) if err != nil { throw.BadRequest(s, w, r, "Invalid series ID", err) return } var series *db.PlayoffSeries var currentSchedule *db.PlayoffSeriesSchedule var rosters map[string][]*db.PlayerWithPlayStatus var previewData *db.MatchPreviewData if ok := conn.WithReadTx(s, w, r, func(ctx context.Context, tx bun.Tx) (bool, error) { var err error series, err = db.GetPlayoffSeriesByID(ctx, tx, seriesID) if err != nil { return false, errors.Wrap(err, "db.GetPlayoffSeriesByID") } if series == nil { throw.NotFound(s, w, r, r.URL.Path) return false, nil } currentSchedule, err = db.GetCurrentSeriesSchedule(ctx, tx, seriesID) if err != nil { return false, errors.Wrap(err, "db.GetCurrentSeriesSchedule") } rosters, err = db.GetSeriesTeamRosters(ctx, tx, series) if err != nil { return false, errors.Wrap(err, "db.GetSeriesTeamRosters") } previewData, err = db.ComputeSeriesPreview(ctx, tx, series) if err != nil { return false, errors.Wrap(err, "db.ComputeSeriesPreview") } return true, nil }); !ok { return } // If completed, redirect to analysis instead if series.Status == db.SeriesStatusCompleted { if r.Method == "GET" { http.Redirect(w, r, fmt.Sprintf("/series/%d/analysis", seriesID), http.StatusSeeOther) } else { respond.HXRedirect(w, "/series/%d/analysis", seriesID) } return } if r.Method == "GET" { renderSafely(seasonsview.SeriesDetailPreviewPage( series, currentSchedule, rosters, previewData, ), s, r, w) } else { renderSafely(seasonsview.SeriesDetailPreviewContent( series, rosters, previewData, ), s, r, w) } }) } // SeriesDetailAnalysisPage renders the match analysis tab of the series detail page func SeriesDetailAnalysisPage( s *hws.Server, conn *db.DB, ) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { seriesID, err := strconv.Atoi(r.PathValue("series_id")) if err != nil { throw.BadRequest(s, w, r, "Invalid series ID", err) return } var series *db.PlayoffSeries var currentSchedule *db.PlayoffSeriesSchedule var rosters map[string][]*db.PlayerWithPlayStatus var previewData *db.MatchPreviewData if ok := conn.WithReadTx(s, w, r, func(ctx context.Context, tx bun.Tx) (bool, error) { var err error series, err = db.GetPlayoffSeriesByID(ctx, tx, seriesID) if err != nil { return false, errors.Wrap(err, "db.GetPlayoffSeriesByID") } if series == nil { throw.NotFound(s, w, r, r.URL.Path) return false, nil } currentSchedule, err = db.GetCurrentSeriesSchedule(ctx, tx, seriesID) if err != nil { return false, errors.Wrap(err, "db.GetCurrentSeriesSchedule") } rosters, err = db.GetSeriesTeamRosters(ctx, tx, series) if err != nil { return false, errors.Wrap(err, "db.GetSeriesTeamRosters") } previewData, err = db.ComputeSeriesPreview(ctx, tx, series) if err != nil { return false, errors.Wrap(err, "db.ComputeSeriesPreview") } return true, nil }); !ok { return } // If not completed, redirect to preview instead if series.Status != db.SeriesStatusCompleted { if r.Method == "GET" { http.Redirect(w, r, fmt.Sprintf("/series/%d/preview", seriesID), http.StatusSeeOther) } else { respond.HXRedirect(w, "/series/%d/preview", seriesID) } return } if r.Method == "GET" { renderSafely(seasonsview.SeriesDetailAnalysisPage( series, currentSchedule, rosters, previewData, ), s, r, w) } else { renderSafely(seasonsview.SeriesDetailAnalysisContent( series, rosters, previewData, ), s, r, w) } }) } // SeriesDetailSchedulePage renders the schedule tab of the series detail page func SeriesDetailSchedulePage( s *hws.Server, conn *db.DB, ) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { seriesID, err := strconv.Atoi(r.PathValue("series_id")) if err != nil { throw.BadRequest(s, w, r, "Invalid series ID", err) return } var series *db.PlayoffSeries var currentSchedule *db.PlayoffSeriesSchedule var history []*db.PlayoffSeriesSchedule var canSchedule bool var userTeamID int if ok := conn.WithReadTx(s, w, r, func(ctx context.Context, tx bun.Tx) (bool, error) { var err error series, err = db.GetPlayoffSeriesByID(ctx, tx, seriesID) if err != nil { return false, errors.Wrap(err, "db.GetPlayoffSeriesByID") } if series == nil { throw.NotFound(s, w, r, r.URL.Path) return false, nil } currentSchedule, err = db.GetCurrentSeriesSchedule(ctx, tx, seriesID) if err != nil { return false, errors.Wrap(err, "db.GetCurrentSeriesSchedule") } history, err = db.GetSeriesScheduleHistory(ctx, tx, seriesID) if err != nil { return false, errors.Wrap(err, "db.GetSeriesScheduleHistory") } user := db.CurrentUser(ctx) canSchedule, userTeamID, err = db.CanScheduleSeries(ctx, tx, series, user) if err != nil { return false, errors.Wrap(err, "db.CanScheduleSeries") } return true, nil }); !ok { return } // If completed, redirect to overview if series.Status == db.SeriesStatusCompleted { if r.Method == "GET" { http.Redirect(w, r, fmt.Sprintf("/series/%d/overview", seriesID), http.StatusSeeOther) } else { respond.HXRedirect(w, "/series/%d/overview", seriesID) } return } if r.Method == "GET" { renderSafely(seasonsview.SeriesDetailSchedulePage( series, currentSchedule, history, canSchedule, userTeamID, ), s, r, w) } else { renderSafely(seasonsview.SeriesDetailScheduleContent( series, currentSchedule, history, canSchedule, userTeamID, ), s, r, w) } }) }