Refactor registers sidebar

Use shared explorer layout and sidebar for the registers browser.

Signed-off-by: codex@lucy.xalior.com
This commit is contained in:
2026-01-11 13:23:49 +00:00
parent 79d161afe1
commit 2d4b1b2d5b
2 changed files with 40 additions and 27 deletions

View File

@@ -1,10 +1,12 @@
'use client'; "use client";
import { useEffect, useState } from 'react'; import { useEffect, useMemo, useState } from "react";
import { usePathname, useRouter, useSearchParams } from 'next/navigation'; import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { Register, RegisterAccess, Note } from '@/utils/register_parser'; import { Register, RegisterAccess, Note } from "@/utils/register_parser";
import { Form, Container, Row, Table, OverlayTrigger, Tooltip } from 'react-bootstrap'; import { Form, Row, Table, OverlayTrigger, Tooltip } from "react-bootstrap";
import RegisterDetail from "@/app/registers/RegisterDetail"; import RegisterDetail from "@/app/registers/RegisterDetail";
import ExplorerLayout from "@/components/explorer/ExplorerLayout";
import FilterSidebar from "@/components/explorer/FilterSidebar";
interface RegisterBrowserProps { interface RegisterBrowserProps {
registers: Register[]; registers: Register[];
@@ -73,7 +75,7 @@ export function renderAccess(access: RegisterAccess, extraNotes: Note[] = []) {
* @returns A React component that allows users to browse and search registers. * @returns A React component that allows users to browse and search registers.
*/ */
export default function RegisterBrowser({ registers }: RegisterBrowserProps) { export default function RegisterBrowser({ registers }: RegisterBrowserProps) {
const [searchTerm, setSearchTerm] = useState(''); const [searchTerm, setSearchTerm] = useState("");
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const router = useRouter(); const router = useRouter();
const pathname = usePathname(); const pathname = usePathname();
@@ -102,30 +104,42 @@ export default function RegisterBrowser({ registers }: RegisterBrowserProps) {
router.replace(url, { scroll: false }); router.replace(url, { scroll: false });
}; };
const filteredRegisters = registers.filter(register => const filteredRegisters = useMemo(() => (
register.search.includes(searchTerm.toLowerCase()) registers.filter((register) => register.search.includes(searchTerm.toLowerCase()))
); ), [registers, searchTerm]);
return ( return (
<Container fluid> <ExplorerLayout
<Form.Group className="mb-3"> title="NextReg Explorer"
subtitle={`${filteredRegisters.length.toLocaleString()} results`}
chips={searchTerm ? [`q: ${searchTerm}`] : []}
onClearChips={() => {
setSearchTerm("");
updateQueryString("");
}}
sidebar={(
<FilterSidebar>
<Form.Group>
<Form.Label className="form-label small text-secondary">Search</Form.Label>
<Form.Control <Form.Control
type="text" type="text"
placeholder="Search registers..." placeholder="Search registers..."
value={searchTerm} value={searchTerm}
onChange={e => { onChange={(e) => {
const v = e.target.value; const v = e.target.value;
setSearchTerm(v); setSearchTerm(v);
updateQueryString(v); updateQueryString(v);
}} }}
/> />
</Form.Group> </Form.Group>
</FilterSidebar>
)}
>
<Row> <Row>
{filteredRegisters.map(register => ( {filteredRegisters.map((register) => (
<RegisterDetail key={register.hex_address} register={register} /> <RegisterDetail key={register.hex_address} register={register} />
))} ))}
</Row> </Row>
</Container> </ExplorerLayout>
); );
} }

View File

@@ -6,7 +6,6 @@ export default async function RegistersPage() {
return ( return (
<div className="container-fluid py-4"> <div className="container-fluid py-4">
<h1 className="mb-4">NextReg Explorer</h1>
<RegisterBrowser registers={registers} /> <RegisterBrowser registers={registers} />
</div> </div>
); );