package service import ( "log/slog" "me-fit/template" "me-fit/template/workout" "database/sql" "net/http" "strconv" "time" ) func HandleWorkoutPage(db *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user := verifySessionAndReturnUser(db, r) if user == nil { http.Redirect(w, r, "/auth/signin", http.StatusSeeOther) return } currentDate := time.Now().Format("2006-01-02") inner := workout.WorkoutComp(currentDate) userComp := UserInfoComp(user) template.Layout(inner, userComp).Render(r.Context(), w) } } func HandleWorkoutNewComp(db *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user := verifySessionAndReturnUser(db, r) if user == nil { w.Header().Add("HX-Redirect", "/auth/signin") return } var dateStr = r.FormValue("date") var typeStr = r.FormValue("type") var setsStr = r.FormValue("sets") var repsStr = r.FormValue("reps") if dateStr == "" || typeStr == "" || setsStr == "" || repsStr == "" { http.Error(w, "Missing required fields", http.StatusBadRequest) return } date, err := time.Parse("2006-01-02", dateStr) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } sets, err := strconv.Atoi(setsStr) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } reps, err := strconv.Atoi(repsStr) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } var rowId int err = db.QueryRow("INSERT INTO workout (user_id, date, type, sets, reps) VALUES (?, ?, ?, ?, ?) RETURNING rowid", user.id, date, typeStr, sets, reps).Scan(&rowId) if err != nil { slog.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } wo := workout.Workout{ Id: strconv.Itoa(rowId), Date: renderDate(date), Type: r.FormValue("type"), Sets: r.FormValue("sets"), Reps: r.FormValue("reps"), } workout.WorkoutItemComp(wo, true).Render(r.Context(), w) } } func HandleWorkoutGetComp(db *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user := verifySessionAndReturnUser(db, r) if user == nil { w.Header().Add("HX-Redirect", "/auth/signin") return } rows, err := db.Query("SELECT rowid, date, type, sets, reps FROM workout WHERE user_id = ? ORDER BY date desc", user.id) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } var workouts = make([]workout.Workout, 0) for rows.Next() { var workout workout.Workout err = rows.Scan(&workout.Id, &workout.Date, &workout.Type, &workout.Sets, &workout.Reps) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } workout.Date, err = renderDateStr(workout.Date) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } workouts = append(workouts, workout) } workout.WorkoutListComp(workouts).Render(r.Context(), w) } } func HandleWorkoutDeleteComp(db *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user := verifySessionAndReturnUser(db, r) if user == nil { w.Header().Add("HX-Redirect", "/auth/signin") return } rowId := r.PathValue("id") if rowId == "" { http.Error(w, "Missing required fields", http.StatusBadRequest) return } res, err := db.Exec("DELETE FROM workout WHERE user_id = ? AND rowid = ?", user.id, rowId) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } rows, err := res.RowsAffected() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if rows == 0 { http.Error(w, "Not found", http.StatusNotFound) return } } } func renderDateStr(date string) (string, error) { t, err := time.Parse("2006-01-02 15:04:05-07:00", date) if err != nil { return "", err } return renderDate(t), nil } func renderDate(date time.Time) string { return date.Format("2006-01-02") }