1
0
Fork 0
mirror of https://gitbruv.vercel.app/api/git/bruv/gitbruv.git synced 2025-12-20 23:24:09 +01:00
gitbruv/app/(main)/[username]/[repo]/page.tsx
2025-12-20 11:19:18 +00:00

149 lines
5.9 KiB
TypeScript

import { notFound } from "next/navigation";
import { getRepoPageData } from "@/actions/repositories";
import { FileTree } from "@/components/file-tree";
import { CodeViewer } from "@/components/code-viewer";
import { CloneUrl } from "@/components/clone-url";
import { StarButton } from "@/components/star-button";
import { BranchSelector } from "@/components/branch-selector";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Lock, Globe, FileCode, Settings, GitCommit, GitBranch } from "lucide-react";
import Link from "next/link";
import { getPublicServerUrl } from "@/lib/utils";
export default async function RepoPage({ params }: { params: Promise<{ username: string; repo: string }> }) {
const { username, repo: repoName } = await params;
const data = await getRepoPageData(username, repoName);
if (!data) {
notFound();
}
const { repo, files, isEmpty, readmeContent, branches, commitCount, isOwner } = data;
return (
<div className="container px-4 py-6">
<div className="flex flex-col lg:flex-row items-start lg:items-center justify-between gap-4 mb-6">
<div className="flex items-center gap-2 flex-wrap">
<Link href={`/${username}`} className="text-accent hover:underline">
<span className="text-xl font-bold">{username}</span>
</Link>
<span className="text-muted-foreground">/</span>
<div className="text-foreground">
<span className="text-xl font-bold">{repo.name}</span>
</div>
<Badge variant="secondary" className="text-xs font-normal">
{repo.visibility === "private" ? (
<>
<Lock className="h-3 w-3 mr-1" />
Private
</>
) : (
<>
<Globe className="h-3 w-3 mr-1" />
Public
</>
)}
</Badge>
</div>
<div className="flex items-center gap-2">
<StarButton repoId={repo.id} initialStarred={repo.starred} initialCount={repo.starCount} />
<CloneUrl username={username} repoName={repo.name} />
{isOwner && (
<Button variant="outline" size="sm" asChild>
<Link href={`/${username}/${repo.name}/settings`}>
<Settings className="h-4 w-4" />
</Link>
</Button>
)}
</div>
</div>
{repo.description && <p className="text-muted-foreground mb-6">{repo.description}</p>}
<div className="grid lg:grid-cols-4 gap-6">
<div className="lg:col-span-3 space-y-6">
<div className="border border-border rounded-lg overflow-hidden">
<div className="flex items-center justify-between gap-4 px-4 py-3 bg-card border-b border-border">
<BranchSelector branches={branches} currentBranch={repo.defaultBranch} username={username} repoName={repo.name} />
{commitCount > 0 && (
<Link
href={`/${username}/${repo.name}/commits/${repo.defaultBranch}`}
className="flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors"
>
<GitCommit className="h-4 w-4" />
<span className="font-medium">{commitCount}</span>
<span className="hidden sm:inline">commits</span>
</Link>
)}
</div>
{isEmpty ? (
<EmptyRepoGuide username={username} repoName={repo.name} />
) : (
<FileTree files={files} username={username} repoName={repo.name} branch={repo.defaultBranch} />
)}
</div>
{readmeContent && (
<div className="border border-border rounded-lg overflow-hidden">
<div className="flex items-center gap-2 px-4 py-3 bg-card border-b border-border">
<FileCode className="h-4 w-4 text-muted-foreground" />
<span className="text-sm font-medium">README.md</span>
</div>
<div className="p-6">
<CodeViewer content={readmeContent} language="markdown" />
</div>
</div>
)}
</div>
<aside className="space-y-6">
<div className="border border-border rounded-lg p-4">
<h3 className="font-semibold mb-3">About</h3>
<p className="text-sm text-muted-foreground">{repo.description || "No description provided."}</p>
</div>
</aside>
</div>
</div>
);
}
function EmptyRepoGuide({ username, repoName }: { username: string; repoName: string }) {
const cloneUrl = `${getPublicServerUrl()}/api/git/${username}/${repoName}.git`;
return (
<div className="p-6 space-y-6">
<div className="text-center py-8">
<GitBranch className="h-12 w-12 mx-auto mb-4 text-muted-foreground" />
<h3 className="text-lg font-medium mb-2">This repository is empty</h3>
<p className="text-muted-foreground">Get started by cloning or pushing to this repository.</p>
</div>
<div className="space-y-4">
<div>
<h4 className="text-sm font-medium mb-2">Create a new repository on the command line</h4>
<pre className="bg-muted p-4 rounded-lg text-sm overflow-x-auto">
<code>{`echo "# ${repoName}" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin ${cloneUrl}
git push -u origin main`}</code>
</pre>
</div>
<div>
<h4 className="text-sm font-medium mb-2">Push an existing repository from the command line</h4>
<pre className="bg-muted p-4 rounded-lg text-sm overflow-x-auto">
<code>{`git remote add origin ${cloneUrl}
git branch -M main
git push -u origin main`}</code>
</pre>
</div>
</div>
</div>
);
}