-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate to functional components with hooks
- Loading branch information
1 parent
966b33b
commit d7e1cbd
Showing
7 changed files
with
11,372 additions
and
10,268 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,17 @@ | ||
import React, {Component} from 'react'; | ||
import Container from '../Container/Container'; | ||
import {Provider} from 'react-redux'; | ||
import configureStore from '../../store'; | ||
import React from "react"; | ||
import Container from "../Container/Container"; | ||
import { Provider } from "react-redux"; | ||
import configureStore from "../../store"; | ||
|
||
import './App.css'; | ||
import "./App.css"; | ||
|
||
const preloadedState = window.__PRELOADED_STATE__; | ||
const store = configureStore(preloadedState); | ||
|
||
class App extends Component { | ||
|
||
render() { | ||
return ( | ||
<Provider store={store}> | ||
<Container/> | ||
</Provider> | ||
); | ||
} | ||
} | ||
const App = () => ( | ||
<Provider store={store}> | ||
<Container /> | ||
</Provider> | ||
); | ||
|
||
export default App; |
72 changes: 23 additions & 49 deletions
72
lab3/src/components/BackgroundColorPicker/BackgroundColorPicker.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,30 @@ | ||
import React, {Component} from 'react'; | ||
import {connect} from 'react-redux'; | ||
import {setBackgroundColor} from '../../actions/backgroundActions'; | ||
|
||
import React from "react"; | ||
import { useDispatch } from "react-redux"; | ||
import { setBackgroundColor } from "../../actions/backgroundActions"; | ||
import colors from "./colors"; | ||
import "./BackgroundColorPicker.css"; | ||
|
||
class BackgroundColorPicker extends Component { | ||
|
||
colors = [ | ||
{ | ||
hex: 'lavender', | ||
name: 'lavender' | ||
}, | ||
{ | ||
hex: 'gold', | ||
name: 'gold' | ||
}, | ||
{ | ||
hex: '#f48c42', | ||
name: '🎃' | ||
}, | ||
{ | ||
hex: 'rebeccapurple', | ||
name: 'Beautiful purple' | ||
} | ||
]; | ||
const BackgroundColorPicker = () => { | ||
const dispatch = useDispatch(); | ||
|
||
handleOnChange = (e) => { | ||
this.props.setBackgroundColor(e.target.value); | ||
const handleOnChange = (e) => { | ||
dispatch(setBackgroundColor(e.target.value)); | ||
}; | ||
|
||
render() { | ||
return ( | ||
<div className="BackgroundColorPicker"> | ||
<h5>Välj bakgrundsfärg</h5> | ||
<select className="custom-select" onChange={this.handleOnChange}> | ||
{this.colors.map((color, index) => { | ||
return ( | ||
<option key={index} value={color.hex}>{color.name}</option> | ||
) | ||
})} | ||
</select> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
const mapDispatchToProps = (dispatch) => { | ||
return { | ||
setBackgroundColor: (color) => { | ||
dispatch(setBackgroundColor(color)); | ||
} | ||
}; | ||
return ( | ||
<div className="BackgroundColorPicker"> | ||
<h5>Välj bakgrundsfärg</h5> | ||
<select className="custom-select" onChange={handleOnChange}> | ||
{colors.map((color) => { | ||
return ( | ||
<option key={`color-${color.name}`} value={color.hex}> | ||
{color.name} | ||
</option> | ||
); | ||
})} | ||
</select> | ||
</div> | ||
); | ||
}; | ||
|
||
export default connect(null, mapDispatchToProps)(BackgroundColorPicker); | ||
export default BackgroundColorPicker; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
const colors = [ | ||
{ | ||
hex: "lavender", | ||
name: "lavender", | ||
}, | ||
{ | ||
hex: "gold", | ||
name: "gold", | ||
}, | ||
{ | ||
hex: "#f48c42", | ||
name: "🎃", | ||
}, | ||
{ | ||
hex: "rebeccapurple", | ||
name: "Beautiful purple", | ||
}, | ||
]; | ||
|
||
export default colors; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,44 @@ | ||
import React, {Component} from 'react'; | ||
import BackgroundColorPicker from '../BackgroundColorPicker/BackgroundColorPicker'; | ||
import List from '../List/List'; | ||
import {connect} from 'react-redux'; | ||
import {getAllUsers} from '../../actions/userActions'; | ||
import React, { useEffect } from "react"; | ||
import BackgroundColorPicker from "../BackgroundColorPicker/BackgroundColorPicker"; | ||
import List from "../List/List"; | ||
import { useDispatch, useSelector } from "react-redux"; | ||
import { getAllUsers } from "../../actions/userActions"; | ||
|
||
import './Container.css'; | ||
import "./Container.css"; | ||
|
||
class Container extends Component { | ||
const Container = () => { | ||
const dispatch = useDispatch(); | ||
const backgroundColor = useSelector((state) => state.background.bgColor); | ||
|
||
// TODO: Task 5 - Get all users upon mounting the component | ||
useEffect(() => {}, []); | ||
|
||
render() { | ||
return ( | ||
<div className="Container container" style={{background: this.props.backgroundColor}}> | ||
<div className="Container-header"> | ||
<p>Lab 3</p> | ||
<p className="Container-header-description"> | ||
<span role="img" aria-label="female technologist">👩💻</span> Öppna upp README.md och | ||
följ instruktionerna <span role="img" aria-label="male technologist">👨💻</span> | ||
</p> | ||
</div> | ||
<BackgroundColorPicker onChange={() => { | ||
console.log("FOO") | ||
}}/> | ||
<List title={'Users'} items={[]}/> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
// Maps the application state directly to component props | ||
const mapStateToProps = (state) => { | ||
return { | ||
backgroundColor: state.background.bgColor | ||
}; | ||
}; | ||
|
||
// Maps the action creators through dispatch directly to component props | ||
const mapDispatchToProps = { | ||
getAllUsers: getAllUsers | ||
return ( | ||
<div | ||
className="Container container" | ||
style={{ background: backgroundColor }} | ||
> | ||
<div className="Container-header"> | ||
<p>Lab 3</p> | ||
<p className="Container-header-description"> | ||
<span role="img" aria-label="female technologist"> | ||
👩💻 | ||
</span>{" "} | ||
Öppna upp README.md och följ instruktionerna{" "} | ||
<span role="img" aria-label="male technologist"> | ||
👨💻 | ||
</span> | ||
</p> | ||
</div> | ||
<BackgroundColorPicker | ||
onChange={() => { | ||
console.log("FOO"); | ||
}} | ||
/> | ||
<List title={"Users"} items={[]} /> | ||
</div> | ||
); | ||
}; | ||
|
||
// Connects the component to the redux cycle | ||
export default connect(mapStateToProps, mapDispatchToProps)(Container); | ||
export default Container; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,55 @@ | ||
import React, {Component} from 'react'; | ||
import SearchBar from '../SearchBar/SearchBar'; | ||
import {connect} from 'react-redux'; | ||
import React, { useState } from "react"; | ||
import SearchBar from "../SearchBar/SearchBar"; | ||
import { connect } from "react-redux"; | ||
|
||
import "./List.css"; | ||
|
||
class List extends Component { | ||
const List = ({ items, title }) => { | ||
const [searchTerm, setSearchTerm] = useState(""); | ||
|
||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
searchTerm: '' | ||
} | ||
} | ||
|
||
onItemClick = (userId) => { | ||
const onItemClick = (userId) => { | ||
console.log("Clicked on user", userId); | ||
}; | ||
|
||
onKeyPressed = (e) => { | ||
this.setState({ | ||
searchTerm: e.target.value | ||
}) | ||
}; | ||
|
||
filterListItemsBySearchTerm = (searchTerm) => { | ||
return this.props.items | ||
.filter(item => { | ||
return item.name.toLowerCase().includes(searchTerm.toLowerCase()) | ||
}) | ||
const onKeyPressed = (e) => { | ||
setSearchTerm(e.target.value); | ||
}; | ||
|
||
render() { | ||
const filteredItems = this.filterListItemsBySearchTerm(this.state.searchTerm); | ||
return ( | ||
<div className="List"> | ||
<h2 className="List-title">{this.props.title}</h2> | ||
<SearchBar onKeyPressed={this.onKeyPressed}/> | ||
{this.props.items.length === 0 ? ( | ||
<div className="alert alert-warning">Empty list...</div>) : ( | ||
<ul className="list-group"> | ||
{this.props.items.length > 0 && | ||
filteredItems.map((item, index) => ( | ||
<li className="List-item list-group-item" key={index} | ||
onClick={(e) => this.onItemClick(item.id)}>{item.name}</li> | ||
)) | ||
} | ||
</ul> | ||
)} | ||
</div> | ||
const filterListItemsBySearchTerm = (searchTerm) => | ||
items.filter((item) => | ||
item.name.toLowerCase().includes(searchTerm.toLowerCase()) | ||
); | ||
} | ||
} | ||
|
||
const filteredItems = filterListItemsBySearchTerm(searchTerm); | ||
|
||
return ( | ||
<div className="List"> | ||
<h2 className="List-title">{title}</h2> | ||
<SearchBar onKeyPressed={onKeyPressed} /> | ||
{filteredItems.length === 0 ? ( | ||
<div className="alert alert-warning">Empty list...</div> | ||
) : ( | ||
<ul className="list-group"> | ||
{filteredItems.length > 0 && | ||
filteredItems.map((item) => ( | ||
<li | ||
className="List-item list-group-item" | ||
key={item.id} | ||
onClick={(e) => onItemClick(item.id)} | ||
> | ||
{item.name} | ||
</li> | ||
))} | ||
</ul> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
const mapStateToProps = (state) => { | ||
return { | ||
items: [] // TODO: Task 6 - Implement mapStateToProps | ||
} | ||
items: [], // TODO: Task 6 - Implement mapStateToProps | ||
}; | ||
}; | ||
|
||
export default connect(mapStateToProps, null)(List); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,27 @@ | ||
import React, {Component} from 'react'; | ||
import React, { Component } from "react"; | ||
|
||
class SearchBar extends Component { | ||
render() { | ||
return ( | ||
<div className="input-group mb-12"> | ||
<div className="input-group-prepend"> | ||
<span className="input-group-text" | ||
id="basic-addon1" role="img" | ||
aria-label="search"> | ||
🔎 | ||
</span> | ||
</div> | ||
<input type="text" | ||
className="form-control" | ||
placeholder="Sökterm" | ||
aria-label="Sökterm" | ||
aria-describedby="basic-addon1" | ||
autoFocus | ||
onChange={this.props.onKeyPressed}/> | ||
</div> | ||
) | ||
} | ||
} | ||
const SearchBar = ({ onKeyPressed }) => ( | ||
<div className="input-group mb-12"> | ||
<div className="input-group-prepend"> | ||
<span | ||
className="input-group-text" | ||
id="basic-addon1" | ||
role="img" | ||
aria-label="search" | ||
> | ||
🔎 | ||
</span> | ||
</div> | ||
<input | ||
type="text" | ||
className="form-control" | ||
placeholder="Sökterm" | ||
aria-label="Sökterm" | ||
aria-describedby="basic-addon1" | ||
autoFocus | ||
onChange={onKeyPressed} | ||
/> | ||
</div> | ||
); | ||
|
||
export default SearchBar; |
Oops, something went wrong.