Shell polish: storage line, status pill, footer strip, sidebar

Backend:
- apps.core with GET /api/status/ (env, git hash, OS, watched folder,
  worker counts) and a TimingMiddleware adding X-Server-Time-Ms
- status endpoint reports its own server-side assembly time

Frontend:
- top bar shows the storage line (watched folder) and a status pill
  with ENV, git hash, host OS, server time (e621 time once it exists)
- fixed 32px footer strip: storage path, active workers, build version
- collapsible filter sidebar: closed by default, Ctrl/Cmd+B toggle,
  overlay drawer with backdrop blur under 1024px
- rating filters, per-page and sidebar state persist in localStorage
This commit is contained in:
2026-09-17 08:19:27 -05:00
parent 0ff6232ba5
commit 3aa42f3703
14 changed files with 401 additions and 110 deletions
+48
View File
@@ -0,0 +1,48 @@
import { Laptop, Monitor, Terminal, type LucideIcon } from "lucide-react";
import { cn } from "@/lib/cn";
import type { SystemStatus } from "@/lib/types";
const osIcons: Record<string, LucideIcon> = {
linux: Terminal,
apple: Laptop,
windows: Monitor,
};
function formatMs(value: number): string {
return value >= 100 ? `${Math.round(value)}ms` : `${value.toFixed(1)}ms`;
}
export function StatusPill({ status }: { status?: SystemStatus }) {
if (!status) return null;
const OsIcon = osIcons[status.os.icon] ?? Monitor;
return (
<span
className="hidden select-none items-center gap-1.5 rounded-full border border-ctp-surface0 bg-ctp-mantle px-2.5 py-1 font-mono text-[11px] text-ctp-overlay1 lg:flex"
title={`${status.os.name} ${status.os.release} · built from ${status.git_hash}`}
>
<span
className={cn(
"font-medium",
status.env === "prod" ? "text-ctp-teal" : "text-ctp-yellow",
)}
>
ENV: {status.env.toUpperCase()}
</span>
<span className="text-ctp-surface2">·</span>
<span>{status.git_hash}</span>
<span className="text-ctp-surface2">·</span>
<OsIcon className="h-3 w-3" />
<span>{status.os.name.toUpperCase()}</span>
<span className="text-ctp-surface2">·</span>
<span>{formatMs(status.server_time_ms)}</span>
{status.e621_time_ms !== null ? (
<>
<span className="text-ctp-surface2">·</span>
<span>e621: {formatMs(status.e621_time_ms)}</span>
</>
) : null}
</span>
);
}