Files
FileCodeBoxFronted2026/src/App.vue
T
2026-06-05 13:01:09 +08:00

122 lines
2.5 KiB
Vue

<script setup lang="ts">
import { RouterView } from 'vue-router'
import ThemeToggle from './components/common/ThemeToggle.vue'
import LanguageSwitcher from './components/common/LanguageSwitcher.vue'
import AlertComponent from '@/components/common/AlertComponent.vue'
import { useAppShell } from '@/composables'
const {
isDarkMode,
isLoading,
routeTransitionMode,
routeTransitionName,
routeViewKey,
showGlobalControls
} = useAppShell()
</script>
<template>
<div :class="['app-container', isDarkMode ? 'dark' : 'light']">
<div v-if="showGlobalControls" class="fixed top-4 right-4 z-50 flex items-center space-x-3">
<LanguageSwitcher />
<ThemeToggle v-model="isDarkMode" />
</div>
<div v-if="isLoading" class="loading-overlay">
<div class="loading-spinner"></div>
</div>
<RouterView v-slot="{ Component }">
<transition :name="routeTransitionName" :mode="routeTransitionMode">
<component :is="Component" :key="routeViewKey" />
</transition>
</RouterView>
<AlertComponent />
</div>
</template>
<style>
.app-container {
min-height: 100vh;
width: 100%;
transition: background-color 0.5s ease;
}
.light {
background:
linear-gradient(135deg, #dfe9eb 0%, #edf3f2 46%, #f7f8f5 100%),
linear-gradient(90deg, rgba(103, 135, 145, 0.12), rgba(162, 172, 154, 0.1));
}
.dark {
background:
linear-gradient(135deg, #10191e 0%, #17252b 48%, #223036 100%),
linear-gradient(90deg, rgba(113, 153, 168, 0.12), rgba(117, 143, 132, 0.08));
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.transfer-fade-enter-active,
.transfer-fade-leave-active {
transition:
opacity 0.2s ease,
transform 0.2s ease;
}
.transfer-fade-enter-from {
opacity: 0;
transform: translateY(8px);
}
.transfer-fade-leave-active {
position: absolute;
inset: 0;
width: 100%;
pointer-events: none;
}
.transfer-fade-leave-to {
opacity: 0;
transform: translateY(-6px);
}
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.loading-spinner {
width: 50px;
height: 50px;
border: 3px solid #fff;
border-top: 3px solid #6f98a6;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>