Intelligence

Artifacts

Browse the repository, read documents, and manage the governance folders. Source, runtime, and infrastructure are read-only.

Repository
.gitignoreDockerfilenext-env.d.tsnext.config.mjspackage-lock.jsonpackage.jsonpostcss.config.mjsREADME.mdtailwind.config.tstsconfig.jsontsconfig.tsbuildinfo
README.md
CONSTITUTION_COMPLIANCE_AUDIT_V1.mdREADME.md
repositories/aaf-holdings/hq01/components/reports/report-search.tsx
2.3 KB
"use client";

import { useMemo, useState } from "react";
import { Search, FileText } from "lucide-react";
import { Input } from "@/components/ui/input";
import { RecordRow, RecordList } from "@/components/shared/record-row";
import { EmptyState } from "@/components/shared/empty-state";

export interface ReportListItem {
  id: string;
  title: string;
  summary: string;
  date: string | null;
  author: string | null;
}

export function ReportSearch({ reports }: { reports: ReportListItem[] }) {
  const [query, setQuery] = useState("");

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return reports;
    return reports.filter((r) =>
      [r.title, r.summary, r.id, r.author ?? ""]
        .join(" ")
        .toLowerCase()
        .includes(q),
    );
  }, [query, reports]);

  return (
    <div>
      <div className="relative mb-5">
        <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
        <Input
          type="search"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="Search reports by title, author, or content…"
          className="pl-9"
        />
      </div>

      {filtered.length === 0 ? (
        query ? (
          <EmptyState
            icon={Search}
            title="No matching reports"
            description={`Nothing matched “${query}”. Try a different term.`}
          />
        ) : (
          <EmptyState
            icon={FileText}
            title="No reports yet"
            description="Reports are markdown files under a reports/ folder. They preserve outcomes and reflection after work terminates."
            hint="src/reports/RP-XXXX.md"
          />
        )
      ) : (
        <RecordList>
          {filtered.map((r) => (
            <RecordRow
              key={r.id}
              href={`/reports/${r.id}`}
              title={r.title}
              description={r.summary}
              meta={
                r.date ? (
                  <span className="text-xs tabular-nums text-muted-foreground">
                    {r.date}
                  </span>
                ) : undefined
              }
            />
          ))}
        </RecordList>
      )}
    </div>
  );
}

root · /srv/aaf