add toast

This commit is contained in:
Julian Freeman
2026-03-22 17:43:46 -04:00
parent 6aff740207
commit dd89dfa426

View File

@@ -29,6 +29,12 @@ const isSettingsOpen = ref(false);
const isTagManagerOpen = ref(false);
const isEventModalOpen = ref(false);
const toast = ref({ message: "", type: "success", visible: false });
const showToast = (message: string, type = "success") => {
toast.value = { message, type, visible: true };
setTimeout(() => { toast.value.visible = false; }, 3000);
};
const mergeScreens = ref(false);
const retainDays = ref(30);
const captureInterval = ref(30);
@@ -95,24 +101,48 @@ const loadTags = async () => { tags.value = await invoke("get_tags"); };
const loadEvents = async () => { dayEvents.value = await invoke("get_events", { date: currentDate.value }); };
const handleAddTag = async (name: string, parentId: number | null, color: string) => {
try {
await invoke("add_tag", { name, parentId, color });
await loadTags();
showToast("标签添加成功");
} catch (e) {
showToast("添加失败: " + e, "error");
}
};
const handleDeleteTag = async (id: number) => {
try {
await invoke("delete_tag", { id });
await loadTags();
showToast("标签已删除");
} catch (e: any) {
if (e.toString().includes("FOREIGN KEY")) {
showToast("该标签正在被使用,无法删除", "error");
} else {
showToast("删除失败: " + e, "error");
}
}
};
const saveEvent = async () => {
try {
await invoke("save_event", { event: editingEvent.value });
isEventModalOpen.value = false;
await loadEvents();
showToast("事件已保存");
} catch (e) {
showToast("保存失败: " + e, "error");
}
};
const deleteEvent = async (id: number) => {
try {
await invoke("delete_event", { id });
await loadEvents();
showToast("事件已删除");
} catch (e) {
showToast("删除失败: " + e, "error");
}
};
const timeToLogicalMinutes = (timeStr: string, isNextDay = false) => {
@@ -336,6 +366,15 @@ const resetTagForm = () => { newTagName.value = ""; newTagParent.value = null; n
</div>
<div v-if="isFullscreen && previewSrc" class="fixed inset-0 z-[200] bg-black/95 flex items-center justify-center p-6 backdrop-blur-xl"><button @click="isFullscreen = false" class="absolute top-10 right-10 w-12 h-12 bg-white/10 rounded-full flex items-center justify-center"><X :size="32" class="text-white" /></button><img :src="previewSrc" class="max-w-full max-h-full object-contain shadow-2xl" /></div>
<!-- Toast Notification -->
<div v-if="toast.visible" class="fixed bottom-10 left-1/2 -translate-x-1/2 z-[300] animate-in fade-in slide-in-from-bottom-4 duration-300">
<div class="px-6 py-3 rounded-2xl shadow-2xl backdrop-blur-md flex items-center gap-3 border border-white/20" :class="toast.type === 'error' ? 'bg-[#FF3B30] text-white' : 'bg-white/90 text-[#1D1D1F]'">
<div v-if="toast.type === 'error'" class="w-5 h-5 rounded-full border-2 border-white flex items-center justify-center text-[12px] font-black">!</div>
<div v-else class="w-5 h-5 rounded-full bg-[#34C759] flex items-center justify-center text-white text-[10px]"></div>
<span class="text-sm font-bold">{{ toast.message }}</span>
</div>
</div>
</div>
</template>