feat: toasts
TS Lint / TypeScript (push) Successful in 1m22s
TS Lint / Oxlint (push) Successful in 1m22s
TS Lint / ESLint (push) Successful in 1m28s

This commit is contained in:
2026-07-14 11:23:33 +02:00
parent 3b499ff791
commit 9f4c8776d5
8 changed files with 103 additions and 2 deletions
+23
View File
@@ -0,0 +1,23 @@
<script setup lang="ts">
import type { Alert } from '@/types';
import { computed, ref } from 'vue';
import { CircleX, CircleAlert, CircleCheck, Info } from '@lucide/vue';
const props = defineProps<{ alert: Alert }>();
const dismissed = ref<boolean>(false);
const visible = computed<boolean>(() => !dismissed.value && (new Date().getTime() - props.alert.created.getTime()) <= props.alert.seconds * 1000);
function onDismiss() {
dismissed.value = true;
}
</script>
<template>
<div v-if="visible" class="alert alert-info alert-soft cursor-pointer" :class="`alert-${alert.type}`" @click="onDismiss">
<CircleX v-if="alert.type === 'error'" />
<CircleAlert v-if="alert.type === 'warning'" />
<CircleCheck v-if="alert.type === 'success'" />
<Info v-if="alert.type === 'info'" />
<span>{{ alert.message }}</span>
</div>
</template>
@@ -0,0 +1,13 @@
<script setup lang="ts">
import { useAlertStore } from '@/stores/alerts';
import { defineAsyncComponent } from 'vue';
const AlertItem = defineAsyncComponent(() => import("@/components/AlertItem.vue"));
const { alerts } = useAlertStore();
</script>
<template>
<div class="toast select-none">
<alert-item v-for="alert in alerts" :key="alert.created.getTime()" :alert="alert" />
</div>
</template>