Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ Let's create a responsive news reader website. To get the latest news the app wi
## README.md

When finished, update this README.md file in your repo. This should explain what the project is, how to run it and how to use it. Someone who is not familiar with the project should be able to look at it and understand what it is and what to do with it. This is quite important as you want to put projects in your portfolio and the information provided here will help a reviewer understand what it is they are looking at.

This project is a responsive news reader which gathers date from the news API.
Once the page loads the top news content will only show on article at a time using a slideshow function. Below the breaking news section is the trending news section, which shows three articles at a time.
Users can use the search bar to find related news to their search, this will still only show three latest articles related to the search. The search functionality does not effect the breaking news content

54 changes: 54 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!DOCTYPE html>

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU"
crossorigin="anonymous">
</head>

<body>
<nav>
<div class="container-burger" id="burger_menu">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
</div>

<div class="logo-container">
<h1>News To You</h1><i class="fas fa-newspaper"></i>
</div>
<ul id="main-menu">
<li><input id="search_input" type="textbox" placeholder="Search.." />
<button id="search_submit" onclick="searchNews()">Search News</button></li>
<li><a href="">Top Stories</a></li>
<li><a href="#trendNews">Trending News</a></li>
<li><a href="">Entertainment</a></li>
<li><a href="">Have A Story?</a></li>
</ul>
</nav>

<div class="top-content">
<h1>Today's Top Stories</h1>
<ul>
<li><button class="topButtons" id="ukButton">UK News</button></li>
<li><button class="topButtons" id="usaButton">USA News</button></li>
</ul>
<!-- <div class="arrows prev"></div>
<div class="arrows next"></div> -->
<div id="main"></div>
</div>

<h1 id="trendNews">Trending News</h1>
<div class="trendingNews"></div>



<script src="script.js" async defer></script>
</body>

</html>
123 changes: 123 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// functions
//function for creating a element
function createNode(element) {
return document.createElement(element)
}

// appendchild function
function append(parent, element) {
return parent.appendChild(element)
}

//function for topstory, only one page at a time
function getTopStory(pageNumber) {
const topStoryUrl = `https://newsapi.org/v2/top-headlines?country=gb&pageSize=1&apiKey=287554a05efe4127bd911a0a216a7b64&page=${pageNumber}`;
fetch(topStoryUrl)
.then(response => {
return response.json()
})
.then(body => {
const topUsaNewsArticles = body.articles
return topUsaNewsArticles.map(article => {
topStoryDiv.innerHTML = "";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might easier to generate using HTML strings

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it would be good to see display logic extracted out to own function so it could re-used later if needed

const mainImg = createNode("img")
const header = createNode("h1")
const span = createNode("span")
const link = createNode("a")
const swiper = createNode("p")
const published = createNode("p")
header.innerHTML = `<h1 class="article-header">${article.title}</h1>`
mainImg.setAttribute("src", article.urlToImage || 'http://placekitten.com/200/300')
span.innerHTML = `</p><span class ="image-span">${article.description || `Nothing to display`}</span></p>`
link.innerHTML = `<p><a class ="btn-more" href=${article.url} target="_blank">Read More<a/></p>`
published.innerHTML = `<p class="publishedAt">${article.published || `Posted Today`}</p>`
// swiper.innerHTML = `<p class="swipe">swipe for latest News</p>`
append(topStoryDiv, header)
append(topStoryDiv, mainImg)
append(topStoryDiv, published)
append(topStoryDiv, swiper)
append(topStoryDiv, span)
append(topStoryDiv, link)
})
})
}

//for slideshow of articles on topstory content
function nextSlide() {
pageNumber++;
getTopStory(pageNumber);
}
//function for creating trending news
function content(url) {
fetch(url)
.then(response => {
return response.json()
})
.then(body => {
console.log(body)
const techNews = body.articles
return techNews.map(article => {
// techNewsDiv.innerHTML="";
const mainImg = createNode("img")
const header = createNode("h1")
const span = createNode("span")
const link = createNode("a")
const swiper = createNode("p")
const published = createNode("p")
header.textContent = article.title
mainImg.setAttribute("src", article.urlToImage || 'http://placekitten.com/200/300')
span.innerHTML = `</p><span class ="image-span">${article.description || `Nothing to display`}</span></p>`
link.innerHTML = `<p><a class ="btn-more" href=${article.url} target="_blank">Read More<a/></p>`
published.innerHTML = `<p class="publishedAt">${article.published || `Posted Today`}</p>`

append(trendNewsDiv, header)
append(trendNewsDiv, mainImg)
append(trendNewsDiv, published)

append(trendNewsDiv, span)
append(trendNewsDiv, link)
})
})
}

