login

<     >

2023-07-25 16:48:23 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

add project creation/deletion

diff --git a/data.lua b/data.lua
index a2d5f12..37a0300 100644
--- a/data.lua
+++ b/data.lua
@@ -74,6 +74,10 @@ function Model:get_user(nick)
     return self.db:execute("SELECT * FROM User WHERE nick = ?;", nick)[1]
 end
 
+function Model:get_project(name)
+    return self.db:execute("SELECT * FROM Project WHERE name = ?;", name)[1]
+end
+
 function Model:get_user_projects(user_id)
     return self.db:execute([[
         SELECT * FROM Project JOIN Membership ON Project.id = Membership.proj_id
@@ -177,6 +181,13 @@ function Model:add_comment(user_id, ticket_id, text)
     ]], ticket_id, user_id, text)
 end
 
+function Model:del_project(proj_id)
+    self.db:execute("DELETE FROM Membership WHERE proj_id = ?;", proj_id)
+    self.db:execute("DELETE FROM Ticket WHERE proj_id = ?;", proj_id)
+    -- TODO: delete associated comments and shifts
+    self.db:execute("DELETE FROM Project WHERE id = ?;", proj_id)
+end
+
 -- return a list of columns ordered by state ID
 -- each column is a list of cards ordered by time
 -- column[0] contains extra info: `name`

diff --git a/skopos.lua b/skopos.lua
index b860d60..613fe11 100644
--- a/skopos.lua
+++ b/skopos.lua
@@ -133,6 +133,42 @@ function App:routes()
         self:log(LOG_INFO, "user "..user.nick.." canceled invite "..uuid)
         return "/invites", 303
     end},
+    {"GET", "/p",
+    function (req)
+        local user = self:get_user(req)
+        if user == nil then return "/login", 303 end
+        local projs = self.model:get_user_projects(user.id)
+        local env = {title=self.title, user=user, projs=projs}
+        return lud.template.render_file("view/projs.html", env)
+    end},
+    {"GET", "/new%-project",
+    function (req)
+        local user = self:get_user(req)
+        if user == nil then return "/login", 303 end
+        local env = {title=self.title, user=user}
+        return lud.template.render_file("view/proj_form.html", env)
+    end},
+    {"POST", "/new%-project",
+    function (req)
+        local user = self:get_user(req)
+        if user == nil then return "/login", 303 end
+        local name = req.form.name
+        local desc = req.form.desc
+        self.model:create_project(user.id, name, desc)
+        self:log(LOG_INFO, "user "..user.nick.." created project "..name)
+        return "/p", 303
+    end},
+    {"POST", "/del%-project/([-_%w]+)",
+    function (req, name)
+        local user = self:get_user(req)
+        if user == nil then return "/login", 303 end
+        local proj = self.model:get_project(name)
+        if proj ~= nil then
+            self.model:del_project(proj.id)
+            self:log(LOG_INFO, "user "..user.nick.." deleted project "..name)
+        end
+        return "/p", 303
+    end},
 } end
 
 local function new_app(db_path, port, title, log_level)

diff --git a/view/proj_form.html b/view/proj_form.html
new file mode 100644
index 0000000..be738d5
--- /dev/null
+++ b/view/proj_form.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>{{$title}}</title>
+  <style>
+    .centered { text-align: center; }
+    % include view/form.css
+  </style>
+</head>
+<body>
+  <h1 class="centered">Project</h1>
+  <form action="/new-project" method="post">
+    <ul class="centered ul-form">
+      <li><input
+        type="text" class="flat-field" name="name" placeholder="Name" required
+        pattern="[-_A-Za-z0-9]+" autofocus>
+      </li>
+      <li><input type="text" class="flat-field" name="desc" placeholder="Description"></li>
+      <li><input type="submit" class="flat-button" value="Create"></li>
+    </ul>
+  </form>
+</body>
+</html>

diff --git a/view/projs.html b/view/projs.html
new file mode 100644
index 0000000..0c2f3e2
--- /dev/null
+++ b/view/projs.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>{{$title}} - Projects</title>
+  <style>
+    .centered { text-align: center; }
+    % include view/table.css
+  </style>
+</head>
+<body>
+  <h1 class="centered">Projects</h1>
+  <div class="centered"><a href="/new-project">new</a></div>
+  <br>
+  <table class="center">
+    <tr>
+      <th>name</th>
+      <th>description</th>
+      <th>delete</th>
+    </tr>
+    % for proj in $projs do
+      <tr>
+        <td><a href="/p/{{$proj.name}}">{{$proj.name}}</a></td>
+        <td>{{$proj.desc}}</td>
+        <td>
+          <form action="/del-project/{{$proj.name}}" method="post">
+            <button type="submit">delete</button>
+          </form>
+        </td>
+      </tr>
+    % end
+  </table>
+</body>
+</html>