Make UI language, timestamps and live feedback consistent

This commit is contained in:
2026-10-07 19:46:40 -04:00
parent 0ed3cd6b47
commit 70185eb98c
81 changed files with 656 additions and 332 deletions
+3 -2
View File
@@ -1,4 +1,5 @@
<script lang="ts">
import RelativeTime from '$ui/components/RelativeTime.svelte';
import { onMount } from 'svelte';
import { page } from '$app/stores';
import { invalidateAll } from '$app/navigation';
@@ -100,7 +101,7 @@
<div class="user-list" aria-label="User accounts">{#each users as user (user.id)}<article class="user-row">
<div class="user-name"><h2>{user.displayName} {#if user.id === $page.data.user?.id}<span class="you">You</span>{/if}</h2><p>@{user.username}</p></div>
<div class="access"><span class="role">{user.role === 'admin' ? 'Administrator' : user.role}</span><span class:disabled={user.disabled}>{user.disabled ? 'Disabled' : 'Enabled'}</span>{#if user.mustChangePassword && !user.disabled}<small>Password change required</small>{/if}</div>
<div class="last-login"><span>Last sign-in</span><p>{user.lastLoginAt ? new Date(user.lastLoginAt).toLocaleString() : 'Never'}</p></div>
<div class="last-login"><span>Last sign-in</span><p><RelativeTime value={user.lastLoginAt} missing={user.id === $page.data.user?.id ? 'Signed in · time not recorded' : 'Not recorded'} /></p></div>
<div class="actions"><Button size="sm" disabled={busy} onclick={() => openEdit(user)}>Edit access</Button><Button size="sm" variant="ghost" disabled={busy} onclick={() => revoke(user)}>Sign out sessions</Button></div>
</article>{/each}</div>
{/if}
@@ -110,7 +111,7 @@
{#if auditLoading && !events.length}<p class="muted" role="status">Loading account activity…</p>
{:else if !events.length}<p class="muted">No account events recorded.</p>
{:else}<div class="table-wrap"><table><thead><tr><th>Time</th><th>Event</th><th>By</th><th>Account</th><th>Details</th></tr></thead><tbody>
{#each events as event (event.id)}{@const details = auditDetails(event.details)}<tr><td class="event-time">{new Date(event.createdAt).toLocaleString()}</td><td>{actionLabels[event.action] ?? event.action}</td><td>{event.actor ? `@${event.actor}` : 'Unauthenticated'}</td><td>{event.targetId ? users.find(user => user.id === event.targetId)?.username ?? event.targetId : '—'}</td><td>{#if details}<details><summary>View details</summary><pre>{details}</pre></details>{:else}—{/if}</td></tr>{/each}
{#each events as event (event.id)}{@const details = auditDetails(event.details)}<tr><td class="event-time"><RelativeTime value={event.createdAt} /></td><td>{actionLabels[event.action] ?? event.action}</td><td>{event.actor ? `@${event.actor}` : 'Unauthenticated'}</td><td>{event.targetId ? users.find(user => user.id === event.targetId)?.username ?? event.targetId : '—'}</td><td>{#if details}<details><summary>View details</summary><pre>{details}</pre></details>{:else}—{/if}</td></tr>{/each}
</tbody></table></div>{/if}
</section>
{/if}