Skip to content

Commit 9448dd9

Browse files
committed
setup: useReducer message
1 parent 7a9ecd0 commit 9448dd9

File tree

3 files changed

+151
-3
lines changed

3 files changed

+151
-3
lines changed

src/components/Message/useReducer.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import React from "react";
2+
3+
import { Card } from "../Card";
4+
import { MessageHeader } from "./Header";
5+
import { Icon, IconButton, IconCountWrapper } from "../Icon";
6+
import "./styles.css";
7+
8+
export const messageReducer = (state, action) => {
9+
switch (action.type) {
10+
case "RETWEET":
11+
// TODO: retweet
12+
case "FAVORITE":
13+
// TODO: favorite
14+
default:
15+
return state;
16+
}
17+
};
18+
19+
export const Message = props => {
20+
const {
21+
user,
22+
created_at,
23+
retweet_count,
24+
retweeted,
25+
favorite_count,
26+
favorited,
27+
text
28+
} = props;
29+
30+
const [state, dispatch] = React.useReducer(messageReducer, {
31+
retweet_count,
32+
retweeted,
33+
favorite_count,
34+
favorited
35+
});
36+
37+
return (
38+
<Card
39+
className="Message"
40+
title="message"
41+
profile_image={user.profile_image_url_https}
42+
>
43+
<div>
44+
<div className="Message_Header">
45+
<MessageHeader
46+
name={user.name}
47+
screen_name={user.screen_name}
48+
created_at={created_at}
49+
/>
50+
</div>
51+
<div className="Message_Body">{text}</div>
52+
<div className="Message_Footer">
53+
<Icon icon="comment" title="comment" />
54+
<IconCountWrapper title="retweet_count" count={0}>
55+
<IconButton
56+
role="retweet"
57+
onClick={() => {
58+
/* toggle retweet */
59+
}}
60+
>
61+
<Icon
62+
icon="retweet"
63+
active={false}
64+
highlight="rgb(23, 191, 99)"
65+
/>
66+
</IconButton>
67+
</IconCountWrapper>
68+
<IconCountWrapper title="favorite_count" count={0}>
69+
<IconButton
70+
role="favorite"
71+
onClick={() => {
72+
/* toggle favorite */
73+
}}
74+
>
75+
<Icon
76+
icon="favorite"
77+
active={false}
78+
highlight="rgb(224, 36, 94)"
79+
/>
80+
</IconButton>
81+
</IconCountWrapper>
82+
<Icon icon="share" title="share" />
83+
</div>
84+
</div>
85+
</Card>
86+
);
87+
};

src/stories/2-Message.stories.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from "react";
2-
import { Message } from "../components/Message/useState";
2+
import { Message as UseStateMessage } from "../components/Message/useState";
3+
import { Message as UseReducerMessage } from "../components/Message/useReducer";
34
import { USER } from "../config";
45

56
export default {
@@ -21,9 +22,17 @@ const post = {
2122
};
2223

2324
export const useStateMessage = () => {
24-
return <Message {...post} />;
25+
return <UseStateMessage {...post} />;
2526
};
2627

2728
useStateMessage.story = {
2829
name: "useState example"
2930
};
31+
32+
export const useReducerMessage = () => {
33+
return <UseReducerMessage {...post} />;
34+
};
35+
36+
useReducerMessage.story = {
37+
name: "useReducer example"
38+
};

src/tests/components/Message.test.js

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22
import { render, fireEvent } from "@testing-library/react";
3-
import { Message } from "../../components/Message/useState";
3+
import { Message, messageReducer } from "../../components/Message/useReducer";
44
import { USER } from "../../config";
55

66
const mockProps = {
@@ -60,3 +60,55 @@ describe("Message", () => {
6060
expect(count.textContent).toBe("12");
6161
});
6262
});
63+
64+
const initialState = {
65+
retweeted: false,
66+
retweet_count: 12,
67+
favorited: false,
68+
favorite_count: 22
69+
};
70+
71+
describe("messageReducer", () => {
72+
test("should display the initial values", () => {
73+
const returnsState = messageReducer(initialState, { type: "UNKNOWN" });
74+
expect(returnsState).toEqual(initialState);
75+
});
76+
77+
test('should increment on "FAVORITE"', () => {
78+
const nextState = messageReducer(initialState, { type: "FAVORITE" });
79+
expect(nextState).toEqual({
80+
...initialState,
81+
favorited: true,
82+
favorite_count: 23
83+
});
84+
});
85+
86+
test('should return to default on second "FAVORITE"', () => {
87+
const first = messageReducer(initialState, { type: "FAVORITE" });
88+
const second = messageReducer(first, { type: "FAVORITE" });
89+
expect(second).toEqual({
90+
...initialState,
91+
favorited: false,
92+
favorite_count: 22
93+
});
94+
});
95+
96+
test('should increment on "RETWEET"', () => {
97+
const nextState = messageReducer(initialState, { type: "RETWEET" });
98+
expect(nextState).toEqual({
99+
...initialState,
100+
retweeted: true,
101+
retweet_count: 13
102+
});
103+
});
104+
105+
test('should return to default on second "RETWEET"', () => {
106+
const first = messageReducer(initialState, { type: "RETWEET" });
107+
const second = messageReducer(first, { type: "RETWEET" });
108+
expect(second).toEqual({
109+
...initialState,
110+
retweeted: false,
111+
retweet_count: 12
112+
});
113+
});
114+
});

0 commit comments

Comments
 (0)