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: