Skip to content

Commit 15a7839

Browse files
authored
Merge pull request #7 from TheCoderAdi/feat/add-popular-tech-news
Add a trending News Section
2 parents fc68786 + 11f81b8 commit 15a7839

File tree

8 files changed

+145
-15
lines changed

8 files changed

+145
-15
lines changed

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
node_modules/
2+
.vscode/

‎src/App.css‎

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ input {
100100

101101

102102

103-
.pagination-btn {
103+
.pagination-btn, .popular-btn {
104104
width: 100%;
105105
display: flex;
106106
justify-content: center;
@@ -166,3 +166,56 @@ button {
166166
font-weight: 200;
167167
font-style: normal;
168168
}
169+
170+
.popular-news-section {
171+
display: flex;
172+
flex-direction: column;
173+
align-items: center;
174+
justify-content: center;
175+
padding: 15px;
176+
border-radius: 8px;
177+
}
178+
179+
.popular-news-section h2 {
180+
font-size: 2.5rem;
181+
color: #110c0a;
182+
margin-bottom: 10px;
183+
text-align: center;
184+
}
185+
186+
.popular-news-section ul {
187+
list-style-type: none;
188+
padding: 0;
189+
}
190+
191+
.popular-news-section li {
192+
display: flex;
193+
justify-content: space-between;
194+
align-items: center;
195+
background: white;
196+
margin: 10px 0;
197+
padding: 2rem;
198+
border-radius: 5px;
199+
transition: 0.3s;
200+
font-size: 1.2rem;
201+
}
202+
203+
.popular-news-section li:hover {
204+
background: #eee;
205+
}
206+
207+
.popular-news-section a {
208+
text-decoration: none;
209+
font-weight: bold;
210+
color: #333;
211+
width: 70%;
212+
font-size: 1.7rem;
213+
}
214+
215+
.badge {
216+
background: #ff5722;
217+
color: white;
218+
padding: 1rem;
219+
border-radius: 10px;
220+
font-size: 1.2rem;
221+
}

‎src/App.js‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@ import Stories from './Stories';
44
import Pagination from './Pagination';
55

66
import './App.css';
7+
import { useGlobalContext } from './Context';
8+
import PopularNews from './PopularNews';
79

810

911

1012
export const App = () => {
11-
13+
const { showPopularNews } = useGlobalContext();
1214
return (
1315

1416
<>
1517

1618
<Search/>
1719
<Pagination/>
18-
<Stories/>
19-
20+
{
21+
showPopularNews ? <PopularNews /> : <Stories/>
22+
}
2023
</>
2124

2225
)

‎src/Context.js‎

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect,useContext,useReducer } from 'react';
1+
import React, { useEffect,useContext,useReducer, useState } from 'react';
22
import reducer from './reducer';
33
// Context created
44
let API="https://hn.algolia.com/api/v1/search?";
@@ -9,12 +9,13 @@ const initialState = {
99
nbPages:0,
1010
page:0,
1111
hits:[],
12+
popularNews:[],
1213
};
1314
const AppContext = React.createContext();
1415
// Now the provider function
1516
const AppProvider = ({ children }) => {
16-
const [state,dispatch]=useReducer(reducer,initialState)
17-
17+
const [state,dispatch]=useReducer(reducer,initialState);
18+
const [showPopularNews, setShowPopularNews] = useState(false);
1819

1920

2021
const fetchApiData= async (url)=>{
@@ -36,6 +37,26 @@ const AppProvider = ({ children }) => {
3637
console.log(error);
3738
}
3839
};
40+
const fetchPopularNews = async () => {
41+
try {
42+
dispatch({type:"SET_LOADING"});
43+
const res = await fetch(`${API}query=technology&tags=story`);
44+
const data = await res.json();
45+
46+
const sortedNews = data.hits
47+
.filter((item) => item.num_comments)
48+
.sort((a, b) => (b.num_comments || 0) - (a.num_comments || 0));
49+
50+
dispatch({
51+
type: "GET_POPULAR_NEWS",
52+
payload: sortedNews.slice(0, 7),
53+
});
54+
55+
} catch (error) {
56+
console.log(error);
57+
}
58+
};
59+
3960

4061
const searchFn= (searchQuery) =>{
4162
dispatch({type:"SEARCH_QUERY",
@@ -57,10 +78,13 @@ const AppProvider = ({ children }) => {
5778
fetchApiData(`${API}query=${state.query}&{state.page}`);
5879
},[state.query,state.page]);
5980

81+
useEffect(() => {
82+
fetchPopularNews();
83+
}, []);
6084

6185

6286
return (
63-
<AppContext.Provider value={{...state,searchFn,getNextPage,getPrevPage}}>
87+
<AppContext.Provider value={{...state,searchFn,getNextPage,getPrevPage,showPopularNews,setShowPopularNews}}>
6488
{children}
6589
</AppContext.Provider>
6690
);

‎src/Pagination.js‎

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@ import React from 'react'
22
import { useGlobalContext } from './Context'
33

44
const Pagination = () => {
5-
const {page,nbPages,getPrevPage,getNextPage}=useGlobalContext();
5+
const {page,nbPages,getPrevPage,getNextPage,setShowPopularNews,showPopularNews}=useGlobalContext();
66
return (
77
<>
8-
<div className='pagination-btn'>
9-
<button onClick={()=>getPrevPage()}>Prev</button>
10-
<p>{page+1} of {nbPages}</p>
11-
<button onClick={()=>getNextPage()}>Next</button>
8+
{
9+
!showPopularNews &&
10+
<div className='pagination-btn'>
11+
<button onClick={()=>getPrevPage()}>Prev</button>
12+
<p>{page+1} of {nbPages}</p>
13+
<button onClick={()=>getNextPage()}>Next</button>
14+
</div>
15+
}
16+
<div className='popular-btn'>
17+
<button onClick={()=>setShowPopularNews(!showPopularNews)} style={{ margin : '2rem'}}>
18+
{
19+
!showPopularNews
20+
? 'Trending Tech News'
21+
: 'Back to Home'
22+
}
23+
</button>
1224
</div>
1325
</>
1426
)

‎src/PopularNews.jsx‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react';
2+
import { useGlobalContext } from './Context';
3+
4+
const PopularNews = () => {
5+
const { isLoading,popularNews } = useGlobalContext();
6+
7+
if (isLoading) {
8+
return <p>Loading popular news...</p>;
9+
}
10+
11+
return (
12+
<div className='popular-news-section'>
13+
<h2>🔥 Trending Tech News</h2>
14+
{popularNews.length > 0 && (
15+
<ul>
16+
{popularNews.map((news) => (
17+
<li key={news.objectID}>
18+
<a href={news.url} target="_blank" rel="noopener noreferrer">
19+
{news.title}
20+
</a>
21+
<span className="badge">💬 {news.num_comments || 0} comments</span>
22+
</li>
23+
))}
24+
</ul>
25+
)}
26+
</div>
27+
);
28+
};
29+
30+
export default PopularNews;

‎src/Search.js‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import{useGlobalContext} from './Context'
33

44

55
const Search = () => {
6-
const {query,searchFn}=useGlobalContext();
6+
const {query,searchFn,showPopularNews}=useGlobalContext();
77
return (
88
<>
99
<h1 style={{
@@ -16,7 +16,7 @@ const Search = () => {
1616
<span style={{ fontSize: '42px' }}>P</span>ulse
1717
</h1>
1818

19-
19+
{!showPopularNews &&
2020
<form>
2121
<div>
2222
<input type="text" placeholder="search here"
@@ -25,6 +25,7 @@ const Search = () => {
2525
/>
2626
</div>
2727
</form>
28+
}
2829
</>
2930

3031

‎src/reducer.js‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ const reducer = (state, action) => {
1212
hits: action.payload.hits,
1313
nbPages: action.payload.nbPages,
1414
};
15+
case "GET_POPULAR_NEWS":
16+
return {
17+
...state,
18+
popularNews: action.payload,
19+
isLoading: false,
20+
};
1521
case "SEARCH_QUERY":
1622
return {
1723
...state,

0 commit comments

Comments
 (0)