Files
WRNexusJS/packages/auth/components/DeviceSessions.wrn
T
Clintchiz 586a6db8ff
Quality / quality (ubuntu-latest) (push) Failing after 21s
Quality / quality (windows-latest) (push) Canceled after 0s
release: WRNexusJS 0.8.0
2026-08-02 23:18:51 +05:30

40 lines
2.0 KiB
Plaintext

component DeviceSessions {
props {
sessions: unknown[] = []
currentSessionId: string = ""
title: string = "Active sessions"
description: string = "Review devices signed in to your account."
revokeAction: string = "/api/auth/sessions/revoke"
revokeSchema: string = "auth-session-revoke"
revokeLabel: string = "Sign out"
successMessage: string = "Session revoked."
color: string = "primary"
size: string = "md"
class: string = ""
}
view {
<Card {...attrs} title='{title}' description='{description}' color='{color}' size='{size}' class='w-full max-w-2xl {class}'>
<div class="divide-y divide-[var(--wire-color-border)]">
{#each sessions as session}
<article class="flex items-center gap-3 py-4">
<Avatar fallback='{session.userAgent || "Device"}' icon="icon-[lucide--monitor-smartphone]" size="sm" color='{color}' />
<div class="min-w-0 flex-1"><p class="m-0 truncate text-sm font-semibold">{session.userAgent || "Unknown device"}</p><p class="m-0 mt-1 text-xs text-[var(--wire-color-muted)]">{session.ip || "Unknown IP"} · Last active {session.lastSeenAt}</p></div>
{#if session.id == currentSessionId}
<Badge label="Current" color="success" variant="soft" size="sm" />
{:else}
<form method="post" action='{revokeAction}' data-schema='{revokeSchema}' novalidate>
<input type="hidden" name="sessionId" value='{session.id}' />
<p data-error="sessionId" class="m-0 min-h-4 text-xs text-[var(--wire-color-danger)]"></p>
<p data-error="_form" role="alert" class="m-0 hidden text-xs text-[var(--wire-color-danger)]"></p>
<p data-success='{successMessage}' role="status" hidden class="m-0 text-xs text-[var(--wire-color-success)]">{successMessage}</p>
<Button type="submit" label='{revokeLabel}' color="danger" variant="ghost" size="sm" />
</form>
{/if}
</article>
{/each}
</div>
</Card>
}
}