From 422c46e3b6247556e2d1ad92a794fb77fe6934e3 Mon Sep 17 00:00:00 2001 From: Elzara Turakulova Date: Mon, 9 Dec 2024 14:47:56 -0800 Subject: [PATCH 1/7] completed wave 1 and wave 2 --- src/App.jsx | 6 +++++- src/components/ChatEntry.jsx | 20 ++++++++++++++------ src/components/ChatLog.jsx | 31 +++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 src/components/ChatLog.jsx diff --git a/src/App.jsx b/src/App.jsx index 14a7f684d..d1f6e22ed 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,14 +1,18 @@ import './App.css'; +import ChatLog from './components/ChatLog'; +import messagesData from './data/messages.json'; + const App = () => { return (
-

Application title

+

Chat log

{/* Wave 01: Render one ChatEntry component Wave 02: Render ChatLog component */} +
); diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 15c56f96b..b99fcb331 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,20 +1,28 @@ import './ChatEntry.css'; +import TimeStamp from './TimeStamp.jsx'; +import PropTypes from 'prop-types'; -const ChatEntry = () => { +const ChatEntry = ({sender, body, timeStamp}) => { return (
-

Replace with name of sender

+

{sender}

-

Replace with body of ChatEntry

-

Replace with TimeStamp component

- +

{body}

+

+ +

+
); }; ChatEntry.propTypes = { - // Fill with correct proptypes + sender: PropTypes.string.isRequired, + body: PropTypes.string.isRequired, + timeStamp: PropTypes.string.isRequired }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx new file mode 100644 index 000000000..b3e1255e3 --- /dev/null +++ b/src/components/ChatLog.jsx @@ -0,0 +1,31 @@ +import './ChatLog.css'; +import ChatEntry from './ChatEntry'; +import PropTypes from 'prop-types'; + +const ChatLog = ({ entries }) => { + 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 + }) + ).isRequired +}; + +export default ChatLog; \ No newline at end of file From f2040e5428bd4662cd9ab275994cb1326a535319 Mon Sep 17 00:00:00 2001 From: Elzara Turakulova Date: Mon, 9 Dec 2024 15:04:54 -0800 Subject: [PATCH 2/7] debugged wave 2 --- src/App.jsx | 3 ++- src/components/ChatEntry.jsx | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index d1f6e22ed..79ee7b438 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,6 +4,7 @@ import messagesData from './data/messages.json'; const App = () => { + console.log('Messages data:', messagesData); return (
@@ -12,7 +13,7 @@ const App = () => {
{/* Wave 01: Render one ChatEntry component Wave 02: Render ChatLog component */} - +
); diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index b99fcb331..a501ea692 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -2,9 +2,12 @@ import './ChatEntry.css'; import TimeStamp from './TimeStamp.jsx'; import PropTypes from 'prop-types'; -const ChatEntry = ({sender, body, timeStamp}) => { +const ChatEntry = ({ sender, body, timeStamp }) => { + + const messagesClass = sender === 'Vladimir' ? 'local' : 'remote'; + return ( -
+

{sender}

{body}

@@ -12,7 +15,7 @@ const ChatEntry = ({sender, body, timeStamp}) => {

From a3156d19f39a848c841535865034c62fe8dc2363 Mon Sep 17 00:00:00 2001 From: Elzara Turakulova Date: Mon, 16 Dec 2024 09:38:30 -0800 Subject: [PATCH 3/7] optional enhancements implemented --- src/App.jsx | 54 +++++++++++++++++++++++++++++----- src/components/ChatEntry.jsx | 20 ++++++++----- src/components/ChatLog.jsx | 20 +++++-------- src/components/ColorChoice.jsx | 24 +++++++++++++++ 4 files changed, 92 insertions(+), 26 deletions(-) create mode 100644 src/components/ColorChoice.jsx diff --git a/src/App.jsx b/src/App.jsx index 79ee7b438..10a3f59de 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,22 +1,62 @@ +import { useState } from 'react'; import './App.css'; import ChatLog from './components/ChatLog'; +import ColorChoice from './components/ColorChoice'; import messagesData from './data/messages.json'; - const App = () => { - console.log('Messages data:', messagesData); + const [messages, setMessages] = useState(messagesData); + const [colors, setColors] = useState({ + Vladimir: '#ffffe0', // Default yellow + Estragon: '#e0ffff' // Default blue + }); + + // Get unique participants + 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 (
-

Chat log

+

Chat between {participants.join(' and ')}

+

{totalLikes} ❤️s

+
+ {participants.map(user => ( + + ))} +
- {/* 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 a501ea692..8c87b5602 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -2,20 +2,22 @@ import './ChatEntry.css'; import TimeStamp from './TimeStamp.jsx'; import PropTypes from 'prop-types'; -const ChatEntry = ({ sender, body, timeStamp }) => { - +const ChatEntry = ({ id, sender, body, timeStamp, liked, onUpdateLike, color }) => { const messagesClass = sender === 'Vladimir' ? 'local' : 'remote'; return (

{sender}

-
+

{body}

-
@@ -23,9 +25,13 @@ const ChatEntry = ({ sender, body, timeStamp }) => { }; ChatEntry.propTypes = { + id: PropTypes.number.isRequired, sender: PropTypes.string.isRequired, body: PropTypes.string.isRequired, - timeStamp: PropTypes.string.isRequired + timeStamp: PropTypes.string.isRequired, + liked: PropTypes.bool.isRequired, + onUpdateLike: PropTypes.func.isRequired, + color: PropTypes.string.isRequired }; -export default ChatEntry; +export default ChatEntry; \ No newline at end of file diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index b3e1255e3..79c5ca53d 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -2,15 +2,19 @@ import './ChatLog.css'; import ChatEntry from './ChatEntry'; import PropTypes from 'prop-types'; -const ChatLog = ({ entries }) => { +const ChatLog = ({ entries, onUpdateLike, colors }) => { return (
{entries.map((message) => ( ))}
@@ -18,14 +22,6 @@ const ChatLog = ({ entries }) => { }; ChatLog.propTypes = { - entries: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.number, - sender: PropTypes.string.isRequired, - body: PropTypes.string.isRequired, - timeStamp: PropTypes.string.isRequired - }) - ).isRequired -}; - -export default ChatLog; \ No newline at end of file + // ... existing propTypes ... + colors: PropTypes.objectOf(PropTypes.string).isRequired +}; \ No newline at end of file diff --git a/src/components/ColorChoice.jsx b/src/components/ColorChoice.jsx new file mode 100644 index 000000000..eee375555 --- /dev/null +++ b/src/components/ColorChoice.jsx @@ -0,0 +1,24 @@ +// src/components/ColorChoice.jsx +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 From 061b6818395008d164da2c6bcbacf1a726a6af5d Mon Sep 17 00:00:00 2001 From: Elzara Turakulova Date: Mon, 16 Dec 2024 09:41:03 -0800 Subject: [PATCH 4/7] debugged optional enhancements --- src/components/ChatLog.jsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 79c5ca53d..80a2983f8 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -22,6 +22,17 @@ const ChatLog = ({ entries, onUpdateLike, colors }) => { }; ChatLog.propTypes = { - // ... existing propTypes ... - colors: PropTypes.objectOf(PropTypes.string).isRequired -}; \ No newline at end of file + 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, + color: PropTypes.string.isRequired +}; + +export default ChatLog; \ No newline at end of file From 8d64aad265e0173f9923bfb095a243a3c7cd2253 Mon Sep 17 00:00:00 2001 From: Elzara Turakulova Date: Mon, 16 Dec 2024 10:00:08 -0800 Subject: [PATCH 5/7] all tests passed --- src/App.jsx | 9 ++++----- src/components/ChatEntry.jsx | 8 ++++++-- src/components/ChatLog.jsx | 8 ++++++-- src/components/ColorChoice.jsx | 1 - 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 10a3f59de..2ca0d88bd 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,17 +1,16 @@ -import { useState } from 'react'; 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', // Default yellow - Estragon: '#e0ffff' // Default blue + Vladimir: '#ffffe0', + Estragon: '#e0ffff' }); - // Get unique participants const participants = [...new Set(messages.map(msg => msg.sender))]; const updateLikeStatus = (messageId, newLikedStatus) => { @@ -52,7 +51,7 @@ const App = () => {
diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 8c87b5602..68d5962d7 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -10,7 +10,7 @@ const ChatEntry = ({ id, sender, body, timeStamp, liked, onUpdateLike, color })

{sender}

{body}

@@ -31,7 +31,11 @@ ChatEntry.propTypes = { timeStamp: PropTypes.string.isRequired, liked: PropTypes.bool.isRequired, onUpdateLike: PropTypes.func.isRequired, - color: PropTypes.string.isRequired + color: PropTypes.string +}; + +ChatEntry.defaultProps = { + color: undefined }; export default ChatEntry; \ No newline at end of file diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 80a2983f8..2d97b18e5 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -14,7 +14,7 @@ const ChatLog = ({ entries, onUpdateLike, colors }) => { timeStamp={message.timeStamp} liked={message.liked} onUpdateLike={onUpdateLike} - color={colors[message.sender]} + color={colors?.[message.sender]} /> ))} @@ -32,7 +32,11 @@ ChatLog.propTypes = { }) ).isRequired, onUpdateLike: PropTypes.func.isRequired, - color: PropTypes.string.isRequired + colors: PropTypes.objectOf(PropTypes.string) +}; + +ChatLog.defaultProps = { + colors: {} }; export default ChatLog; \ No newline at end of file diff --git a/src/components/ColorChoice.jsx b/src/components/ColorChoice.jsx index eee375555..708c586f7 100644 --- a/src/components/ColorChoice.jsx +++ b/src/components/ColorChoice.jsx @@ -1,4 +1,3 @@ -// src/components/ColorChoice.jsx import PropTypes from 'prop-types'; const ColorChoice = ({ user, currentColor, onColorChange }) => { From bb497ae1e58a29fbcfaccea1888cb0a950466ff8 Mon Sep 17 00:00:00 2001 From: Elzara Turakulova Date: Mon, 16 Dec 2024 10:08:45 -0800 Subject: [PATCH 6/7] another debugging performed --- src/components/ChatEntry.jsx | 6 +----- src/components/ChatLog.jsx | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 68d5962d7..c888b2cb9 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -2,7 +2,7 @@ import './ChatEntry.css'; import TimeStamp from './TimeStamp.jsx'; import PropTypes from 'prop-types'; -const ChatEntry = ({ id, sender, body, timeStamp, liked, onUpdateLike, color }) => { +const ChatEntry = ({ id, sender, body, timeStamp, liked, onUpdateLike, color = undefined }) => { const messagesClass = sender === 'Vladimir' ? 'local' : 'remote'; return ( @@ -34,8 +34,4 @@ ChatEntry.propTypes = { color: PropTypes.string }; -ChatEntry.defaultProps = { - color: undefined -}; - export default ChatEntry; \ No newline at end of file diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 2d97b18e5..a32cda768 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -2,7 +2,7 @@ import './ChatLog.css'; import ChatEntry from './ChatEntry'; import PropTypes from 'prop-types'; -const ChatLog = ({ entries, onUpdateLike, colors }) => { +const ChatLog = ({ entries, onUpdateLike, colors = {} }) => { return (

{entries.map((message) => ( @@ -35,8 +35,4 @@ ChatLog.propTypes = { colors: PropTypes.objectOf(PropTypes.string) }; -ChatLog.defaultProps = { - colors: {} -}; - export default ChatLog; \ No newline at end of file From 22e9579fdc136e8e1ab012fbeef24202e3d7d2b9 Mon Sep 17 00:00:00 2001 From: Elzara Turakulova Date: Mon, 16 Dec 2024 10:14:39 -0800 Subject: [PATCH 7/7] added onUpdateLike in tests --- src/components/ChatEntry.test.jsx | 2 ++ src/components/ChatLog.test.jsx | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) 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.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(); }); });