Adds lucide-react (vrek dec-1vnz5fw, chosen over Heroicons and React Icons) for the icons goal gol-m8je1wc. - Camera status badge on each card (iss-scj42jq): Live, Connecting, Needs login, Not activated, Offline, Session ended. Each is an icon plus a visible label, derived from existing query state with no extra device calls. Logic in src/app/camera-status.tsx. - Action icons (iss-chrdd0v): scan (radar, then spinner), refresh rate, change or forget login, retry, the camera web page link (replaces ↗), save, sign in and sign out. - Warning and error icons (iss-egy082x): unsecured banner, setup panel, inline errors, session-ended notice, login and setup headings. Icons are decorative (aria-hidden), spinners respect reduced motion, and every accessible name is unchanged (all 403 prior tests pass untouched). 416 tests, 99.9% line coverage. The vitest threshold comment now points to principle pri-be2smzk. Refreshes the vrek export. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
30 lines
940 B
TypeScript
30 lines
940 B
TypeScript
"use client";
|
|
|
|
import { Timer } from "lucide-react";
|
|
import { usePathname, useRouter } from "next/navigation";
|
|
import { REFRESH_OPTIONS_MS } from "./refresh-rate";
|
|
|
|
/** Keeps the refresh rate in the URL so the server-rendered grid can read it. */
|
|
export default function RefreshRateSelect({ value }: { value: number }) {
|
|
const router = useRouter();
|
|
const pathname = usePathname();
|
|
|
|
return (
|
|
<label className="flex items-center gap-2 text-sm">
|
|
<Timer aria-hidden className="size-4" />
|
|
Snapshot refresh
|
|
<select
|
|
value={value}
|
|
onChange={(e) => router.replace(`${pathname}?refresh=${e.target.value}`, { scroll: false })}
|
|
className="rounded border border-zinc-300 bg-transparent px-2 py-1 dark:border-zinc-700"
|
|
>
|
|
{REFRESH_OPTIONS_MS.map((ms) => (
|
|
<option key={ms} value={ms}>
|
|
{ms / 1000} s
|
|
</option>
|
|
))}
|
|
</select>
|
|
</label>
|
|
);
|
|
}
|