Initialer Laravel Commit für BetiX
This commit is contained in:
67
resources/js/components/ui/Notification.vue
Normal file
67
resources/js/components/ui/Notification.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<script setup>
|
||||
import { ref, nextTick, onMounted, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
toasts: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
const closeToast = (id) => {
|
||||
emit('close', id);
|
||||
};
|
||||
|
||||
// Re-run lucide icons when toasts change
|
||||
watch(() => props.toasts, () => {
|
||||
nextTick(() => {
|
||||
if (window.lucide) window.lucide.createIcons();
|
||||
});
|
||||
}, { deep: true });
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
if (window.lucide) window.lucide.createIcons();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<teleport to="body">
|
||||
<div id="notif-container">
|
||||
<div v-for="toast in toasts" :key="toast.id"
|
||||
:class="['toast', toast.type, { active: toast.active, 'fly-out': toast.flyingOut }]"
|
||||
@click="closeToast(toast.id)">
|
||||
<div class="toast-icon"><i :data-lucide="toast.icon"></i></div>
|
||||
<div style="flex:1">
|
||||
<div class="toast-title">{{ toast.title }}</div>
|
||||
<div class="toast-desc">{{ toast.desc }}</div>
|
||||
</div>
|
||||
<div class="toast-progress" :style="{ transform: `scaleX(${toast.progress/100})` }"></div>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
#notif-container { position: fixed; top: 85px; right: 20px; display: flex; flex-direction: column; gap: 12px; z-index: 5000; pointer-events: auto; backdrop-filter: none; }
|
||||
.toast { background: rgba(13,13,13,0.95); border: 1px solid #222; padding: 14px 20px; border-radius: 12px; display: flex; align-items: center; gap: 14px; width: 300px; transform: translateX(120%); transition: 0.4s cubic-bezier(0.2, 0, 0, 1); box-shadow: 0 10px 40px rgba(0,0,0,0.9); position: relative; overflow: hidden; cursor: pointer; backdrop-filter: none; }
|
||||
.toast.active { transform: translateX(0); }
|
||||
.toast.fly-out { transform: translate(100px, -200px) scale(0); opacity: 0; }
|
||||
.toast-icon { padding: 8px; border-radius: 10px; color: white; display: flex; align-items: center; justify-content: center; }
|
||||
.toast-progress { position: absolute; bottom: 0; left: 0; height: 3px; background: rgba(255,255,255,0.1); width: 100%; transform-origin: left; }
|
||||
.toast:hover { transform: scale(1.05) translateX(-5px); z-index: 1001; }
|
||||
.toast.green { border-left: 4px solid var(--green); }
|
||||
.toast.green .toast-icon { background: rgba(0,255,157,0.1); color: var(--green); }
|
||||
.toast.magenta { border-left: 4px solid var(--magenta); }
|
||||
.toast.magenta .toast-icon { background: rgba(255,0,122,0.1); color: var(--magenta); }
|
||||
.toast-title { font-size: 11px; font-weight: 900; color: #fff; letter-spacing: 0.5px; margin-bottom: 2px; text-transform: uppercase; }
|
||||
.toast-desc { font-size: 11px; color: #bbb; font-weight: 500; }
|
||||
|
||||
:global(:root) {
|
||||
--green: #00ff9d;
|
||||
--magenta: #ff007a;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user