chrysopedia/frontend/src/components/ModeToggle.tsx
jlightner 34733b199d feat: Built complete admin review queue UI: queue list page with stats…
- "frontend/src/pages/ReviewQueue.tsx"
- "frontend/src/pages/MomentDetail.tsx"
- "frontend/src/components/StatusBadge.tsx"
- "frontend/src/components/ModeToggle.tsx"
- "frontend/src/App.tsx"
- "frontend/src/App.css"

GSD-Task: S04/T03
2026-03-29 23:29:01 +00:00

59 lines
1.6 KiB
TypeScript

/**
* Review / Auto mode toggle switch.
*
* Reads and writes mode via getReviewMode / setReviewMode API.
* Green dot = review mode active; amber = auto mode.
*/
import { useEffect, useState } from "react";
import { getReviewMode, setReviewMode } from "../api/client";
export default function ModeToggle() {
const [reviewMode, setReviewModeState] = useState<boolean | null>(null);
const [toggling, setToggling] = useState(false);
useEffect(() => {
let cancelled = false;
getReviewMode()
.then((res) => {
if (!cancelled) setReviewModeState(res.review_mode);
})
.catch(() => {
// silently fail — mode indicator will just stay hidden
});
return () => { cancelled = true; };
}, []);
async function handleToggle() {
if (reviewMode === null || toggling) return;
setToggling(true);
try {
const res = await setReviewMode(!reviewMode);
setReviewModeState(res.review_mode);
} catch {
// swallow — leave previous state
} finally {
setToggling(false);
}
}
if (reviewMode === null) return null;
return (
<div className="mode-toggle">
<span
className={`mode-toggle__dot ${reviewMode ? "mode-toggle__dot--review" : "mode-toggle__dot--auto"}`}
/>
<span className="mode-toggle__label">
{reviewMode ? "Review Mode" : "Auto Mode"}
</span>
<button
type="button"
className={`mode-toggle__switch ${reviewMode ? "mode-toggle__switch--active" : ""}`}
onClick={handleToggle}
disabled={toggling}
aria-label={`Switch to ${reviewMode ? "auto" : "review"} mode`}
/>
</div>
);
}