From 5e332fa0ed83cd06faa8c8ff7c999f3728395979 Mon Sep 17 00:00:00 2001 From: Malik Elmessiry Date: Mon, 9 Jun 2025 22:55:32 +0200 Subject: [PATCH 1/5] setup --- src/App.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.jsx b/src/App.jsx index 14a7f684d..b50d44de6 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,7 +4,7 @@ const App = () => { return (
-

Application title

+

Chat Log

{/* Wave 01: Render one ChatEntry component From 348f4d513dfb0eb3f302ed094952b5fa0ba0e998 Mon Sep 17 00:00:00 2001 From: Malik Elmessiry Date: Sat, 14 Jun 2025 21:57:45 +0200 Subject: [PATCH 2/5] adds ChatLog to App --- src/App.jsx | 6 ++++-- src/components/ChatEntry.jsx | 11 +++++++---- src/components/ChatLog.jsx | 21 +++++++++++++++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 src/components/ChatLog.jsx diff --git a/src/App.jsx b/src/App.jsx index b50d44de6..e64edbc30 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,4 +1,7 @@ import './App.css'; +import ChatLog from './components/ChatLog'; +import data from '/src/data/messages.json'; + const App = () => { return ( @@ -7,8 +10,7 @@ const App = () => {

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..0707891ac 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,12 +1,15 @@ import './ChatEntry.css'; +import TimeStamp from './TimeStamp'; -const ChatEntry = () => { +const ChatEntry = ({ sender, body, timeStamp, liked }) => { return (
-

Replace with name of sender

+

{sender}

-

Replace with body of ChatEntry

-

Replace with TimeStamp component

+

{body}

+

+ +

diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx new file mode 100644 index 000000000..4c191a6d0 --- /dev/null +++ b/src/components/ChatLog.jsx @@ -0,0 +1,21 @@ +import './ChatLog.css'; +import ChatEntry from './ChatEntry'; + +const ChatLog = ({ entries }) => { + const chatEntries = entries.map(entry => ( + + )); + + return ( +
{chatEntries}
+ ) + +}; + +export default ChatLog; \ No newline at end of file From a6e777a66f381353f80cc84407f80b760b650f88 Mon Sep 17 00:00:00 2001 From: Malik Elmessiry Date: Sat, 14 Jun 2025 22:58:24 +0200 Subject: [PATCH 3/5] adds total like count --- src/App.jsx | 19 ++++++++++++++++++- src/components/ChatEntry.jsx | 12 +++++++++--- src/components/ChatLog.jsx | 4 +++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index e64edbc30..58f2e8284 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,16 +1,33 @@ import './App.css'; import ChatLog from './components/ChatLog'; import data from '/src/data/messages.json'; +import { useState } from 'react'; const App = () => { + + const [entries, setEntries] = useState(data) + + function toggleLike(id) { + const updatedEntries = entries.map(entry => { + if (entry.id === id) { + return { ...entry, liked: !entry.liked } + } + return entry; + }); + setEntries(updatedEntries); + }; + + const totalLikes = entries.filter(entry => entry.liked).length; + return (

Chat Log

+

{totalLikes} ❤️s

- +
); diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 0707891ac..c73a2f0f5 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,7 +1,9 @@ import './ChatEntry.css'; import TimeStamp from './TimeStamp'; +import propTypes from 'prop-types'; + +const ChatEntry = ({ id, sender, body, timeStamp, liked, toggleLike }) => { -const ChatEntry = ({ sender, body, timeStamp, liked }) => { return (

{sender}

@@ -10,14 +12,18 @@ const ChatEntry = ({ sender, body, timeStamp, liked }) => {

- +
); }; ChatEntry.propTypes = { - // Fill with correct proptypes + sender: propTypes.string.isRequired, + body: propTypes.string.isRequired, + timeStamp: propTypes.string.isRequired, + liked: propTypes.bool.isRequired, + toggleLike: propTypes.func.isRequired }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 4c191a6d0..c0dcb3a4d 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -1,7 +1,7 @@ import './ChatLog.css'; import ChatEntry from './ChatEntry'; -const ChatLog = ({ entries }) => { +const ChatLog = ({ entries, onToggleLike }) => { const chatEntries = entries.map(entry => ( { sender={entry.sender} body={entry.body} timeStamp={entry.timeStamp} + liked={entry.liked} + toggleLike={onToggleLike} /> )); From d4a05ecccf7976300cdfdcbcee7a2f2ad13a488d Mon Sep 17 00:00:00 2001 From: Malik Elmessiry Date: Sat, 14 Jun 2025 23:19:07 +0200 Subject: [PATCH 4/5] adds optional enhancement --- src/App.jsx | 2 +- src/components/ChatEntry.jsx | 10 ++++++---- src/components/ChatLog.jsx | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 58f2e8284..3d63a904f 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -23,7 +23,7 @@ const App = () => { return (
-

Chat Log

+

Chat Between Vladimir and Estragon

{totalLikes} ❤️s

diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index c73a2f0f5..eb3696414 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -2,17 +2,19 @@ import './ChatEntry.css'; import TimeStamp from './TimeStamp'; import propTypes from 'prop-types'; -const ChatEntry = ({ id, sender, body, timeStamp, liked, toggleLike }) => { +const ChatEntry = ({ id, sender, body, timeStamp, liked, onToggleLike }) => { + const localOrRemote = sender === 'Vladimir' ? 'chat-entry local' : 'chat-entry remote'; + return ( -
+

{sender}

{body}

- +
); @@ -23,7 +25,7 @@ ChatEntry.propTypes = { body: propTypes.string.isRequired, timeStamp: propTypes.string.isRequired, liked: propTypes.bool.isRequired, - toggleLike: propTypes.func.isRequired + onToggleLike: propTypes.func.isRequired }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index c0dcb3a4d..da3bd0698 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -10,7 +10,7 @@ const ChatLog = ({ entries, onToggleLike }) => { body={entry.body} timeStamp={entry.timeStamp} liked={entry.liked} - toggleLike={onToggleLike} + onToggleLike={onToggleLike} /> )); From 252f6f6bf75dbd149e44b9664ca7d7a97641922a Mon Sep 17 00:00:00 2001 From: Malik Elmessiry Date: Mon, 16 Jun 2025 16:07:52 +0200 Subject: [PATCH 5/5] makes toggle an optional prop --- src/components/ChatEntry.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index eb3696414..7e592ffbd 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -25,7 +25,7 @@ ChatEntry.propTypes = { body: propTypes.string.isRequired, timeStamp: propTypes.string.isRequired, liked: propTypes.bool.isRequired, - onToggleLike: propTypes.func.isRequired + onToggleLike: propTypes.func }; export default ChatEntry;