Skip to content

Commit c75c99b

Browse files
committed
[WIP] Remove & Edit user
1 parent 4fd539b commit c75c99b

File tree

8 files changed

+166
-39
lines changed

8 files changed

+166
-39
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo
99
* [Rebass](http://jxnblk.com/rebass/)
1010
* [react-snapshot](https://www.npmjs.com/package/react-snapshot)
1111
* [styled-components](https://github.com/styled-components/styled-components)
12+
* [faker](https://github.com/marak/Faker.js//)

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"version": "0.1.0",
55
"private": true,
66
"dependencies": {
7+
"faker": "^4.1.0",
78
"gh-pages": "^1.0.0",
89
"prop-types": "^15.5.10",
910
"react": "^15.6.1",

src/components/UserCreation/index.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,40 @@ class UserCreation extends PureComponent {
1414

1515
static defaultProps = {
1616
name: '',
17-
age: 10,
17+
age: 0,
1818
nickname: '',
1919
onChange: (field, value) => {},
2020
onSave: user => {},
2121
onCancel: () => {}
2222
};
2323

24+
onSubmit = evt => {
25+
evt.preventDefault();
26+
console.warn('onSubmit');
27+
};
28+
2429
render() {
2530
const { age, name, nickname } = this.props;
26-
2731
return (
2832
<Container>
2933
<Row>
3034
<Input
35+
required
3136
placeholder="Name"
3237
name="name"
3338
value={name}
3439
onChange={evt => this.props.onChange('name', evt.target.value)}
3540
/>
3641
<Input
42+
required
3743
type="number"
3844
placeholder="0"
3945
name="age"
4046
value={age}
4147
onChange={evt => this.props.onChange('age', evt.target.value)}
4248
/>
4349
<Input
50+
required
4451
placeholder="Nickname"
4552
name="nickname"
4653
value={nickname}

src/components/UserList/UserItem.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,26 @@ import { Row, Column, Button } from 'rebass';
44

55
class UserItem extends Component {
66
static propTypes = {
7-
id: PropTypes.number.isRequired,
7+
id: PropTypes.string.isRequired,
88
name: PropTypes.string.isRequired,
99
age: PropTypes.number.isRequired,
1010
nickname: PropTypes.string.isRequired,
11-
isEdit: PropTypes.bool.isRequired
11+
isEdit: PropTypes.bool.isRequired,
12+
onEdit: PropTypes.func.isRequired,
13+
onRemove: PropTypes.func.isRequired
1214
};
1315

1416
static defaultProps = {
1517
id: 0,
1618
name: '',
1719
age: 0,
1820
nickname: '',
19-
isEdit: false
21+
isEdit: false,
22+
onEdit: (userId, user) => {},
23+
onRemove: userId => {}
2024
};
2125

22-
renderAction = isEdit => {
26+
renderAction = ({ id, isEdit }) => {
2327
if (isEdit) {
2428
return (
2529
<Column>
@@ -31,7 +35,12 @@ class UserItem extends Component {
3135
return (
3236
<Column>
3337
<Button children="Edit" />
34-
<Button children="Delete" />
38+
<Button
39+
onClick={() => {
40+
this.props.onRemove(id);
41+
}}
42+
children="Delete"
43+
/>
3544
</Column>
3645
);
3746
};
@@ -49,7 +58,7 @@ class UserItem extends Component {
4958
<Column>
5059
{nickname}
5160
</Column>
52-
{this.renderAction(isEdit)}
61+
{this.renderAction(this.props)}
5362
</Row>
5463
);
5564
}

src/components/UserList/index.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
1-
import React, { PureComponent } from 'react';
1+
import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
33
import { Container, Row, Column, Divider } from 'rebass';
44
import UserItem from './UserItem';
55

6-
class UserList extends PureComponent {
6+
class UserList extends Component {
77
static propTypes = {
8-
users: PropTypes.array.isRequired
8+
users: PropTypes.array.isRequired,
9+
onEdit: PropTypes.func.isRequired,
10+
onRemove: PropTypes.func.isRequired
911
};
1012

1113
static defaultProps = {
12-
users: []
14+
users: [],
15+
onEdit: (userId, user) => {},
16+
onRemove: userId => {}
1317
};
1418

1519
renderUserRow = users => {
1620
return users.map(item =>
17-
<UserItem key={`${item.id}-${item.nickname}`} {...item} />
21+
<UserItem
22+
key={`${item.id}-${item.nickname}`}
23+
{...item}
24+
onEdit={this.props.onEdit}
25+
onRemove={this.props.onRemove}
26+
/>
1827
);
1928
};
2029

src/containers/Users/index.js

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,65 @@
11
import React, { Component } from 'react';
2+
import { Flex, Box, Button } from 'rebass';
23
import UserList from '../../components/UserList';
34
import UserCreation from '../../components/UserCreation';
4-
import { Flex, Box, Button } from 'rebass';
5+
import {
6+
getUsers,
7+
addUser,
8+
updateUser,
9+
removeUser,
10+
initFakeData
11+
} from '../../store/user';
512

613
class Users extends Component {
714
state = {
815
users: [],
916
isAdding: false,
1017
newUser: {
1118
name: '',
12-
age: 10,
19+
age: 0,
1320
nickname: ''
1421
}
1522
};
1623

17-
showNewUserForm = () => {
24+
onShowNewUserForm = () => {
1825
this.setState(prevState => ({ isAdding: true }));
1926
};
2027

21-
closeNewUserForm = () => {
28+
onCloseNewUserForm = () => {
2229
this.setState(prevState => ({ isAdding: false }));
2330
};
2431

25-
addUser = () => {
26-
console.warn('addUser');
27-
const { newUser } = this.state;
28-
this.setState(
29-
prevState => ({
30-
users: [].concat(prevState.users, { ...newUser, id: Date.now() })
31-
}),
32-
() => {
33-
this.setState({
34-
newUser: {
35-
name: '',
36-
age: 10,
37-
nickname: ''
38-
}
39-
});
40-
}
41-
);
32+
onAddUser = () => {
33+
const { newUser, users } = this.state;
34+
console.warn('onAddUser', newUser);
35+
addUser(newUser, () => {
36+
this.setState({
37+
users: getUsers(),
38+
newUser: {
39+
name: '',
40+
age: 0,
41+
nickname: ''
42+
}
43+
});
44+
});
45+
};
46+
47+
onUpdateUser = (id, user) => {
48+
console.warn('onRemoveUser', id);
49+
updateUser(id, user, () => {
50+
this.setState({
51+
users: getUsers()
52+
});
53+
});
54+
};
55+
56+
onRemoveUser = id => {
57+
console.warn('onRemoveUser', id);
58+
removeUser(id, () => {
59+
this.setState({
60+
users: getUsers()
61+
});
62+
});
4263
};
4364

4465
onChangeInput = (field, value) => {
@@ -51,7 +72,7 @@ class Users extends Component {
5172
hasChange = true;
5273
break;
5374
case 'age':
54-
updateData = Object.assign({}, newUser, { age: value });
75+
updateData = Object.assign({}, newUser, { age: Number(value) });
5576
hasChange = true;
5677
break;
5778
case 'nickname':
@@ -68,25 +89,38 @@ class Users extends Component {
6889
}
6990
};
7091

92+
componentWillMount() {
93+
console.warn('componentWillMount');
94+
initFakeData();
95+
this.setState({
96+
users: getUsers()
97+
});
98+
}
99+
71100
render() {
72101
const { users, isAdding, newUser } = this.state;
102+
console.warn('Users render', users, isAdding, newUser);
73103
return (
74104
<Flex column align="center">
75105
<Box m="auto">
76-
<UserList users={users} />
106+
<UserList
107+
users={users}
108+
onEdit={this.onUpdateUser}
109+
onRemove={this.onRemoveUser}
110+
/>
77111
</Box>
78112
{isAdding &&
79113
<Box m="auto">
80114
<UserCreation
81115
{...newUser}
82-
onSave={this.addUser}
83-
onCancel={this.closeNewUserForm}
116+
onSave={this.onAddUser}
117+
onCancel={this.onCloseNewUserForm}
84118
onChange={this.onChangeInput}
85119
/>
86120
</Box>}
87121
{!isAdding &&
88122
<Box m="auto">
89-
<Button onClick={this.showNewUserForm} children="Add" />
123+
<Button onClick={this.onShowNewUserForm} children="Add" />
90124
</Box>}
91125
</Flex>
92126
);

src/store/user.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import faker from 'faker';
2+
const DB_KEY = 'REACT_USERS';
3+
let data = [];
4+
5+
function getRandomIntInclusive(min, max) {
6+
min = Math.ceil(min);
7+
max = Math.floor(max);
8+
return Math.floor(Math.random() * (max - min + 1)) + min; //The maximum is inclusive and the minimum is inclusive
9+
}
10+
11+
function initFakeData() {
12+
try {
13+
data = JSON.parse(localStorage.getItem(DB_KEY));
14+
} catch (error) {
15+
data = [];
16+
}
17+
if (data.length === 0) {
18+
for (let index = 0; index < 5; index++) {
19+
data.push({
20+
id: faker.random.uuid(),
21+
name: faker.name.findName(),
22+
age: getRandomIntInclusive(20, 40),
23+
nickname: faker.internet.userName()
24+
});
25+
}
26+
localStorage.setItem(DB_KEY, JSON.stringify(data));
27+
}
28+
}
29+
30+
function addUser(user, callback) {
31+
const newUser = { id: faker.random.uuid(), ...user };
32+
data.push(newUser);
33+
localStorage.setItem(DB_KEY, JSON.stringify(data));
34+
callback && callback();
35+
}
36+
37+
function removeUser(userId, callback) {
38+
const foundIndex = data.findIndex(item => item.id === userId);
39+
40+
if (foundIndex !== -1) {
41+
data.splice(foundIndex, 1);
42+
}
43+
localStorage.setItem(DB_KEY, JSON.stringify(data));
44+
callback && callback();
45+
}
46+
47+
function updateUser(userId, user, callback) {
48+
const foundIndex = data.find(item => item.id === userId);
49+
if (foundIndex !== -1) {
50+
const updateData = Object.assign({}, data[foundIndex], user);
51+
data.splice(foundIndex, 1, updateData);
52+
}
53+
localStorage.setItem(DB_KEY, JSON.stringify(data));
54+
callback && callback();
55+
}
56+
57+
function getUsers() {
58+
console.warn('getUsers', data);
59+
return data;
60+
}
61+
62+
export { initFakeData, getUsers, addUser, updateUser, removeUser };

yarn.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2982,6 +2982,10 @@ extsprintf@1.3.0, extsprintf@^1.2.0:
29822982
version "1.3.0"
29832983
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
29842984

2985+
faker@^4.1.0:
2986+
version "4.1.0"
2987+
resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f"
2988+
29852989
fast-deep-equal@^1.0.0:
29862990
version "1.0.0"
29872991
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"

0 commit comments

Comments
 (0)