End of chapter 31
This commit is contained in:
parent
e98f23de32
commit
2ebd5d5c2a
@ -5,6 +5,8 @@
|
|||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/App.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/App.js" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/App.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/App.js" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/components/users/Search.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/users/Search.js" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/components/users/Search.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/users/Search.js" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/components/users/User.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/users/User.js" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/components/users/Users.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/users/Users.js" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/context/github/GithubState.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/context/github/GithubState.js" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/context/github/GithubState.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/context/github/GithubState.js" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/context/github/githubReducer.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/context/github/githubReducer.js" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/context/github/githubReducer.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/context/github/githubReducer.js" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
@ -120,7 +122,7 @@
|
|||||||
<workItem from="1570713775683" duration="2307000" />
|
<workItem from="1570713775683" duration="2307000" />
|
||||||
<workItem from="1570716281021" duration="2536000" />
|
<workItem from="1570716281021" duration="2536000" />
|
||||||
<workItem from="1570719196036" duration="7092000" />
|
<workItem from="1570719196036" duration="7092000" />
|
||||||
<workItem from="1571151198512" duration="168000" />
|
<workItem from="1571151198512" duration="2197000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="End of Chapter 14">
|
<task id="LOCAL-00001" summary="End of Chapter 14">
|
||||||
<created>1569512995385</created>
|
<created>1569512995385</created>
|
||||||
@ -241,7 +243,14 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1570721044833</updated>
|
<updated>1570721044833</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="18" />
|
<task id="LOCAL-00018" summary="End of chapter 30">
|
||||||
|
<created>1571151552015</created>
|
||||||
|
<option name="number" value="00018" />
|
||||||
|
<option name="presentableId" value="LOCAL-00018" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1571151552015</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="19" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
@ -278,6 +287,7 @@
|
|||||||
<MESSAGE value="End of chapter 27" />
|
<MESSAGE value="End of chapter 27" />
|
||||||
<MESSAGE value="End of chapter 28" />
|
<MESSAGE value="End of chapter 28" />
|
||||||
<MESSAGE value="End of chapter 29" />
|
<MESSAGE value="End of chapter 29" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="End of chapter 29" />
|
<MESSAGE value="End of chapter 30" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="End of chapter 30" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
53
src/App.js
53
src/App.js
@ -14,43 +14,11 @@ import GithubState from './context/github/GithubState';
|
|||||||
import './App.css';
|
import './App.css';
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [users, setUsers] = useState([]);
|
|
||||||
const [user, setUser] = useState({});
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [alert, setAlert] = useState(null);
|
const [alert, setAlert] = useState(null);
|
||||||
const [repos, setRepos] = useState([]);
|
const [repos, setRepos] = useState([]);
|
||||||
|
|
||||||
// Search github users
|
|
||||||
/*
|
|
||||||
* const searchUsers = async text => {
|
|
||||||
* setLoading(true);
|
|
||||||
* const res = await axios.get(
|
|
||||||
* `https://api.github.com/search/users?q=${text}&client_id=${
|
|
||||||
* process.env.REACT_APP_GITHUB_CLIENT_ID
|
|
||||||
* }&client_secret=${process.env.REACT_APP_GITHUB_CLIENT_SECRET}`
|
|
||||||
* );
|
|
||||||
*
|
|
||||||
* setUsers(res.data.items);
|
|
||||||
* setLoading(false);
|
|
||||||
* };
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Get Single user
|
|
||||||
|
|
||||||
const getUser = async username => {
|
|
||||||
setLoading(true);
|
|
||||||
const res = await axios.get(
|
|
||||||
`https://api.github.com/users/${username}?client_id=${
|
|
||||||
process.env.REACT_APP_GITHUB_CLIENT_ID
|
|
||||||
}&client_secret=${process.env.REACT_APP_GITHUB_CLIENT_SECRET}`
|
|
||||||
);
|
|
||||||
|
|
||||||
setUser(res.data);
|
|
||||||
setLoading(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getUserRepos = async username => {
|
const getUserRepos = async username => {
|
||||||
setLoading(true);
|
// setLoading(true);
|
||||||
const res = await axios.get(
|
const res = await axios.get(
|
||||||
`https://api.github.com/users/${username}/repos?per_page=5&sort=created:asc&client_id=${
|
`https://api.github.com/users/${username}/repos?per_page=5&sort=created:asc&client_id=${
|
||||||
process.env.REACT_APP_GITHUB_CLIENT_ID
|
process.env.REACT_APP_GITHUB_CLIENT_ID
|
||||||
@ -58,14 +26,7 @@ const App = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
setRepos(res.data);
|
setRepos(res.data);
|
||||||
setLoading(false);
|
// setLoading(false);
|
||||||
};
|
|
||||||
|
|
||||||
// Clear Users from State
|
|
||||||
|
|
||||||
const clearUsers = () => {
|
|
||||||
setUsers([]);
|
|
||||||
setLoading(false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Show an alert
|
// Show an alert
|
||||||
@ -91,11 +52,10 @@ const App = () => {
|
|||||||
render={props => (
|
render={props => (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<Search
|
<Search
|
||||||
clearUsers={clearUsers}
|
|
||||||
showClear={users.length > 0}
|
|
||||||
setAlert={showAlert}
|
setAlert={showAlert}
|
||||||
/>
|
/>
|
||||||
<Users loading={loading} users={users} />
|
<Users />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@ -106,10 +66,9 @@ const App = () => {
|
|||||||
render={props => (
|
render={props => (
|
||||||
<User
|
<User
|
||||||
{...props}
|
{...props}
|
||||||
getUser={getUser}
|
|
||||||
getUserRepos={getUserRepos}
|
getUserRepos={getUserRepos}
|
||||||
user={user}
|
|
||||||
loading={loading}
|
|
||||||
repos={repos}
|
repos={repos}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import React, { useState, useContext } from "react";
|
import React, { useState, useContext } from 'react';
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import GithubContext from '../../context/github/githubContext';
|
import GithubContext from '../../context/github/githubContext';
|
||||||
|
|
||||||
const Search = ({ showClear, clearUsers, setAlert }) => {
|
const Search = ({ setAlert }) => {
|
||||||
const githubContext = useContext(GithubContext);
|
const githubContext = useContext(GithubContext);
|
||||||
const [text, setText] = useState("");
|
const [text, setText] = useState('');
|
||||||
const onChange = e => {
|
const onChange = e => {
|
||||||
setText(e.target.value);
|
setText(e.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = e => {
|
const onSubmit = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (text === "") {
|
if (text === '')
|
||||||
setAlert("Please enter something", "light");
|
setAlert('Please enter something', 'light');
|
||||||
} else {
|
else {
|
||||||
githubContext.searchUsers(text);
|
githubContext.searchUsers(text);
|
||||||
setText('');
|
setText('');
|
||||||
}
|
}
|
||||||
@ -36,8 +36,8 @@ const Search = ({ showClear, clearUsers, setAlert }) => {
|
|||||||
className="btn btn-dark btn-block"
|
className="btn btn-dark btn-block"
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
{showClear && (
|
{githubContext.users.length > 0 && (
|
||||||
<button className="btn btn-light btn-block" onClick={clearUsers}>
|
<button className="btn btn-light btn-block" onClick={githubContext.clearUsers}>
|
||||||
Clear
|
Clear
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
@ -47,9 +47,7 @@ const Search = ({ showClear, clearUsers, setAlert }) => {
|
|||||||
|
|
||||||
Search.propTypes = {
|
Search.propTypes = {
|
||||||
|
|
||||||
clearUsers: PropTypes.func.isRequired,
|
'setAlert': PropTypes.func.isRequired
|
||||||
showClear: PropTypes.bool.isRequired,
|
|
||||||
setAlert: PropTypes.func.isRequired
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Search;
|
export default Search;
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
import React, { useEffect, Fragment } from 'react';
|
import React, { useEffect, Fragment, useContext } from 'react';
|
||||||
import Spinner from '../layout/Spinner';
|
import Spinner from '../layout/Spinner';
|
||||||
import Repos from '../repos/Repos';
|
import Repos from '../repos/Repos';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import GithubContext from '../../context/github/githubContext';
|
||||||
|
|
||||||
|
const User = ({ getUserRepos, repos, match }) => {
|
||||||
|
const githubContext = useContext(GithubContext);
|
||||||
|
const { getUser, loading, user } = githubContext;
|
||||||
|
|
||||||
const User = ({ user, loading, getUser, getUserRepos, repos, match }) => {
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getUser(match.params.login);
|
getUser(match.params.login);
|
||||||
getUserRepos(match.params.login);
|
getUserRepos(match.params.login);
|
||||||
@ -101,9 +105,6 @@ const User = ({ user, loading, getUser, getUserRepos, repos, match }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
User.propTypes = {
|
User.propTypes = {
|
||||||
'loading': PropTypes.bool,
|
|
||||||
'user': PropTypes.object.isRequired,
|
|
||||||
'getUser': PropTypes.func.isRequired,
|
|
||||||
'getUserRepos': PropTypes.func.isRequired,
|
'getUserRepos': PropTypes.func.isRequired,
|
||||||
'repos': PropTypes.array.isRequired
|
'repos': PropTypes.array.isRequired
|
||||||
};
|
};
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
import React from 'react';
|
import React, { useContext } from 'react';
|
||||||
import UserItem from './UserItem';
|
import UserItem from './UserItem';
|
||||||
import Spinner from '../layout/Spinner';
|
import Spinner from '../layout/Spinner';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const Users = ({ users, loading }) => {
|
import GithubContext from '../../context/github/githubContext';
|
||||||
|
|
||||||
|
const Users = () => {
|
||||||
|
const githubContext = useContext(GithubContext);
|
||||||
|
|
||||||
|
const { loading, users } = githubContext;
|
||||||
|
|
||||||
if(loading)
|
if(loading)
|
||||||
return <Spinner/>;
|
return <Spinner/>;
|
||||||
else
|
else
|
||||||
@ -17,11 +22,6 @@ const Users = ({ users, loading }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Users.propTypes = {
|
|
||||||
'users': PropTypes.array.isRequired,
|
|
||||||
'loading': PropTypes.bool.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
const userStyle = {
|
const userStyle = {
|
||||||
'display':'grid',
|
'display':'grid',
|
||||||
'gridTemplateColumns':'repeat(3, 1fr)',
|
'gridTemplateColumns':'repeat(3, 1fr)',
|
||||||
|
@ -33,11 +33,32 @@ const GithubState = props => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// get user
|
/*
|
||||||
|
* get user
|
||||||
|
* Get Single user
|
||||||
|
*/
|
||||||
|
|
||||||
|
const getUser = async username => {
|
||||||
|
setLoading();
|
||||||
|
const res = await axios.get(
|
||||||
|
`https://api.github.com/users/${username}?client_id=${
|
||||||
|
process.env.REACT_APP_GITHUB_CLIENT_ID
|
||||||
|
}&client_secret=${process.env.REACT_APP_GITHUB_CLIENT_SECRET}`
|
||||||
|
);
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
'type':GET_USER, 'payload':res.data
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// get repos
|
// get repos
|
||||||
|
|
||||||
// clear users
|
/*
|
||||||
|
* clear users
|
||||||
|
* Clear Users from State
|
||||||
|
*/
|
||||||
|
|
||||||
|
const clearUsers = () => dispatch({ 'type':CLEAR_USERS });
|
||||||
|
|
||||||
// set loading
|
// set loading
|
||||||
|
|
||||||
@ -50,7 +71,9 @@ const GithubState = props => {
|
|||||||
'user': state.user,
|
'user': state.user,
|
||||||
'repos': state.repos,
|
'repos': state.repos,
|
||||||
'loading': state.loading,
|
'loading': state.loading,
|
||||||
searchUsers
|
searchUsers,
|
||||||
|
clearUsers,
|
||||||
|
getUser
|
||||||
}}
|
}}
|
||||||
|
|
||||||
>
|
>
|
||||||
|
@ -16,6 +16,18 @@ export default (state, action) => {
|
|||||||
users: action.payload,
|
users: action.payload,
|
||||||
loading: false
|
loading: false
|
||||||
};
|
};
|
||||||
|
case GET_USER:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
user: action.payload,
|
||||||
|
loading: false
|
||||||
|
};
|
||||||
|
case CLEAR_USERS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
users:[],
|
||||||
|
loading:false
|
||||||
|
};
|
||||||
case SET_LOADING:
|
case SET_LOADING:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
Loading…
Reference in New Issue
Block a user