From 6a663a5d821bddde5f6b9e43aac0ab1c5dee571b Mon Sep 17 00:00:00 2001 From: Michael Mainguy Date: Sun, 20 Sep 2026 07:27:00 -0500 Subject: [PATCH] Put the camera login where the picture would be A camera that can't log in has no picture to show, so the form stands in for the snapshot instead of appearing under it, with the status badge above it so the card still says what is wrong. Saving brings the picture back. Co-Authored-By: Claude Opus 5 (1M context) --- src/app/camera-card.test.tsx | 14 +++++++++++ src/app/camera-card.tsx | 45 +++++++++++++++++++++--------------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/app/camera-card.test.tsx b/src/app/camera-card.test.tsx index 23a46c3..e24896d 100644 --- a/src/app/camera-card.test.tsx +++ b/src/app/camera-card.test.tsx @@ -258,6 +258,20 @@ describe("CameraCard", () => { expect(JSON.parse(String(init?.body))).toEqual({ username: "saved-user", password: "pw" }); }); + it("stands in for the picture, rather than appearing below it", async () => { + stubFetch({ + [`GET ${base}/info`]: () => json({ error: "Wrong login", code: "auth" }, 401), + [`GET ${base}/credentials`]: () => json(noLogin), + }); + const { container } = renderWithQuery(); + + expect(await screen.findByText("Camera login")).toBeTruthy(); + expect(screen.queryByRole("img", { name: "Porch" })).toBeNull(); + expect(screen.queryByRole("link", { name: "Pop out Porch" })).toBeNull(); + // The status still says what is wrong, where the picture would have been. + expect(container.querySelector("[data-status='auth']")).toBeTruthy(); + }); + it("keeps a username the user typed over the saved one", async () => { stubFetch({ [`GET ${base}/info`]: () => json({ error: "Wrong login", code: "auth" }, 401), diff --git a/src/app/camera-card.tsx b/src/app/camera-card.tsx index e26293c..5420956 100644 --- a/src/app/camera-card.tsx +++ b/src/app/camera-card.tsx @@ -169,17 +169,35 @@ export default function CameraCard({ const showSetup = problem?.kind === "inactive"; const showLogin = !showSetup && (problem?.kind === "auth" || editingLogin); + const status = cameraStatus({ + problem: problem?.kind ?? null, + hasFrame: snapshot.data !== undefined, + }); + return (
  • - + {/* A camera that can't log in has no picture to show, so the form takes its place. */} + {showLogin ? ( +
    + + setEditingLogin(false)} + onCancel={problem?.kind === "auth" ? undefined : () => setEditingLogin(false)} + /> +
    + ) : ( + + )}
    @@ -189,15 +207,6 @@ export default function CameraCard({ {showSetup && } - {showLogin && ( - setEditingLogin(false)} - onCancel={problem?.kind === "auth" ? undefined : () => setEditingLogin(false)} - /> - )} - {problem?.kind === "signed-out" && (