@@ -11,8 +11,6 @@ import { CustomizeCTA } from './components/CustomizeCTA';
1111import { useRecentSearches } from '@/hooks/useRecentSearches' ;
1212import { useDebounce } from '@/hooks/useDebounce' ;
1313import { Footer } from '@/app/components/Footer' ;
14- import InteractiveViewer from '@/components/InteractiveViewer' ;
15- import DOMPurify from 'dompurify' ;
1614
1715const Icons = {
1816 Github : ( ) => (
@@ -72,7 +70,6 @@ const Icons = {
7270export default function LandingPage ( ) {
7371 const [ username , setUsername ] = useState ( '' ) ;
7472 const [ copied , setCopied ] = useState ( false ) ;
75- const [ svgContent , setSvgContent ] = useState < string | null > ( null ) ;
7673 const [ svgState , setSvgState ] = useState < 'idle' | 'loading' | 'loaded' | 'error' > ( 'idle' ) ;
7774 const [ errorMessage , setErrorMessage ] = useState < string | null > ( null ) ;
7875 const guideRef = useRef < HTMLDivElement > ( null ) ;
@@ -92,27 +89,21 @@ export default function LandingPage() {
9289 const siteUrl = process . env . NEXT_PUBLIC_SITE_URL ?? 'https://commitpulse.vercel.app' ;
9390 const markdown = `` ;
9491
95- // Fetch SVG content whenever debounced username changes .
92+ // Probe badge URL for errors; actual rendering uses a native <img> tag .
9693 useEffect ( ( ) => {
9794 if ( ! hasUsername ) {
9895 // eslint-disable-next-line react-hooks/set-state-in-effect
99- setSvgContent ( null ) ;
100-
10196 setSvgState ( 'idle' ) ;
10297 return ;
10398 }
10499
105100 setSvgState ( 'loading' ) ;
106101
107- setSvgContent ( null ) ;
108-
109102 const controller = new AbortController ( ) ;
110103
111104 fetch ( badgeUrl , { signal : controller . signal } )
112105 . then ( async ( res ) => {
113- const text = await res . text ( ) ;
114106 if ( ! res . ok ) {
115- setSvgContent ( null ) ;
116107 setSvgState ( 'error' ) ;
117108 if ( res . status === 404 || res . status === 400 || res . status === 429 ) {
118109 setErrorMessage ( 'GitHub user not found' ) ;
@@ -121,11 +112,6 @@ export default function LandingPage() {
121112 }
122113 return ;
123114 }
124- return text ;
125- } )
126- . then ( ( text ) => {
127- if ( ! text ) return ;
128- setSvgContent ( text ) ;
129115 setSvgState ( 'loaded' ) ;
130116 setErrorMessage ( null ) ;
131117 } )
@@ -357,7 +343,7 @@ export default function LandingPage() {
357343
358344 < div className = "group relative mt-10" >
359345 < div className = "absolute -inset-1 rounded-[2.5rem] bg-gradient-to-r from-emerald-500/20 to-cyan-500/20 opacity-50 blur-2xl transition duration-1000 group-hover:opacity-100" />
360- < InteractiveViewer className = "relative flex min-h-[360px] items-center justify-center overflow-hidden rounded-3xl border border-black/5 bg-white/50 p-8 backdrop-blur-xl shadow-2xl dark:border-white/10 dark:bg-[#0a0a0a]/80" >
346+ < div className = "relative flex min-h-[480px] md:min-h-[520px] items-center justify-center overflow-visible rounded-3xl border border-black/5 bg-white/50 p-8 backdrop-blur-xl shadow-2xl dark:border-white/10 dark:bg-[#0a0a0a]/80" >
361347 { hasUsername ? (
362348 < div className = "w-full flex items-center justify-center" >
363349 { svgState === 'loading' && (
@@ -388,21 +374,21 @@ export default function LandingPage() {
388374 </ p >
389375 </ div >
390376 ) }
391- { svgState === 'loaded' && svgContent && (
377+ { svgState === 'loaded' && (
392378 < motion . div
393379 initial = { { opacity : 0 , scale : 0.95 } }
394380 animate = { { opacity : 1 , scale : 1 } }
395381 transition = { { duration : 0.5 , ease : 'easeOut' } }
396- className = "cp-svg-container w-full max-w-[700px] drop-shadow-[0_30px_60px_rgba(0,0,0,0.15)] dark:drop-shadow-[0_30px_60px_rgba(0,0,0,0.5)] [&>svg]:w-full [&>svg]:h-auto "
397- dangerouslySetInnerHTML = { {
398- __html : DOMPurify . sanitize ( svgContent , {
399- USE_PROFILES : { svg : true , html : true } ,
400- } ) ,
401- } }
402- />
403- ) }
404- { svgState === 'loaded' && ! svgContent && errorMessage && (
405- < p className = "text-red-400 text-sm text-center" > { errorMessage } </ p >
382+ className = "w-full max-w-[700px] drop-shadow-[0_30px_60px_rgba(0,0,0,0.15)] dark:drop-shadow-[0_30px_60px_rgba(0,0,0,0.5)]"
383+ >
384+ { /* eslint-disable-next-line @next/next/no-img-element */ }
385+ < img
386+ data-testid = "badge-img"
387+ src = { badgeUrl }
388+ alt = { `CommitPulse badge for ${ debouncedUsername } ` }
389+ className = "w-full h-auto"
390+ />
391+ </ motion . div >
406392 ) }
407393 </ div >
408394 ) : (
@@ -419,7 +405,7 @@ export default function LandingPage() {
419405 </ p >
420406 </ div >
421407 ) }
422- </ InteractiveViewer >
408+ </ div >
423409 </ div >
424410 </ section >
425411
0 commit comments