Add ConfirmModal component and implement delete note logic
authorAdam Dullage <redacted>
Fri, 3 May 2024 08:07:24 +0000 (09:07 +0100)
committerAdam Dullage <redacted>
Fri, 3 May 2024 08:07:24 +0000 (09:07 +0100)
client/api.js
client/components/ConfirmModal.vue [new file with mode: 0644]
client/components/CustomButton.vue
client/views/Note.vue

index 196d4c4f85629c28185643b4d6009d6c5649e471..53acae7f1900264f1a3404f5b460f3af8b208815 100644 (file)
@@ -73,9 +73,7 @@ export async function getNotes(term, sort, order, limit) {
         limit: limit,
       },
     });
-    return response.data.map(
-      (note) => new SearchResult(note),
-    );
+    return response.data.map((note) => new SearchResult(note));
   } catch (response) {
     return Promise.reject(response);
   }
@@ -93,3 +91,11 @@ export async function getNote(title) {
     return Promise.reject(response);
   }
 }
+
+export async function deleteNote(title) {
+  try {
+    await api.delete(`/api/notes/${title}`);
+  } catch (response) {
+    return Promise.reject(response);
+  }
+}
diff --git a/client/components/ConfirmModal.vue b/client/components/ConfirmModal.vue
new file mode 100644 (file)
index 0000000..154f9e9
--- /dev/null
@@ -0,0 +1,54 @@
+<template>
+  <!-- Mask -->
+  <div
+    class="fixed left-0 top-0 z-50 flex h-dvh w-dvw items-center justify-center bg-theme-background-tint/40 backdrop-blur-sm"
+    :class="{ hidden: !isVisible }"
+  >
+    <!-- Modal -->
+    <div
+      class="max-w-96 grow rounded-lg border border-theme-border bg-theme-background px-6 py-4 shadow-lg"
+      :class="{ 'border border-l-4 border-l-theme-failure': isDanger }"
+    >
+      <!-- Title -->
+      <div class="mb-6 text-xl">{{ title }}</div>
+      <!-- Message -->
+      <div class="mb-6">{{ message }}</div>
+      <!-- Buttons -->
+      <div class="flex justify-end">
+        <CustomButton label="Cancel" @click="cancelHandler" class="mr-2" />
+        <CustomButton label="Confirm" @click="confirmHandler" isCta />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { defineExpose, ref } from "vue";
+
+import CustomButton from "./CustomButton.vue";
+
+const props = defineProps({
+  title: { type: String, default: "Confirmation" },
+  message: String,
+  isDanger: Boolean,
+});
+const emit = defineEmits(["confirm", "cancel"]);
+
+const isVisible = ref(false);
+
+function toggle() {
+  isVisible.value = !isVisible.value;
+}
+
+function cancelHandler() {
+  isVisible.value = false;
+  emit("cancel");
+}
+
+function confirmHandler() {
+  isVisible.value = false;
+  emit("confirm");
+}
+
+defineExpose({ toggle });
+</script>
index 36dc9de038d57b147e101d054c0c969b1304480d..64f92d945eed39348b9eafe4ebabeb550a637350 100644 (file)
@@ -1,6 +1,10 @@
 <template>
   <button
-    class="rounded px-2 py-1 text-theme-text-muted hover:bg-theme-background-tint hover:dark:bg-theme-background-elevated"
+    class="rounded px-2 py-1 hover:bg-theme-background-tint hover:dark:bg-theme-background-elevated"
+    :class="{
+      'text-theme-text-muted': !isCta,
+      'border border-theme-border': isCta,
+    }"
   >
     <IconLabel :iconPath="iconPath" :iconSize="iconSize" :label="label" />
   </button>
@@ -13,5 +17,6 @@ defineProps({
   iconPath: String,
   iconSize: String,
   label: String,
+  isCta: Boolean,
 });
 </script>
index c0ae0caffcdc3f6f95ed898ae5d7b44f78f0c8a9..78aa91932e1fa8443404f257c8e34f1a4abb9a27 100644 (file)
@@ -1,5 +1,12 @@
 <template>
   <div>
+    <ConfirmModal
+      ref="deleteConfirmModal"
+      title="Confirm Deletion"
+      :message="`Are you sure you want to delete the note '${note.title}'?`"
+      isDanger
+      @confirm="deleteConfirmedHandler"
+    />
     <!-- Header -->
     <div class="flex items-end">
       <!-- View -->
@@ -54,7 +61,8 @@ import { useToast } from "primevue/usetoast";
 import { ref, watch } from "vue";
 import { useRouter } from "vue-router";
 
-import { getNote } from "../api.js";
+import { deleteNote, getNote } from "../api.js";
+import ConfirmModal from "../components/ConfirmModal.vue";
 import CustomButton from "../components/CustomButton.vue";
 import { getUnknownServerErrorToastOptions } from "../helpers.js";
 
@@ -63,6 +71,7 @@ const props = defineProps({
 });
 
 const editMode = ref(false);
+const deleteConfirmModal = ref();
 const note = ref({});
 const noteUpdate = ref({});
 const router = useRouter();
@@ -90,8 +99,17 @@ function editHandler() {
 }
 
 function deleteHandler() {
-  console.log("delete");
-  // TODO: Implement delete
+  deleteConfirmModal.value.toggle();
+}
+
+function deleteConfirmedHandler() {
+  deleteNote(note.value.title)
+    .then(() => {
+      router.push({ name: "home" });
+    })
+    .catch(() => {
+      toast.add(getUnknownServerErrorToastOptions());
+    });
 }
 
 function cancelHandler() {
git clone https://git.99rst.org/PROJECT