Skip to content

Commit

Permalink
Create Video Search
Browse files Browse the repository at this point in the history
Add Search Bar
Add Axios to fetch Youtube API
Add Style with semantic UI
display youtube thumbnails and name with videoList and VideoItem components
Add VideoItem css
Add VideoDetails Component to add Callbacks and display VideoDetail in App
Add some style to VideoDetails
  • Loading branch information
Isalafont committed Apr 15, 2022
1 parent a122b50 commit c534fe8
Show file tree
Hide file tree
Showing 19 changed files with 177 additions and 118 deletions.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,23 @@
/build

# misc
.idea/
.vscode/
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

*.tgz
my-app*
template/src/__tests__/__snapshots__/
lerna-debug.log

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/.changelog
.npm/
yarn.lock
8 changes: 8 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.0.1",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.26.1",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-scripts": "5.0.1",
Expand Down
7 changes: 7 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
name="description"
content="Web site created using create-react-app"
/>
<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"
referrerpolicy="no-referrer"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
Expand Down
38 changes: 0 additions & 38 deletions src/App.css

This file was deleted.

25 changes: 0 additions & 25 deletions src/App.js

This file was deleted.

8 changes: 0 additions & 8 deletions src/App.test.js

This file was deleted.

14 changes: 14 additions & 0 deletions src/apis/youtube.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import axios from 'axios';

const KEY = 'AIzaSyBJDGB39IlFbvrMJ1rC8PIIzvsXePaKSi8';

export default axios.create({
baseURL: 'https://www.googleapis.com/youtube/v3',
params: {
part: 'snippet',
type: 'video',
maxResults: 5,
key: KEY,
},
});

38 changes: 38 additions & 0 deletions src/components/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import SearchBar from './SearchBar';
import youtube from '../apis/youtube';
import VideoList from './VideoList';
import VideoDetail from './VideoDetail';

class App extends React.Component {
state = { videos: [], selectedVideo: null };

onTermSubmit = async term => {
const response = await youtube.get('/search', {
params: {
q: term,
}
});

this.setState({ videos: response.data.items });
};

onVideoSelect = (video) => {
this.setState({ selectedVideo: video })
};

render() {
return (
<div className="ui container" style={{ marginTop: '30px' }}>
<SearchBar onFormSubmit={this.onTermSubmit} />
<VideoDetail video={this.state.selectedVideo} />
<VideoList
onVideoSelect={this.onVideoSelect}
videos={this.state.videos}
/>
</div>
)
}
}

export default App;
38 changes: 38 additions & 0 deletions src/components/SearchBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';

class SearchBar extends React.Component {
state = { term: '' };

onInputChange = (event) => {
this.setState({ term: event.target.value })
};

onFormSubmit = event =>{
event.preventDefault();

this.props.onFormSubmit(this.state.term)
};

render () {
return (
<div className="search-bar ui segment">
<form onSubmit={this.onFormSubmit} className="ui form">
<div className="field">
<label>Video Search</label>
<div className="ui icon input">
<input
className="prompt"
type="text" placeholder="Search videos..."
value={this.state.term}
onChange={this.onInputChange}
/>
<i className="search icon"></i>
</div>
</div>
</form>
</div>
);
}
}

export default SearchBar;
18 changes: 18 additions & 0 deletions src/components/VideoDetail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from "react";

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

return (
<div>
<div className="ui segment">
<h4 className="ui header">{video.snippet.title}</h4>
<p className="">{video.snippet.description}</p>
</div>
</div>
);
};

export default VideoDetail;
9 changes: 9 additions & 0 deletions src/components/VideoItem.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.video-item {
display: flex !important;
align-items: center;
cursor: pointer;
}

.video-item.item img {
max-width: 180px;
}
15 changes: 15 additions & 0 deletions src/components/VideoItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import './VideoItem.css';
import React from 'react';

const VideoItem = ({ video, onVideoSelect }) => {
return (
<div onClick={() => onVideoSelect(video)} className='video-item item'>
<img className='ui image' alt={video.snippet.description} src={video.snippet.thumbnails.medium.url} />
<div className='content'>
<div className='header'>{video.snippet.title} </div>
</div>
</div>
)
};

export default VideoItem;
12 changes: 12 additions & 0 deletions src/components/VideoList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import VideoItem from './VideoItem';

const VideoList = ({ videos, onVideoSelect }) => {
const renderedList = videos.map((video) => {
return <VideoItem onVideoSelect={onVideoSelect} video={video} />;
});

return <div className='ui relaxed divided list'>{renderedList}</div>
};

export default VideoList;
13 changes: 0 additions & 13 deletions src/index.css

This file was deleted.

21 changes: 6 additions & 15 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import ReactDOM from 'react-dom';
import App from './components/App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
ReactDOM.render(
<App />,
document.querySelector('#root')
);
1 change: 0 additions & 1 deletion src/logo.svg

This file was deleted.

13 changes: 0 additions & 13 deletions src/reportWebVitals.js

This file was deleted.

5 changes: 0 additions & 5 deletions src/setupTests.js

This file was deleted.

0 comments on commit c534fe8

Please sign in to comment.