Skip to content

Instantly share code, notes, and snippets.

@ChristopherHButler
Created October 18, 2020 23:59
Show Gist options
  • Save ChristopherHButler/12f7db2d5fd48d1c5b777c66bb2b41a3 to your computer and use it in GitHub Desktop.
Save ChristopherHButler/12f7db2d5fd48d1c5b777c66bb2b41a3 to your computer and use it in GitHub Desktop.
ReactTube

ReactTube

This Gist was generated by Contrived.

Do not modify the metadata file if you want to open in Contrived again. Otherwise, it is safe to delete.

Happy Hacking!

{"user":"5f0c542a4a2ce5e528e01fdf","templateVersion":"1","templateId":"reactjs","resources":["<meta charset=\"UTF-8\" />","<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">","<script src=\"https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js\" integrity=\"sha512-dqw6X88iGgZlTsONxZK9ePmJEFrmHwpuMrsUChjAw1mRUhUITE5QU9pkcSox+ynfLhL15Sv2al5A0LVyDCmtUw==\" crossorigin=\"anonymous\"></script>","<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css\" integrity=\"sha512-8bHTC73gkZ7rZ7vpqUQThUDhqcNFyYi2xgDgPDHc+GXVGHXq+xPjynxIopALmOPqzo9JZj0k6OqqewdGO3EsrQ==\" crossorigin=\"anonymous\" />"],"dependencies":[{"name":"react","version":"16.13.1","type":"js","url":"https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"},{"name":"react-dom","version":"16.13.1","type":"js","url":"https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"},{"name":"axios","type":"js","url":"https://cdnjs.cloudflare.com/ajax/libs/axios/0.20.0/axios.min.js","version":"0.20.0"}],"files":[{"id":1,"parentId":0,"name":"public","type":"folder","isRoot":true,"selected":false,"expanded":false,"children":[{"id":2}]},{"id":2,"parentId":1,"name":"index.html","type":"file","mimeType":"html","isRoot":false,"open":false,"selected":false,"content":"<div id=\"root\"></div>\n"},{"id":3,"parentId":0,"name":"src","type":"folder","isRoot":true,"selected":false,"expanded":false,"children":[{"id":4},{"id":5},{"id":6}]},{"id":4,"parentId":3,"name":"App.js","type":"file","mimeType":"es6","isRoot":false,"open":true,"selected":true,"content":"const { useEffect, useState } = React;\n\nconst API_KEY = 'AIzaSyAFPbefcDTjeCcmNd06VmZfewoHVGJCT1I';\n\nconst api = axios.create({\n\tbaseURL: 'https://www.googleapis.com/youtube/v3',\n\tparams: {\n\t\tpart: 'snippet',\n\t\ttype: 'video',\n\t\tmaxResults: 5,\n\t\tkey: API_KEY,\n\t},\n});\n\nconst SearchBar = ({ onTermSubmit }) => {\n\n\tconst [term, setTerm] = useState('');\n\n\tconst onFormSubmit = (e) => {\n\t\te.preventDefault();\n\t\tonTermSubmit(term);\n\t};\n\n\treturn (\n\t\t<div className=\"search-bar ui segment\">\n\t\t\t<form onSubmit={onFormSubmit} className=\"ui form\">\n\t\t\t <div className=\"field\">\n\t\t\t\t\t<input type=\"text\" placeholder=\"Search\" value={term} onChange={e => setTerm(e.target.value)} />\n\t\t\t\t</div>\n\t\t\t</form>\n\t\t</div>\n\t);\n};\n\nconst VideoDetail = ({ video }) => {\n\n\tif (!video) return <div>Loading...</div>;\n\n\tconst videoSrc = `https://www.youtube.com/embed/${video.id.videoId}`;\n\n\treturn (\n\t\t<div>\n\t\t\t<div className=\"ui embed\">\n\t\t\t\t<iframe title=\"video player\" src={videoSrc} />\n\t\t\t</div>\n\t\t\t<div className=\"ui segment\">\n\t\t\t\t<h4 className=\"ui header\">{video.snippet.title}</h4>\n\t\t\t\t<p>{video.snippet.description}</p>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nconst VideoList = ({ videos, onVideoSelect }) => {\n\n\tconst renderedList = videos.map((video) => {\n\t\treturn <VideoItem key={video.id.videoId} video={video} onVideoSelect={onVideoSelect} />;\n\t});\n\n\treturn (\n\t\t<div className=\"ui relaxed divided list\">\n\t\t\t{renderedList}\n\t\t</div>\n\t);\n};\n\nconst VideoItem = ({ video, onVideoSelect }) => {\n\treturn (\n\t\t<div className=\"video-item item\" onClick={() => onVideoSelect(video)}>\n\t\t\t<img alt={video.snippet.title} className=\"ui image\" src={video.snippet.thumbnails.medium.url} />\n\t\t\t<div className=\"content\">\n\t\t\t\t<div className=\"header\">{video.snippet.title}</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nconst App = () => {\n const [videos, setVideos] = useState([]);\n\tconst [selectedVideo, setSelectedVideo] = useState(null);\n\n useEffect(() => {\n onTermSubmit('vampire weekend harmony hall');\n }, []);\n\n const onTermSubmit = async (term) => {\n const response = await api.get(\"/search\", {\n params: {\n q: term,\n part: \"snippet\",\n type: 'video',\n maxResults: 5,\n key: API_KEY,\n }\n });\n\n setVideos(response.data.items);\n setSelectedVideo(response.data.items[0]);\n };\n\n const onVideoSelect = (video) => setSelectedVideo(video);\n\n return (\n <div className='App ui container'>\n <h1>ReactTube</h1>\n <SearchBar onTermSubmit={onTermSubmit} />\n <VideoDetail video={selectedVideo} />\n <VideoList videos={videos} onVideoSelect={onVideoSelect} />\n </div>\n );\n};\n\nexport default App;"},{"id":5,"parentId":3,"name":"index.js","type":"file","mimeType":"es6","isRoot":false,"isEntry":true,"open":false,"selected":false,"content":"\nimport App from 'App.js';\n\n\nReactDOM.render(<App/>, document.getElementById('root'));\n"},{"id":6,"parentId":3,"name":"styles.css","type":"file","mimeType":"css","isRoot":false,"open":true,"selected":false,"content":".App {\n\tfont-family: sans-serif;\n\ttext-align: center;\n}"}],"experimentId":"5f8cd6e7bb3bcec3f158d85a"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment