Skip to content

Commit eebff86

Browse files
committed
Refactor code for better readability 👀
1 parent e3ad58a commit eebff86

File tree

3 files changed

+220
-212
lines changed

3 files changed

+220
-212
lines changed

src/components/Main/CreateTodo.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class CreateTodoContainer extends React.Component {
6464

6565
render() {
6666
const { input } = this.state;
67-
const { id, theme } = this.props;
67+
const { productId, theme } = this.props;
6868

6969
return (
7070
<InputBox>
@@ -99,7 +99,7 @@ class CreateTodoContainer extends React.Component {
9999
update={(cache, { data: { createTodo } }) => {
100100
const data = cache.readQuery({
101101
query: GET_TODOS_BY_PRODUCT,
102-
variables: { id, completed: status === "DONE" },
102+
variables: { id: productId, completed: status === "DONE" },
103103
});
104104
const todos = data.product.todos.map(t => t); // make a shallow copy otherwise error "Object is not extensible" is thrown
105105
todos.push(createTodo);
@@ -109,7 +109,7 @@ class CreateTodoContainer extends React.Component {
109109
};
110110
cache.writeQuery({
111111
query: GET_TODOS_BY_PRODUCT,
112-
variables: { id, completed: status === "DONE" },
112+
variables: { id: productId, completed: status === "DONE" },
113113
data: newData,
114114
});
115115
}}

src/components/Main/TodoBox.js

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import React from "react";
2+
import styled from "react-emotion";
3+
import { Mutation } from "react-apollo";
4+
import { withTheme } from "emotion-theming";
5+
import reactStringReplace from "react-string-replace";
6+
import { v4 } from "uuid";
7+
import { Icon } from "react-icons-kit";
8+
import { checkmark } from "react-icons-kit/icomoon/checkmark";
9+
import { cross } from "react-icons-kit/icomoon/cross";
10+
11+
import { DeleteTodo } from "./DeleteTodo";
12+
13+
import { GET_TODOS_BY_PRODUCT } from "../../graphql/queries/GET_TODOS_BY_PRODUCT";
14+
import { COMPLETE_TODO } from "../../graphql/mutation/COMPLETE_TODO";
15+
import { UNCOMPLETE_TODO } from "../../graphql/mutation/UNCOMPLETE_TODO";
16+
17+
const TodoContainer = styled.li`
18+
display: flex;
19+
align-items: center;
20+
`;
21+
22+
const Todo = styled.label`
23+
font-size: 1.6rem;
24+
font-family: ${props => props.theme.global.fontFamily};
25+
font-weight: 300;
26+
line-height: 2;
27+
`;
28+
29+
const Hashtag = styled.span`
30+
color: ${props => props.theme.hashtag.textColor};
31+
background: ${props => props.theme.hashtag.bgColor};
32+
border-bottom: 0.1rem solid ${props => props.theme.hashtag.underlineColor};
33+
padding: 0.3rem;
34+
`;
35+
36+
const StatusIcon = styled(Icon)`
37+
padding-right: 1rem;
38+
padding-top: 0.8rem;
39+
align-self: flex-start;
40+
`;
41+
42+
class TodoBoxContainer extends React.Component {
43+
_getHashtag = (body, hashtag) => {
44+
return reactStringReplace(body, `#${hashtag}`, (match, i) => (
45+
<Hashtag key={v4()}>{match}</Hashtag>
46+
));
47+
};
48+
49+
render() {
50+
const { status, todo, hashtag, productId, theme } = this.props;
51+
const completed_at = completed ? new Date().toISOString() : null;
52+
const completed = status === "DONE";
53+
return (
54+
<Mutation
55+
key={v4()}
56+
mutation={completed ? UNCOMPLETE_TODO : COMPLETE_TODO}
57+
optimisticResponse={{
58+
__typename: "Mutation",
59+
[completed ? "uncompleteTodo" : "completeTodo"]: {
60+
__typename: "Todo",
61+
id: todo.id,
62+
body: todo.body,
63+
completed_at,
64+
},
65+
}}
66+
update={(cache, { data }) => {
67+
// remove todo item from current status ,i.e, PENDING or DONE
68+
const cacheData1 = cache.readQuery({
69+
query: GET_TODOS_BY_PRODUCT,
70+
variables: {
71+
id: productId,
72+
completed,
73+
},
74+
});
75+
76+
const todos1 = cacheData1.product.todos.filter(t => t.id !== todo.id); // make a shallow copy otherwise error "Object is not extensible" is thrown
77+
78+
const newData1 = {
79+
...cacheData1,
80+
product: {
81+
...cacheData1.product,
82+
todos: todos1,
83+
},
84+
};
85+
86+
cache.writeQuery({
87+
query: GET_TODOS_BY_PRODUCT,
88+
variables: {
89+
id: productId,
90+
completed,
91+
},
92+
data: newData1,
93+
});
94+
95+
// add todo item to current status ,i.e, PENDING or DONE
96+
const cacheData2 = cache.readQuery({
97+
query: GET_TODOS_BY_PRODUCT,
98+
variables: {
99+
id: productId,
100+
completed: status !== "DONE",
101+
},
102+
});
103+
104+
const todos2 = cacheData2.product.todos.map(t => t); // make a shallow copy otherwise error "Object is not extensible" is thrown
105+
todos2.push({
106+
...data[completed ? "uncompleteTodo" : "completeTodo"],
107+
id: todo.id,
108+
completed_at,
109+
});
110+
const newData2 = {
111+
...cacheData2,
112+
product: {
113+
...cacheData2.product,
114+
todos: todos2,
115+
},
116+
};
117+
118+
cache.writeQuery({
119+
query: GET_TODOS_BY_PRODUCT,
120+
variables: {
121+
id: productId,
122+
completed: status !== "DONE",
123+
},
124+
data: newData2,
125+
});
126+
}}
127+
>
128+
{mutate => (
129+
<TodoContainer>
130+
<StatusIcon
131+
onClick={() => {
132+
mutate({ variables: { id: todo.id } });
133+
}}
134+
icon={completed ? checkmark : cross}
135+
color={
136+
completed
137+
? theme.statusIcon.doneColor
138+
: theme.statusIcon.pendingColor
139+
}
140+
size={16}
141+
/>
142+
<Todo>
143+
{this._getHashtag(todo.body, hashtag)}
144+
<DeleteTodo
145+
id={todo.id}
146+
productId={productId}
147+
completed={completed}
148+
/>
149+
</Todo>
150+
</TodoContainer>
151+
)}
152+
</Mutation>
153+
);
154+
}
155+
}
156+
157+
export const TodoBox = withTheme(TodoBoxContainer);

0 commit comments

Comments
 (0)