g1t

syntaqx/g1t

public

Git for AI scale: a forge for thousands of agents working on the same code at once.

g1t/apps/web/app/routes/explore.tsx

49 lines1,858 bytes
import { Search } from "lucide-react";
import { Form } from "react-router";

import type { Route } from "./+types/explore";
import { RepoList } from "../components/repo-list";
import { repos } from "../lib/services.server";
import { getViewer } from "../lib/session.server";

export function meta({ loaderData }: Route.MetaArgs) {
  return [
    { title: loaderData?.query ? `${loaderData.query} · Search · g1t` : "Explore · g1t" },
  ];
}

/** Serves both /explore and /search?q=. */
export async function loader({ request, context }: Route.LoaderArgs) {
  const query = new URL(request.url).searchParams.get("q")?.trim() ?? "";
  return { query, repos: await repos.list(getViewer(context), { query }) };
}

export default function Explore({ loaderData }: Route.ComponentProps) {
  const { query, repos } = loaderData;
  return (
    <main className="mx-auto max-w-4xl px-4 py-10">
      <h1 className="text-2xl font-semibold tracking-tight">
        {query ? "Search" : "Explore"}
      </h1>
      <p className="mt-1 text-muted">
        {query
          ? `${repos.length} ${repos.length === 1 ? "repository matches" : "repositories match"} "${query}".`
          : "Public repositories on g1t."}
      </p>
      <Form action="/search" role="search" className="relative mt-6">
        <Search
          size={16}
          className="pointer-events-none absolute top-1/2 left-3.5 -translate-y-1/2 text-faint"
        />
        <input
          name="q"
          defaultValue={query}
          placeholder="Search by name or description"
          aria-label="Search repositories"
          className="w-full rounded-lg border border-line bg-surface py-2.5 pr-4 pl-10 outline-none transition-colors placeholder:text-faint hover:border-line-strong focus:border-accent-dim"
        />
      </Form>
      <RepoList repos={repos} />
    </main>
  );
}