From 6265861f369d26f7260e1a30e212e589d99025ef Mon Sep 17 00:00:00 2001 From: Esther Kang Date: Sun, 15 Jun 2025 14:18:39 -0700 Subject: [PATCH 1/5] renders one chat entry successfully --- src/App.jsx | 3 +++ src/components/ChatEntry.jsx | 13 +++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 14a7f684d..3c5b98818 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,4 +1,6 @@ import './App.css'; +import ChatEntry from './components/ChatEntry'; +import DATA from './data/messages.json'; const App = () => { return ( @@ -9,6 +11,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 15c56f96b..c4c3824b8 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,12 +1,14 @@ import './ChatEntry.css'; +import PropTypes from 'prop-types'; +import TimeStamp from './TimeStamp'; -const ChatEntry = () => { +const ChatEntry = ({sender, body, timeStamp}) => { return (
-

Replace with name of sender

+

{sender}

-

Replace with body of ChatEntry

-

Replace with TimeStamp component

+

{body}

+

@@ -15,6 +17,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 2126f69aef59fd826359097517cd451b522b8f7b Mon Sep 17 00:00:00 2001 From: Esther Kang Date: Sun, 15 Jun 2025 15:56:49 -0700 Subject: [PATCH 2/5] renders all chat data as entries in a chat log --- src/App.jsx | 4 ++-- src/components/ChatLog.jsx | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/components/ChatLog.jsx diff --git a/src/App.jsx b/src/App.jsx index 3c5b98818..93a1f21b3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,5 +1,5 @@ import './App.css'; -import ChatEntry from './components/ChatEntry'; +import ChatLog from './components/ChatLog'; import DATA from './data/messages.json'; const App = () => { @@ -11,7 +11,7 @@ const App = () => {
{/* Wave 01: Render one ChatEntry component Wave 02: Render ChatLog component */} -
+
); diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx new file mode 100644 index 000000000..e1b7e362f --- /dev/null +++ b/src/components/ChatLog.jsx @@ -0,0 +1,33 @@ +import './ChatLog.css'; +import PropTypes from 'prop-types'; +import ChatEntry from './ChatEntry'; + +const ChatLog = (props) => { + const chatEntryComponents = props.chatData.map((chat) => { + return ( + + ); + }); + return ( +
+ {chatEntryComponents} +
+ ); +}; + +ChatLog.propTypes = { + chatData: 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; From bef93059ae3e2684c00f91c032e1dbcae1d5dd74 Mon Sep 17 00:00:00 2001 From: Esther Kang Date: Sun, 15 Jun 2025 16:00:47 -0700 Subject: [PATCH 3/5] fixes name for data to 'entries' according to tests --- src/App.jsx | 2 +- src/components/ChatLog.jsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 93a1f21b3..12d85c9c1 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -11,7 +11,7 @@ const App = () => {
{/* Wave 01: Render one ChatEntry component Wave 02: Render ChatLog component */} -
+
); diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index e1b7e362f..710d4b7e1 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import ChatEntry from './ChatEntry'; const ChatLog = (props) => { - const chatEntryComponents = props.chatData.map((chat) => { + const chatEntryComponents = props.entries.map((chat) => { return ( { }; ChatLog.propTypes = { - chatData: PropTypes.arrayOf(PropTypes.shape({ + entries: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.number.isRequired, sender: PropTypes.string.isRequired, body: PropTypes.string.isRequired, From bec9d4e4dfbbd481a30738007d822872e18b2064 Mon Sep 17 00:00:00 2001 From: Esther Kang Date: Mon, 16 Jun 2025 07:25:52 -0700 Subject: [PATCH 4/5] implements liking and unliking messages --- src/App.jsx | 33 +++++++++++++++++++++++++++++++-- src/components/ChatEntry.jsx | 9 +++++++-- src/components/ChatLog.jsx | 14 +++++++++----- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 12d85c9c1..a4a4b74cc 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,17 +1,46 @@ import './App.css'; import ChatLog from './components/ChatLog'; import DATA from './data/messages.json'; +import { useState } from 'react'; + +const calculateLikedCount = (entries) => { + let likedCount = 0; + for (const entry of entries) { + if (entry.liked) { + likedCount++; + } + } + return likedCount; +}; const App = () => { + const [entries, setEntries] = useState(DATA); + const likedCount = calculateLikedCount(entries); + + const likeEntry = (id) => { + setEntries((entries) => { + return entries.map((entry) => { + if (entry.id === id) { + return {...entry, liked: !entry.liked}; + } else { + return entry; + } + }); + }); + }; + return (
-

Application title

+

Chat Between Vladimir and Estragon

+
+

{likedCount} ❤️s

+
{/* Wave 01: Render one ChatEntry component Wave 02: Render ChatLog component */} -
+
); diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index c4c3824b8..76dae80f9 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -2,14 +2,16 @@ import './ChatEntry.css'; import PropTypes from 'prop-types'; import TimeStamp from './TimeStamp'; -const ChatEntry = ({sender, body, timeStamp}) => { +const ChatEntry = ({id, sender, body, timeStamp, liked, onLikeEntry}) => { + const emoji = liked ? '❤️' : '🤍'; + return (

{sender}

{body}

- +
); @@ -17,9 +19,12 @@ const ChatEntry = ({sender, body, timeStamp}) => { 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, + onLikeEntry: PropTypes.func.isRequired, }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 710d4b7e1..8c385f868 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -3,13 +3,16 @@ import PropTypes from 'prop-types'; import ChatEntry from './ChatEntry'; const ChatLog = (props) => { - const chatEntryComponents = props.entries.map((chat) => { + const chatEntryComponents = props.entries.map((entry) => { return ( ); }); @@ -28,6 +31,7 @@ ChatLog.propTypes = { timeStamp: PropTypes.string.isRequired, liked: PropTypes.bool.isRequired })).isRequired, + onLikeEntry: PropTypes.func.isRequired, }; export default ChatLog; From 12327ad615f0e8ffdb8e2fcad131cd0345e2b9b0 Mon Sep 17 00:00:00 2001 From: Esther Kang Date: Mon, 16 Jun 2025 08:32:43 -0700 Subject: [PATCH 5/5] implements chat entries being on opposite sides depending on sender --- 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 76dae80f9..c1eeacb1b 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -4,9 +4,10 @@ import TimeStamp from './TimeStamp'; const ChatEntry = ({id, sender, body, timeStamp, liked, onLikeEntry}) => { const emoji = liked ? '❤️' : '🤍'; + const entrySender = sender === 'Vladimir' ? 'local' : 'remote'; return ( -
+

{sender}

{body}