|
<script lang="ts"> |
|
import { authStore } from '$lib/stores/auth'; |
|
import type { HuggingFaceLibs } from '$lib/types'; |
|
|
|
interface Props { |
|
hfAuth: HuggingFaceLibs | null; |
|
currentTab?: string; |
|
} |
|
|
|
let { hfAuth, currentTab = 'Piclets' }: Props = $props(); |
|
const auth = $derived(authStore); |
|
|
|
async function handleSignIn() { |
|
if (!hfAuth) return; |
|
|
|
const url = await hfAuth.oauthLoginUrl({ scopes: ["inference-api"] }); |
|
window.location.href = url; |
|
} |
|
</script> |
|
|
|
<header class="app-header"> |
|
<h1 class="app-title">{currentTab}</h1> |
|
|
|
{#if $auth.showSignIn && !$auth.userInfo} |
|
<button class="sign-in-btn" onclick={handleSignIn}> |
|
Sign In |
|
</button> |
|
{:else if $auth.userInfo} |
|
<div class="user-info"> |
|
<span class="username">{$auth.userInfo.preferred_username || 'User'}</span> |
|
</div> |
|
{/if} |
|
</header> |
|
|
|
{#if $auth.bannerMessage} |
|
<div class="auth-banner"> |
|
{$auth.bannerMessage} |
|
</div> |
|
{/if} |
|
|
|
<style> |
|
.app-header { |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
padding: 1rem; |
|
background: white; |
|
border-bottom: 1px solid #f0f0f0; |
|
} |
|
|
|
.app-title { |
|
margin: 0; |
|
font-size: 1.25rem; |
|
font-weight: 700; |
|
color: #333; |
|
} |
|
|
|
.sign-in-btn { |
|
padding: 0.5rem 1rem; |
|
background: #007bff; |
|
color: white; |
|
border: none; |
|
border-radius: 20px; |
|
font-size: 0.875rem; |
|
font-weight: 500; |
|
cursor: pointer; |
|
transition: background 0.2s; |
|
} |
|
|
|
.sign-in-btn:active { |
|
background: #0056b3; |
|
} |
|
|
|
.user-info { |
|
display: flex; |
|
align-items: center; |
|
gap: 0.5rem; |
|
} |
|
|
|
.username { |
|
font-size: 0.875rem; |
|
color: #666; |
|
font-weight: 500; |
|
} |
|
|
|
.auth-banner { |
|
padding: 0.75rem 1rem; |
|
background: #fff3cd; |
|
color: #856404; |
|
font-size: 0.875rem; |
|
text-align: center; |
|
border-bottom: 1px solid #ffeeba; |
|
} |
|
</style> |