NuxtAuthDashboardRepository/frontend/app/components/ui/Alert.vue

88 lines
3.0 KiB
Vue

<template>
<!-- Alert Box -->
<div v-if="isVisible" :class="alertClasses" class="flex items-center p-4 mb-4 border-l-4 rounded-lg shadow">
<!-- Alert Icon -->
<svg v-if="type === 'success'" class="w-5 h-5 text-green-500 mr-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
</svg>
<svg v-if="type === 'error'" class="w-5 h-5 text-red-500 mr-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
<svg v-if="type === 'warning'" class="w-5 h-5 text-yellow-500 mr-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v4m0 4h.01M19.5 12a7.5 7.5 0 11-15 0 7.5 7.5 0 0115 0z" />
</svg>
<!-- Alert Message -->
<span class="text-sm text-gray-700">{{ message }}</span>
<!-- Close Button -->
<button @click="closeAlert" class="ml-auto text-gray-500 hover:text-gray-700">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
// Props for the Alert component
const props = defineProps({
type: {
type: String,
default: 'success', // 'success', 'error', 'warning'
},
message: {
type: String,
required: true,
},
duration: {
type: Number,
default: 5000, // Duration before auto-hide
},
isVisible: {
type: Boolean,
default: false,
},
})
// Emits to notify parent component to hide the alert
const emit = defineEmits(['update:isVisible'])
// Internal ref to control visibility
const isAlertVisible = ref(props.isVisible)
// Watch for changes in the `isVisible` prop
watch(() => props.isVisible, (newVal) => {
isAlertVisible.value = newVal
if (newVal) {
// Auto-hide after the given duration
setTimeout(() => closeAlert(), props.duration)
}
})
// Alert Classes based on type
const alertClasses = computed(() => {
if (props.type === 'success') return 'bg-green-100 border-green-500 text-green-700'
if (props.type === 'error') return 'bg-red-100 border-red-500 text-red-700'
if (props.type === 'warning') return 'bg-yellow-100 border-yellow-500 text-yellow-700'
return 'bg-blue-100 border-blue-500 text-blue-700'
})
// Close alert function
const closeAlert = () => {
emit('update:isVisible', false) // Hide the alert
}
</script>
<style scoped>
button:focus {
outline: none;
}
button:hover {
cursor: pointer;
}
</style>