11'use client'
22
3- import React , { useEffect , useRef , useState } from 'react'
3+ import React , { useEffect , useId , useRef , useState } from 'react'
44import Image from 'next/image'
55import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
66import { faCheck , faTimes } from '@fortawesome/free-solid-svg-icons'
@@ -38,7 +38,8 @@ const PortfolioModal: React.FC<PortfolioModalProps> = ({
3838} ) => {
3939 const [ openAccordion , setOpenAccordion ] = useState < number | null > ( null )
4040 const backdropRef = useRef < HTMLDivElement > ( null )
41- const titleId = useRef ( `portfolio-modal-title-${ Math . random ( ) . toString ( 36 ) . slice ( 2 ) } ` )
41+ const generatedId = useId ( )
42+ const titleId = `portfolio-modal-title-${ generatedId } `
4243
4344 useEffect ( ( ) => {
4445 if ( isOpen ) {
@@ -65,24 +66,29 @@ const PortfolioModal: React.FC<PortfolioModalProps> = ({
6566 if ( e . target === backdropRef . current ) onClose ( )
6667 }
6768
68- // Safely render description with an optional inline link
69+ // Safely render description with optional inline links for all occurrences of link.label
6970 const renderDescription = ( ) => {
7071 if ( ! link || ! description . includes ( link . label ) ) {
7172 return description
7273 }
7374 const parts = description . split ( link . label )
7475 return (
7576 < >
76- { parts [ 0 ] }
77- < a
78- href = { link . href }
79- target = "_blank"
80- rel = "noopener noreferrer"
81- className = "text-[#09afdf] hover:underline"
82- >
83- { link . label }
84- </ a >
85- { parts . slice ( 1 ) . join ( link . label ) }
77+ { parts . map ( ( part , i ) => (
78+ < React . Fragment key = { i } >
79+ { part }
80+ { i < parts . length - 1 && (
81+ < a
82+ href = { link . href }
83+ target = "_blank"
84+ rel = "noopener noreferrer"
85+ className = "text-[#09afdf] hover:underline"
86+ >
87+ { link . label }
88+ </ a >
89+ ) }
90+ </ React . Fragment >
91+ ) ) }
8692 </ >
8793 )
8894 }
@@ -92,7 +98,7 @@ const PortfolioModal: React.FC<PortfolioModalProps> = ({
9298 ref = { backdropRef }
9399 role = "dialog"
94100 aria-modal = "true"
95- aria-labelledby = { titleId . current }
101+ aria-labelledby = { titleId }
96102 className = "fixed inset-0 z-50 flex items-center justify-center bg-black/50 animate-fadeIn"
97103 onClick = { handleBackdropClick }
98104 >
@@ -101,7 +107,7 @@ const PortfolioModal: React.FC<PortfolioModalProps> = ({
101107 >
102108 { /* Modal Header */ }
103109 < div className = "flex items-center justify-between px-5 py-3 border-b border-gray-200" >
104- < h4 id = { titleId . current } className = "text-lg font-semibold text-[#333]" > { title } </ h4 >
110+ < h4 id = { titleId } className = "text-lg font-semibold text-[#333]" > { title } </ h4 >
105111 < button
106112 onClick = { onClose }
107113 className = "text-gray-400 hover:text-gray-700 transition-colors text-xl leading-none p-1"
0 commit comments