limit: limit,
},
});
- return response.data.map(
- (note) => new SearchResult(note),
- );
+ return response.data.map((note) => new SearchResult(note));
} catch (response) {
return Promise.reject(response);
}
return Promise.reject(response);
}
}
+
+export async function deleteNote(title) {
+ try {
+ await api.delete(`/api/notes/${title}`);
+ } catch (response) {
+ return Promise.reject(response);
+ }
+}
--- /dev/null
+<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>
<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>
iconPath: String,
iconSize: String,
label: String,
+ isCta: Boolean,
});
</script>
<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 -->
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";
});
const editMode = ref(false);
+const deleteConfirmModal = ref();
const note = ref({});
const noteUpdate = ref({});
const router = useRouter();
}
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() {