custom_ui/frontend/src/components/common/GlobalLoadingOverlay.vue

61 lines
1.5 KiB
Vue

<template>
<div
v-if="showOverlay"
class="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center z-[9999] transition-opacity duration-200"
:class="{ 'opacity-100': showOverlay, 'opacity-0 pointer-events-none': !showOverlay }"
>
<div class="bg-white rounded-lg p-6 shadow-xl max-w-sm w-full mx-4 text-center">
<div class="mb-4">
<i class="pi pi-spin pi-spinner text-4xl text-blue-500"></i>
</div>
<h3 class="text-lg font-semibold text-gray-800 mb-2">Loading</h3>
<p class="text-gray-600">{{ loadingMessage }}</p>
</div>
</div>
</template>
<script setup>
import { computed } from "vue";
import { useLoadingStore } from "../../stores/loading";
const props = defineProps({
// Show overlay only for global loading, not component-specific
globalOnly: {
type: Boolean,
default: true,
},
// Minimum display time to prevent flashing
minDisplayTime: {
type: Number,
default: 300,
},
});
const loadingStore = useLoadingStore();
const showOverlay = computed(() => {
if (props.globalOnly) {
return loadingStore.isLoading;
}
return loadingStore.isAnyLoading;
});
const loadingMessage = computed(() => {
return loadingStore.loadingMessage;
});
</script>
<style scoped>
/* Additional styling for better visual appearance */
.bg-opacity-30 {
background-color: rgba(0, 0, 0, 0.3);
}
/* Backdrop blur effect for modern browsers */
@supports (backdrop-filter: blur(4px)) {
.fixed.inset-0 {
backdrop-filter: blur(4px);
}
}
</style>