seth.blog

freeCodeCamp Zipline: Camper News

My latest project for freeCodeCamp is a stylized “camper news” page, using their latest news API to display recent stories and meet the following requirements:

  • User Story: As a user, I can browse recent posts from Camper News.
  • User Story: As a user, I can click on a post to be taken to the story’s original URL.
  • Bonus User Story: As a user, I can see how many upvotes each story has.

First off, I decided to use flex styling for the structure, which turned out really well. Here’s my styling for the container and each of the news items:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.flex-container {
  display: inline-flex;
  width:100%;
  padding-top:10px;
  flex-wrap: wrap;
  justify-content: space-around;
}

.flex-item {
  width:200px;
  padding:0px;
  margin:10px;
  background: #fff;
  border-radius:5px;
  color: #8A62D3;
}

For this project, the HTML I set up is actually pretty barren. All you need to do is create the flex-container, and the actual content is generated by the JS.

The JS isn’t particularly complicated either. Just use the map function on the array from the API call, and build a new flex-item from each object. Code with commenting below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
$(document).ready(function() {

  // The initial API call here, storing data in 'json'
  $.getJSON('http://www.freecodecamp.com/news/hot', function(json) {

	// Create a variable to store the HTML we'll be adding for each object
    var html= "";

	// Apply the following to each object
    json.map(function(obj) {

      // First add the flex-item container and the structure for CSS animation
      html += "<div class='flex-item'><div class='card'>";

      // Including the author's user image
      html += "<img width='200px' class='img-responsive' src='" + obj.author.picture + "'>";

      // This is what will show on hover: upvotes with heart icon & discuss button
      html += "<div class='caption'><span class='hearts'>" +
      obj.upVotes.length + "</span>&nbsp;&nbsp;<i class='fa fa-heart fa-2x'>
      </i><br><br><a target='_blank' href='http://www.freecodecamp.com/news/" +
      obj.storyLink + "'><button class='btn btn-default'>DISCUSS</button></a>
      </div></div>";

      // Convert the date to readable format and include it
      var date = new Date(obj.timePosted).toUTCString().slice(0, -13);
      html += "<span class='date'>posted " + date + "</span>";

      // Separate div for trimmed headline and author credit
      html += "<div class='metadata'>";
      var headline = obj.headline.substr(0, 23) + "...";

      html += "<span class='headline'>
      <a title='" + obj.headline + "' target='_blank' href='" +
      obj.link + "'>" + headline + "</a></span>";

      html += "<br><span class='author'>by: <a target='blank'
      href='https://www.freecodecamp.com/" + obj.author.username +
      "'>" + obj.author.username + "</a></span>";

      html += "</div></div>";

    });

    // Pop all the generated flex-items into the container
    $(".flex-container").html(html);

  });

})

I’ve been wanting to play around with CSS animations, so here I saw an opportunity for an easy trial: an animation to show upvotes and a link to the post’s page when the user hovers over the item. div.card holds two elements: an image, and div.caption, which is hidden by default. div.caption is positioned absolutely with opacity = 0, so it is effectively hidden behind the image. When a user hovers over it, the opacity transitions to 1, and it appears over the image with a nice semi-transparent background so the image is still slightly visible.

This project was a lot of fun to put together, and the next few assignments also deal with APIs, so I’m looking forward to digging into them too. Check out the codepen for this project and see my full work below!

See the Pen freeCodeCamp prettyNews by seth dehaan (@sethxd) on CodePen.