From 432332f5a3e23a8875dc66c84fb8d65c12f54346 Mon Sep 17 00:00:00 2001 From: Jen Nguyen <26128269+ItsJenOClock@users.noreply.github.com> Date: Tue, 17 Dec 2024 00:48:58 -0600 Subject: [PATCH 1/6] wave 1 implementation --- src/App.jsx | 9 ++++++++- src/components/ChatEntry.jsx | 15 +++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 14a7f684..d6a849e9 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,14 +1,21 @@ import './App.css'; +import messagesData from './data/messages.json'; +import ChatEntry from './components/ChatEntry'; const App = () => { return (
-

Application title

+

Chat

{/* Wave 01: Render one ChatEntry component Wave 02: Render ChatLog component */} + +
); diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 15c56f96..fc149c3b 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,12 +1,16 @@ import './ChatEntry.css'; +import PropTypes from 'prop-types'; +import TimeStamp from './TimeStamp'; -const ChatEntry = () => { +const ChatEntry = (props) => { return (
-

Replace with name of sender

+

{props.sender}

-

Replace with body of ChatEntry

-

Replace with TimeStamp component

+

{props.body}

+

+ +

@@ -15,6 +19,9 @@ const ChatEntry = () => { ChatEntry.propTypes = { // Fill with correct proptypes + sender: PropTypes.string.isRequired, + body: PropTypes.string.isRequired, + timeStamp: PropTypes.string.isRequired, }; export default ChatEntry; From ea6cf5144ffa64a1657d45b8dae0bdf4e2b5427b Mon Sep 17 00:00:00 2001 From: Jen Nguyen <26128269+ItsJenOClock@users.noreply.github.com> Date: Tue, 17 Dec 2024 01:47:54 -0600 Subject: [PATCH 2/6] wave 2 implementation --- src/App.jsx | 10 ++------- src/components/ChatEntry.jsx | 3 ++- src/components/ChatLog.jsx | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 src/components/ChatLog.jsx diff --git a/src/App.jsx b/src/App.jsx index d6a849e9..60a40ead 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,6 @@ import './App.css'; import messagesData from './data/messages.json'; -import ChatEntry from './components/ChatEntry'; +import ChatLog from './components/ChatLog'; const App = () => { return ( @@ -9,13 +9,7 @@ const App = () => {

Chat

- {/* Wave 01: Render one ChatEntry component - Wave 02: Render ChatLog component */} - - +
); diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index fc149c3b..c0322f09 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -18,10 +18,11 @@ const ChatEntry = (props) => { }; 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, }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx new file mode 100644 index 00000000..ab851c42 --- /dev/null +++ b/src/components/ChatLog.jsx @@ -0,0 +1,39 @@ +import './ChatLog.css'; +import ChatEntry from './ChatEntry'; +import PropTypes from 'prop-types'; + +const ChatLog = (props) => { + const chatEntryComponents = props.entries.map((chatEntry, index) => { + return ( +
+ + +
+ ); + }); + + return ( +
+ {chatEntryComponents} +
+ ); +}; + +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, +}; + +export default ChatLog; \ No newline at end of file From 4b277d5d57c6a07c28fd08746f06c612e1566030 Mon Sep 17 00:00:00 2001 From: Jen Nguyen <26128269+ItsJenOClock@users.noreply.github.com> Date: Wed, 18 Dec 2024 08:04:48 -0600 Subject: [PATCH 3/6] wave 3 implementation --- src/App.jsx | 35 ++++++++++++++++++++++++++++++++--- src/components/ChatEntry.jsx | 11 ++++++++--- src/components/ChatLog.jsx | 21 +++++++++++---------- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 60a40ead..d4aa5888 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,18 +1,47 @@ import './App.css'; import messagesData from './data/messages.json'; import ChatLog from './components/ChatLog'; +import { useState } from 'react'; const App = () => { + const [chatData, setChatData] = useState(messagesData); + const [likedCount, setLikedCount] = useState(0); + const toggleLike = (chatEntryId) => { + setChatData((prevChatData) => { + const updatedChatData = prevChatData.map((chatEntry) => { + if (chatEntry.id === chatEntryId) { + return { ...chatEntry, liked: !chatEntry.liked }; + } else { + return chatEntry; + } + }); + let totalLikes = 0; + updatedChatData.forEach((chatEntry) => { + if (chatEntry.liked) { + totalLikes++; + } + }); + setLikedCount(totalLikes); + return updatedChatData; + }); + }; + return (
-

Chat

+

Chat Between {messagesData[0].sender} and {messagesData[1].sender}

+
+ {likedCount} ❤️s +
- +
); }; -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 c0322f09..e971fa1e 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -3,6 +3,10 @@ import PropTypes from 'prop-types'; import TimeStamp from './TimeStamp'; const ChatEntry = (props) => { + const likeButtonClick = () => { + props.onLikeToggle(props.id); + }; + return (

{props.sender}

@@ -11,7 +15,7 @@ const ChatEntry = (props) => {

- +
); @@ -22,7 +26,8 @@ ChatEntry.propTypes = { sender: PropTypes.string.isRequired, body: PropTypes.string.isRequired, timeStamp: PropTypes.string.isRequired, - liked: PropTypes.bool, + liked: PropTypes.bool.isRequired, + onLikeToggle: PropTypes.func.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 ab851c42..7468fba3 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -3,17 +3,17 @@ import ChatEntry from './ChatEntry'; import PropTypes from 'prop-types'; const ChatLog = (props) => { - const chatEntryComponents = props.entries.map((chatEntry, index) => { + const chatEntryComponents = props.entries.map((chatEntry) => { return ( -
- - -
+ ); }); @@ -34,6 +34,7 @@ ChatLog.propTypes = { liked: PropTypes.bool.isRequired, }), ).isRequired, + onLikeToggle: PropTypes.func.isRequired, }; export default ChatLog; \ No newline at end of file From 0c5ed6c6fa028c4ce396708ff316c6cd9ff84761 Mon Sep 17 00:00:00 2001 From: Jen Nguyen <26128269+ItsJenOClock@users.noreply.github.com> Date: Wed, 18 Dec 2024 08:55:35 -0600 Subject: [PATCH 4/6] differentiate local vs remote via id --- src/components/ChatEntry.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index e971fa1e..2d297b96 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -6,9 +6,10 @@ const ChatEntry = (props) => { const likeButtonClick = () => { props.onLikeToggle(props.id); }; + const senderType = (props.id % 2) ? 'local' : 'remote'; return ( -
+

{props.sender}

{props.body}

From 92d051df2a348eb978f98510766cdc3c01b0487c Mon Sep 17 00:00:00 2001 From: Jen Nguyen <26128269+ItsJenOClock@users.noreply.github.com> Date: Wed, 18 Dec 2024 09:03:17 -0600 Subject: [PATCH 5/6] updated onLikeToggle --- src/components/ChatEntry.jsx | 2 +- src/components/ChatLog.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 2d297b96..ba2db890 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -28,7 +28,7 @@ ChatEntry.propTypes = { body: PropTypes.string.isRequired, timeStamp: PropTypes.string.isRequired, liked: PropTypes.bool.isRequired, - onLikeToggle: PropTypes.func.isRequired, + onLikeToggle: PropTypes.func, }; export default ChatEntry; \ No newline at end of file diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 7468fba3..186669a0 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -34,7 +34,7 @@ ChatLog.propTypes = { liked: PropTypes.bool.isRequired, }), ).isRequired, - onLikeToggle: PropTypes.func.isRequired, + onLikeToggle: PropTypes.func, }; export default ChatLog; \ No newline at end of file From 6b85319ea2ae780d42db47a0021a8148ec6bd2d6 Mon Sep 17 00:00:00 2001 From: Jen Nguyen <26128269+ItsJenOClock@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:01:06 -0600 Subject: [PATCH 6/6] destructured props --- src/components/ChatEntry.jsx | 16 ++++++++-------- src/components/ChatLog.jsx | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index ba2db890..b6d2c57c 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -2,21 +2,21 @@ import './ChatEntry.css'; import PropTypes from 'prop-types'; import TimeStamp from './TimeStamp'; -const ChatEntry = (props) => { +const ChatEntry = ({ id, sender, body, timeStamp, liked, onLikeToggle }) => { const likeButtonClick = () => { - props.onLikeToggle(props.id); + onLikeToggle(id); }; - const senderType = (props.id % 2) ? 'local' : 'remote'; + const senderType = (sender === 'Vladimir') ? 'local' : 'remote'; return (
-

{props.sender}

+

{sender}

-

{props.body}

+

{body}

- +

- +
); @@ -28,7 +28,7 @@ ChatEntry.propTypes = { body: PropTypes.string.isRequired, timeStamp: PropTypes.string.isRequired, liked: PropTypes.bool.isRequired, - onLikeToggle: PropTypes.func, + onLikeToggle: PropTypes.func.isRequired, }; export default ChatEntry; \ No newline at end of file diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 186669a0..18bbe522 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -2,8 +2,8 @@ import './ChatLog.css'; import ChatEntry from './ChatEntry'; import PropTypes from 'prop-types'; -const ChatLog = (props) => { - const chatEntryComponents = props.entries.map((chatEntry) => { +const ChatLog = ({ entries, onLikeToggle }) => { + const chatEntryComponents = entries.map((chatEntry) => { return ( { body={chatEntry.body} timeStamp={chatEntry.timeStamp} liked={chatEntry.liked} - onLikeToggle={props.onLikeToggle} + onLikeToggle={onLikeToggle} > ); }); @@ -34,7 +34,7 @@ ChatLog.propTypes = { liked: PropTypes.bool.isRequired, }), ).isRequired, - onLikeToggle: PropTypes.func, + onLikeToggle: PropTypes.func.isRequired, }; export default ChatLog; \ No newline at end of file