<!DOCTYPE html>
<html>

  <head>
    <link data-require="bootstrap@4.0.5" data-semver="4.0.5" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />
    <link rel="stylesheet" href="style.css" />
    <script data-require="lodash.js@4.17.4" data-semver="4.17.4" src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"></script>
    <script src="https://jspm.io/system@0.18.js"></script>
    <script src="config.js"></script>
    <script>
      System.import('app').catch(console.error.bind(console));
    </script>
  </head>

  <body>
    <div id="app" class="container"></div>
  </body>

</html>
.search-bar {
  margin: 20px;
  text-align: center;
}

.search-bar input {
  border: 1px solid #ccc;
  margin: 0 auto;
  width: 75%;
}

.video-item img {
  max-width: 64px;
}

.video-detail .details {
  margin-top: 10px;
  padding: 10px;
}

.media-heading {
  margin-left:10px;
}

.list-group-item {
  cursor: pointer;
  border: none;
}

.list-group-item:hover {
  background-color: #eee;
}
/*global System */
'use strict';

System.config({
  transpiler: 'babel',
  map: {
    'react': 'https://unpkg.com/react@16.0.0/umd/react.production.min.js',
    'react-dom': 'https://unpkg.com/react-dom@16.0.0/umd/react-dom.production.min.js',
    'axios': 'https://unpkg.com/axios/dist/axios.min.js',
    'youtube-api-search': 'https://unpkg.com/youtube-api-search@0.0.5/index.js',
    'app': './src'
  },
  packages: {
    app: {
      main: './index.jsx',
      defaultExtension: false,
    },
  }
});

//import _ from "lodash";
import React, { Component } from "react";
import ReactDOM from "react-dom";
import YTSearch from "youtube-api-search";

import SearchBar from "./components/search_bar.jsx";
import VideoDetail from "./components/video_detail.jsx";
import VideoList from "./components/video_list.jsx";

const API_KEY = "AIzaSyBgWEQ_Fbc4NW36c_Re03wf9FSw_MH5P44";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      videos: [],
      selectedVideo: null
    };
    
    this.videoSearch("surfboards");
  }
  
  videoSearch(term) {
    YTSearch({ key: API_KEY, term: term }, videos => {
      this.setState({
        videos: videos,
        selectedVideo: videos[0]
      });
    });
  }
  
  render() {
    const videoSearch = _.debounce(term => {
      this.videoSearch(term);
    }, 300);
    
    return (
      <div>
        <SearchBar onSearchTermChange={videoSearch} />
        <VideoDetail video={this.state.selectedVideo} />
        <VideoList
          onVideoSelect={selectedVideo => this.setState({ selectedVideo })}
          videos={this.state.videos}
        />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.querySelector("#app"));
import React from "react";

const VideoDetail = ({ video }) => {
  if (!video) {
    return (
      <div>
        Loading...
      </div>
    );
  }

  const videoId = video.id.videoId;
  //const url = "https://www.youtube.com/embed/" + videoId;
  const url = `https://www.youtube.com/embed/${videoId}`;

  return (
    <div className="video-detail col-md-8">
      <div className="embed-responsive embed-responsive-16by9">
        <iframe className="embed-responsive-item" src={url} />
      </div>
      <div className="details">
        <div>{video.snippet.title}</div>
        <div>{video.snippet.description}</div>
      </div>
    </div>
  );
};

export default VideoDetail;
import React, { Component } from "react";

class SearchBar extends Component {
  constructor(props) {
    super(props);
    this.state = { term: "" };
  }

  render() {
    return (
      <div className="search-bar">
        <input
          className="form-control"
          onChange={event => this.onInputChange(event.target.value)}
          placeholder="Search YouTube"
          value={this.state.term}
        />
      </div>
    );
  }

  onInputChange(term) {
    this.setState({ term });
    this.props.onSearchTermChange(term);
  }
}

export default SearchBar;
import React from "react";

const VideoListItem = ({ video, onVideoSelect }) => {
  //const video = props.video;
  //const onVideoSelect = props.onVideoSelect;
  const imageUrl = video.snippet.thumbnails.default.url;

  return (
    <li onClick={() => onVideoSelect(video)} className="list-group-item">
      <div className="video-list media">
        <div className="media-left">
          <img className="media-object" src={imageUrl} />
        </div>
        <div className="media-body">
          <div className="media-heading">{video.snippet.title}</div>
        </div>
      </div>
    </li>
  );
};

export default VideoListItem;
import React from "react";
import VideoListItem from "./video_list_item.jsx";

const VideoList = props => {
  const videoItems = props.videos.map(video => {
    return (
      <VideoListItem
        onVideoSelect={props.onVideoSelect}
        key={video.etag}
        video={video}
      />
    );
  });

  return (
    <ul className="col-md-4 list-group">
      {videoItems}
    </ul>
  );
};

export default VideoList;