chrysopedia/frontend/src/components/AdminDropdown.tsx
jlightner 17b43d9778 feat: Added LightRAG /query/data as primary search engine with file_sou…
- "backend/config.py"
- "backend/search_service.py"

GSD-Task: S01/T01
2026-04-04 04:44:24 +00:00

125 lines
3.3 KiB
TypeScript

import { useCallback, useEffect, useRef, useState } from "react";
import { Link } from "react-router-dom";
const DESKTOP_MQ = "(min-width: 769px)";
const LEAVE_DELAY_MS = 150;
export default function AdminDropdown() {
const [open, setOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
const isDesktopRef = useRef(false);
const leaveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
// Track desktop breakpoint via matchMedia
useEffect(() => {
const mql = window.matchMedia(DESKTOP_MQ);
isDesktopRef.current = mql.matches;
const onChange = (e: MediaQueryListEvent) => {
isDesktopRef.current = e.matches;
};
mql.addEventListener("change", onChange);
return () => mql.removeEventListener("change", onChange);
}, []);
// Clear leave timer on unmount
useEffect(() => {
return () => {
if (leaveTimerRef.current) clearTimeout(leaveTimerRef.current);
};
}, []);
const handleMouseEnter = useCallback(() => {
if (leaveTimerRef.current) {
clearTimeout(leaveTimerRef.current);
leaveTimerRef.current = null;
}
if (isDesktopRef.current) setOpen(true);
}, []);
const handleMouseLeave = useCallback(() => {
if (!isDesktopRef.current) return;
leaveTimerRef.current = setTimeout(() => {
setOpen(false);
leaveTimerRef.current = null;
}, LEAVE_DELAY_MS);
}, []);
// Close on outside click
useEffect(() => {
function handler(e: MouseEvent) {
if (
dropdownRef.current &&
!dropdownRef.current.contains(e.target as Node)
) {
setOpen(false);
}
}
document.addEventListener("mousedown", handler);
return () => document.removeEventListener("mousedown", handler);
}, []);
// Close on Escape
useEffect(() => {
function handler(e: KeyboardEvent) {
if (e.key === "Escape") setOpen(false);
}
if (open) {
document.addEventListener("keydown", handler);
return () => document.removeEventListener("keydown", handler);
}
}, [open]);
return (
<div
className="admin-dropdown"
ref={dropdownRef}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<button
className="admin-dropdown__trigger"
onClick={() => setOpen((prev) => !prev)}
aria-expanded={open}
aria-haspopup="true"
>
Admin
</button>
{open && (
<div className="admin-dropdown__menu" role="menu">
<Link
to="/admin/reports"
className="admin-dropdown__item"
role="menuitem"
onClick={() => setOpen(false)}
>
Reports
</Link>
<Link
to="/admin/pipeline"
className="admin-dropdown__item"
role="menuitem"
onClick={() => setOpen(false)}
>
Pipeline
</Link>
<Link
to="/admin/techniques"
className="admin-dropdown__item"
role="menuitem"
onClick={() => setOpen(false)}
>
Techniques
</Link>
<Link
to="/admin/users"
className="admin-dropdown__item"
role="menuitem"
onClick={() => setOpen(false)}
>
Users
</Link>
</div>
)}
</div>
);
}