diff --git a/images/react-chatlog-demo.png b/images/react-chatlog-demo.png index 6b7a83446..8b8d15050 100644 Binary files a/images/react-chatlog-demo.png and b/images/react-chatlog-demo.png differ diff --git a/src/App.jsx b/src/App.jsx index 14a7f684d..5ebd018bd 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,17 +1,54 @@ import './App.css'; +import messagesData from './data/messages.json'; +import ChatLog from './components/ChatLog'; +import { useState } from 'react'; -const App = () => { - return ( -
-
-

Application title

-
-
- {/* Wave 01: Render one ChatEntry component - Wave 02: Render ChatLog component */} -
-
+const toggleLikes = entry => { + return {...entry, liked: !entry.liked}; +}; + +const countTotalLikes = messages => { + let total = 0; + for ( const entry of messages){ + if (entry.liked) { + total += 1; + } + } + return total; +}; + +function App() { + const[messages, setMessages] = useState(messagesData); + + const handleLikes = id => { + setMessages(prevMessages=>{ + return prevMessages.map(entry => { + if(entry.id === id){ + return toggleLikes(entry); + } else { + return entry; + } + }); + }); + + }; + + const totalLikes = countTotalLikes(messages); + return ( +
+
+

Chat between Vladimir and Estragon

+

{`${totalLikes} ❤️s`}

+
+
+ +
+
); }; + export default App; + diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index fe05efa0f..f7bb14d6f 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,21 +1,32 @@ import './ChatEntry.css'; +import PropTypes from 'prop-types'; +import TimeStamp from './TimeStamp'; +import { DateTime } from 'luxon'; -const ChatEntry = () => { +const ChatEntry = ({id,sender,body,timeStamp,onLikes, liked}) => { + const buttonClass = liked ? 'like__item__toggle--liked' : ''; return ( // Replace the outer tag name with a semantic element that fits our use case - -

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, + onLikes:PropTypes.func, }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx new file mode 100644 index 000000000..51e8a708c --- /dev/null +++ b/src/components/ChatLog.jsx @@ -0,0 +1,37 @@ +import './ChatLog.css'; +import ChatEntry from './ChatEntry'; +import PropTypes from 'prop-types'; + +const ChatLog =({entries, onLikeEntry }) => { + const ChatEntryLogs = entries.map(entry=> { + return ( + + ); + }); + return( +
{ChatEntryLogs}
+ //rename tag + ); +}; + +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, + onLikeEntry: PropTypes.func, + +}; +export default ChatLog; \ No newline at end of file