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\">","<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\n\tconst [videos, setVideos] = useState([]);\n\tconst [selectedVideo, setSelectedVideo] = useState(null);\n\n\tuseEffect(() => {\n\t\tonTermSubmit('vampire weekend harmony hall');\n\t}, []);\n\n\tconst 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\t\tsetVideos(response.data.items);\n\t\tsetSelectedVideo(response.data.items[0]);\n };\n\n\tconst onVideoSelect = (video) => setSelectedVideo(video);\n\n\treturn (\n\t\t<div className='App ui container'>\n\t\t\t<h1>ReactTube</h1>\n\t\t\t<SearchBar onTermSubmit={onTermSubmit} />\n\t\t\t<VideoDetail video={selectedVideo} />\n\t\t\t<VideoList videos={videos} onVideoSelect={onVideoSelect} />\n\t\t</div>\n\t);\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":"5f8cb971ff8bbb5639fa24af"} |