phase 3 initial completion

This commit is contained in:
2026-05-07 00:22:45 +02:00
parent 5d8662595c
commit ce2aa2c776
19 changed files with 1216 additions and 37 deletions
+109
View File
@@ -0,0 +1,109 @@
import { useState } from 'react'
import { useParams, Link } from 'react-router-dom'
import { usePR } from '../api/queries/prs'
import { DiffViewer } from '../components/diff/DiffViewer'
import { MobileComment } from '../components/diff/MobileComment'
import { Skeleton } from '../ui/Skeleton'
import { cn } from '../lib/utils'
export default function PRDetailPage() {
const { owner = '', repo = '', prId = '' } = useParams<{ owner: string; repo: string; prId: string }>()
const { data: pr, isLoading, isError } = usePR(owner, repo, parseInt(prId, 10))
const [comment, setComment] = useState<{ file: string; line: number } | null>(null)
if (isLoading) {
return (
<div className="max-w-5xl mx-auto px-4 py-6 space-y-4">
<Skeleton className="h-6 w-64" />
<Skeleton className="h-4 w-48" />
<Skeleton className="h-40 w-full" />
</div>
)
}
if (isError || !pr) {
return <div className="p-6 text-sm text-[#DE350B]">Pull request not found.</div>
}
const statusColor = pr.status === 'open'
? 'bg-[#E3FCEF] text-[#006644] border-[#79F2C0]'
: pr.status === 'merged'
? 'bg-[#EAE6FF] text-[#403294] border-[#C0B6F2]'
: 'bg-[#F4F5F7] text-[#5E6C84] border-[#DFE1E6]'
return (
<div className="max-w-5xl mx-auto px-4 md:px-6 py-6 space-y-6">
{/* Breadcrumb */}
<div className="flex items-center gap-1 text-sm flex-wrap">
<Link to={`/repos/${owner}/${repo}`} className="text-[#0052CC] hover:underline">{repo}</Link>
<span className="text-[#5E6C84]">/</span>
<Link to={`/repos/${owner}/${repo}/pulls`} className="text-[#0052CC] hover:underline">Pull requests</Link>
<span className="text-[#5E6C84]">/</span>
<span className="text-[#172B4D]">#{pr.id}</span>
</div>
{/* Title + status */}
<div>
<div className="flex items-center gap-3 flex-wrap">
<h1 className="text-xl font-semibold text-[#172B4D]">{pr.title}</h1>
<span className={cn('text-xs font-semibold px-2 py-0.5 rounded-full border', statusColor)}>
{pr.status}
</span>
</div>
<p className="text-xs text-[#5E6C84] mt-1">
#{pr.id} · <span className="font-mono">{pr.sourceBranch}</span>
{' → '}
<span className="font-mono">{pr.targetBranch}</span>
</p>
</div>
{/* Body */}
{pr.body && (
<div className="p-4 border border-[#DFE1E6] rounded text-sm text-[#172B4D] whitespace-pre-wrap">
{pr.body}
</div>
)}
{/* Diff placeholder */}
<div>
<h2 className="text-sm font-semibold text-[#172B4D] mb-3 flex items-center gap-2">
<svg width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.5" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
</svg>
Files changed
</h2>
{/* Demo diff — real diff loads when repo has commits on both branches */}
<DiffViewer files={DEMO_DIFF} />
</div>
{/* Mobile comment sheet */}
<MobileComment
open={!!comment}
onClose={() => setComment(null)}
filePath={comment?.file ?? ''}
lineNumber={comment?.line ?? 0}
/>
</div>
)
}
// Demo diff to show the component before real git data is available
const DEMO_DIFF = [
{
path: 'README.md',
additions: 6,
deletions: 1,
patch: `@@ -1,3 +1,8 @@
-# Project
+# My Project
+
+A sovereign, federated git collaboration platform.
+
+## Features
+- Fast Go backend
+- React 18 frontend
+- ActivityPub federation
`,
},
]