@@ -2,78 +2,88 @@ import React, { useEffect, useState } from 'react';
22import axios from 'axios' ;
33
44function CryptoNewsAnalyzer ( { coins } ) {
5- const [ suggestedCoins , setSuggestedCoins ] = useState ( [ ] ) ;
6- const [ isLoading , setIsLoading ] = useState ( true ) ;
7- const [ error , setError ] = useState ( null ) ;
5+ const [ suggestedCoins , setSuggestedCoins ] = useState ( [ ] ) ;
6+ const [ isLoading , setIsLoading ] = useState ( true ) ;
7+ const [ error , setError ] = useState ( null ) ;
88
9- useEffect ( ( ) => {
10- const apiKey = "6c5c579db7c045039231d1b5df237f10" ; // Use the environment variable
11- axios . get ( `https://newsapi.org/v2/everything?q=cryptocurrency&apiKey=${ apiKey } ` )
12- . then ( response => {
13- const positiveKeywords = [ 'bull' , 'rally' , 'rise' , 'gain' , 'positive' , 'buy' , 'up' ] ;
14- const articles = response . data . articles ;
15- const suggestedCoins = [ ] ;
9+ useEffect ( ( ) => {
10+ const apiKey = process . env . REACT_APP_NEWS_API_KEY ;
1611
17- articles . forEach ( article => {
18- const title = article . title ? article . title . toLowerCase ( ) : '' ;
19- const description = article . description ? article . description . toLowerCase ( ) : '' ;
12+ const NEWS_API_URL = `https://api.allorigins.win/get?url=${ encodeURIComponent (
13+ `https://newsapi.org/v2/top-headlines?country=us&apiKey=${ apiKey } `
14+ ) } `;
15+ const MARKET_API_URL = 'https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=50&page=1' ;
2016
21- positiveKeywords . forEach ( keyword => {
22- if ( title . includes ( keyword ) || description . includes ( keyword ) ) {
23- // Check if a cryptocurrency name is mentioned in the title or description
24- coins . forEach ( coin => {
25- if ( coin . name && ( title . includes ( coin . name . toLowerCase ( ) ) || description . includes ( coin . name . toLowerCase ( ) ) ) ) {
26- suggestedCoins . push ( coin ) ;
27- }
28- } ) ;
29- }
30- } ) ;
31- } ) ;
17+ Promise . all ( [
18+ axios . get ( NEWS_API_URL ) ,
19+ axios . get ( MARKET_API_URL ) ,
20+ ] )
21+ . then ( ( [ newsResponse , marketResponse ] ) => {
22+ const parsedData = JSON . parse ( newsResponse . data . contents ) ;
23+ const articles = parsedData . articles ;
24+ const positiveKeywords = [
25+ 'bull' , 'rally' , 'rise' , 'gain' , 'positive' , 'buy' , 'up' ,
26+ 'growth' , 'increase' , 'profit' , 'investment' , 'crypto' , 'currency'
27+ ] ;
28+ const marketData = marketResponse . data ;
3229
33- // Remove duplicates
34- const uniqueSuggestedCoins = Array . from ( new Set ( suggestedCoins . map ( coin => coin . id ) ) )
35- . map ( id => suggestedCoins . find ( coin => coin . id === id ) ) ;
30+ // Filter coins based on news sentiment
31+ const suggestedCoins = marketData . filter ( coin => {
32+ return articles . some ( article => {
33+ const title = article . title ? article . title . toLowerCase ( ) : '' ;
34+ const description = article . description ? article . description . toLowerCase ( ) : '' ;
35+ return positiveKeywords . some ( keyword => title . includes ( keyword ) || description . includes ( keyword ) ) &&
36+ ( title . includes ( coin . name . toLowerCase ( ) ) || description . includes ( coin . name . toLowerCase ( ) ) ) ;
37+ } ) ;
38+ } ) ;
3639
37- // Sort by 24h price change and select top 10
38- uniqueSuggestedCoins . sort ( ( a , b ) => b . price_change_24h - a . price_change_24h ) ;
39- setSuggestedCoins ( uniqueSuggestedCoins . slice ( 0 , 10 ) ) ;
40+ // If no coins match news sentiment, fallback to top 10 by market cap
41+ if ( suggestedCoins . length === 0 ) {
42+ setSuggestedCoins ( marketData . slice ( 0 , 10 ) ) ;
43+ } else {
44+ setSuggestedCoins ( suggestedCoins . slice ( 0 , 10 ) ) ;
45+ }
4046
41- setIsLoading ( false ) ;
42- } )
43- . catch ( error => {
44- console . error ( error ) ;
45- setError ( 'Failed to fetch news ' ) ;
46- setIsLoading ( false ) ;
47- } ) ;
48- } , [ coins ] ) ;
47+ setIsLoading ( false ) ;
48+ } )
49+ . catch ( error => {
50+ console . error ( 'API Error:' , error ) ;
51+ setError ( 'Failed to fetch data ' ) ;
52+ setIsLoading ( false ) ;
53+ } ) ;
54+ } , [ ] ) ;
4955
50- if ( isLoading ) {
51- return < div > Loading...</ div > ;
52- }
56+ if ( isLoading ) {
57+ return < div > Loading...</ div > ;
58+ }
5359
54- if ( error ) {
55- return < div > { error } </ div > ;
56- }
60+ if ( error ) {
61+ return < div > { error } </ div > ;
62+ }
5763
58- return (
59- < div className = "crypto-news-analyzer" >
60- < h2 > Top 10 Cryptocurrencies to Buy Based on News Sentiment</ h2 >
61- { suggestedCoins . map ( ( coin , index ) => (
62- < div key = { index } className = "suggested-coin" style = { { display : 'flex' , flexDirection : 'column' , alignItems : 'center' , width : '300px' } } >
63- < div style = { { display : 'flex' , alignItems : 'center' } } >
64- < img src = { coin . image } alt = { coin . name } style = { { width : '20px' , height : '20px' , marginRight : '10px' } } />
65- < h3 style = { { margin : 0 } } > { coin . name } ({ coin . symbol . toUpperCase ( ) } )</ h3 >
66- </ div >
67- < div style = { { position : 'relative' , width : '100%' } } >
68- < p style = { { fontSize : '1.9em' } } > { coin . current_price . toFixed ( 2 ) } </ p >
69- < span style = { { position : 'absolute' , top : 2 , right : 120 , color : coin . price_change_24h < 0 ? 'red' : 'green' } } >
70- { coin . price_change_24h . toFixed ( 2 ) }
71- </ span >
72- </ div >
73- </ div >
74- ) ) }
64+ if ( suggestedCoins . length === 0 ) {
65+ return < div > No cryptocurrencies matched the news sentiment.</ div > ;
66+ }
67+
68+ return (
69+ < div className = "crypto-news-analyzer" >
70+ < h2 > Top 10 Cryptocurrencies to Buy Based on News Sentiment</ h2 >
71+ { suggestedCoins . map ( ( coin , index ) => (
72+ < div key = { index } className = "suggested-coin" style = { { display : 'flex' , flexDirection : 'column' , alignItems : 'center' , width : '300px' } } >
73+ < div style = { { display : 'flex' , alignItems : 'center' } } >
74+ < img src = { coin . image } alt = { coin . name } style = { { width : '20px' , height : '20px' , marginRight : '10px' } } />
75+ < h3 style = { { margin : 0 } } > { coin . name } ({ coin . symbol . toUpperCase ( ) } )</ h3 >
76+ </ div >
77+ < div style = { { position : 'relative' , width : '100%' } } >
78+ < p style = { { fontSize : '1.9em' } } > { coin . current_price . toFixed ( 2 ) } </ p >
79+ < span style = { { position : 'absolute' , top : 2 , right : 120 , color : coin . price_change_24h < 0 ? 'red' : 'green' } } >
80+ { coin . price_change_24h . toFixed ( 2 ) }
81+ </ span >
82+ </ div >
7583 </ div >
76- ) ;
77- }
84+ ) ) }
85+ </ div >
86+ ) ;
87+ }
7888
79- export default CryptoNewsAnalyzer ;
89+ export default CryptoNewsAnalyzer ;
0 commit comments