@@ -4,7 +4,7 @@ import { useBlogPost } from "@docusaurus/plugin-content-blog/client";
44import BlogPostItemFooterOriginal from "@theme-original/BlogPostItem/Footer" ;
55import type BlogPostItemFooterType from "@theme/BlogPostItem/Footer" ;
66import type { WrapperProps } from "@docusaurus/types" ;
7- import { getAuthorProfile } from "@site/src /utils/authors" ;
7+ import { getAuthorProfile } from "../../.. /utils/authors" ;
88
99import styles from "./styles.module.css" ;
1010
@@ -26,6 +26,29 @@ function getGitHubUrl(author: {
2626 return undefined ;
2727}
2828
29+ function getGitHubHandle ( author : {
30+ key ?: string ;
31+ url ?: string ;
32+ name ?: string ;
33+ } ) : string | undefined {
34+ if ( author . url && / g i t h u b \. c o m \/ / i. test ( author . url ) ) {
35+ const matched = author . url . match ( / g i t h u b \. c o m \/ ( [ ^ / ? # ] + ) / i) ;
36+ if ( matched ?. [ 1 ] ) {
37+ return `@${ matched [ 1 ] } ` ;
38+ }
39+ }
40+
41+ if ( author . key ) {
42+ return `@${ author . key } ` ;
43+ }
44+
45+ if ( author . name ) {
46+ return `@${ author . name . toLowerCase ( ) . replace ( / \s + / g, "" ) } ` ;
47+ }
48+
49+ return undefined ;
50+ }
51+
2952export default function BlogPostItemFooterWrapper ( props : Props ) : JSX . Element {
3053 const { metadata, isBlogPostPage } = useBlogPost ( ) ;
3154 const primaryAuthor = metadata . authors ?. [ 0 ] ;
@@ -46,20 +69,26 @@ export default function BlogPostItemFooterWrapper(props: Props): JSX.Element {
4669
4770 const roundedReadTime = Math . max ( 1 , Math . ceil ( metadata . readingTime || 0 ) ) ;
4871 const readTimeText = `${ roundedReadTime } min read` ;
72+ const authorHandle = primaryAuthor
73+ ? getGitHubHandle ( {
74+ key : primaryAuthor . key ,
75+ name : primaryAuthor . name ,
76+ url : primaryAuthor . url ,
77+ } )
78+ : undefined ;
4979 const authorSummary =
5080 primaryAuthor ?. description ||
5181 profile ?. description ||
5282 primaryAuthor ?. title ||
5383 profile ?. title ;
5484 const blogDate =
55- metadata . formattedDate ||
56- ( metadata . date
57- ? new Date ( metadata . date ) . toLocaleDateString ( "en-US" , {
58- year : "numeric" ,
59- month : "short" ,
60- day : "numeric" ,
61- } )
62- : "" ) ;
85+ metadata . date &&
86+ new Date ( metadata . date ) . toLocaleDateString ( "en-US" , {
87+ year : "numeric" ,
88+ month : "short" ,
89+ day : "numeric" ,
90+ } ) ;
91+ const metaItems = [ authorHandle , blogDate , readTimeText ] . filter ( Boolean ) . join ( " • " ) ;
6392
6493 const showAuthorCard = Boolean ( isBlogPostPage && primaryAuthor && authorName ) ;
6594
@@ -68,7 +97,8 @@ export default function BlogPostItemFooterWrapper(props: Props): JSX.Element {
6897 < BlogPostItemFooterOriginal { ...props } />
6998 { showAuthorCard && (
7099 < section className = { styles . authorCard } aria-label = "Post author details" >
71- < div className = { styles . authorLeft } >
100+ < div className = { styles . authorBody } >
101+ < div className = { styles . authorAvatarWrapper } >
72102 { authorAvatar ? (
73103 < img
74104 className = { styles . authorAvatar }
@@ -81,28 +111,39 @@ export default function BlogPostItemFooterWrapper(props: Props): JSX.Element {
81111 { authorName ?. charAt ( 0 ) . toUpperCase ( ) }
82112 </ div >
83113 ) }
114+ < span className = { styles . verifiedBadge } aria-hidden = "true" >
115+ ✓
116+ </ span >
117+ </ div >
84118 < div className = { styles . authorIdentity } >
85- < p className = { styles . authorName } > { authorName } </ p >
86- { blogDate ? < p className = { styles . authorDate } > { blogDate } </ p > : null }
119+ < div className = { styles . authorNameRow } >
120+ < p className = { styles . authorName } > { authorName } </ p >
121+ < span className = { styles . authorBadge } > Author</ span >
122+ </ div >
123+ { metaItems ? < p className = { styles . authorMeta } > { metaItems } </ p > : null }
87124 { authorSummary ? (
88125 < p className = { styles . authorSummary } > { authorSummary } </ p >
89126 ) : null }
127+ { githubUrl ? (
128+ < Link
129+ className = { styles . githubButton }
130+ to = { githubUrl }
131+ target = "_blank"
132+ rel = "noopener noreferrer"
133+ >
134+ < span className = { styles . githubIcon } aria-hidden = "true" >
135+ < svg viewBox = "0 0 16 16" width = "14" height = "14" focusable = "false" >
136+ < path
137+ fill = "currentColor"
138+ d = "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.5-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82A7.5 7.5 0 0 1 8 3.8c.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8Z"
139+ />
140+ </ svg >
141+ </ span >
142+ GitHub
143+ </ Link >
144+ ) : null }
90145 </ div >
91146 </ div >
92-
93- < div className = { styles . authorRight } >
94- < p className = { styles . readTime } > { readTimeText } </ p >
95- { githubUrl ? (
96- < Link
97- className = { styles . githubButton }
98- to = { githubUrl }
99- target = "_blank"
100- rel = "noopener noreferrer"
101- >
102- GitHub Profile
103- </ Link >
104- ) : null }
105- </ div >
106147 </ section >
107148 ) }
108149 </ >
0 commit comments