71 lines
2.1 KiB
Vue
71 lines
2.1 KiB
Vue
<template>
|
|
<div class="min-h-screen bg-noctune-cream">
|
|
<div v-if="!isAuthPage" class="flex flex-col min-h-screen">
|
|
<AppHeader />
|
|
<div class="flex flex-1">
|
|
<Sidebar />
|
|
<main class="flex-1 overflow-auto" :class="{ 'pb-20': hasPlayer }">
|
|
<router-view />
|
|
</main>
|
|
</div>
|
|
<PlayerBar />
|
|
</div>
|
|
<router-view v-else />
|
|
<div class="fixed top-4 right-4 z-[100] space-y-2">
|
|
<div v-for="toast in uiStore.toasts" :key="toast.id"
|
|
class="px-4 py-3 rounded-lg border-2 border-black font-bold text-sm shadow-[4px_4px_0px_0px_#000] transition-all animate-slide-in"
|
|
:class="toastClass(toast.type)"
|
|
>
|
|
<div class="flex items-center gap-2">
|
|
<span>{{ toast.message }}</span>
|
|
<button @click="uiStore.dismissToast(toast.id)" class="ml-2 opacity-60 hover:opacity-100">×</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, onMounted } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import { useAuthStore } from './stores/authStore.js'
|
|
import { useUiStore } from './stores/uiStore.js'
|
|
import { usePlayerStore } from './stores/playerStore.js'
|
|
import AppHeader from './components/AppHeader.vue'
|
|
import Sidebar from './components/Sidebar.vue'
|
|
import PlayerBar from './components/PlayerBar.vue'
|
|
|
|
const route = useRoute()
|
|
const authStore = useAuthStore()
|
|
const uiStore = useUiStore()
|
|
const playerStore = usePlayerStore()
|
|
|
|
const isAuthPage = computed(() => {
|
|
return route.meta?.guest === true || route.path === '/register'
|
|
})
|
|
|
|
const hasPlayer = computed(() => !!playerStore.currentTrack)
|
|
|
|
function toastClass(type) {
|
|
return {
|
|
info: 'bg-noctune-teal text-black',
|
|
success: 'bg-green-400 text-black',
|
|
error: 'bg-red-400 text-white',
|
|
}[type] || 'bg-noctune-yellow text-black'
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await authStore.checkSession()
|
|
})
|
|
</script>
|
|
|
|
<style>
|
|
.animate-slide-in {
|
|
animation: slideIn 0.3s ease-out;
|
|
}
|
|
@keyframes slideIn {
|
|
from { opacity: 0; transform: translateX(100%); }
|
|
to { opacity: 1; transform: translateX(0); }
|
|
}
|
|
</style>
|