11'use client'
22
3- import { useEffect , useState } from 'react'
3+ import { useState } from 'react'
44import { copyText , promptCopy } from '@/lib/clipboard'
55
66const MONO = `var(--font-courier), system-ui, sans-serif`
@@ -11,8 +11,6 @@ interface Props {
1111
1212export default function ReadmeBadge ( { username } : Props ) {
1313 const [ copied , setCopied ] = useState ( false )
14- const [ svg , setSvg ] = useState < string | null > ( null )
15- const [ svgError , setSvgError ] = useState ( false )
1614
1715 // Version param forces GitHub's camo proxy to refetch when we redesign the badge.
1816 const BADGE_VERSION = '3'
@@ -21,24 +19,6 @@ export default function ReadmeBadge({ username }: Props) {
2119 const altText = `Commitment Issues — @${ username } 's graveyard`
2220 const markdown = `[](${ profileUrl } )`
2321
24- useEffect ( ( ) => {
25- let cancelled = false
26- setSvg ( null )
27- setSvgError ( false )
28- fetch ( `/api/badge?username=${ encodeURIComponent ( username ) } &v=${ BADGE_VERSION } &frame=0` )
29- . then ( r => {
30- if ( ! r . ok ) throw new Error ( 'badge fetch failed' )
31- return r . text ( )
32- } )
33- . then ( text => {
34- if ( ! cancelled ) setSvg ( text )
35- } )
36- . catch ( ( ) => {
37- if ( ! cancelled ) setSvgError ( true )
38- } )
39- return ( ) => { cancelled = true }
40- } , [ username , BADGE_VERSION ] )
41-
4222 async function handleCopy ( ) {
4323 const ok = await copyText ( markdown )
4424 if ( ! ok ) promptCopy ( markdown , 'Copy this README badge markdown' )
@@ -49,44 +29,15 @@ export default function ReadmeBadge({ username }: Props) {
4929 return (
5030 < div className = "readme-badge-block readme-badge-block--profile record-card" style = { { width : '100%' , marginBottom : '22px' , border : '2px solid #1a1a1a' } } >
5131 { /* Badge preview — the SVG already has its own border; keep the wrapper borderless */ }
52- < div className = "readme-badge-preview" style = { { width : '100%' , aspectRatio : '440 / 96' , display : 'flex' , alignItems : 'center' , justifyContent : 'center' } } >
53- { svg ? (
54- < div
55- aria-label = { altText }
56- role = "img"
57- style = { { width : '100%' , height : '100%' , display : 'block' } }
58- // SVG is generated by our own API route.
59- dangerouslySetInnerHTML = { { __html : svg } }
60- />
61- ) : (
62- < div
63- aria-label = { altText }
64- role = "img"
65- style = { {
66- width : '100%' ,
67- height : '100%' ,
68- background : 'transparent' ,
69- display : 'flex' ,
70- alignItems : 'center' ,
71- justifyContent : 'center' ,
72- padding : '10px' ,
73- textAlign : 'center' ,
74- } }
75- >
76- < span
77- style = { {
78- fontFamily : MONO ,
79- fontSize : '11px' ,
80- fontWeight : 700 ,
81- letterSpacing : '0.12em' ,
82- textTransform : 'uppercase' ,
83- color : svgError ? '#8B0000' : 'var(--c-muted)' ,
84- } }
85- >
86- { svgError ? 'could not load graveyard badge' : 'loading graveyard badge…' }
87- </ span >
88- </ div >
89- ) }
32+ < div className = "readme-badge-preview" style = { { width : '100%' , aspectRatio : '440 / 96' } } >
33+ { /* eslint-disable-next-line @next/next/no-img-element */ }
34+ < img
35+ src = { `/api/badge?username=${ encodeURIComponent ( username ) } &v=${ BADGE_VERSION } &frame=0` }
36+ alt = { altText }
37+ loading = "lazy"
38+ decoding = "async"
39+ style = { { width : '100%' , height : '100%' , display : 'block' } }
40+ />
9041 </ div >
9142
9243 { /* Copy row */ }
0 commit comments