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
16 changes: 14 additions & 2 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
z-index: 100;
text-align: center;
align-items: center;
height: 80px;
}

#App main {
padding-left: 2em;
padding-right: 2em;
padding-bottom: 5rem;
padding-top: 10rem;
margin: auto;
}

#App h1 {
Expand All @@ -28,14 +30,20 @@

#App header section {
background-color: #e0ffff;
color: black;
height: 100%;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center
}

#App .widget {
display: inline-block;
line-height: 0.5em;
/* line-height: 0.5em; */
border-radius: 10px;
color: black;
font-size:0.8em;
font-size: 0.8em;
padding-left: 1em;
padding-right: 1em;
}
Expand Down Expand Up @@ -71,4 +79,8 @@

.purple {
color: purple
}

.black {
color: black
}
56 changes: 53 additions & 3 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,66 @@
import React from 'react';
import './App.css';
import chatMessages from './data/messages.json';
import ChatLog from './components/ChatLog';
import ColorChoice from './components/ColorChoice';

const App = () => {
const [messages, setMessages] = React.useState(chatMessages);

Choose a reason for hiding this comment

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

👍 We need a piece of state to track changes to our messages, initialized from the json file we loaded.


const likeMessage = (id) => {
setMessages(
messages.map((message) => (message.id === id ? {
...message,
liked: !message.liked
} : message))
);
};
Comment on lines +10 to +17
Copy link

@ameerrah9 ameerrah9 Jul 11, 2023

Choose a reason for hiding this comment

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

This is an optimal approach to update the state of the heart without needing the entire entry, all you need to do is send the id of the liked entry up to App.js.


const [colorChoice, setColor] = React.useState({
[messages[0].sender]: 'red',
[messages[1].sender]: 'green'
})

const setColorChoice = (sender, chosenColor) => {
console.log(sender, chosenColor)
setColor(prevColor => {
return {
...prevColor,
[sender]: chosenColor
}
})
}


console.log(colorChoice)

let totalHearts = 0;

for (let message of messages) {
if (message.liked) {
totalHearts++
}
}
Comment on lines +37 to +43

Choose a reason for hiding this comment

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

This is an optimal approach to calculating the number of likes, great job 😁

This is a great place to calculate & display the total likes


return (
<div id="App">
<header>
<h1>Application title</h1>
<h1>Chat between
<i className={colorChoice[messages[0].sender]}>{messages[0].sender}</i> and <i className={colorChoice[messages[1].sender]}>{messages[1].sender}</i></h1>
<section>
<span className="widget">
<ColorChoice sender={messages[0].sender} setColorCallback={setColorChoice}/>
</span>
<span id="heartWidget">
<p>{totalHearts} ❤️s</p>
</span>
<span className="widget">
<ColorChoice sender={messages[1].sender} setColorCallback={setColorChoice}/>
</span>
</section>
</header>
<main>
{/* Wave 01: Render one ChatEntry component
Wave 02: Render ChatLog component */}
<ChatLog entries={messages} colorChoice={colorChoice} likeMessage={likeMessage} />
</main>
</div>
);
Expand Down
46 changes: 34 additions & 12 deletions src/components/ChatEntry.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
import React from 'react';
import './ChatEntry.css';
import PropTypes from 'prop-types';
import TimeStamp from './TimeStamp';

const ChatEntry = (props) => {
return (
<div className="chat-entry local">
<h2 className="entry-name">Replace with name of 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>
</section>
</div>
);
const ChatEntry = ({ id, sender, body, timeStamp, liked, likeMessage, colorChoice = 'black' }) => {
const likedHeart = '❤️';
const notLikedHeart = '🤍';
const likedClass = liked ? likedHeart : notLikedHeart;

const bubbleClass = colorChoice[sender] ?? 'black'

// console.log(bubbleClass)

const stateMessage = (sender) => {
return sender === 'Vladimir' ? 'local' : 'remote';
};
Comment on lines +11 to +17

Choose a reason for hiding this comment

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

Nice work completing this optional alignment feature


return (
<div className={'chat-entry ' + stateMessage(sender)}>
<h2 className={`entry-name ${bubbleClass}`}>{sender}</h2>
<section className={`entry-bubble ${bubbleClass}`}>
<p>{body}</p>
<p className="entry-time">
<TimeStamp time={timeStamp} />
</p>
Comment on lines +24 to +26

Choose a reason for hiding this comment

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

Nice job utilizing the TimeStamp component provided!

<button className="like" onClick={() => likeMessage(id)}>

Choose a reason for hiding this comment

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

👍 We need a function that will update the state of the entry that is click

{likedClass}
</button>
</section>
</div>
);
};

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,
colorChoice: PropTypes.func
Comment on lines 35 to +41

Choose a reason for hiding this comment

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

👍

};

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

const ChatLog = ({ entries, likeMessage, colorChoice }) => {
const entryComponents = entries.map(entry => {
return (
<ChatEntry
id= {entry.id}
sender= {entry.sender}
body= {entry.body}
timeStamp= {entry.timeStamp}
liked= {entry.liked}
likeMessage= {likeMessage}
colorChoice={colorChoice}
/>
Comment on lines +6 to +16

Choose a reason for hiding this comment

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

Nice job utilizing this map feature to iterate over the entries 👍🏾

)
})

return (
<div className="chat-log">
<section>{entryComponents}</section>
</div>
)
}

export default ChatLog
19 changes: 19 additions & 0 deletions src/components/ColorChoice.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ul {
list-style: none;
display: flex;
flex-direction: row;
gap: 10px;
overflow: hidden;
padding: 0
}

#color-picker {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

li {
float: left;
}
21 changes: 21 additions & 0 deletions src/components/ColorChoice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import './ColorChoice.css'

const ColorChoice = ({ setColorCallback, sender }) => {
return (
<div>
<p>{`${sender}'s Color:`}</p>
<ul>
<li onClick={() => setColorCallback(sender, 'red')}>🔴</li>
<li onClick={() => setColorCallback(sender, 'orange')}>🟠</li>
Comment on lines +4 to +10

Choose a reason for hiding this comment

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

🎉

<li onClick={() => setColorCallback(sender, 'yellow')}>🟡</li>
<li onClick={() => setColorCallback(sender, 'green')}>🟢</li>
<li onClick={() => setColorCallback(sender, 'blue')}>🔵</li>
<li onClick={() => setColorCallback(sender,'purple')}>🟣</li>
</ul>
</div>

)
}

export default ColorChoice