style(ui): improve code formatting and consistency in App.svelte

This commit is contained in:
warkanum committed 2026-04-05 10:52:25 +02:00
1 parent 4bf1c1fe60
commit f0d9c4dc09
6 files changed
+1412 -60

No files matched your search

+1
View File
@@ -33,3 +33,4 @@ bin/
OB1/ OB1/
ui/node_modules/ ui/node_modules/
ui/.svelte-kit/ ui/.svelte-kit/
internal/app/ui/dist
-1
View File
@@ -1 +0,0 @@
/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-emerald-400:oklch(76.5% .177 163.223);--color-cyan-100:oklch(95.6% .045 203.388);--color-cyan-200:oklch(91.7% .08 205.041);--color-cyan-300:oklch(86.5% .127 207.078);--color-cyan-400:oklch(78.9% .154 211.53);--color-violet-100:oklch(94.3% .029 294.588);--color-violet-300:oklch(81.1% .111 293.571);--color-violet-400:oklch(70.2% .183 293.541);--color-rose-100:oklch(94.1% .03 12.58);--color-rose-400:oklch(71.2% .194 13.428);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-900:oklch(20.8% .042 265.755);--color-slate-950:oklch(12.9% .042 264.695);--color-white:#fff;--spacing:.25rem;--container-3xl:48rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--radius-3xl:1.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:coLine truncated
-1
View File
@@ -1 +0,0 @@
var Ei=Object.defineProperty;var $n=e=>{throw TypeError(e)};var ki=(e,t,n)=>t in e?Ei(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var fe=(e,t,n)=>ki(e,typeof t!="symbol"?t+"":t,n),hn=(e,t,n)=>t.has(e)||$n("Cannot "+n);var l=(e,t,n)=>(hn(e,t,"read from private field"),n?n.call(e):t.get(e)),b=(e,t,n)=>t.has(e)?$n("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),E=(e,t,n,r)=>(hn(e,t,"write to private field"),r?r.call(e,n):t.set(e,n),n),N=(e,t,n)=>(hn(e,t,"access private method"),n);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))r(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const a of s.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&r(a)}).observe(document,{childList:!0,subtree:!0});function n(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function r(i){if(i.ep)return;i.ep=!0;const s=n(i);fetch(i.href,s)}})();const Si="5";var ur;typeof window<"u"&&((ur=window.__svelte??(window.__svelte={})).v??(ur.v=new Set)).add(Si);let Pt=!1,Ai=!1;function Ti(){Pt=!0}Ti();const Mi=1,Ci=2,dr=4,Ni=8,Oi=16,Ri=2,j=Symbol(),hr="http://www.w3.org/1999/xhtml",Di=!1;var vr=Array.isArray,Fi=Array.prototype.indexOf,_t=Array.prototype.includes,fn=Array.from,Ii=Object.defineProperty,Tt=Object.getOwnPropertyDescriptor,pr=Object.getOwnPropertyDescriptors,Li=Object.prototype,Pi=Array.prototype,On=Object.getPrototypeOf,Gn=Object.isExtensible;const ji=()=>{};function qi(e){return e()}function _n(e){for(var t=0;t<e.length;t++)e[t]()}function _r(){var e,t,n=new Promise((r,i)=>{e=r,t=i});return{promise:n,resolve:e,reject:t}}const P=2,gt=4,jt=8,gr=1<<24,De=16,ve=32,tt=64,gn=128,re=512,I=1024,z=2048,xe=4096,K=8192,ie=16384,lt=32768,Xn=1<<25,mt=65536,mn=1<<17,mr=1<<18,ot=1<<19,wr=1<<20,ye=1<<25,nt=65536,wn=1<<21,un=1<<22,Be=1<<23,Mt=Symbol("$state"),Me=new class extends Error{constructor(){super(...arguments);fe(this,"name","StaleReactionError");fe(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}};function zi(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function Hi(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function Bi(e,t,n){throw new Error("https://svelte.dev/e/each_key_duplicate")}function Vi(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function Ui(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function Yi(e){throw new Error("https://svelte.dev/e/effect_orphan")}function Ki(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function Wi(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function $i(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function Gi(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function Xi(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}function Zi(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function br(e){return e===this.v}function Ji(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function yr(e){return!Ji(e,this.v)}let R=null;function wt(e){R=e}function xr(e,t=!1,n){R={p:R,i:!1,c:null,e:null,s:e,x:null,r:k,l:Pt&&!t?{s:null,u:null,$:[]}:null}}function Er(e){var t=R,n=t.e;if(n!==null){t.e=null;for(var r of n)Kr(r)}return t.i=!0,R=t.p,{}}function qt(){return!Pt||R!==null&&R.l===null}let ut=[];function Qi(){var e=ut;ut=[],_n(e)}function Ve(e){if(ut.length===0){var t=ut;queueMicrotask(()=>{t===ut&&Qi()})}ut.push(e)}function kr(e){var t=k;if(t===null)return y.f|=Be,e;if((t.f&lt)===0&&(t.f&gt)===0)throw e;He(e,t)}function He(e,t){for(;t!==null;){if((t.f&gn)!==0){if((t.f&lt)===0)throw e;try{t.b.error(e);return}catch(n){e=n}}t=t.parent}throw e}const es=-7169;function O(e,t){e.f=e.f&es|t}function Rn(e){(e.f&re)!==0||e.deps===null?O(e,I):O(e,xe)}function Sr(e){if(e!==null)for(const t of e)(t.f&P)===0||(t.f&nt)===0||(t.f^=nt,Sr(t.deps))}function Ar(e,t,n){(e.f&z)!==0?t.add(e):(e.f&xe)!==0&&n.add(e),Sr(e.deps),O(e,I)}const Ie=new Set;let x=null,q=null,bn=null,vn=!1,ct=null,Zt=null;var Zn=0;let ts=1;var dt,ht,Ce,_e,Ot,X,Rt,qe,Ne,ge,vt,Ge,F,Jt,Tr,Qt,yn,xn,Mr;const ln=class ln{constructor(){b(this,F);fe(this,"id",ts++);fe(this,"current",new Map);fe(this,"previous",new Map);b(this,dt,new Set);b(this,ht,new Set);b(this,Ce,new Map);b(this,_e,new Map);b(this,Ot,null);b(this,X,[]);b(this,Rt,[]);b(this,qe,new Set);b(this,Ne,new Set);b(this,ge,new Map);fe(this,"is_fork",!1);b(this,vt,!1);b(this,Ge,new Set)}skip_effect(t){l(this,ge).has(t)||l(this,ge).set(t,{d:[],m:[]})}unskip_effect(t){var n=l(this,ge).get(t);if(n){l(this,ge).delete(t);for(var Line truncated
-17
View File
@@ -1,17 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AMCS</title>
<meta
name="description"
content="AMCS is a memory server that captures, links, and retrieves structured project thoughts for AI assistants using semantic search, summaries, and MCP tools."
/>
<script type="module" crossorigin src="/assets/index-CAayb6ka.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BDhMN0_9.css">
</head>
<body class="bg-slate-950">
<div id="app"></div>
</body>
</html>
+1291
View File
File diff suppressed because it is too large. Load diff
+120 -41
View File
@@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte'; import { onMount } from "svelte";
type AccessEntry = { type AccessEntry = {
key_id: string; key_id: string;
@@ -23,26 +23,26 @@
let data: StatusResponse | null = null; let data: StatusResponse | null = null;
let loading = true; let loading = true;
let error = ''; let error = "";
const quickLinks = [ const quickLinks = [
{ href: '/llm', label: 'LLM Instructions' }, { href: "/llm", label: "LLM Instructions" },
{ href: '/healthz', label: 'Health Check' }, { href: "/healthz", label: "Health Check" },
{ href: '/readyz', label: 'Readiness Check' } { href: "/readyz", label: "Readiness Check" },
]; ];
async function loadStatus() { async function loadStatus() {
loading = true; loading = true;
error = ''; error = "";
try { try {
const response = await fetch('/api/status'); const response = await fetch("/api/status");
if (!response.ok) { if (!response.ok) {
throw new Error(`Status request failed with ${response.status}`); throw new Error(`Status request failed with ${response.status}`);
} }
data = (await response.json()) as StatusResponse; data = (await response.json()) as StatusResponse;
} catch (err) { } catch (err) {
error = err instanceof Error ? err.message : 'Failed to load status'; error = err instanceof Error ? err.message : "Failed to load status";
} finally { } finally {
loading = false; loading = false;
} }
@@ -60,98 +60,166 @@
</svelte:head> </svelte:head>
<div class="min-h-screen bg-slate-950 text-slate-100"> <div class="min-h-screen bg-slate-950 text-slate-100">
<main class="mx-auto flex min-h-screen max-w-7xl flex-col px-4 py-6 sm:px-6 lg:px-8"> <main
<section class="overflow-hidden rounded-3xl border border-white/10 bg-slate-900 shadow-2xl shadow-slate-950/40"> class="mx-auto flex min-h-screen max-w-7xl flex-col px-4 py-6 sm:px-6 lg:px-8"
<img src="/images/project.jpg" alt="Avelon Memory Crystal" class="h-64 w-full object-cover object-center sm:h-80" /> >
<section
class="overflow-hidden rounded-3xl border border-white/10 bg-slate-900 shadow-2xl shadow-slate-950/40"
>
<img
src="/images/project.jpg"
alt="Avelon Memory Crystal"
class="h-64 w-full object-cover object-center sm:h-80"
/>
<div class="grid gap-8 p-6 sm:p-8 lg:grid-cols-[1.6fr_1fr] lg:p-10"> <div class="grid gap-8 p-6 sm:p-8 lg:grid-cols-[1.6fr_1fr] lg:p-10">
<div class="space-y-6"> <div class="space-y-6">
<div class="space-y-4"> <div class="space-y-4">
<div class="inline-flex items-center gap-2 rounded-full border border-cyan-400/20 bg-cyan-400/10 px-3 py-1 text-sm font-medium text-cyan-200"> <div
class="inline-flex items-center gap-2 rounded-full border border-cyan-400/20 bg-cyan-400/10 px-3 py-1 text-sm font-medium text-cyan-200"
>
<span class="h-2 w-2 rounded-full bg-emerald-400"></span> <span class="h-2 w-2 rounded-full bg-emerald-400"></span>
Avalon Memory Crystal Server Avalon Memory Crystal Server
</div> </div>
<div> <div>
<h1 class="text-3xl font-semibold tracking-tight text-white sm:text-4xl">Avelon Memory Crystal Server (AMCS)</h1> <h1
<p class="mt-3 max-w-3xl text-base leading-7 text-slate-300 sm:text-lg"> class="text-3xl font-semibold tracking-tight text-white sm:text-4xl"
{data?.description ?? 'AMCS is a memory server that captures, links, and retrieves structured project thoughts for AI assistants using semantic search, summaries, and MCP tools.'} >
Avelon Memory Crystal Server (AMCS)
</h1>
<p
class="mt-3 max-w-3xl text-base leading-7 text-slate-300 sm:text-lg"
>
{data?.description ??
"AMCS is a memory server that captures, links, and retrieves structured project thoughts for AI assistants using semantic search, summaries, and MCP tools."}
</p> </p>
</div> </div>
</div> </div>
<div class="flex flex-wrap gap-3"> <div class="flex flex-wrap gap-3">
{#each quickLinks as link} {#each quickLinks as link}
<a class="inline-flex items-center justify-center rounded-xl border border-cyan-300/20 bg-cyan-400/10 px-4 py-2 text-sm font-semibold text-cyan-100 transition hover:border-cyan-300/40 hover:bg-cyan-400/20" href={link.href}>{link.label}</a> <a
class="inline-flex items-center justify-center rounded-xl border border-cyan-300/20 bg-cyan-400/10 px-4 py-2 text-sm font-semibold text-cyan-100 transition hover:border-cyan-300/40 hover:bg-cyan-400/20"
href={link.href}>{link.label}</a
>
{/each} {/each}
{#if data?.oauth_enabled} {#if data?.oauth_enabled}
<a class="inline-flex items-center justify-center rounded-xl border border-violet-300/20 bg-violet-400/10 px-4 py-2 text-sm font-semibold text-violet-100 transition hover:border-violet-300/40 hover:bg-violet-400/20" href="/oauth-authorization-server">OAuth Authorization Server</a> <a
class="inline-flex items-center justify-center rounded-xl border border-violet-300/20 bg-violet-400/10 px-4 py-2 text-sm font-semibold text-violet-100 transition hover:border-violet-300/40 hover:bg-violet-400/20"
href="/oauth-authorization-server">OAuth Authorization Server</a
>
{/if} {/if}
</div> </div>
<div class="grid gap-4 sm:grid-cols-3"> <div class="grid gap-4 sm:grid-cols-3">
<div class="rounded-2xl border border-white/10 bg-white/5 p-5"> <div class="rounded-2xl border border-white/10 bg-white/5 p-5">
<p class="text-sm uppercase tracking-[0.2em] text-slate-400">Connected users</p> <p class="text-sm uppercase tracking-[0.2em] text-slate-400">
<p class="mt-2 text-3xl font-semibold text-white">{data?.connected_count ?? '—'}</p> Connected users
</p>
<p class="mt-2 text-3xl font-semibold text-white">
{data?.connected_count ?? "—"}
</p>
</div> </div>
<div class="rounded-2xl border border-white/10 bg-white/5 p-5"> <div class="rounded-2xl border border-white/10 bg-white/5 p-5">
<p class="text-sm uppercase tracking-[0.2em] text-slate-400">Known principals</p> <p class="text-sm uppercase tracking-[0.2em] text-slate-400">
<p class="mt-2 text-3xl font-semibold text-white">{data?.total_known ?? '—'}</p> Known principals
</p>
<p class="mt-2 text-3xl font-semibold text-white">
{data?.total_known ?? "—"}
</p>
</div> </div>
<div class="rounded-2xl border border-white/10 bg-white/5 p-5"> <div class="rounded-2xl border border-white/10 bg-white/5 p-5">
<p class="text-sm uppercase tracking-[0.2em] text-slate-400">Version</p> <p class="text-sm uppercase tracking-[0.2em] text-slate-400">
<p class="mt-2 break-all text-2xl font-semibold text-white">{data?.version ?? '—'}</p> Version
</p>
<p class="mt-2 break-all text-2xl font-semibold text-white">
{data?.version ?? "—"}
</p>
</div> </div>
</div> </div>
</div> </div>
<aside class="space-y-4 rounded-2xl border border-white/10 bg-slate-950/50 p-5"> <aside
class="space-y-4 rounded-2xl border border-white/10 bg-slate-950/50 p-5"
>
<div> <div>
<h2 class="text-lg font-semibold text-white">Build details</h2> <h2 class="text-lg font-semibold text-white">Build details</h2>
<p class="mt-1 text-sm text-slate-400">The same status info as the old landing page, just without looking like it escaped from 2004.</p> <p class="mt-1 text-sm text-slate-400">The same status info.</p>
</div> </div>
<dl class="space-y-3 text-sm text-slate-300"> <dl class="space-y-3 text-sm text-slate-300">
<div> <div>
<dt class="text-slate-500">Build date</dt> <dt class="text-slate-500">Build date</dt>
<dd class="mt-1 font-medium text-white">{data?.build_date ?? 'unknown'}</dd> <dd class="mt-1 font-medium text-white">
{data?.build_date ?? "unknown"}
</dd>
</div> </div>
<div> <div>
<dt class="text-slate-500">Commit</dt> <dt class="text-slate-500">Commit</dt>
<dd class="mt-1 break-all rounded-lg bg-white/5 px-3 py-2 font-mono text-xs text-cyan-100">{data?.commit ?? 'unknown'}</dd> <dd
class="mt-1 break-all rounded-lg bg-white/5 px-3 py-2 font-mono text-xs text-cyan-100"
>
{data?.commit ?? "unknown"}
</dd>
</div> </div>
<div> <div>
<dt class="text-slate-500">Connected window</dt> <dt class="text-slate-500">Connected window</dt>
<dd class="mt-1 font-medium text-white">{data?.connected_window ?? 'last 10 minutes'}</dd> <dd class="mt-1 font-medium text-white">
{data?.connected_window ?? "last 10 minutes"}
</dd>
</div> </div>
</dl> </dl>
</aside> </aside>
</div> </div>
</section> </section>
<section class="mt-6 rounded-3xl border border-white/10 bg-slate-900/80 p-6 shadow-xl shadow-slate-950/20 sm:p-8"> <section
<div class="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between"> class="mt-6 rounded-3xl border border-white/10 bg-slate-900/80 p-6 shadow-xl shadow-slate-950/20 sm:p-8"
>
<div
class="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between"
>
<div> <div>
<h2 class="text-2xl font-semibold text-white">Recent access</h2> <h2 class="text-2xl font-semibold text-white">Recent access</h2>
<p class="mt-1 text-sm text-slate-400">Authenticated principals AMCS has seen recently.</p> <p class="mt-1 text-sm text-slate-400">
Authenticated principals AMCS has seen recently.
</p>
</div> </div>
<button class="inline-flex items-center justify-center rounded-xl border border-white/10 bg-white/5 px-4 py-2 text-sm font-medium text-slate-200 transition hover:bg-white/10" on:click={loadStatus}> <button
class="inline-flex items-center justify-center rounded-xl border border-white/10 bg-white/5 px-4 py-2 text-sm font-medium text-slate-200 transition hover:bg-white/10"
on:click={loadStatus}
>
Refresh Refresh
</button> </button>
</div> </div>
{#if loading} {#if loading}
<div class="mt-6 rounded-2xl border border-dashed border-white/10 bg-slate-950/40 px-4 py-10 text-center text-slate-400">Loading status…</div> <div
class="mt-6 rounded-2xl border border-dashed border-white/10 bg-slate-950/40 px-4 py-10 text-center text-slate-400"
>
Loading status…
</div>
{:else if error} {:else if error}
<div class="mt-6 rounded-2xl border border-rose-400/30 bg-rose-400/10 px-4 py-6 text-sm text-rose-100"> <div
class="mt-6 rounded-2xl border border-rose-400/30 bg-rose-400/10 px-4 py-6 text-sm text-rose-100"
>
<p class="font-semibold">Couldn’t load the status snapshot.</p> <p class="font-semibold">Couldn’t load the status snapshot.</p>
<p class="mt-1 text-rose-100/80">{error}</p> <p class="mt-1 text-rose-100/80">{error}</p>
</div> </div>
{:else if data && data.entries.length === 0} {:else if data && data.entries.length === 0}
<div class="mt-6 rounded-2xl border border-dashed border-white/10 bg-slate-950/40 px-4 py-10 text-center text-slate-400">No authenticated access recorded yet.</div> <div
class="mt-6 rounded-2xl border border-dashed border-white/10 bg-slate-950/40 px-4 py-10 text-center text-slate-400"
>
No authenticated access recorded yet.
</div>
{:else if data} {:else if data}
<div class="mt-6 overflow-hidden rounded-2xl border border-white/10"> <div class="mt-6 overflow-hidden rounded-2xl border border-white/10">
<div class="overflow-x-auto"> <div class="overflow-x-auto">
<table class="min-w-full divide-y divide-white/10 text-left text-sm text-slate-300"> <table
<thead class="bg-white/5 text-xs uppercase tracking-[0.2em] text-slate-500"> class="min-w-full divide-y divide-white/10 text-left text-sm text-slate-300"
>
<thead
class="bg-white/5 text-xs uppercase tracking-[0.2em] text-slate-500"
>
<tr> <tr>
<th class="px-4 py-3 font-medium">Principal</th> <th class="px-4 py-3 font-medium">Principal</th>
<th class="px-4 py-3 font-medium">Last accessed</th> <th class="px-4 py-3 font-medium">Last accessed</th>
@@ -162,10 +230,21 @@
<tbody class="divide-y divide-white/5 bg-slate-950/30"> <tbody class="divide-y divide-white/5 bg-slate-950/30">
{#each data.entries as entry} {#each data.entries as entry}
<tr class="hover:bg-white/[0.03]"> <tr class="hover:bg-white/[0.03]">
<td class="px-4 py-3 align-top"><code class="rounded bg-white/5 px-2 py-1 font-mono text-xs text-cyan-100">{entry.key_id}</code></td> <td class="px-4 py-3 align-top"
<td class="px-4 py-3 align-top text-slate-200">{formatDate(entry.last_accessed_at)}</td> ><code
<td class="px-4 py-3 align-top"><code class="text-slate-100">{entry.last_path}</code></td> class="rounded bg-white/5 px-2 py-1 font-mono text-xs text-cyan-100"
<td class="px-4 py-3 align-top font-semibold text-white">{entry.request_count}</td> >{entry.key_id}</code
></td
>
<td class="px-4 py-3 align-top text-slate-200"
>{formatDate(entry.last_accessed_at)}</td
>
<td class="px-4 py-3 align-top"
><code class="text-slate-100">{entry.last_path}</code></td
>
<td class="px-4 py-3 align-top font-semibold text-white"
>{entry.request_count}</td
>
</tr> </tr>
{/each} {/each}
</tbody> </tbody>