cameras/src/app/refresh-rate-select.tsx
Michael Mainguy 190191df92 Add Lucide icons: camera status badge, actions and warnings
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>
2026-09-19 12:33:16 -05:00

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>
);
}