57 lines
2.2 KiB
TypeScript
57 lines
2.2 KiB
TypeScript
import { Link } from 'react-router-dom'
|
|
import type { Repository } from '../../types/api'
|
|
|
|
interface RepoCardProps {
|
|
repo: Repository
|
|
}
|
|
|
|
export function RepoCard({ repo }: RepoCardProps) {
|
|
const ago = timeAgo(repo.updatedAt)
|
|
|
|
return (
|
|
<Link
|
|
to={`/repos/${repo.ownerId}/${repo.name}`}
|
|
className="flex items-start gap-4 p-4 border border-[#DFE1E6] rounded hover:border-[#4C9AFF] hover:bg-[#FAFBFC] transition-colors group"
|
|
>
|
|
{/* Icon */}
|
|
<div className="flex items-center justify-center w-9 h-9 rounded bg-[#0052CC]/10 text-[#0052CC] shrink-0">
|
|
<svg width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.5" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 9.776c.112-.017.227-.026.344-.026h15.812c.117 0 .232.009.344.026m-16.5 0a2.25 2.25 0 0 0-1.883 2.542l.857 6a2.25 2.25 0 0 0 2.227 1.932H19.05a2.25 2.25 0 0 0 2.227-1.932l.857-6a2.25 2.25 0 0 0-1.883-2.542m-16.5 0V6A2.25 2.25 0 0 1 6 3.75h3.879a1.5 1.5 0 0 1 1.06.44l2.122 2.12a1.5 1.5 0 0 0 1.06.44H18A2.25 2.25 0 0 1 20.25 9v.776" />
|
|
</svg>
|
|
</div>
|
|
|
|
{/* Info */}
|
|
<div className="flex-1 min-w-0">
|
|
<div className="flex items-center gap-2 flex-wrap">
|
|
<span className="text-sm font-semibold text-[#0052CC] group-hover:underline truncate">
|
|
{repo.name}
|
|
</span>
|
|
{repo.isPrivate && (
|
|
<span className="text-[10px] font-medium px-1.5 py-0.5 rounded-full border border-[#DFE1E6] text-[#5E6C84] shrink-0">
|
|
Private
|
|
</span>
|
|
)}
|
|
</div>
|
|
{repo.description && (
|
|
<p className="text-xs text-[#5E6C84] mt-0.5 truncate">{repo.description}</p>
|
|
)}
|
|
<p className="text-xs text-[#5E6C84] mt-1">
|
|
Updated {ago} · {repo.defaultBranch}
|
|
</p>
|
|
</div>
|
|
</Link>
|
|
)
|
|
}
|
|
|
|
function timeAgo(iso: string): string {
|
|
const diff = Date.now() - new Date(iso).getTime()
|
|
const m = Math.floor(diff / 60000)
|
|
if (m < 1) return 'just now'
|
|
if (m < 60) return `${m}m ago`
|
|
const h = Math.floor(m / 60)
|
|
if (h < 24) return `${h}h ago`
|
|
const d = Math.floor(h / 24)
|
|
if (d < 30) return `${d}d ago`
|
|
return new Date(iso).toLocaleDateString()
|
|
}
|