48 lines · 1.7 KB
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { z } from "zod";
import { searchCode } from "~/fns/code";
import { CodeSearchResults } from "~/components/CodeSearchResults";
import { Panel } from "~/ui/Panel";
import { CodeSearchForm } from "~/components/CodeSearchForm";

export const Route = createFileRoute("/$owner/$repo/search")({
  validateSearch: z.object({ q: z.string().optional() }),
  loaderDeps: ({ search }) => ({ q: search.q?.trim() ?? "" }),
  loader: async ({ params, deps }) => ({
    q: deps.q,
    ...(await searchCode({ data: { q: deps.q, owner: params.owner, repo: params.repo } })),
  }),
  component: RepoSearchPage,
});

function RepoSearchPage() {
  const data = Route.useLoaderData();
  const navigate = useNavigate({ from: Route.fullPath });
  const status = data.status;
  return (
    <div className="space-y-4">
      <CodeSearchForm initial={data.q} onSearch={(q) => navigate({ search: { q } })} />
      <Panel
        title={data.q ? `Code results for “${data.q}”` : "Search code on the default branch"}
        actions={
          <span className="text-xs text-gray-500">
            {status
              ? `${status.fileCount} files indexed at ${status.commitSha.slice(0, 7)}${status.truncated ? " (partial)" : ""}${data.indexing ? " — updating…" : ""}`
              : data.indexing
                ? "Indexing the default branch — results will appear shortly"
                : "Not indexed yet"}
          </span>
        }
      >
        <CodeSearchResults
          hits={data.hits}
          showRepo={false}
          empty={