<template> <main class="flex items-center justify-center page-container"> <div class="card"> <div class="card-body text-center"> <div v-if="loading" class="spinner-dots" role="status"> <span /><span /><span /> </div> <p v-else-if="error" class="text-error">{{ error }}</p> <p v-else>Redirecting...</p> </div> </div> </main> </template> <script setup lang="ts"> import { ref, onMounted } from 'vue'; import { useRoute, useRouter } from 'vue-router'; import { useAuthStore } from '@/stores/auth'; import { useNotificationStore } from '@/stores/notifications'; const route = useRoute(); const router = useRouter(); const authStore = useAuthStore(); const notificationStore = useNotificationStore(); const loading = ref(true); const error = ref<string | null>(null); onMounted(async () => { try { const accessToken = route.query.access_token as string | undefined; const refreshToken = route.query.refresh_token as string | undefined; const legacyToken = route.query.token as string | undefined; const tokenToUse = accessToken || legacyToken; if (!tokenToUse) { throw new Error('No token provided'); } await authStore.setTokens({ access_token: tokenToUse, refresh_token: refreshToken }); notificationStore.addNotification({ message: 'Login successful', type: 'success' }); router.push('/'); } catch (err) { error.value = err instanceof Error ? err.message : 'Authentication failed'; notificationStore.addNotification({ message: error.value, type: 'error' }); } finally { loading.value = false; } }); </script> <style scoped> .page-container { min-height: 100vh; min-height: 100dvh; padding: 1rem; } .card { width: 100%; max-width: 400px; text-align: center; } .spinner-dots { display: inline-flex; align-items: center; gap: 0.5rem; } .spinner-dots span { width: 0.75rem; height: 0.75rem; background-color: var(--primary); border-radius: 50%; animation: bounce 0.5s infinite alternate; } .spinner-dots span:nth-child(2) { animation-delay: 0.2s; } .spinner-dots span:nth-child(3) { animation-delay: 0.4s; } @keyframes bounce { from { transform: translateY(0); } to { transform: translateY(-0.5rem); } } </style>