11import Image from "next/image" ;
22import Link from "next/link" ;
3+ import type { DocContributorsRecord } from "@/lib/contributors" ;
34
4- interface Contributor {
5- login : string ;
6- avatar_url : string ;
7- html_url : string ;
5+ interface ContributorsProps {
6+ entry : DocContributorsRecord | null ;
87}
98
10- export function Contributors ( {
11- contributors,
12- } : {
13- contributors : Contributor [ ] ;
14- } ) {
9+ function formatLastContributedAt ( value : string | null ) {
10+ if ( ! value ) return null ;
11+ const date = new Date ( value ) ;
12+ if ( Number . isNaN ( date . getTime ( ) ) ) return null ;
13+ return new Intl . DateTimeFormat ( "zh-CN" , {
14+ year : "numeric" ,
15+ month : "2-digit" ,
16+ day : "2-digit" ,
17+ } ) . format ( date ) ;
18+ }
19+
20+ export function Contributors ( { entry } : ContributorsProps ) {
21+ const contributors = entry ?. contributors ?? [ ] ;
22+
1523 if ( contributors . length === 0 ) {
1624 return null ;
1725 }
@@ -21,25 +29,54 @@ export function Contributors({
2129 < hr className = "border-border/70 !mt-10 !mb-5" />
2230 < h2 id = "contributors-heading" > 贡献者</ h2 >
2331 < ul className = "mt-0 mb-0 flex flex-wrap items-center gap-x-6 gap-y-4 list-none p-0" >
24- { contributors . map ( ( contributor ) => (
25- < li key = { contributor . login } >
26- < Link
27- href = { contributor . html_url }
28- target = "_blank"
29- rel = "noopener noreferrer"
30- className = "inline-flex items-center gap-3 text-base font-medium text-primary transition-colors hover:text-primary/80 no-underline"
31- >
32+ { contributors . map ( ( contributor ) => {
33+ const displayName = contributor . login ?? `#${ contributor . githubId } ` ;
34+ const href = contributor . htmlUrl ?? undefined ;
35+ const avatarSrc =
36+ contributor . avatarUrl ??
37+ `https://avatars.githubusercontent.com/u/${ contributor . githubId } ` ;
38+ const lastDate = formatLastContributedAt (
39+ contributor . lastContributedAt ,
40+ ) ;
41+
42+ const content = (
43+ < >
3244 < Image
33- src = { contributor . avatar_url }
34- alt = { contributor . login }
45+ src = { avatarSrc }
46+ alt = { displayName }
3547 width = { 35 }
3648 height = { 35 }
3749 className = "!m-0 h-10 w-10 rounded-full border border-border/50 object-cover shadow-sm"
3850 />
39- < span > { contributor . login } </ span >
40- </ Link >
41- </ li >
42- ) ) }
51+ < span className = "flex flex-col text-left leading-tight" >
52+ < span className = "font-medium" > { displayName } </ span >
53+ < span className = "text-sm text-muted-foreground" >
54+ 贡献 { contributor . contributions } 次
55+ { lastDate ? ` · 最近 ${ lastDate } ` : "" }
56+ </ span >
57+ </ span >
58+ </ >
59+ ) ;
60+
61+ return (
62+ < li key = { contributor . githubId } >
63+ { href ? (
64+ < Link
65+ href = { href }
66+ target = "_blank"
67+ rel = "noopener noreferrer"
68+ className = "inline-flex items-center gap-3 text-base text-primary transition-colors hover:text-primary/80 no-underline"
69+ >
70+ { content }
71+ </ Link >
72+ ) : (
73+ < div className = "inline-flex items-center gap-3 text-base" >
74+ { content }
75+ </ div >
76+ ) }
77+ </ li >
78+ ) ;
79+ } ) }
4380 </ ul >
4481 < hr className = "!mb-0 !mt-5 border-border/70" />
4582 </ section >
0 commit comments