Browse Source

feat: do not delete completed TODOs but rather mark them as done and preserve

master
parent
commit
58255b0393
  1. 6
      pages/index.html
  2. 2
      src/db/db.go
  3. 14
      src/db/todo.go
  4. 27
      src/server/api.go

6
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);

2
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))`,
)

14
src/db/todo.go

@ -36,6 +36,8 @@ type Todo struct {
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,
)

27
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 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 delete %s's TODO: %s", GetUsernameFromAuth(req), err)
http.Error(w, "Failed to delete TODO", http.StatusInternalServerError)
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:

Loading…
Cancel
Save