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

42 lines1,437 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

API and MCP server, Rust identity service, registration, site redesign1import { env } from "cloudflare:workers";
2import { data } from "react-router";
3
4import type { Route } from "./+types/profile";
5import { RepoList } from "../components/repo-list";
6import { Avatar } from "../components/ui";
7import { identity } from "../lib/services.server";
8import { getViewer } from "../lib/session.server";
9
10export function meta({ params }: Route.MetaArgs) {
11 return [{ title: `${params.owner} · g1t` }];
12}
13
14export async function loader({ params, context }: Route.LoaderArgs) {
15 const [user, repos] = await Promise.all([
16 identity.userByUsername(params.owner),
17 env.REPOS.list(getViewer(context), { namespace: params.owner }),
18 ]);
19 if (!user) throw data(null, { status: 404 });
20 return { user, repos };
21}
22
23export default function Profile({ loaderData }: Route.ComponentProps) {
24 const { user, repos } = loaderData;
25 return (
26 <main className="mx-auto max-w-4xl px-4 py-10">
27 <div className="flex items-center gap-4">
28 <Avatar name={user.username} size={56} />
29 <div>
30 <h1 className="font-mono text-2xl font-semibold tracking-tight">
31 {user.username}
32 </h1>
33 <p className="text-sm text-muted">
34 {repos.length} {repos.length === 1 ? "repository" : "repositories"}
35 </p>
36 </div>
37 </div>
38 <h2 className="mt-10 text-sm font-medium text-muted">Repositories</h2>
39 <RepoList repos={repos} />
40 </main>
41 );
42}