From 58255b039360f5b7afb1df213fc231d46c704561 Mon Sep 17 00:00:00 2001 From: Unbewohnte Date: Sun, 24 Sep 2023 17:32:29 +0300 Subject: [PATCH] feat: do not delete completed TODOs but rather mark them as done and preserve --- pages/index.html | 6 +++++- src/db/db.go | 2 ++ src/db/todo.go | 26 +++++++++++++++++--------- src/server/api.go | 27 ++++++++++++++++++++++----- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/pages/index.html b/pages/index.html index 55e8abd..2ab31e7 100644 --- a/pages/index.html +++ b/pages/index.html @@ -59,7 +59,11 @@ document.addEventListener('DOMContentLoaded', async function() { if (response.ok && todosJson != null) { let todosDiv = document.getElementById("todos"); todosJson.forEach((item) => { - console.log(item); + // Do not work with completed TODOs yet + if (item.isDone == true) { + return; + } + todos.push(item); let todoCompleteBtnID = "btn-complete-" + String(item.id); diff --git a/src/db/db.go b/src/db/db.go index bd4cbe1..166477a 100644 --- a/src/db/db.go +++ b/src/db/db.go @@ -61,6 +61,8 @@ func setUpTables(db *DB) error { time_created_unix INTEGER, due_unix INTEGER, owner_username TEXT NOT NULL, + is_done INTEGER, + completion_time_unix INTEGER, FOREIGN KEY(group_id) REFERENCES todo_groups(id), FOREIGN KEY(owner_username) REFERENCES users(username))`, ) diff --git a/src/db/todo.go b/src/db/todo.go index 42f2264..6ef858c 100644 --- a/src/db/todo.go +++ b/src/db/todo.go @@ -30,12 +30,14 @@ type TodoGroup struct { // Todo structure type Todo struct { - ID uint64 `json:"id"` - GroupID uint64 `json:"groupId"` - Text string `json:"text"` - TimeCreatedUnix uint64 `json:"timeCreatedUnix"` - DueUnix uint64 `json:"dueUnix"` - OwnerUsername string `json:"ownerUsername"` + ID uint64 `json:"id"` + GroupID uint64 `json:"groupId"` + Text string `json:"text"` + TimeCreatedUnix uint64 `json:"timeCreatedUnix"` + DueUnix uint64 `json:"dueUnix"` + OwnerUsername string `json:"ownerUsername"` + IsDone bool `json:"isDone"` + CompletionTimeUnix uint64 `json:"completionTimeUnix"` } // Creates a new TODO group in the database @@ -136,6 +138,8 @@ func scanTodo(rows *sql.Rows) (*Todo, error) { &newTodo.TimeCreatedUnix, &newTodo.DueUnix, &newTodo.OwnerUsername, + &newTodo.IsDone, + &newTodo.CompletionTimeUnix, ) if err != nil { return nil, err @@ -188,12 +192,14 @@ func (db *DB) GetTodos() ([]*Todo, error) { // Creates a new TODO in the database func (db *DB) CreateTodo(todo Todo) error { _, err := db.Exec( - "INSERT INTO todos(group_id, text, time_created_unix, due_unix, owner_username) VALUES(?, ?, ?, ?, ?)", + "INSERT INTO todos(group_id, text, time_created_unix, due_unix, owner_username, is_done, completion_time_unix) VALUES(?, ?, ?, ?, ?, ?, ?)", todo.GroupID, todo.Text, todo.TimeCreatedUnix, todo.DueUnix, todo.OwnerUsername, + todo.IsDone, + todo.CompletionTimeUnix, ) return err @@ -209,13 +215,15 @@ func (db *DB) DeleteTodo(id uint64) error { return err } -// Updates TODO's due date, text and group id +// Updates TODO's due date, text, done state, completion time and group id func (db *DB) UpdateTodo(todoID uint64, updatedTodo Todo) error { _, err := db.Exec( - "UPDATE todos SET group_id=?, due_unix=?, text=? WHERE id=?", + "UPDATE todos SET group_id=?, due_unix=?, text=?, is_done=?, completion_time_unix=? WHERE id=?", updatedTodo.GroupID, updatedTodo.DueUnix, updatedTodo.Text, + updatedTodo.IsDone, + updatedTodo.CompletionTimeUnix, todoID, ) diff --git a/src/server/api.go b/src/server/api.go index c03d50e..725fc96 100644 --- a/src/server/api.go +++ b/src/server/api.go @@ -150,16 +150,33 @@ func (s *Server) TodoEndpoint(w http.ResponseWriter, req *http.Request) { return } - // Now delete - err = s.db.DeleteTodo(todoID) + // Mark TODO as done and assign a completion time + updatedTodo, err := s.db.GetTodo(todoID) if err != nil { - logger.Error("[Server] Failed to delete %s's TODO: %s", GetUsernameFromAuth(req), err) - http.Error(w, "Failed to delete TODO", http.StatusInternalServerError) + logger.Error("[Server] Failed to get todo with id %d for marking completion: %s", todoID, err) + http.Error(w, "TODO retrieval error", http.StatusInternalServerError) return } + updatedTodo.IsDone = true + updatedTodo.CompletionTimeUnix = uint64(time.Now().Unix()) + + err = s.db.UpdateTodo(todoID, *updatedTodo) + if err != nil { + logger.Error("[Server] Failed to update TODO with id %d: %s", todoID, err) + http.Error(w, "Failed to update TODO information", http.StatusInternalServerError) + return + } + + // Now delete + // err = s.db.DeleteTodo(todoID) + // if err != nil { + // logger.Error("[Server] Failed to delete %s's TODO: %s", GetUsernameFromAuth(req), err) + // http.Error(w, "Failed to delete TODO", http.StatusInternalServerError) + // return + // } // Success! - logger.Info("[Server] deleted TODO with ID %d", todoID) + logger.Info("[Server] updated (marked as done) TODO with ID %d", todoID) w.WriteHeader(http.StatusOK) case http.MethodPost: