VibeGame / src /lib /components /auth /LoginButton.svelte
dylanebert's picture
initial commit
794cf6c
<script lang="ts">
import { onMount } from 'svelte';
import { authStore } from '../../services/auth';
import gsap from 'gsap';
let authState = {
isAuthenticated: false,
user: null as any,
loading: true,
error: null as string | null
};
let loginBtn: HTMLButtonElement;
authStore.subscribe(state => {
authState = state;
});
onMount(async () => {
await authStore.init();
if (loginBtn && !authState.isAuthenticated) {
gsap.to(loginBtn, {
boxShadow: '0 0 20px rgba(255, 255, 255, 0.15)',
duration: 2,
repeat: -1,
yoyo: true,
ease: 'sine.inOut'
});
}
});
$: if (loginBtn && !authState.isAuthenticated && !authState.loading) {
gsap.to(loginBtn, {
boxShadow: '0 0 20px rgba(255, 255, 255, 0.15)',
duration: 2,
repeat: -1,
yoyo: true,
ease: 'sine.inOut'
});
}
function handleLogin() {
authStore.login();
}
function handleLogout() {
authStore.logout();
}
</script>
<div class="auth-container">
{#if authState.loading}
<div class="loading">Loading...</div>
{:else if authState.error}
<div class="error">
<span>{authState.error}</span>
<button on:click={handleLogin} class="retry-btn">Try Again</button>
</div>
{:else if authState.isAuthenticated}
<div class="user-info">
{#if authState.user?.avatarUrl}
<img src={authState.user.avatarUrl} alt={authState.user.name} class="avatar" />
{/if}
<span class="username">{authState.user?.name || 'User'}</span>
<button on:click={handleLogout} class="logout-btn">Logout</button>
</div>
{:else}
<button bind:this={loginBtn} on:click={handleLogin} class="login-btn">
Sign in
</button>
{/if}
</div>
<style>
.auth-container {
display: flex;
align-items: center;
gap: 0.5rem;
}
.loading {
color: #888;
font-size: 0.875rem;
}
.error {
display: flex;
align-items: center;
gap: 0.5rem;
color: #ff6b6b;
font-size: 0.875rem;
}
.retry-btn {
padding: 0.25rem 0.5rem;
background: #ff6b6b;
color: white;
border: none;
border-radius: 0.25rem;
cursor: pointer;
font-size: 0.75rem;
}
.retry-btn:hover {
background: #ff5252;
}
.user-info {
display: flex;
align-items: center;
gap: 0.5rem;
}
.avatar {
width: 24px;
height: 24px;
border-radius: 50%;
}
.username {
color: #ccc;
font-size: 0.875rem;
}
.logout-btn {
padding: 0.25rem 0.5rem;
background: transparent;
color: #888;
border: 1px solid #333;
border-radius: 0.25rem;
cursor: pointer;
font-size: 0.75rem;
transition: all 0.2s;
}
.logout-btn:hover {
background: #333;
color: #fff;
}
.login-btn {
padding: 0.35rem 0.85rem;
background: rgba(255, 255, 255, 0.03);
color: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 0.35rem;
cursor: pointer;
font-size: 0.75rem;
font-weight: 500;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
position: relative;
overflow: hidden;
}
.login-btn:hover {
background: rgba(255, 255, 255, 0.08);
color: rgba(255, 255, 255, 0.95);
border-color: rgba(255, 255, 255, 0.15);
transform: translateY(-1px);
}
.login-btn:active {
transform: translateY(0);
}
</style>