Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion project-docs/wave-02.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

**Learn Topics: React Components and Props required for this wave**

Implement a `ChatLog` component and update the `App` component to display an entire chat log. `ChatLog` should display a sequence of individual `ChatEntry` components.
--Implement a `ChatLog` component and
--update the `App` component to display an entire chat log.
--`ChatLog` should display a sequence of individual `ChatEntry` components.
Comment on lines +5 to +7

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to make this change? In industry, you'll be submitting PR's with code you'd like your entire team to have. Is this change necessary? If not, we can be warier on what file changes we git add. So instead of using, git add . to add all files we changed locally, we can specify which file we want to add to our commit via git add nameOfFile.js


`ChatLog` takes one prop named `entries` (which is an array).

Expand Down
1 change: 1 addition & 0 deletions project-docs/wave-03.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
In this wave we will update the components to manage a **like** feature.

- Add behavior to heart button in `ChatEntry` so that when it is clicked it toggles from an empty heart (🤍) to a filled heart (❤️) and from a filled heart (❤️) to an empty heart (🤍).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was not necessary either. The previous comment also applies here.

- Manage the click event and state of the chat entries such that when the like status of a chat message changes by clicking the heart button, it is tracked by the `App` and the `App` reports the number of total messages that have been liked.
- Example: If the user has liked three messages, `3 ❤️s` will appear at the top of the screen.

Expand Down
29 changes: 23 additions & 6 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
import React from 'react';
import React, {useState} from 'react';
import './App.css';
import chatMessages from './data/messages.json';
import ChatLog from './components/ChatLog';

const App = () => {
const [messageData, setMessageData] = useState(chatMessages)

const updateMessageData = (updatedMessage) => {
const messages = messageData.map((message) => {
if (message.id === updatedMessage.id) {
return updatedMessage;
} else {
return message;
}
});

setMessageData(messages)
}
Comment on lines +7 to +19

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work managing the data and returning a brand new object!

Here's a refresher on updating state in React:

React components re-render whenever there is a change/update to state data. In this case, our data is an object and we are modifying values nested within that object.

Under the hood, React uses Object.is() to compare the previous state object with the one that's been provided viasetMessages(updatedMessages). Object.is() checks if the object has changed and more specifically if the object passed has a different reference in memory. In Javascript, changing the properties and/or values in an object does NOT change the object reference, which is why we must create a new version of our state object ( contains a copy of all the properties that weren't updated along with the properties/values that were).

Here is an article with more info: https://www.valentinog.com/blog/react-object-is/


return (
<div id="App">
<div id="App" >
<header>
<h1>Application title</h1>
<h1>Chatlog</h1>
</header>
<main>
{/* Wave 01: Render one ChatEntry component
Wave 02: Render ChatLog component */}
<main className="chat-log">
<ChatLog
messages={messageData}
onUpdateMessage={updateMessageData}
></ChatLog>
</main>
</div>
);
Expand Down
84 changes: 75 additions & 9 deletions src/components/ChatEntry.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,88 @@
import React from 'react';
import './ChatEntry.css';
import PropTypes from 'prop-types';
// import PropTypes from 'prop-types';


const ChatEntry = ({
id,
sender,
body,
timeStamp,
liked,
onUpdate
}) => {


// console.log({
// id,
// sender,
// body,
// timeStamp,
// liked,
// onUpdate
// })
// const firstMessage = props.messages[0]
Comment on lines +16 to +24

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In industry, you'll be submitting PR's containing code you'd like your team members to have. In this case, is it necessary for your teammates to have this console.log ? If not, we can remove this line.

const onLikeButtonClick = () => {
const updatedMessage = {
id: id,
sender: sender,
body: body,
timeStamp: timeStamp,
liked: !liked,
}
onUpdate(updatedMessage)

// const button = document.getElementById('button');

// if (!props.liked === true){
// button.textContent = '🌻'
// } else {
// button.textContent = '🤍'
// }

// const emojiChange = () => {
// if (!props.liked === true){
// button.textContent = '🌻'
// } else {
// button.textContent = '🤍'
// }
// }

}

// not right
// const button = document.getElementById('button');
// this is not right.....
// const emojiChange = props.liked ? button.textContent = '🌻' : button.textContent = '🤍';
// experimenting
// const emojiChange = props.liked ? 'green' : 'red';
Comment on lines +35 to +58

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make sure we remove commented out code that we don't want our teammates to pull.



let icon = ''

if (liked === true){
icon = '🌻'
} else {
icon = '🤍'
}
Comment on lines +63 to +67

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the tests fail because it's expecting a different icon however I don't mind this creative deviance :)


const ChatEntry = (props) => {
return (
<div className="chat-entry local">
<h2 className="entry-name">Replace with name of sender</h2>
<h2 className="entry-name">{sender}</h2>
<section className="entry-bubble">
<p>Replace with body of ChatEntry</p>
<p className="entry-time">Replace with TimeStamp component</p>
<button className="like">🤍</button>
<p>{body}</p>
<p className="entry-time">{timeStamp}</p>
<button className="emojiChange" onClick={onLikeButtonClick} id="button">{icon}</button>
</section>
</div>
);
};

ChatEntry.propTypes = {
//Fill with correct proptypes
};
// ChatEntry.propTypes = {
// //Fill with correct proptypes
// sender: PropTypes.string.isRequired,
// body: PropTypes.string.isRequired,
// timeStamp: PropTypes.string.isRequired,
// };

export default ChatEntry;
31 changes: 31 additions & 0 deletions src/components/ChatLog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import './ChatLog.css';
import './ChatEntry.css';
// import PropTypes from 'prop-types';
import ChatEntry from './ChatEntry';

const ChatLog = ({messages, onUpdateMessage}) => {
// console.log(messages)


Comment on lines +9 to +10

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unneeded whitespace

const messageComponents = messages.map((message,index) => {
return(
<div key={message.id}>
<ChatEntry
id={message.id}
sender={message.sender}
body={message.body}
timeStamp={message.timeStamp}
liked={message.liked}
onUpdate={onUpdateMessage}
></ChatEntry>
</div>
)
});
Comment on lines +11 to +24

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work creating multiple sibling components!!


return(
<section>{messageComponents}</section>
);
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to add PropTypes to help validate our props and avoid future errors.

ChatLog.propTypes = {
  messages: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.number.isRequired,
      sender: PropTypes.string.isRequired,
      body: PropTypes.string.isRequired,
      timeStamp: PropTypes.string.isRequired,
      liked: PropTypes.bool,
    })
  ),
  onUpdateMessage: PropTypes.func.isRequired,
};

export default ChatLog;