<div id="main"></div>
html, body, h1, h2, h3, h4, h5, small {
  font-family: 'Noto Sans', sans-serif;
}

a {
  color: teal;
}

h1 {
  text-transform: uppercase;
  letter-spacing: 0.3em;
  font-size: 40px;
  color: white;
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
}

.top-bar, .top-bar ul {
   background: none;
   color: #999;
}

.top-bar {
  position: fixed;
  width: 100%;
  z-index: 5000;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
  transition: all 0.5s ease;
}

.top-bar.scrollNav {
  background: #ffffff;
  opacity: 0.92;
  transition: all 0.5s ease;
  border-bottom: 1px solid rgba(200, 200, 200, 0.8);
  .menu li, .menu li a {
    color: #555;
  }
}

.big-banner {
  background: url(https://upload.wikimedia.org/wikipedia/commons/1/14/Panorama_puy_de_dome_sud.jpg) center 80%;
  background-size: cover;
  margin-bottom: 50px;
  transition: 0.5s ease all;
  &.blurred {
    filter: blur(2px);
  }
}

.highlight {
  opacity: 0.7;
  color: teal;
}

.menu li, .menu li a {
  color: white;
}

.callout.primary {
  background: none;
}

.callout.large {
  padding: 9em 3em 7em;
}


.callout {
  background-color: #333;
}

.callout.callout-post {
  border-top: 3px solid #333;
  border-left: none;
  border-right: none;
  border-bottom: 1px solid #aaa;
  background: #f9f9f9;
  .menu a {
    color: #aaa;
  }
}

.blog-post {
  margin-bottom: 70px;
  h3 {
    text-transform: uppercase;
    color: #666;
    letter-spacing: 0.05em;
    font-size: 25px;
  }
  small {
    float: right;
    margin-top: 20px;
    font-size: 18px;
  }
}

.form-area {
  margin-bottom: 60px;
  button {
    background: teal;
    text-align: center;
    color: white;
    padding: 0.7em;
    border-radius: 4px;
    width: 100%;
    margin: 10px auto;
    transition: 0.3s all ease;
    &:hover {
      background: #1A9696;
    }
  }
}

h5 {
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: teal;
}

.callout.secondary {
  background-color: #f9f9f9;
  border-color: #ddd;
  border-radius: 4px;
  input {
    border-color: #ddd;
    border-radius: 4px;
  }
}

@media screen and (max-width: 900px) {
    .blog-post small {
        font-size: 12px !important;
    }
  
    h1 {
      letter-spacing: 0.15em;
      font-size: 30px;
    }
}
View Compiled
//helper functions
var h =  {
  rando : function(arr) {
    return arr[Math.floor(Math.random() * arr.length)];
  },
  getTime : function() {
      var month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
      var d = new Date();
      var mon = month[d.getMonth()];
      var day = d.getDate();
      var year = d.getFullYear();
      var dateAll = mon + " " + day + ", " + year;
    
      return dateAll;
  },
  getTaggedName : function() {
    var adjectives = ['trusted', 'secure', 'hot', 'new', 'interesting', 'best practice', 'exciting'];
    
    var nouns = ['es6', 'browserify', 'webpack', 'gulp', 'reactDOM', 'devTools'];
    
    return this.rando(adjectives) + ' ' + this.rando(nouns);
  }
}

// App
var App = React.createClass({
  getInitialState : function() {
    return {
      posts : {}
    }
  }, 
  addPost : function(post) {
    var timestamp = (new Date()).getTime();
    // update the state object
    this.state.posts['post-' + timestamp] = post;
    // set the state
    this.setState({ posts : this.state.posts });
  },
  renderPost : function(key){
    return <NewPost key={key} index={key} details={this.state.posts[key]} />
  },
  render : function() {
    var imgOne = "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Balaton_Hungary_Landscape.jpg/1024px-Balaton_Hungary_Landscape.jpg";
    var imgTwo ="https://c2.staticflickr.com/8/7432/9087815445_1a14743549_b.jpg";
    var imgThree ="https://c2.staticflickr.com/6/5738/23929500196_b6a1ce1dfb_b.jpg";
    var imgFour ="https://pixabay.com/static/uploads/photo/2015/09/14/19/15/aerial-landscape-939963_960_720.jpg";
    var dummyPost = "Praesent id metus massa, ut blandit odio. Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec congue lacinia dui, a porttitor lectus condimentum laoreet. Nunc eu ullamcorper orci. Quisque eget odio ac lectus vestibulum faucibus eget in metus. In pellentesque faucibus vestibulum. Nulla at nulla justo, eget luctus.";
    return (
      <div>
        <Banner />
        <div className="row medium-8 large-7 columns">
          <Post ptitle="Flux flack" pimg={imgOne} date="Nov 2, 2015" postbody={dummyPost} author="Fred Armisen" comments="2" tags=""/>
          <Post ptitle="Inline Styles Aren't Necessary" pimg={imgTwo} postbody={dummyPost} date="Aug 15, 2015" author="Amy Schumer" comments="5"/>
          <Post ptitle="Webpack and ES6" pimg={imgThree} date="Mar 9, 2015" postbody={dummyPost} author="Victoria Bell" comments="3"/>
          <Post ptitle="No More Goobers" pimg={imgFour} date="Jan 11, 2015" postbody={dummyPost} author="Jack Sherlock" comments="7"/>
      
          <div className="list-of-posts">
              {Object.keys(this.state.posts).map(this.renderPost)}
          </div>
          <AddPostForm addPost={this.addPost}/>
        </div>
      </div>
    )
  }
  
});

/*
  Add Post Form
  <AddPostForm />
*/
var AddPostForm = React.createClass({
  createPost : function(event) {
    event.preventDefault();
    // take the data from the form and create an object
    var post = {
      title : this.refs.title.value,
      name : this.refs.name.value,
      desc : this.refs.desc.value,
      image : this.refs.image.value
    }
    // add the post to the App State
    this.props.addPost(post);
    this.refs.postForm.reset();
  },
  render : function() {
    return (
      <div className="callout secondary form-area">
      <h5>Add a Post to the React Blog</h5>
        <form className="post-edit" ref="postForm" onSubmit={this.createPost}>
          <label>Post Title
            <input type="text" ref="title" placeholder="Post Title" required/>
          </label>
          <label>Author Name
            <input type="text" ref="name" placeholder="Full Name required" required/>
          </label>
          <label>Post Body
          <textarea
            ref="desc"
            placeholder="Write your post here" required/>
          </label>
          <label>Image URL - <span className="highlight">use this one to test 'https://bit.ly/1P9prpc'</span>
            <input type="url" ref="image" placeholder="The URL of the featured image for your post" required/>
          </label>
          <button type="submit" class="button">Add Post</button>
        </form>
      </div>
    )
  }
});


/*
  NewPost
  <NewPost />
*/
var NewPost = React.createClass({
  render : function() {
    var details = this.props.details;
    return (
      <div className="blog-post">
        <h3 className="ptitle">{details.title}<small>{h.getTime()}</small></h3>
        <img className="thumbnail" src={details.image} alt={details.name}/>
        <p>{details.desc}</p>
        <div className="callout callout-post">
          <ul className="menu simple">
          <li><a href="#">Author: {details.name}</a></li>
          <li><a href="#">Comments: 0</a></li>
          <li><a href="#">Tags: {h.getTaggedName()}</a></li>
          </ul>
        </div>
      </div>
    )
  }
});


// Nav component
var Nav = React.createClass({
  
  render : function() {
    return (
      <div className="top-bar">
        <div className="top-bar-left">
          <ul className="menu">
            <li className="menu-text">React Blog</li>
            <li><a href="#">One</a></li>
            <li><a href="#">Two</a></li>
            <li><a href="#">Three</a></li>
          </ul>
        </div>
      </div>
    )
  }
  
});


// Banner component
var Banner = React.createClass({
  
  render : function() {
    return (
      <div>
        <Nav />
        <div className="big-banner">
          <div className="callout large primary">
            <div className="row column text-center">
              <h1>React Blog</h1>
            </div>
          </div>
        </div>
      </div>
    )
  }
  
});


// Blog Post
var Post = React.createClass({
  tryClick : function() {
    alert('just trying out click events lalala');
  },
  render : function() {
    var com = "Comments";
    return (
      <div className="blog-post">
        <h3 className="ptitle">{this.props.ptitle}<small>{this.props.date}</small></h3>
        <img className="thumbnail" src={this.props.pimg} />
        <p>{this.props.postbody}</p>
        <div className="callout callout-post">
          <ul className="menu simple">
          <li><a href="#" onClick={this.tryClick}>Author: {this.props.author}</a></li>
          <li><a href="#">{com}: {this.props.comments}</a></li>
          <li><a href="#">Tags: {h.getTaggedName()}</a></li>
          </ul>
        </div>
      </div>
    )
  }
});

//instead of ReactDOM like in the video:
React.render(<App/>, document.querySelector("#main"));

//polyfill for key
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
if (!Object.keys) {
  Object.keys = (function() {
    'use strict';
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
        dontEnums = [
          'toString',
          'toLocaleString',
          'valueOf',
          'hasOwnProperty',
          'isPrototypeOf',
          'propertyIsEnumerable',
          'constructor'
        ],
        dontEnumsLength = dontEnums.length;

    return function(obj) {
      if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
        throw new TypeError('Object.keys called on non-object');
      }

      var result = [], prop, i;

      for (prop in obj) {
        if (hasOwnProperty.call(obj, prop)) {
          result.push(prop);
        }
      }

      if (hasDontEnumBug) {
        for (i = 0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) {
            result.push(dontEnums[i]);
          }
        }
      }
      return result;
    };
  }());
}

//header scroll stuff
window.onscroll = function(e) {  
  var nav = document.getElementsByClassName("top-bar")[0],
      banner = document.getElementsByClassName("big-banner")[0],
      range = 70,
      scrollTop = document.body.scrollTop;
  
  if (scrollTop > range) {
      nav.classList.add("scrollNav");
      banner.classList.add("blurred");
    }
    else {
      nav.classList.remove("scrollNav");
      banner.classList.remove("blurred");
  }
};

View Compiled

External CSS

  1. //dhbhdrzi4tiry.cloudfront.net/cdn/sites/foundation.min.css

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.min.js