Add Loader
This commit is contained in:
parent
1e7a183668
commit
a3da5c9d55
5 changed files with 83 additions and 1 deletions
2
Frontend-Learner/.nuxt/components.d.ts
vendored
2
Frontend-Learner/.nuxt/components.d.ts
vendored
|
|
@ -16,6 +16,7 @@ type LazyComponent<T> = DefineComponent<HydrationStrategies, {}, {}, {}, {}, {},
|
||||||
|
|
||||||
export const AppHeader: typeof import("../components/common/AppHeader.vue").default
|
export const AppHeader: typeof import("../components/common/AppHeader.vue").default
|
||||||
export const FormInput: typeof import("../components/common/FormInput.vue").default
|
export const FormInput: typeof import("../components/common/FormInput.vue").default
|
||||||
|
export const GlobalLoader: typeof import("../components/common/GlobalLoader.vue").default
|
||||||
export const LandingFooter: typeof import("../components/common/LandingFooter.vue").default
|
export const LandingFooter: typeof import("../components/common/LandingFooter.vue").default
|
||||||
export const LandingHeader: typeof import("../components/common/LandingHeader.vue").default
|
export const LandingHeader: typeof import("../components/common/LandingHeader.vue").default
|
||||||
export const LoadingSkeleton: typeof import("../components/common/LoadingSkeleton.vue").default
|
export const LoadingSkeleton: typeof import("../components/common/LoadingSkeleton.vue").default
|
||||||
|
|
@ -172,6 +173,7 @@ export const Body: typeof import("../node_modules/nuxt/dist/head/runtime/compone
|
||||||
export const NuxtIsland: typeof import("../node_modules/nuxt/dist/app/components/nuxt-island").default
|
export const NuxtIsland: typeof import("../node_modules/nuxt/dist/app/components/nuxt-island").default
|
||||||
export const LazyAppHeader: LazyComponent<typeof import("../components/common/AppHeader.vue").default>
|
export const LazyAppHeader: LazyComponent<typeof import("../components/common/AppHeader.vue").default>
|
||||||
export const LazyFormInput: LazyComponent<typeof import("../components/common/FormInput.vue").default>
|
export const LazyFormInput: LazyComponent<typeof import("../components/common/FormInput.vue").default>
|
||||||
|
export const LazyGlobalLoader: LazyComponent<typeof import("../components/common/GlobalLoader.vue").default>
|
||||||
export const LazyLandingFooter: LazyComponent<typeof import("../components/common/LandingFooter.vue").default>
|
export const LazyLandingFooter: LazyComponent<typeof import("../components/common/LandingFooter.vue").default>
|
||||||
export const LazyLandingHeader: LazyComponent<typeof import("../components/common/LandingHeader.vue").default>
|
export const LazyLandingHeader: LazyComponent<typeof import("../components/common/LandingHeader.vue").default>
|
||||||
export const LazyLoadingSkeleton: LazyComponent<typeof import("../components/common/LoadingSkeleton.vue").default>
|
export const LazyLoadingSkeleton: LazyComponent<typeof import("../components/common/LoadingSkeleton.vue").default>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// generated by the @nuxtjs/tailwindcss <https://github.com/nuxt-modules/tailwindcss> module at 13/1/2569 11:39:33
|
// generated by the @nuxtjs/tailwindcss <https://github.com/nuxt-modules/tailwindcss> module at 13/1/2569 11:47:48
|
||||||
import "@nuxtjs/tailwindcss/config-ctx"
|
import "@nuxtjs/tailwindcss/config-ctx"
|
||||||
import configMerger from "@nuxtjs/tailwindcss/merger";
|
import configMerger from "@nuxtjs/tailwindcss/merger";
|
||||||
|
|
||||||
|
|
|
||||||
2
Frontend-Learner/.nuxt/types/components.d.ts
vendored
2
Frontend-Learner/.nuxt/types/components.d.ts
vendored
|
|
@ -16,6 +16,7 @@ type LazyComponent<T> = DefineComponent<HydrationStrategies, {}, {}, {}, {}, {},
|
||||||
interface _GlobalComponents {
|
interface _GlobalComponents {
|
||||||
'AppHeader': typeof import("../../components/common/AppHeader.vue").default
|
'AppHeader': typeof import("../../components/common/AppHeader.vue").default
|
||||||
'FormInput': typeof import("../../components/common/FormInput.vue").default
|
'FormInput': typeof import("../../components/common/FormInput.vue").default
|
||||||
|
'GlobalLoader': typeof import("../../components/common/GlobalLoader.vue").default
|
||||||
'LandingFooter': typeof import("../../components/common/LandingFooter.vue").default
|
'LandingFooter': typeof import("../../components/common/LandingFooter.vue").default
|
||||||
'LandingHeader': typeof import("../../components/common/LandingHeader.vue").default
|
'LandingHeader': typeof import("../../components/common/LandingHeader.vue").default
|
||||||
'LoadingSkeleton': typeof import("../../components/common/LoadingSkeleton.vue").default
|
'LoadingSkeleton': typeof import("../../components/common/LoadingSkeleton.vue").default
|
||||||
|
|
@ -172,6 +173,7 @@ interface _GlobalComponents {
|
||||||
'NuxtIsland': typeof import("../../node_modules/nuxt/dist/app/components/nuxt-island").default
|
'NuxtIsland': typeof import("../../node_modules/nuxt/dist/app/components/nuxt-island").default
|
||||||
'LazyAppHeader': LazyComponent<typeof import("../../components/common/AppHeader.vue").default>
|
'LazyAppHeader': LazyComponent<typeof import("../../components/common/AppHeader.vue").default>
|
||||||
'LazyFormInput': LazyComponent<typeof import("../../components/common/FormInput.vue").default>
|
'LazyFormInput': LazyComponent<typeof import("../../components/common/FormInput.vue").default>
|
||||||
|
'LazyGlobalLoader': LazyComponent<typeof import("../../components/common/GlobalLoader.vue").default>
|
||||||
'LazyLandingFooter': LazyComponent<typeof import("../../components/common/LandingFooter.vue").default>
|
'LazyLandingFooter': LazyComponent<typeof import("../../components/common/LandingFooter.vue").default>
|
||||||
'LazyLandingHeader': LazyComponent<typeof import("../../components/common/LandingHeader.vue").default>
|
'LazyLandingHeader': LazyComponent<typeof import("../../components/common/LandingHeader.vue").default>
|
||||||
'LazyLoadingSkeleton': LazyComponent<typeof import("../../components/common/LoadingSkeleton.vue").default>
|
'LazyLoadingSkeleton': LazyComponent<typeof import("../../components/common/LoadingSkeleton.vue").default>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
|
<GlobalLoader />
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
|
|
|
||||||
77
Frontend-Learner/components/common/GlobalLoader.vue
Normal file
77
Frontend-Learner/components/common/GlobalLoader.vue
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
/**
|
||||||
|
* @file GlobalLoader.vue
|
||||||
|
* @description Global full-screen loading overlay that triggers during page navigation.
|
||||||
|
* Uses a premium pulsing logo animation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const nuxtApp = useNuxtApp()
|
||||||
|
const isLoading = ref(false)
|
||||||
|
|
||||||
|
// Hook into Nuxt page transitions
|
||||||
|
nuxtApp.hook('page:start', () => {
|
||||||
|
isLoading.value = true
|
||||||
|
})
|
||||||
|
|
||||||
|
nuxtApp.hook('page:finish', () => {
|
||||||
|
// Add a small delay for better UX (prevents flickering on fast loads)
|
||||||
|
setTimeout(() => {
|
||||||
|
isLoading.value = false
|
||||||
|
}, 500)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Transition name="fade">
|
||||||
|
<div v-if="isLoading" class="fixed inset-0 z-[99999] flex flex-col items-center justify-center bg-white dark:bg-[#0f172a] transition-colors duration-300">
|
||||||
|
<div class="relative flex flex-col items-center">
|
||||||
|
<!-- Main Logo Box -->
|
||||||
|
<div class="w-20 h-20 bg-blue-50 dark:bg-blue-900/20 rounded-2xl flex items-center justify-center mb-6 animate-pulse-soft">
|
||||||
|
<div class="w-12 h-12 bg-blue-600 rounded-xl flex items-center justify-center shadow-lg shadow-blue-600/30 animate-bounce-subtle">
|
||||||
|
<span class="text-2xl font-black text-white">E</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Loading Text -->
|
||||||
|
<div class="flex flex-col items-center gap-2">
|
||||||
|
<h3 class="text-lg font-bold text-slate-800 dark:text-white tracking-wide">e-Learning</h3>
|
||||||
|
<div class="flex gap-1">
|
||||||
|
<div class="w-2 h-2 rounded-full bg-blue-500 animate-bounce" style="animation-delay: 0s"/>
|
||||||
|
<div class="w-2 h-2 rounded-full bg-blue-500 animate-bounce" style="animation-delay: 0.1s"/>
|
||||||
|
<div class="w-2 h-2 rounded-full bg-blue-500 animate-bounce" style="animation-delay: 0.2s"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-from,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse-soft {
|
||||||
|
0%, 100% { transform: scale(1); opacity: 1; }
|
||||||
|
50% { transform: scale(1.05); opacity: 0.9; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounce-subtle {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-5px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-pulse-soft {
|
||||||
|
animation: pulse-soft 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-bounce-subtle {
|
||||||
|
animation: bounce-subtle 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue