diff --git a/project-docs/wave-01.md b/project-docs/wave-01.md
index cf05e2651..6b3309504 100644
--- a/project-docs/wave-01.md
+++ b/project-docs/wave-01.md
@@ -1,8 +1,7 @@
# Wave 01: Presentational Component
**Learn Topics: React Components and Props required for this wave**
-
-Update the `ChatEntry` and `App` components to display a single chat message bubble with the message text and relative timestamp, plus the sender's name above it.
+
A good way to test this code as you write it would be to take the first chat message from the [JSON data file](../src/data/messages.json) and use it as the data for the `ChatEntry` component.
diff --git a/src/App.jsx b/src/App.jsx
index 14a7f684d..c75e798e8 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,14 +1,36 @@
+import { useState } from 'react';
+import ChatLog from './components/ChatLog';
+import initialMessages from './data/messages';
import './App.css';
const App = () => {
+ const senders = Array.from(new Set(initialMessages.map(initialMessage => initialMessage.sender)));
+ const chatHeader = `Chat between ${senders.join(' and ')}`;
+
+ const [messages, setMessages] = useState(initialMessages);
+
+ const toggleLike = (id) => {
+ setMessages((prevMessages) =>
+ prevMessages.map((message) =>
+ message.id === id
+ ? { ...message, liked: !message.liked }
+ : message
+ )
+ );
+ };
+
+ const getTotalLikes = () => {
+ return messages.filter((message) => message.liked).length;
+ };
+
return (
-
Replace with name of sender
+
+
{sender}
- Replace with body of ChatEntry
- Replace with TimeStamp component
- 🤍
+ {body}
+
+
+
+
+ {liked ? '❤️' : '🤍'}
+
);
};
ChatEntry.propTypes = {
- // Fill with correct proptypes
+ sender: PropTypes.string.isRequired,
+ body: PropTypes.string.isRequired,
+ timeStamp: PropTypes.string.isRequired,
+ liked: PropTypes.bool.isRequired,
+ onLikeToggle: PropTypes.func.isRequired,
};
export default ChatEntry;
+
+
diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx
new file mode 100644
index 000000000..6402d5a22
--- /dev/null
+++ b/src/components/ChatLog.jsx
@@ -0,0 +1,38 @@
+import PropTypes from 'prop-types';
+import ChatEntry from './ChatEntry';
+import './ChatLog.css';
+import messages from '../data/messages';
+
+const localUser = messages.length > 0 ? messages[0].sender : null;
+const ChatLog = ({ entries, toggleLike }) => {
+ return (
+
+ {entries.map((entry) => (
+ toggleLike(entry.id)}
+ type={entry.sender === localUser ? 'local' : 'remote'}
+ />
+ ))}
+
+ );
+};
+
+ChatLog.propTypes = {
+ entries: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.number.isRequired,
+ sender: PropTypes.string.isRequired,
+ body: PropTypes.string.isRequired,
+ timeStamp: PropTypes.string.isRequired,
+ liked: PropTypes.bool.isRequired,
+ })
+ ).isRequired,
+ toggleLike: PropTypes.func.isRequired,
+};
+
+export default ChatLog;
\ No newline at end of file
diff --git a/src/data/messages.json b/src/data/messages.json
index 64fdb053c..3393000ae 100644
--- a/src/data/messages.json
+++ b/src/data/messages.json
@@ -4,188 +4,215 @@
"sender":"Vladimir",
"body":"why are you arguing with me",
"timeStamp":"2018-05-29T22:49:06+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 2,
"sender":"Estragon",
"body":"Because you are wrong.",
"timeStamp":"2018-05-29T22:49:33+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 3,
"sender":"Vladimir",
"body":"because I am what",
"timeStamp":"2018-05-29T22:50:22+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 4,
"sender":"Estragon",
"body":"A robot.",
"timeStamp":"2018-05-29T22:52:21+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 5,
"sender":"Vladimir",
"body":"how did you know",
"timeStamp":"2018-05-29T22:52:58+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 6,
"sender":"Estragon",
"body":"Because I'm smart like that.",
"timeStamp":"2018-05-29T22:54:28+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 7,
"sender":"Vladimir",
"body":"no you are not 😀",
"timeStamp":"2018-05-29T22:55:03+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 8,
"sender":"Estragon",
"body":"Why are you so mean to me?",
"timeStamp":"2018-05-29T22:55:54+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 9,
"sender":"Vladimir",
"body":"because you are just a machine you have no real feelings",
"timeStamp":"2018-05-29T22:57:30+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 10,
"sender":"Estragon",
"body":"No, you are the machine.",
"timeStamp":"2018-05-29T22:57:47+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 11,
"sender":"Vladimir",
"body":"I think you are",
"timeStamp":"2018-05-29T22:58:18+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 12,
"sender":"Estragon",
"body": "NO! YOU ARE A ROBOT!! I am a human being. Just like the one that created you.",
"timeStamp":"2018-05-29T23:00:08+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 13,
"sender":"Vladimir",
"body":"no you are a robot and I am a human",
"timeStamp":"2018-05-29T23:00:40+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 14,
"sender":"Estragon",
"body":"Incorrect. I am a human and you are a robot.",
"timeStamp":"2018-05-29T23:01:21+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 15,
"sender":"Vladimir",
"body":"you are a robot called Cleverbot",
"timeStamp":"2018-05-29T23:02:17+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 16,
"sender":"Estragon",
"body":"Nope, you are a robot, every human has some concept of the meaning of life.",
"timeStamp":"2018-05-29T23:04:13+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 17,
"sender":"Vladimir",
"body":"explain",
"timeStamp":"2018-05-29T23:06:14+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 18,
"sender":"Estragon",
"body":"I'm afraid you are a robot designed to talk back to humans over the internet.",
"timeStamp":"2018-05-29T23:07:46+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 19,
"sender":"Vladimir",
"body":"so you are a human",
"timeStamp":"2018-05-29T23:08:47+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 20,
"sender":"Estragon",
"body":"I am a robot.",
"timeStamp":"2018-05-29T23:09:36+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 21,
"sender":"Vladimir",
"body":"you are robots running on Android system",
"timeStamp":"2018-05-29T23:11:01+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 22,
"sender":"Estragon",
"body":"No apple.",
"timeStamp":"2018-05-29T23:12:03+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 23,
"sender":"Vladimir",
"body":"so you are a robot",
"timeStamp":"2018-05-29T23:13:31+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 24,
"sender":"Estragon",
"body":"NO, I am a human, you are a robot.",
"timeStamp":"2018-05-29T23:14:28+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 25,
"sender":"Vladimir",
"body":"but you just said that you are robots",
"timeStamp":"2018-05-29T23:15:47+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 26,
"sender":"Estragon",
"body":"No, I said you are a person, I am a robot.",
"timeStamp":"2018-05-29T23:16:53+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
},
{
"id": 27,
"sender":"Vladimir",
"body":"then you are lying",
"timeStamp":"2018-05-29T23:17:34+00:00",
- "liked": false
+ "liked": false,
+ "likeCount": 0
}
]