Skip to content
50 changes: 24 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,39 @@
* From address book directory, run yarn install, yarn start

### Do
* Import the array of users into index.js
* Create a folder in src called components to hold all our components
* Create the UserDetail and ListOfUsers functional components
* Import and use components in App
* Send the user array into Apps and then into ListOfUsers
* Send the first user from the array down into the UserDetail component
* xImport the array of users into index.js
* xCreate a folder in src called components to hold all our components
* xCreate the UserDetail and ListOfUsers functional components
* xImport and use components in App
* xSend the user array into Apps and then into ListOfUsers
* xSend the first user from the array down into the UserDetail component

### Do
* Add a button to the ListOfUsers component that says Hide
* Add an onClick to the button and a handler
* Make clicking the button hide the list and change the text to “Show”
* If you click it again it will show the list and change the text back to “Hide”
* xAdd a button to the ListOfUsers component that says Hide
* xAdd an onClick to the button and a handler
* xMake clicking the button hide the list and change the text to “Show”
* xIf you click it again it will show the list and change the text back to “Hide”

### Do
* Change ListOfUsers to be a class component
* Add a constructor
* Add a property called “state” that is an object
* Add a property on the state object called "visible"
* Add a method called “render” that returns the jsx the function returned
* xChange ListOfUsers to be a class component
* xAdd a constructor
* xAdd a property called “state” that is an object
* xAdd a property on the state object called "visible"
* xAdd a method called “render” that returns the jsx the function returned

### Do
* Add text box anywhere to ListOfUsers with a label “Search”
* In ListOfUsers add a state property “searchText”, default to “”
* Assign searchText to the value attribute of the text box
* xAdd text box anywhere to ListOfUsers with a label “Search”
* xIn ListOfUsers add a state property “searchText”, default to “”
* xAssign searchText to the value attribute of the text box

### Do
* Add onChange to text box
* In onChange handler function, setState the searchText to the value from the textbox
* xAdd onChange to text box
* xIn onChange handler function, setState the searchText to the value from the textbox

### Do
* Create a variable called currentUser in index.js.
* Define a function in index.js called selectUser that will take a user as a parameter and then set that user as the currentUser.
* Send this function down the child tree so that ListOfUsers can call it
* Change index.js to send currentUser down the child tree instead of App.js hard coding the first one
* xCreate a variable called currentUser in index.js.
* xDefine a function in index.js called selectUser that will take a user as a parameter and then set that user as the currentUser.
* xSend this function down the child tree so that ListOfUsers can call it
* xChange index.js to send currentUser down the child tree instead of App.js hard coding the first one
* Register click event for ListOfUsers view link, call the function sent into props by parents, supply the argument of whatever user was clicked on.
* Re render the components


16 changes: 12 additions & 4 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import ListOfUsers from "./components/ListOfUsers.js";
import UserDetail from "./components/UserDetail.js";
import SearchBox from "./components/SearchBox.js";

function App() {

function App(props) {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>

<div>
<SearchBox />
<ListOfUsers />
<UserDetail />
</div>

</div>
);
}
Expand Down
13 changes: 13 additions & 0 deletions src/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function setCurrentUser(user){
return {
type:"SET_CURRENT_USER",
value: user
}
}

export function setSearchText(text) {
return {
type: "SET_TEXT",
value: text
}
}
73 changes: 73 additions & 0 deletions src/components/ListOfUsers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react';
import { connect } from 'react-redux';
import {setCurrentUser} from '../actions';

class ListOfUsers extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: true
};
// this.buttonClick = this.buttonClick.bind(this);
// this.props.SelectUser = this.props.SelectUser.bind(this);
}

buttonClick = () => {
this.setState(prevState => ({
visible: !prevState.visible
}));
}

render() {

// filterUsers filters the
console.log(this.props.searchText);
var filterUsers = this.props.users.filter((u) => {
if(this.props.searchText === "") {
return true;
};
if(u.first_name.indexOf(this.props.searchText) > -1) {
return true;
} else return false;
});

const userDivs = filterUsers.map((user) => {
if (this.state.visible) {

return <div key={user.id}>
{user.first_name}
<a onClick={ (e) => {e.preventDefault(); this.props.setCurrentUser(user)} }> View </a>
</div>
}
else return <div></div>
});

return (
<div>
<div>{userDivs}</div>
<button onClick={this.buttonClick}>{this.state.visible ? 'HIDE' : 'SHOW'}</button>

</div>
)
}
}

function mapStateToProps(state) {
return {
users: state.users,
searchText: state.searchText
}
}

function mapDispatchToProps(dispatch){
return {
setCurrentUser:function(user){
dispatch(setCurrentUser(user));
}
}
}

export default connect(mapStateToProps, mapDispatchToProps)(ListOfUsers);;


// export default ListOfUsers;
24 changes: 24 additions & 0 deletions src/components/SearchBox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import {setSearchText} from '../actions';
import { connect } from 'react-redux';



function SearchBox(props) {
return (
<input placeholder="search"
onChange={ (e) =>{
e.preventDefault();
props.setSearchText(e.target.value);
} } />
)
}

function mapDispatchToProps(dispatch){
return {
setSearchText:function(text){
dispatch(setSearchText(text));
}
}
}
export default connect(null, mapDispatchToProps)(SearchBox);;
23 changes: 23 additions & 0 deletions src/components/UserDetail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import { connect } from 'react-redux';


function UserDetail(props) {
return <div>
<h1>{props.selectedUser.first_name} {props.selectedUser.last_name}</h1>
<div>{props.selectedUser.address}</div>
<div>{props.selectedUser.phone}</div>
<div>{props.selectedUser.occupation}</div>
<div><img src={props.selectedUser.avatar} alt="" /></div>
</div>
}

function mapStateToProps(state) {
return {
selectedUser: state.currentUser
}
}

const UserDetailContainer = connect(mapStateToProps)(UserDetail);
export default UserDetailContainer
// export default UserDetail;
16 changes: 13 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@ import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import "./index.css";
import users from "./users";
import store from "./store";
import {Provider} from 'react-redux';


// var selectedUser = '';
//
// function selectUser(user) {
// selectedUser = user;
// render();
// };

function render() {
ReactDOM.render(
<App />,
document.getElementById("root")
<Provider store={store}><App /></Provider>,
document.getElementById('root')
);
}
render();

// export default selectUser;
26 changes: 26 additions & 0 deletions src/reducers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {combineReducers} from 'redux';


function users(state=[], action) {
return state;
}

function currentUser(state={}, action) {
if (action.type === "SET_CURRENT_USER") {
return action.value;
}
return state;
}

function searchText(state="", action) {
if (action.type === "SET_TEXT") {
return action.value
}
return state;
}


const rootReducer = combineReducers({
users,searchText,currentUser
});
export default rootReducer;
8 changes: 8 additions & 0 deletions src/state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import users from './users';


export default {
users: users,
currentUser: users[0],
searchText: "",
}
8 changes: 8 additions & 0 deletions src/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {createStore} from 'redux';
import state from "./state";
import reducers from './reducers';


var store = createStore(reducers,state);

export default store;