44 lines · 1.5 KB
import { createFileRoute, Link } from "@tanstack/react-router";
import { z } from "zod";
import { exploreRepos } from "~/fns/repos";
import { RepoList } from "~/components/RepoList";
import { PageContainer } from "~/ui/PageContainer";
import { Panel } from "~/ui/Panel";
import { buttonClass } from "~/ui/Button";
import { Heading } from "~/ui/Heading";

export const Route = createFileRoute("/explore")({
  validateSearch: z.object({ q: z.string().optional(), page: z.number().int().min(1).optional() }),
  loaderDeps: ({ search }) => search,
  loader: ({ deps }) => exploreRepos({ data: { q: deps.q, page: deps.page ?? 1 } }),
  component: ExplorePage,
});

function ExplorePage() {
  const { repos, hasMore } = Route.useLoaderData();
  const search = Route.useSearch();
  const page = search.page ?? 1;
  return (
    <PageContainer className="space-y-4">
      <Heading size="xl">Explore</Heading>
      <Panel title={search.q ? `Repositories matching “${search.q}”` : "Recently updated repositories"}>
        <RepoList repos={repos} empty="No repositories found." />
      </Panel>
      <div className="flex justify-between">
        {page > 1 ? (
          <Link to="/explore" search={{ ...search, page: page - 1 }} className={buttonClass("secondary", "sm")}>
            Previous
          </Link>
        ) : (
          <span />
        )}
        {hasMore && (
          <Link to="/explore" search={{ ...search, page: page + 1 }} className={buttonClass("secondary", "sm")}>
            Next
          </Link>
        )}
      </div>