import { useSuspenseQuery } from "@tanstack/react-query";
import { createFileRoute, Link } from "@tanstack/react-router";
import { GitBranchIcon, LockIcon } from "lucide-react";
import { getReposByOwnerOpts } from "@/api/repos";
import { NotFoundComponent } from "@/components/404-components";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Card,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
export const Route = createFileRoute("/_layout/$owner")({
component: RouteComponent,
notFoundComponent: NotFoundComponent,
loader: async ({ params, context: { queryClient } }) => {
await queryClient.ensureQueryData(
getReposByOwnerOpts({ owner: params.owner })
);
},
});
function RouteComponent() {
const { owner } = Route.useParams();
const { data: repositories } = useSuspenseQuery(
getReposByOwnerOpts({ owner })
);
return (
<div className="py-8">
<div className="grid gap-8 md:grid-cols-4">
<div className="col-span-1">
<Avatar className="mb-4 size-48 rounded-full">
<AvatarImage
alt={`@${owner}`}
src={`https://api.dicebear.com/9.x/notionists/svg?seed=${owner}&scale=150&backgroundType=solid,gradientLinear&backgroundColor=b6e3f4,c0aede,d1d4f9,ffd5dc,ffdfbf`}
/>
<AvatarFallback>
{owner
.split(" ")
.map((w) => w.at(0))
.join("")}
</AvatarFallback>
</Avatar>
<div>
<h2 className="font-bold text-2xl">{owner}</h2>
<p className="text-muted-foreground">{owner}</p>
</div>
</div>
<div className="col-span-3">
<h2 className="mb-4 font-semibold text-xl">Repositories</h2>
<div className="grid gap-4 md:grid-cols-2">
{repositories.length === 0 ? (
<p className="text-muted-foreground">No repositories found</p>
) : (
repositories.map((repo) => (
<Link
className="h-full"
key={repo.id}
params={{ owner: repo.owner, repo: repo.name }}
to="/$owner/$repo"
>
<Card className="h-full transition-colors hover:bg-accent">
<CardHeader>
<div className="flex items-start justify-between">
<div className="flex items-center gap-2">
<GitBranchIcon className="size-4 text-muted-foreground" />
<CardTitle>{repo.name}</CardTitle>
</div>
{repo.isPrivate && (
<LockIcon className="size-4 text-muted-foreground" />
)}
</div>
{repo.description && (
<CardDescription className="line-clamp-2 text-sm">
{repo.description}
</CardDescription>
)}
</CardHeader>
</Card>
</Link>
))
)}
</div>
</div>
</div>
</div>
);
}