R: Learning (Movie App)

by kyllle

HTML

<script src="https://npmcdn.com/classnames/index.js"></script>
<script src="https://npmcdn.com/[email protected]/dist/react-dom.min.js"></script>
<header class="global-header js-header">
	<nav class="main-nav">
		<a href="/" class="main-nav__link is-active js-nav-link">Popular</a>
		<a href="/watchlist" class="main-nav__link js-nav-link">Watchlist</a>
	</nav>
</header>

<div class="main-content js-app"></div>


	
<script type="text/template" class="tmpl-watchlist-movie">
	<a href="/movie/<%= id %>" class="js-movie--show" data-id="<%= id %>">
		<img src="<%= backdrop_small %>" alt="" class="trans-img is-hidden js-trans-img">

		<span class="movie__info">
			<h2><%= title %></h2>

			<button class="action action-watchlist--remove js-watchlist--remove">
				<svg height="80px" width="80px" class="action__icon action__icon--remove" viewBox="0 0 80 80"><polygon points="56.971,52.728 44.243,40 56.971,27.272 52.728,23.029 40,35.757 27.272,23.029 23.029,27.272 35.757,40 23.029,52.728 27.272,56.971 40,44.243 52.728,56.971"/></svg>
			</button>
		</span>
	</a>
</script>
	
<script type="text/template" class="tmpl-watchlist-movie-btn">
	 <% if(!watchlist) { %>
		<button class="action action-watchlist--added js-watchlist--add">
			<svg height="80px" width="80px" class="action__icon action__icon--add" viewBox="0 0 80 80"><polygon points="61,37 43,37 43,19 37,19 37,37 19,37 19,43 37,43 37,61 43,61 43,43 61,43 "/></svg>
			Add to watchlist
		</button>
	<% } else { %>
		<button class="action action-watchlist--removed js-watchlist--remove">
			<svg height="80px" width="80px" class="action__icon action__icon--remove" viewBox="0 0 80 80"><polygon points="56.971,52.728 44.243,40 56.971,27.272 52.728,23.029 40,35.757 27.272,23.029 23.029,27.272 35.757,40 23.029,52.728 27.272,56.971 40,44.243 52.728,56.971"/></svg>
			Remove from watchlist
		</button>
	<% } %>
</script>
		
<script type="text/template" class="tmpl-loader">
	<div class="loader">Loading...</div>
</script>

SCSS

@import url(http://fonts.googleapis.com/css?family=Raleway:400,700);
* {
  -webkit-font-smoothing: antialiased;
  box-sizing: border-box;
}

html, body {
  height: 100%;
}

html {
  font-size: 62.5%;
}

body {
  font-family: Raleway, Arial;
  font-weight: 400;
  font-size: 1.6em;
  line-height: 1.4;
  color: black;
  letter-spacing: 0.02em;
  background: white;
  padding-top: 55px;
}
@media (min-width: 660px) {
  body {
    padding-top: 70px;
  }
}

h1, h2, h3 {
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1;
}

h2 {
  font-size: 2rem;
}
@media (min-width: 660px) {
  h2 {
    font-size: 2.4rem;
  }
}

a {
  text-decoration: none;
  color: black;
}

.global-header {
  background: black;
  color: white;
  height: 55px;
  width: 100%;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
}
@media (min-width: 660px) {
  .global-header {
    /* position: static; */
    height: 70px;
  }
}

.main-nav__link {
  font-weight: 700;
  color: white;
  text-transform: uppercase;
  font-size: 2rem;
  margin: 0 1rem;
}
.main-nav__link.is-active {
  border-bottom: 0.3rem solid white;
}

@media (min-width: 660px) {
  .movie-grid {
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-flex-wrap: wrap;
        -ms-flex-wrap: wrap;
            flex-wrap: wrap;
    margin: auto;
  }
}

.movie {
  display: block;
  position: relative;
  color: black;
  background: black;
  overflow: hidden;
}
@media (min-width: 660px) {
  .movie {
    width: 50%;
    display: inline-block;
  }
}
.movie__info {
  padding: 1.6rem;
  position: absolute;
  bottom: 0;
  left: 0;
  right:...

Babel + JSX

console.clear();

/**
 *	@todos
 *	- Make a main app component that renders out to .js-app.
 *	- Make a movie component.
 *	- Make a movies component.
 *	- Make a preloader component.
 *	- Fetch some data -> show a loader -> onSuccess render -> hide loader.
 */

var data = [{
			"adult": false,
			"backdrop_path": "/kiWvoV78Cc3fUwkOHKzyBgVdrDD.jpg",
			"genre_ids": [18, 12],
			"id": 281957,
			"original_language": "en",
			"original_title": "The Revenant",
			"overview": "In the 1820s, a frontiersman, Hugh Glass, sets out on a path of vengeance against those who left him for dead after a bear mauling.",
			"release_date": "2015-12-25",
			"poster_path": "/oXUWEc5i3wYyFnL1Ycu8ppxxPvs.jpg",
			"popularity": 2.295314,
			"title": "The Revenant",
			"video": false,
			"vote_average": 5,
			"vote_count": 20
		},
		{
			"adult": false,
			"backdrop_path": "/pgSkCrrPO5NWZcvHpXG2l8DxTou.jpg",
			"genre_ids": [28, 12, 878, 14],
			"id": 140607,
			"original_language": "en",
			"original_title": "Star Wars: Episode VII - The Force Awakens",
			"overview": "A continuation of the saga created by George Lucas, set thirty years after Star Wars: Episode VI – Return of the Jedi.",
			"release_date": "2015-12-18",
			"poster_path": "/fYzpM9GmpBlIC893fNjoWCwE24H.jpg",
			"popularity": 12.066421,
			"title": "Star Wars: Episode VII - The Force Awakens",
			"video": false,
			"vote_average": 7.8,
			"vote_count": 115
		}];

var App = React.createClass({
	render() {
		return (
			<Movies movies={this.props.movies} />
		)
	}
});

var Movie = React.createClass({
	render() {
		return (
			<a href={'/movie/'+this.props.movie.id} className="movie">
				<img src={'http://image.tmdb.org/t/p/w1280/'+this.props.movie.backdrop_path} alt={this.props.movie.title} />

				<span className="movie__info">
					<h2>{this.props.movie.title}</h2>
				</span>
			</a>
		)
	}
});

var Movies = React.createClass({
	render() {
		var movies = this.props.movies.map((movie) => {
			return <Movie movie={movie}...