129 lines
4.9 KiB
Vue
Executable File
129 lines
4.9 KiB
Vue
Executable File
<template>
|
|
<div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-primary to-blue-700 px-4">
|
|
<div class="max-w-md w-full">
|
|
<!-- Login Card -->
|
|
<div class="bg-white rounded-2xl shadow-2xl p-8">
|
|
<!-- Logo and Title -->
|
|
<div class="text-center mb-8">
|
|
<div class="text-5xl font-bold text-primary mb-2">SBA</div>
|
|
<h1 class="text-2xl font-bold text-gray-900 mb-2">
|
|
Welcome Back
|
|
</h1>
|
|
<p class="text-gray-600">
|
|
Sign in to access your games
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Error Message -->
|
|
<div
|
|
v-if="error"
|
|
class="mb-6 p-4 bg-red-50 border border-red-200 rounded-lg"
|
|
>
|
|
<div class="flex items-start space-x-3">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-5 w-5 text-red-500 flex-shrink-0 mt-0.5"
|
|
viewBox="0 0 20 20"
|
|
fill="currentColor"
|
|
>
|
|
<path
|
|
fill-rule="evenodd"
|
|
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
|
|
clip-rule="evenodd"
|
|
/>
|
|
</svg>
|
|
<div class="text-sm text-red-800">
|
|
{{ error }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Discord Login Button -->
|
|
<button
|
|
:disabled="isLoading"
|
|
class="w-full flex items-center justify-center space-x-3 px-6 py-4 bg-[#5865F2] hover:bg-[#4752C4] disabled:bg-gray-400 text-white font-semibold rounded-lg transition shadow-lg hover:shadow-xl disabled:cursor-not-allowed"
|
|
@click="handleDiscordLogin"
|
|
>
|
|
<svg
|
|
v-if="!isLoading"
|
|
class="w-6 h-6"
|
|
viewBox="0 0 24 24"
|
|
fill="currentColor"
|
|
>
|
|
<path
|
|
d="M20.317 4.37a19.791 19.791 0 00-4.885-1.515a.074.074 0 00-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 00-5.487 0a12.64 12.64 0 00-.617-1.25a.077.077 0 00-.079-.037A19.736 19.736 0 003.677 4.37a.07.07 0 00-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 00.031.057a19.9 19.9 0 005.993 3.03a.078.078 0 00.084-.028a14.09 14.09 0 001.226-1.994a.076.076 0 00-.041-.106a13.107 13.107 0 01-1.872-.892a.077.077 0 01-.008-.128a10.2 10.2 0 00.372-.292a.074.074 0 01.077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 01.078.01c.12.098.246.198.373.292a.077.077 0 01-.006.127a12.299 12.299 0 01-1.873.892a.077.077 0 00-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 00.084.028a19.839 19.839 0 006.002-3.03a.077.077 0 00.032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 00-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418z"
|
|
/>
|
|
</svg>
|
|
<div
|
|
v-if="isLoading"
|
|
class="w-6 h-6 border-4 border-white/20 border-t-white rounded-full animate-spin"
|
|
/>
|
|
<span>{{ isLoading ? 'Connecting...' : 'Continue with Discord' }}</span>
|
|
</button>
|
|
|
|
<!-- Additional Info -->
|
|
<div class="mt-6 text-center text-sm text-gray-600">
|
|
<p>
|
|
By signing in, you agree to our
|
|
<a href="#" class="text-primary hover:underline">Terms of Service</a>
|
|
and
|
|
<a href="#" class="text-primary hover:underline">Privacy Policy</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Additional Links -->
|
|
<div class="mt-6 text-center">
|
|
<NuxtLink
|
|
to="/"
|
|
class="text-white hover:text-gray-200 transition text-sm font-medium"
|
|
>
|
|
← Back to Home
|
|
</NuxtLink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { useAuthStore } from '~/store/auth'
|
|
|
|
definePageMeta({
|
|
layout: false, // Don't use default layout
|
|
})
|
|
|
|
const authStore = useAuthStore()
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
|
|
const isLoading = ref(false)
|
|
const error = ref<string | null>(null)
|
|
|
|
// Check if already authenticated
|
|
onMounted(() => {
|
|
if (authStore.isAuthenticated) {
|
|
// Redirect to intended page or home
|
|
const redirect = (route.query.redirect as string) || '/'
|
|
router.push(redirect)
|
|
}
|
|
})
|
|
|
|
const handleDiscordLogin = () => {
|
|
try {
|
|
isLoading.value = true
|
|
error.value = null
|
|
|
|
// Trigger Discord OAuth flow (will redirect to Discord)
|
|
authStore.loginWithDiscord()
|
|
} catch (err: any) {
|
|
isLoading.value = false
|
|
error.value = err.message || 'Failed to initiate login. Please try again.'
|
|
console.error('Login error:', err)
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* Additional component styles if needed */
|
|
</style>
|