1- import { Link } from "react-router-dom" ;
1+ import React , { useState } from "react" ;
2+ import { Link } from "react-router-dom" ;
23import "../../styles/components/activities/ActivityCard.css"
34
4- export const ActivityCard = ( { activity} ) => {
5+ export const ActivityCard = ( { activity } ) => {
6+ const [ imageLoaded , setImageLoaded ] = useState ( false ) ;
7+ const [ imageError , setImageError ] = useState ( false ) ;
8+
9+ const handleImageLoad = ( ) => {
10+ setImageLoaded ( true ) ;
11+ } ;
12+
13+ const handleImageError = ( ) => {
14+ setImageError ( true ) ;
15+ setImageLoaded ( true ) ;
16+ } ;
17+
18+ // Default icon for activities without an image
19+ const defaultIcon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODAiIGhlaWdodD0iODAiIHZpZXdCb3g9IjAgMCA4MCA4MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjgwIiBoZWlnaHQ9IjgwIiByeD0iMTIiIGZpbGw9IiNlMmU4ZjAiLz4KPHN2ZyB4PSIyNCIgeT0iMjQiIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM2Mzc0OGIiIHN0cm9rZS13aWR0aD0iMiI+CjxwYXRoIGQ9Im0xMiAzLTEuOTEyIDUuODEzYTIgMiAwIDAgMS0xLjI3NSAxLjI3NUwzIDEybDUuODEzIDEuOTEyYTIgMiAwIDAgMSAxLjI3NSAxLjI3NUwxMiAyMWwxLjkxMi01LjgxM2EyIDIgMCAwIDEgMS4yNzUtMS4yNzVMMjEgMTJsLTUuODEzLTEuOTEyYTIgMiAwIDAgMS0xLjI3NS0xLjI3NUwxMiAzeiIvPgo8L3N2Zz4KPC9zdmc+" ;
20+
521 return (
6- < Link className = "activity-card-root" to = { `/activities/${ activity . urlTerm } ` } >
7- < img src = { activity . icon } alt = { activity . title } />
8- < h1 className = "activity-card-title" > { activity . title } </ h1 >
9- < div className = "activity-card-desc" > { activity . description } </ div >
22+ < Link
23+ className = "activity-card-root"
24+ to = { `/activities/${ activity . urlTerm } ` }
25+ role = "button"
26+ tabIndex = { 0 }
27+ aria-label = { `Navigate to ${ activity . title } activity: ${ activity . description } ` }
28+ >
29+ < div className = "activity-card-image-container" >
30+ { ! imageLoaded && ! imageError && (
31+ < div className = "image-placeholder" >
32+ < div className = "loading-spinner" > </ div >
33+ </ div >
34+ ) }
35+ < img
36+ src = { imageError ? defaultIcon : activity . icon }
37+ alt = { `${ activity . title } icon` }
38+ onLoad = { handleImageLoad }
39+ onError = { handleImageError }
40+ style = { {
41+ opacity : imageLoaded ? 1 : 0 ,
42+ transition : 'opacity 0.3s ease'
43+ } }
44+ />
45+ </ div >
46+ < h2 className = "activity-card-title" > { activity . title } </ h2 >
47+ < p className = "activity-card-desc" > { activity . description } </ p >
1048 </ Link >
1149 )
12- }
50+ }
0 commit comments