import { useParams } from "react-router"; import { NavLink, Outlet } from "react-router"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { client } from "@/client"; import { Lock, Globe, Archive, GitFork, Star, Eye, EyeOff } from "lucide-react"; import { cn } from "@/lib/utils"; function formatSize(bytes: number) { if (bytes === 0) return "Empty"; if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; } function formatDate(date: string) { const now = new Date(); const d = new Date(date); const diff = now.getTime() - d.getTime(); const days = Math.floor(diff / 86400000); if (days < 1) return "today"; if (days === 1) return "1 day ago"; if (days < 30) return `${days} days ago`; if (days < 365) return `${Math.floor(days / 30)}mo ago`; return `${Math.floor(days / 365)}y ago`; } const tabs = [ { label: "Code", to: "code" }, { label: "Commits", to: "commits" }, { label: "Branches", to: "branches" }, { label: "Tags", to: "tags" }, { label: "Pull Requests", to: "pulls" }, { label: "Contributors", to: "contributors" }, { label: "Webhooks", to: "webhooks" }, { label: "Settings", to: "settings" }, ]; export default function RepoLayout() { const { projectName = "", repoName = "" } = useParams(); const qc = useQueryClient(); const { data: repo, isLoading } = useQuery({ queryKey: ["repo", projectName, repoName], queryFn: async () => { const res = await client.gitGetRepo(projectName, repoName); return res.data; }, enabled: Boolean(projectName) && Boolean(repoName), retry: false, }); const { data: starData } = useQuery({ queryKey: ["repo", projectName, repoName, "star"], queryFn: async () => { const res: any = await client.gitStarStatus(projectName, repoName); return res.data as { starred: boolean; count: number }; }, enabled: Boolean(projectName) && Boolean(repoName), retry: false, }); const starRepo = useMutation({ mutationFn: async () => { if (starData?.starred) { await client.gitUnstarRepo(projectName, repoName); } else { await client.gitStarRepo(projectName, repoName); } }, onSuccess: () => qc.invalidateQueries({ queryKey: ["repo", projectName, repoName, "star"] }), }); const { data: watchData } = useQuery({ queryKey: ["repo", projectName, repoName, "watch"], queryFn: async () => { const res: any = await client.gitWatchStatus(projectName, repoName); return res.data as { watching: boolean; count: number }; }, enabled: Boolean(projectName) && Boolean(repoName), retry: false, }); const watchRepo = useMutation({ mutationFn: async () => { if (watchData?.watching) { await client.gitUnwatchRepo(projectName, repoName); } else { await client.gitWatchRepo(projectName, repoName, {} as any); } }, onSuccess: () => qc.invalidateQueries({ queryKey: ["repo", projectName, repoName, "watch"] }), }); // Check if README exists const { data: readme } = useQuery({ queryKey: ["repo", projectName, repoName, "readme"], queryFn: async () => { const res = await client.gitGetReadme(projectName, repoName); return res.data; }, enabled: Boolean(projectName) && Boolean(repoName), retry: false, }); const allTabs = [ ...(readme?.html ? [{ label: "README", to: "readme" }] : []), ...tabs, ]; if (isLoading) { return (
); } if (!repo) { return (

Repository not found

This repository doesn't exist or you don't have permission to view it.

); } return (
{/* Header */}

{repo.name}

{repo.visibility === "private" ? ( Private ) : ( Public )} {repo.is_archived && ( Archived )} {repo.is_mirror && ( Mirror )} {repo.is_template && ( Template )}
{repo.description && (

{repo.description}

)}
default branch: {repo.default_branch} | {formatSize(repo.size_bytes)} | created {formatDate(repo.created_at)}
{/* Tab nav */} {/* Content */}
); }