strat-gameplay-webapp/frontend-sba/pages/auth/login.vue
Cal Corum 2381456189 test: Skip unstable test suites
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 20:18:33 -06:00

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>