feat(web): consolidate paired devices, self-contained sections, docs + lint
Web console - Pairing/Library/Stats refactored into self-contained subsections that each own their own queries + mutations; a shared slot-based layout (view.tsx) is filled by the live page (containers) and Storybook (pure cards + fixtures) so the layout can't drift. - All paired devices in one list on Pairing with a protocol column (punktfunk/1 + Moonlight), routing each unpair to the right endpoint; the redundant Clients page is removed. - Library: overview grid split from the add/edit form into separate files. - Login screen links out to the docs. Docs - "Console login password" section on every host page (apt/RPM/Bazzite/SteamOS/Windows) plus a new "Forgot your Password?" troubleshooting page, linked from the login screen. - Console served as HTTP/1.1 over TLS (drop the unusable HTTP/3 advertising) across the Bun entry, launchers, systemd units, and packaging. Tooling - Biome now respects .gitignore (stops linting generated code), config migrated to 2.5.1; all lint issues fixed cleanly. Also includes this branch's in-progress host, Apple client, packaging, and CI changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import type { FC, ReactNode } from "react";
|
||||
import { m } from "@/paraglide/messages";
|
||||
|
||||
/** ms → `m:ss`. */
|
||||
export function fmtDuration(ms: number): string {
|
||||
const s = Math.max(0, Math.floor(ms / 1000));
|
||||
return `${Math.floor(s / 60)}:${(s % 60).toString().padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
export function fmtTimestamp(unixMs: number): string {
|
||||
if (!unixMs) return "—";
|
||||
return new Date(unixMs).toLocaleString();
|
||||
}
|
||||
|
||||
export function kindLabel(kind: string): string {
|
||||
if (kind === "gamestream") return m.stats_kind_gamestream();
|
||||
if (kind === "native") return m.stats_kind_native();
|
||||
return kind;
|
||||
}
|
||||
|
||||
export const Stat: FC<{ label: string; value: string }> = ({
|
||||
label,
|
||||
value,
|
||||
}) => (
|
||||
<div className="flex flex-col">
|
||||
<dt className="text-xs text-muted-foreground">{label}</dt>
|
||||
<dd className="font-medium">{value}</dd>
|
||||
</div>
|
||||
);
|
||||
|
||||
export const ChartBlock: FC<{
|
||||
title: string;
|
||||
desc?: string;
|
||||
children: ReactNode;
|
||||
}> = ({ title, desc, children }) => (
|
||||
<div className="space-y-2">
|
||||
<div>
|
||||
<h3 className="text-sm font-medium">{title}</h3>
|
||||
{desc && <p className="text-xs text-muted-foreground">{desc}</p>}
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
Reference in New Issue
Block a user