diff --git a/backend/api_test.go b/backend/api_test.go index 584364b..15e8480 100644 --- a/backend/api_test.go +++ b/backend/api_test.go @@ -516,6 +516,7 @@ func TestPutAllowanceById(t *testing.T) { "name": TestAllowanceName, "target": 5000, "weight": 10, + "colour": "#FF5733", } resp := e.POST("/user/1/allowance").WithJSON(requestBody).Expect().Status(201).JSON().Object() allowanceId := int(resp.Value("id").Number().Raw()) @@ -525,6 +526,7 @@ func TestPutAllowanceById(t *testing.T) { "name": "Updated Allowance", "target": 6000, "weight": 15, + "colour": "#3357FF", } e.PUT("/user/1/allowance/" + strconv.Itoa(allowanceId)).WithJSON(updateRequest).Expect().Status(200) @@ -534,6 +536,7 @@ func TestPutAllowanceById(t *testing.T) { result.Value("name").IsEqual("Updated Allowance") result.Value("target").IsEqual(6000) result.Value("weight").IsEqual(15) + result.Value("colour").IsEqual("#3357FF") } func TestCompleteTask(t *testing.T) { diff --git a/backend/db.go b/backend/db.go index 71bd650..0c58a85 100644 --- a/backend/db.go +++ b/backend/db.go @@ -2,6 +2,7 @@ package main import ( "errors" + "fmt" "log" "math" "time" @@ -112,12 +113,13 @@ func (db *Db) GetUserAllowanceById(userId int, allowanceId int) (*Allowance, err return nil, err } } else { - var target, progress int64 - err := db.db.Query("select id, name, target, balance, weight from allowances where user_id = ? and id = ?"). + var target, progress, colour int64 + err := db.db.Query("select id, name, target, balance, weight, colour from allowances where user_id = ? and id = ?"). Bind(userId, allowanceId). - ScanSingle(&allowance.ID, &allowance.Name, &target, &progress, &allowance.Weight) + ScanSingle(&allowance.ID, &allowance.Name, &target, &progress, &allowance.Weight, &colour) allowance.Target = float64(target) / 100.0 allowance.Progress = float64(progress) / 100.0 + allowance.Colour = fmt.Sprintf("#%06X", colour) if err != nil { return nil, err } @@ -125,6 +127,23 @@ func (db *Db) GetUserAllowanceById(userId int, allowanceId int) (*Allowance, err return allowance, nil } +func ConvertStringToColour(colourStr string) (int, error) { + if len(colourStr) == 0 { + return 0xFF0000, nil // Default colour if no string is provided + } + if colourStr[0] == '#' { + colourStr = colourStr[1:] + } + if len(colourStr) != 6 && len(colourStr) != 3 { + return 0, errors.New("colour must be a valid hex string") + } + colour, err := fmt.Sscanf(colourStr, "%x", &colourStr) + if err != nil { + return 0, fmt.Errorf("invalid colour format: %v", err) + } + return colour, nil +} + func (db *Db) CreateAllowance(userId int, allowance *CreateAllowanceRequest) (int, error) { // Check if user exists before attempting to create an allowance exists, err := db.UserExists(userId) @@ -141,9 +160,15 @@ func (db *Db) CreateAllowance(userId int, allowance *CreateAllowanceRequest) (in } defer tx.MustRollback() + // Convert string colour to a valid hex format + colour, err := ConvertStringToColour(allowance.Colour) + if err != nil { + return 0, err + } + // Insert the new allowance - err = tx.Query("insert into allowances (user_id, name, target, weight) values (?, ?, ?, ?)"). - Bind(userId, allowance.Name, int(math.Round(allowance.Target*100.0)), allowance.Weight). + err = tx.Query("insert into allowances (user_id, name, target, weight, colour) values (?, ?, ?, ?, ?)"). + Bind(userId, allowance.Name, int(math.Round(allowance.Target*100.0)), allowance.Weight, colour). Exec() if err != nil { @@ -255,9 +280,14 @@ func (db *Db) UpdateAllowance(userId int, allowanceId int, allowance *UpdateAllo } defer tx.MustRollback() + colour, err := ConvertStringToColour(allowance.Colour) + if err != nil { + return err + } + target := int(math.Round(allowance.Target * 100.0)) - err = tx.Query("update allowances set name=?, target=?, weight=? where id = ? and user_id = ?"). - Bind(allowance.Name, target, allowance.Weight, allowanceId, userId). + err = tx.Query("update allowances set name=?, target=?, weight=?, colour=? where id = ? and user_id = ?"). + Bind(allowance.Name, target, allowance.Weight, allowanceId, userId, colour). Exec() if err != nil { return err diff --git a/backend/dto.go b/backend/dto.go index 3b859d1..5773f45 100644 --- a/backend/dto.go +++ b/backend/dto.go @@ -36,18 +36,21 @@ type Allowance struct { Target float64 `json:"target"` Progress float64 `json:"progress"` Weight float64 `json:"weight"` + Colour string `json:"colour"` } type CreateAllowanceRequest struct { Name string `json:"name"` Target float64 `json:"target"` Weight float64 `json:"weight"` + Colour string `json:"colour"` } type UpdateAllowanceRequest struct { Name string `json:"name"` Target float64 `json:"target"` Weight float64 `json:"weight"` + Colour string `json:"colour"` } type BulkUpdateAllowanceRequest struct { diff --git a/backend/migrations/2_add_colour.sql b/backend/migrations/2_add_colour.sql new file mode 100644 index 0000000..2381df8 --- /dev/null +++ b/backend/migrations/2_add_colour.sql @@ -0,0 +1,2 @@ +alter table allowances +add column colour integer not null;