//search function, which is through onclick
function searchNews() {
let keyword = '"' + document.querySelector("#search_input").value.replace(" ", "") +
'"';

let apiKey = "287554a05efe4127bd911a0a216a7b64";

let sortBy = "publishedAt";

let newsUrl = `https://newsapi.org/v2/everything?q=${keyword}&pageSize=3&sortBy=${sortBy}&apiKey=${apiKey}`;

trendNewsDiv.innerHTML = "";

contentH1.innerHTML = `Trending ${keyword} News`
content(newsUrl);
}



//varibles and selectors
const usaNews = `https://newsapi.org/v2/top-headlines?country=us&pageSize=1&apiKey=287554a05efe4127bd911a0a216a7b64&page=${pageNumber}`;
const ukButton = document.querySelector("#ukButton")
const usaButton = document.querySelector("#usaButton")
const topStoryDiv = document.querySelector("#main");
const trendNewsDiv = document.querySelector(".trendingNews")
const techUrl = `https://newsapi.org/v2/top-headlines?sources=techcrunch&pageSize=3&apiKey=287554a05efe4127bd911a0a216a7b64`
var pageNumber = 1;
const contentH1 = document.querySelector("#trendNews")
getTopStory(1); //reset page back page 1
content(techUrl)
let slideInterval = setInterval(nextSlide,4000);



//menu toggle
var open_menu = document.querySelector("#main-menu");
var burger_menu = document.querySelector("#burger_menu");
burger_menu.addEventListener("click", function () {
burger_menu.classList.toggle("active-burger");
open_menu.classList.toggle("show-menu-mobile");
});
200 changes: 200 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
* {
box-sizing: border-box;
}

body {
text-align: center;
margin: 0;
font-family: Arial;
}


img {

width: 40vh;
height: 30vh;
}


.topButtons {
text-transform: uppercase;
background-color: black;
color: #fff;
margin: 10px 10px;
padding: 5px 15px;
border-radius: 40%;
}

.topButtons:hover {
transform: scale(1.1);
}

.btn-more {
display: inline-block;
text-transform: uppercase;
color: #0e2f44;
font-size: 0.8rem;
border: 1px solid #0e2f44;
margin: 10px 0;
padding: 5px 15px;
text-decoration: none;
}

.btn-more:hover {
background-color: #0e2f44;
color: #fff;
transition: 0.4s;
text-decoration: underline;
}


ul {
display: flex;
justify-content: center;
margin-right: 45px;
}

li {
display: inline-block;

}


.publishedAt {
font-size: 10px;
}

.top-content {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
background-color: red;

}





/* Navbar */

nav {
background-color: black;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
}

nav .logo-container {
color: white;
margin-left: .5em;
font-size: 1.5em;
}

nav ul {
display: flex;
padding: 0;
margin: .5em 0 .5em 0;
}

nav li {
list-style: none;
margin-right: 1em;
padding: .8em;
}

nav li:hover {
background-color: #8a929a;
}

nav a {
color: white;
text-decoration: none;
}

.container-burger {
display: none;
cursor: pointer;
position: absolute;
right: .5em;
}

.line1,
.line2,
.line3 {
width: 30px;
height: 3px;
background-color: white;
margin: 5px 0;
transition: .2s;
}

.active-burger .line1 {
transform: rotate(-45deg) translate(-6px, 5px);
}

.active-burger .line2 {
opacity: 0;
}

.active-burger .line3 {
transform: rotate(45deg) translate(-6px, -5px);
}

.show-menu-mobile {
display: flex;
flex-direction: column;
align-items: center;
}






/* media queries */
@media screen and (max-width: 749px) {
.container-burger {
display: block;
}

nav {
flex-direction: column;
align-items: flex-start;
padding: .5em 0;
/* max-height: 16vh; */
}

nav ul {
display: none;
margin: 0;
width: 100%;
}

nav .logo-container {
font-size: 1.0em;
padding: 0.8em
}
}



/* ipad screen and desktop */
@media screen and (min-width: 780px) {
img {
display: flex;
height: 4s0vh;
width: 60vh;
margin-left: 5vh;

}

.article-header {
/* font-size: 1.75rem; */

display: inline-block;

}
}