Files
Inventory/app/components/ToastContainer.vue
Matthieu 36b7ce93ec feat: Layout principal et composants de base
- app.vue : Layout principal avec navbar et navigation
- ToastContainer.vue : Système de notifications toast
- app.css : Styles globaux avec DaisyUI et accessibilité
- Configuration des paramètres d'affichage (zoom, densité, contraste)
- Navigation responsive avec menu déroulant
- Bouton 'Nouveau' avec actions rapides
2025-07-30 08:16:33 +02:00

95 lines
3.2 KiB
Vue

<template>
<div class="toast-container fixed top-4 right-4 z-50 space-y-2 pointer-events-none">
<TransitionGroup name="toast">
<div
v-for="toast in toasts"
:key="toast.id"
class="toast-item"
:class="[
'transform transition-all duration-300 ease-in-out',
toast.visible ? 'translate-x-0 opacity-100 pointer-events-auto' : 'translate-x-full opacity-0 pointer-events-none'
]"
>
<div
class="alert shadow-lg max-w-sm"
:class="getToastClasses(toast.type)"
>
<div class="flex items-center gap-2">
<!-- Icon -->
<div class="flex-shrink-0">
<svg v-if="toast.type === 'success'" class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
<svg v-else-if="toast.type === 'error'" class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
<svg v-else-if="toast.type === 'warning'" class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"></path>
</svg>
<svg v-else class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<!-- Message -->
<div class="flex-1">
<span class="text-sm font-medium">{{ toast.message }}</span>
</div>
<!-- Close button -->
<button
@click="removeToast(toast.id)"
class="btn btn-ghost btn-xs"
>
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
</div>
</div>
</TransitionGroup>
</div>
</template>
<script setup>
import { useToast } from '~/composables/useToast'
const { toasts, removeToast } = useToast()
const getToastClasses = (type) => {
switch (type) {
case 'success':
return 'alert-success'
case 'error':
return 'alert-error'
case 'warning':
return 'alert-warning'
case 'info':
return 'alert-info'
default:
return 'alert-info'
}
}
</script>
<style scoped>
.toast-enter-active,
.toast-leave-active {
transition: all 0.3s ease;
}
.toast-enter-from {
opacity: 0;
transform: translateX(100%);
}
.toast-leave-to {
opacity: 0;
transform: translateX(100%);
}
.toast-move {
transition: transform 0.3s ease;
}
</style>