diff --git a/src/App.jsx b/src/App.jsx
index 14a7f684d..2ca0d88bd 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,17 +1,61 @@
import './App.css';
+import ChatLog from './components/ChatLog';
+import ColorChoice from './components/ColorChoice';
+import messagesData from './data/messages.json';
+import { useState } from 'react';
const App = () => {
+ const [messages, setMessages] = useState(messagesData);
+ const [colors, setColors] = useState({
+ Vladimir: '#ffffe0',
+ Estragon: '#e0ffff'
+ });
+
+ const participants = [...new Set(messages.map(msg => msg.sender))];
+
+ const updateLikeStatus = (messageId, newLikedStatus) => {
+ setMessages(messages.map(message => {
+ if (message.id === messageId) {
+ return { ...message, liked: newLikedStatus };
+ }
+ return message;
+ }));
+ };
+
+ const handleColorChange = (user, newColor) => {
+ setColors(prevColors => ({
+ ...prevColors,
+ [user]: newColor
+ }));
+ };
+
+ const totalLikes = messages.filter(message => message.liked).length;
+
return (
- {/* Wave 01: Render one ChatEntry component
- Wave 02: Render ChatLog component */}
+
);
};
-export default App;
+export default App;
\ No newline at end of file
diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx
index 15c56f96b..c888b2cb9 100644
--- a/src/components/ChatEntry.jsx
+++ b/src/components/ChatEntry.jsx
@@ -1,20 +1,37 @@
import './ChatEntry.css';
+import TimeStamp from './TimeStamp.jsx';
+import PropTypes from 'prop-types';
+
+const ChatEntry = ({ id, sender, body, timeStamp, liked, onUpdateLike, color = undefined }) => {
+ const messagesClass = sender === 'Vladimir' ? 'local' : 'remote';
-const ChatEntry = () => {
return (
-
-
Replace with name of sender
-
- Replace with body of ChatEntry
- Replace with TimeStamp component
-
+
+
{sender}
+
+ {body}
+
+
+
+
);
};
ChatEntry.propTypes = {
- // Fill with correct proptypes
+ id: PropTypes.number.isRequired,
+ sender: PropTypes.string.isRequired,
+ body: PropTypes.string.isRequired,
+ timeStamp: PropTypes.string.isRequired,
+ liked: PropTypes.bool.isRequired,
+ onUpdateLike: PropTypes.func.isRequired,
+ color: PropTypes.string
};
-export default ChatEntry;
+export default ChatEntry;
\ No newline at end of file
diff --git a/src/components/ChatEntry.test.jsx b/src/components/ChatEntry.test.jsx
index 85eff9256..4508b236b 100644
--- a/src/components/ChatEntry.test.jsx
+++ b/src/components/ChatEntry.test.jsx
@@ -3,6 +3,7 @@ import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
describe('Wave 01: ChatEntry', () => {
+ const mockOnUpdateLike = () => { };
beforeEach(() => {
render(
{
body="Get out by 8am. I'll count the silverware"
timeStamp="2018-05-18T22:12:03Z"
liked={false}
+ onUpdateLike={mockOnUpdateLike}
/>
);
});
diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx
new file mode 100644
index 000000000..a32cda768
--- /dev/null
+++ b/src/components/ChatLog.jsx
@@ -0,0 +1,38 @@
+import './ChatLog.css';
+import ChatEntry from './ChatEntry';
+import PropTypes from 'prop-types';
+
+const ChatLog = ({ entries, onUpdateLike, colors = {} }) => {
+ return (
+
+ {entries.map((message) => (
+
+ ))}
+
+ );
+};
+
+ChatLog.propTypes = {
+ entries: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.number,
+ sender: PropTypes.string.isRequired,
+ body: PropTypes.string.isRequired,
+ timeStamp: PropTypes.string.isRequired,
+ liked: PropTypes.bool.isRequired
+ })
+ ).isRequired,
+ onUpdateLike: PropTypes.func.isRequired,
+ colors: PropTypes.objectOf(PropTypes.string)
+};
+
+export default ChatLog;
\ No newline at end of file
diff --git a/src/components/ChatLog.test.jsx b/src/components/ChatLog.test.jsx
index dfcfeda99..626d9294c 100644
--- a/src/components/ChatLog.test.jsx
+++ b/src/components/ChatLog.test.jsx
@@ -41,8 +41,10 @@ const LOG = [
];
describe('Wave 02: ChatLog', () => {
+ const mockOnUpdateLike = () => { };
+
beforeEach(() => {
- render();
+ render();
});
test('renders without crashing and shows all the names', () => {
@@ -66,7 +68,7 @@ describe('Wave 02: ChatLog', () => {
});
test('renders an empty list without crashing', () => {
- const element = render();
+ const element = render();
expect(element).not.toBeNull();
});
});
diff --git a/src/components/ColorChoice.jsx b/src/components/ColorChoice.jsx
new file mode 100644
index 000000000..708c586f7
--- /dev/null
+++ b/src/components/ColorChoice.jsx
@@ -0,0 +1,23 @@
+import PropTypes from 'prop-types';
+
+const ColorChoice = ({ user, currentColor, onColorChange }) => {
+ return (
+
+
+ onColorChange(user, e.target.value)}
+ />
+
+ );
+};
+
+ColorChoice.propTypes = {
+ user: PropTypes.string.isRequired,
+ currentColor: PropTypes.string.isRequired,
+ onColorChange: PropTypes.func.isRequired
+};
+
+export default ColorChoice;
\ No newline at end of file