From 598d5f22fcb91b14c6502403aabe1dcb0df39ce3 Mon Sep 17 00:00:00 2001
From: Santo Cariotti <santo@dcariotti.me>
Date: Thu, 22 Sep 2022 18:47:24 +0200
Subject: Delete a model

---
 pages/models/_id.vue | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

(limited to 'pages/models/_id.vue')

diff --git a/pages/models/_id.vue b/pages/models/_id.vue
index b7b30d3..909d5d9 100644
--- a/pages/models/_id.vue
+++ b/pages/models/_id.vue
@@ -1,5 +1,39 @@
 <template lang="pug">
   .mx-auto.w-90p.py-6#modelpage(class="sm:px-6 lg:px-8 md:max-w-7xl")
+    .relative.z-10(aria-labelledby="modal-title", role="dialog", aria-modal="true" v-if="boxDeleteModel")
+      .fixed.inset-0.bg-gray-900.bg-opacity-90.transition-opacity
+      .fixed.inset-0.z-10.overflow-y-auto
+        .flex.min-h-full.items-end.justify-center.p-4.text-center(class="sm:items-center sm:p-0")
+          .relative.transform.overflow-hidden.rounded-lg.bg-white.text-left.shadow-xl.transition-all(class="sm:my-8 sm:w-full sm:max-w-lg")
+            .bg-white.px-4.pt-5.pb-4(class="sm:p-6 sm:pb-4")
+              div(class="sm:flex sm:items-start")
+                .mx-auto.flex.h-12.w-12.flex-shrink-0.items-center.justify-center.rounded-full.bg-red-100(class="sm:mx-0 sm:h-10 sm:w-10")
+                  svg.h-6.w-6.text-red-600(xmlns="http://www.w3.org/2000/svg", fill="none", viewbox="0 0 24 24", stroke-width="1.5", stroke="currentColor", aria-hidden="true")
+                    path(stroke-linecap="round", stroke-linejoin="round", d="M12 10.5v3.75m-9.303 3.376C1.83 19.126 2.914 21 4.645 21h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 4.88c-.866-1.501-3.032-1.501-3.898 0L2.697 17.626zM12 17.25h.007v.008H12v-.008z")
+                .mt-3.text-center(class="sm:mt-0 sm:ml-4 sm:text-left")
+                  h3#modal-title.text-lg.font-medium.leading-6.text-gray-900 Are you sure?
+                  .mt-2
+                    p.text-sm.text-gray-500
+                      | Model data and all of the files will be deleted. This action cannot be undone.
+            .bg-gray-50.px-4.py-3(class="sm:flex sm:flex-row-reverse sm:px-6")
+              button.inline-flex.w-full.justify-center.rounded-md.border.border-transparent.bg-red-600.px-4.py-2.text-base.font-medium.text-white.shadow-sm(
+                type="button"
+                :class="{'hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 sm:ml-3 sm:w-auto sm:text-sm': true, 'opacity-25 cursor-default': isLoading}"
+                :disabled="isLoading"
+                :readonly="isLoading"
+                @click="deleteModel"
+              )
+                <svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" v-if="isLoading">
+                  <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
+                  <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
+                </svg>
+                | Yes, confirm
+              button.mt-3.inline-flex.w-full.justify-center.rounded-md.border.border-gray-300.bg-white.px-4.py-2.text-base.font-medium.text-gray-700.shadow-sm(
+                type="button"
+                class="hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
+                @click="boxDeleteModel = !boxDeleteModel"
+              ) Cancel
+
     section.mb-5
       .flow-root
         .float-left
@@ -15,6 +49,22 @@
       .description.mt-3
         p {{ model.description }}
 
+    .mb-5.text-right(v-if="me && me.id == model.author_id")
+      button.inline-flex.leading-6.justify-center.rounded-md.border.border-transparent.bg-gray-600.py-2.px-4.mr-2.text-sm.font-medium.text-white.shadow-sm(
+        class="hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2"
+      )
+        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
+          <path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125" />
+        </svg>
+        | Edit
+      button.inline-flex.leading-6.justify-center.rounded-md.border.border-transparent.bg-red-600.py-2.px-4.text-sm.font-medium.text-white.shadow-sm(
+        class="hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2"
+        @click="boxDeleteModel = !boxDeleteModel"
+      )
+        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
+          <path stroke-linecap="round" stroke-linejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
+        </svg>
+        | Delete
     .images.shadow-sm.rounded-lg.bg-white.p-4.w-full(v-if="model.uploads")
       .block.gap-4.h-full(class="md:flex")
         .w-full(class="md:w-4/5")
@@ -122,6 +172,8 @@
 import { ModelStl, ModelObj } from "vue-3d-model";
 import UserAvatar from "@/components/UserAvatar.vue";
 
+import { mapGetters } from "vuex";
+
 export default {
   name: "ModelView",
   layout: "default",
@@ -137,6 +189,7 @@ export default {
         z: 0,
       },
       boxFilesToDownload: false,
+      boxDeleteModel: false,
     };
   },
   head() {
@@ -149,6 +202,10 @@ export default {
     ModelObj,
     "user-avatar": UserAvatar,
   },
+  computed: {
+    ...mapGetters(["isLoading"]),
+    ...mapGetters("auth", ["me"]),
+  },
   created() {
     this.id = this.$route.params.id;
     this.baseAPI = this.$config.api;
@@ -185,6 +242,22 @@ export default {
     getFileName(path) {
       return path.split("/").at(-1);
     },
+    deleteModel() {
+      if (this.model.id) {
+        this.$store
+          .dispatch("models/deleteModel", this.model.id)
+          .then((response) => {
+            if (response.status == 204) {
+              this.$toast.success("Model deleted!");
+              setTimeout(() => {
+                window.location.href = "/models";
+              }, 1000);
+            } else {
+              this.$toast.error(response.data);
+            }
+          });
+      }
+    },
   },
 };
 </script>
-- 
cgit v1.2.3-71-g8e6c

