@@ -5,13 +5,14 @@ import "./AssetDetail.css";
5
5
6
6
7
7
// component to display details of a selected NASA asset
8
- // fetching asset dynamically, no need for {asset}
8
+ // fetching asset dynamically via useParams
9
9
const AssetDetail = ( ) => {
10
- // get asset ID from URL (url parameter)
10
+ // get asset id from URL (url parameter - nasa_id: /asset/nasa_id )
11
11
const { id } = useParams ( ) ;
12
12
const [ asset , setAsset ] = useState ( null ) ;
13
13
const navigate = useNavigate ( ) ;
14
14
const location = useLocation ( ) ;
15
+ const [ mediaUrl , setMediaUrl ] = useState ( "" ) ; // store media url
15
16
16
17
useEffect ( ( ) => {
17
18
const fetchAsset = async ( ) => {
@@ -20,6 +21,20 @@ const AssetDetail = () => {
20
21
// set the first item found
21
22
setAsset ( response . data . collection . items [ 0 ] ) ;
22
23
24
+ // fetch video/audio file URL
25
+ const mediaResponse = await axios . get ( `https://images-api.nasa.gov/asset/${ id } ` ) ;
26
+ const mediaItems = mediaResponse . data . collection . items ;
27
+ //console.log("Media Items:", mediaItems);
28
+
29
+ // find the first available MP4 (video) or MP3, m4a (audio) file
30
+ const playback = mediaItems . find ( item =>
31
+ item . href . endsWith ( ".mp4" ) || item . href . endsWith ( ".mp3" ) || item . href . endsWith ( ".m4a" )
32
+ ) ;
33
+
34
+ if ( playback ) {
35
+ setMediaUrl ( playback . href ) ;
36
+ }
37
+
23
38
} catch ( error ) {
24
39
console . error ( "Error fetching asset details" , error ) ;
25
40
}
@@ -32,26 +47,55 @@ const AssetDetail = () => {
32
47
const queryParams = new URLSearchParams ( location . search ) ;
33
48
const storedPage = queryParams . get ( "page" ) || localStorage . getItem ( "currentPage" ) || "1" ;
34
49
35
- // debug storedPage
36
- //console.log(`Navigating back to page: ${storedPage}`);
37
-
38
50
const handleBack = ( ) => {
39
51
navigate ( `/?page=${ storedPage } ` ) ; // ,{replace: true}
40
52
} ;
53
+ // debug storedPage
54
+ //console.log(`Navigating back to page: ${storedPage}`);
41
55
42
56
if ( ! asset ) return < div className = "asset-detail-container" > Loading...</ div > ;
57
+ const mediaType = asset . data ?. [ 0 ] ?. media_type || "unknown" ;
58
+
59
+ // limit description text
60
+ const limTxt = ( text , maxLength ) => {
61
+ if ( ! text ) return "" ;
62
+ return text . length > maxLength ? text . slice ( 0 , maxLength ) + " ..." : text ;
63
+ } ;
64
+
43
65
44
66
return (
45
67
< div className = "asset-detail-container" >
46
68
{ /* back button */ }
47
69
< button className = "back-button" onClick = { handleBack } > Back </ button >
48
- < h3 className = "asset-title" > { asset . data [ 0 ] . title } </ h3 > { /* display asset title */ }
49
- < p className = "asset-description" > { asset . data [ 0 ] . description } </ p > { /* display asset description */ }
70
+ { /* display asset title, description */ }
71
+ < h3 className = "asset-title" > { asset . data [ 0 ] . title } </ h3 >
72
+ < p className = "asset-description" > { limTxt ( asset . data [ 0 ] . description , 1250 ) } </ p >
50
73
51
- { /* render image if asset contains media links */ }
52
- { asset . links && (
53
- // image URL from API response & Alt text for accessibility
54
- < img src = { asset . links [ 0 ] . href } alt = { asset . data [ 0 ] . title } className = "asset-media" />
74
+ { /* render media based on type */ }
75
+ { asset . links && asset . links [ 0 ] && (
76
+ < >
77
+ { mediaType === "image" && (
78
+ < img src = { asset . links [ 0 ] . href } alt = { asset . data [ 0 ] . title } className = "asset-media" />
79
+ ) }
80
+
81
+ { mediaType === "video" && mediaUrl && (
82
+ < video controls className = "asset-video" >
83
+ < source src = { mediaUrl } type = "video/mp4" />
84
+ It seems your browser does not support video elements
85
+ </ video >
86
+ ) }
87
+
88
+ { mediaType === "audio" && mediaUrl && (
89
+ < audio controls className = "asset-audio" >
90
+ < source src = { mediaUrl } type = { mediaUrl . endsWith ( ".mp3" ) ? "audio/mpeg" : "audio/mp4" } />
91
+ It seems your browser does not support audio elements
92
+ </ audio >
93
+ ) }
94
+
95
+ { ! mediaUrl && ( mediaType === "video" || mediaType === "audio" ) && (
96
+ < p > Media file not available.</ p >
97
+ ) }
98
+ </ >
55
99
) }
56
100
</ div >
57
101
) ;
@@ -63,6 +107,11 @@ export default AssetDetail;
63
107
64
108
65
109
110
+ // const {id} = useParams;
111
+ /*
112
+ extract url params from react router
113
+ example URL /asset/56789 → id = "56789"
114
+ */
66
115
67
116
68
117
0 commit comments