diff --git a/pages/category.html b/pages/category.html index 28135eb..f13a505 100644 --- a/pages/category.html +++ b/pages/category.html @@ -16,13 +16,13 @@
{{ range .Groups }} - -
- {{ .Name }} - {{ .TimeCreated }} + +
+ {{ .Name }} + {{ .TimeCreated }}
{{ if not .Removable }} -
Not removable
+
Not removable
{{ end }}
{{ end }} @@ -61,10 +61,11 @@ {{ range .Todos }} {{ if not .IsDone }} - - {{ .Text }} - {{ .TimeCreated }} - {{ .Due }} + + {{ .Text }} + {{ .TimeCreated }} + {{ .Due }} + {{ .DueUnix }} @@ -121,6 +122,39 @@ async function showDone() { dueTodos.style.display = "none"; } +function allowDrop(event) { + event.preventDefault(); +} + +function dragStart(event) { + event.dataTransfer.setData("text", event.target.id); + event.dataTransfer.effectAllowed = "move"; +} + +async function drop(event) { + event.preventDefault(); + + var todoPageId = event.dataTransfer.getData("text"); + let draggedTodo = document.getElementById(todoPageId); + let todoId = todoPageId.split("-")[1]; + let targetGroupId = event.target.id.split("-")[1]; + if (targetGroupId == document.getElementById("categoryId").innerText) { + // Do nothing + return; + } + console.log("passed"); + + // Add a copy of this ToDo in the corresponding group + let result = await postNewTodo({ + text: draggedTodo.getElementsByClassName("todo-text")[0].innerText, + groupId: Number(targetGroupId), + dueUnix: Number(draggedTodo.getElementsByClassName("todo-due-unix")[0].innerText), + }); + + // Delete this ToDo in this group + await deleteTodoRefresh(todoId); +} + document.addEventListener('DOMContentLoaded', async function() { document.getElementById("new-todo-text").focus(); diff --git a/src/db/group.go b/src/db/group.go index b9b1630..4b0d7c1 100644 --- a/src/db/group.go +++ b/src/db/group.go @@ -150,6 +150,23 @@ func (db *DB) DeleteTodoGroup(id uint64) error { return err } +// Deletes all ToDos associated with this group and then the group itself +func (db *DB) DeleteTodoGroupClean(groupId uint64) error { + _, err := db.Exec("DELETE FROM todos WHERE group_id=?", + groupId, + ) + if err != nil { + return err + } + + _, err = db.Exec( + "DELETE FROM todo_groups WHERE id=?", + groupId, + ) + + return err +} + // Updates TODO group's name func (db *DB) UpdateTodoGroup(groupID uint64, updatedGroup TodoGroup) error { _, err := db.Exec( diff --git a/src/server/endpoints.go b/src/server/endpoints.go index 76ca9a8..a3ab00d 100644 --- a/src/server/endpoints.go +++ b/src/server/endpoints.go @@ -407,6 +407,11 @@ func (s *Server) EndpointTodoDelete(w http.ResponseWriter, req *http.Request) { func (s *Server) EndpointTodoCreate(w http.ResponseWriter, req *http.Request) { // Create a new TODO defer req.Body.Close() + if req.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + // Read body body, err := io.ReadAll(req.Body) if err != nil { @@ -431,6 +436,16 @@ func (s *Server) EndpointTodoCreate(w http.ResponseWriter, req *http.Request) { } // Add TODO to the database + if newTodo.GroupID == 0 { + http.Error(w, "No group ID was provided", http.StatusBadRequest) + return + } + + if !s.db.DoesUserOwnGroup(newTodo.GroupID, GetLoginFromReq(req)) { + http.Error(w, "You do not own this group", http.StatusForbidden) + return + } + newTodo.OwnerLogin = GetLoginFromReq(req) newTodo.TimeCreatedUnix = uint64(time.Now().Unix()) err = s.db.CreateTodo(newTodo) @@ -485,6 +500,11 @@ func (s *Server) EndpointTodoGroupDelete(w http.ResponseWriter, req *http.Reques // Delete an existing group defer req.Body.Close() + if req.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + // Check if given user actually owns this group if !IsUserAuthorizedReq(req, s.db) { http.Error(w, "Invalid user auth data", http.StatusForbidden) @@ -516,8 +536,8 @@ func (s *Server) EndpointTodoGroupDelete(w http.ResponseWriter, req *http.Reques return } - // Delete - err = s.db.DeleteTodoGroup(groupId) + // Delete all ToDos associated with this group and then delete the group itself + err = s.db.DeleteTodoGroupClean(groupId) if err != nil { logger.Error("[Server][EndpointGroupDelete] Failed to delete %s's TODO group: %s", GetLoginFromReq(req), err) http.Error(w, "Failed to delete TODO group", http.StatusInternalServerError) @@ -525,13 +545,19 @@ func (s *Server) EndpointTodoGroupDelete(w http.ResponseWriter, req *http.Reques } // Success! - logger.Info("[Server][EndpointGroupDelete] Deleted group ID: %d for %s", groupId, GetLoginFromReq(req)) + logger.Info("[Server][EndpointGroupDelete] Cleanly deleted group ID: %d for %s", groupId, GetLoginFromReq(req)) w.WriteHeader(http.StatusOK) } func (s *Server) EndpointTodoGroupCreate(w http.ResponseWriter, req *http.Request) { // Create a new TODO group defer req.Body.Close() + + if req.Method != http.MethodPost { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + // Read body body, err := io.ReadAll(req.Body) if err != nil { @@ -568,7 +594,6 @@ func (s *Server) EndpointTodoGroupCreate(w http.ResponseWriter, req *http.Reques // Success! w.WriteHeader(http.StatusOK) logger.Info("[Server] Created a new TODO group for %s", newGroup.OwnerLogin) - } func (s *Server) EndpointTodoGroupGet(w http.ResponseWriter, req *http.Request) {