package service import ( "me-fit/db" "me-fit/types" "me-fit/utils" "database/sql" "errors" "log/slog" "net/http" "strconv" "time" ) type ServiceWorkout interface { AddWorkout(user *User, workoutDto *WorkoutDto) (*WorkoutDto, error) } type ServiceWorkoutImpl struct { dbWorkout db.DbWorkout randomGenerator RandomGenerator clock Clock mailService MailService serverSettings *types.ServerSettings } func NewServiceWorkoutImpl(dbAuth db.DbAuth, randomGenerator RandomGenerator, clock Clock, mailService MailService, serverSettings *types.ServerSettings) *ServiceAuthImpl { return &ServiceAuthImpl{ dbAuth: dbAuth, randomGenerator: randomGenerator, clock: clock, mailService: mailService, serverSettings: serverSettings, } } type WorkoutDto struct { RowId string Date string Type string Sets string Reps string } func NewWorkoutDtoFromDb(workout *db.Workout) *WorkoutDto { return &WorkoutDto{ RowId: strconv.Itoa(workout.RowId), Date: renderDate(workout.Date), Type: workout.Type, Sets: strconv.Itoa(workout.Sets), Reps: strconv.Itoa(workout.Reps), } } func NewWorkoutDto(rowId string, date string, workoutType string, sets string, reps string) *WorkoutDto { return &WorkoutDto{ RowId: rowId, Date: date, Type: workoutType, Sets: sets, Reps: reps, } } var ( ErrInputValues = errors.New("Invalid input values") ) func (service ServiceWorkoutImpl) AddWorkout(user *User, workoutDto WorkoutDto) (*WorkoutDto, error) { if workoutDto.Date == "" || workoutDto.Type == "" || workoutDto.Sets == "" || workoutDto.Reps == "" { return nil, ErrInputValues } date, err := time.Parse("2006-01-02", workoutDto.Date) if err != nil { return nil, ErrInputValues } sets, err := strconv.Atoi(workoutDto.Sets) if err != nil { return nil, ErrInputValues } reps, err := strconv.Atoi(workoutDto.Reps) if err != nil { return nil, ErrInputValues } workoutInsert := db.NewWorkoutInsert(date, workoutDto.Type, sets, reps) workout, err := service.dbWorkout.InsertWorkout(user.Id, workoutInsert) if err != nil { return nil, err } return NewWorkoutDtoFromDb(workout), nil } func HandleWorkoutDeleteComp(db *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { user := utils.GetUser(r) if user == nil { utils.DoRedirect(w, r, "/auth/signin") return } rowId := r.PathValue("id") if rowId == "" { http.Error(w, "Missing required fields", http.StatusBadRequest) slog.Warn("Missing required fields for workout delete") utils.TriggerToast(w, r, "error", "Missing ID field") 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) utils.LogError("Could not delete workout", err) utils.TriggerToast(w, r, "error", "Internal Server Error") return } rows, err := res.RowsAffected() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) utils.LogError("Could not get rows affected", err) utils.TriggerToast(w, r, "error", "Internal Server Error") return } if rows == 0 { http.Error(w, "Not found", http.StatusNotFound) slog.Warn("Could not find workout to delete") utils.TriggerToast(w, r, "error", "Not found. Refresh the page.") 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") }