You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.1 KiB
104 lines
2.1 KiB
<script lang="ts">
|
|
import type { ActiveApp } from '$active-app';
|
|
import { DEMO_USERS, type DemoCredential, type DemoUser } from '../app.svelte';
|
|
|
|
let { App }: { App: ActiveApp } = $props();
|
|
|
|
const Sess = $derived(App.session);
|
|
|
|
let userIndex = $state(0);
|
|
let busy = $state(false);
|
|
|
|
async function signIn() {
|
|
busy = true;
|
|
const user = DEMO_USERS[userIndex];
|
|
Sess.adopt({
|
|
user,
|
|
credential: { accessToken: `tok-${user.id}-${Date.now()}` },
|
|
expiresAt: Date.now() + 60_000,
|
|
issuedAt: Date.now()
|
|
});
|
|
busy = false;
|
|
}
|
|
|
|
async function switchUser() {
|
|
busy = true;
|
|
userIndex = (userIndex + 1) % DEMO_USERS.length;
|
|
await signIn();
|
|
}
|
|
|
|
async function refresh() {
|
|
busy = true;
|
|
try {
|
|
await Sess.refresh();
|
|
} finally {
|
|
busy = false;
|
|
}
|
|
}
|
|
|
|
async function signOut() {
|
|
busy = true;
|
|
try {
|
|
await Sess.revoke();
|
|
} finally {
|
|
busy = false;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<section class="card">
|
|
<h2>{App.lang.t('session.title')}</h2>
|
|
<dl>
|
|
<dt>{App.lang.t('session.identity')}</dt>
|
|
<dd>
|
|
{#if Sess.current}
|
|
<strong>{Sess.current.user.name}</strong>
|
|
<span class="role">({Sess.current.user.role})</span>
|
|
{:else}
|
|
<em>{App.lang.t('session.anonymous')}</em>
|
|
{/if}
|
|
</dd>
|
|
<dt>{App.lang.t('session.generation')}</dt>
|
|
<dd>#{Sess.generation}</dd>
|
|
</dl>
|
|
<div class="actions">
|
|
{#if Sess.current}
|
|
<button onclick={switchUser} disabled={busy}>{App.lang.t('session.switchUser')}</button>
|
|
<button onclick={refresh} disabled={busy}>{App.lang.t('session.refresh')}</button>
|
|
<button onclick={signOut} disabled={busy}>{App.lang.t('session.signOut')}</button>
|
|
{:else}
|
|
<button onclick={signIn} disabled={busy}>{App.lang.t('session.signIn')}</button>
|
|
{/if}
|
|
</div>
|
|
</section>
|
|
|
|
<style>
|
|
.card {
|
|
border: 1px solid var(--border, #ccc);
|
|
border-radius: 6px;
|
|
padding: 12px;
|
|
}
|
|
dl {
|
|
display: grid;
|
|
grid-template-columns: max-content 1fr;
|
|
gap: 4px 12px;
|
|
margin: 8px 0;
|
|
}
|
|
dt {
|
|
font-weight: 600;
|
|
color: #666;
|
|
}
|
|
.role {
|
|
color: #888;
|
|
font-size: 0.9em;
|
|
}
|
|
.actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
flex-wrap: wrap;
|
|
}
|
|
button {
|
|
padding: 4px 10px;
|
|
}
|
|
</style>
|