diff --git a/src/App.js b/src/App.js index c10859093..c54eed24e 100644 --- a/src/App.js +++ b/src/App.js @@ -1,16 +1,59 @@ -import React from 'react'; +import React, { useState } from 'react'; import './App.css'; +import ChatLog from './components/ChatLog'; import chatMessages from './data/messages.json'; +import ColorChoice from './components/ColorChoice'; const App = () => { + const [messages, setMessages] = useState(() => { + const participants = Array.from(new Set(chatMessages.map((message) => message.sender))); + const updatedMessages = chatMessages.map((message) => ({ + ...message, + type: participants.indexOf(message.sender) === 0 ? 'local' : 'remote', + })); + return updatedMessages; + }); + + const [color, setColor] = useState('#000000'); + const [heartCount, setHeartCount] = useState(0); + + const toggleLike = (id) => { + setMessages((prevMessages) => { + return prevMessages.map((message) => { + if (message.id === id) { + const updatedMessage = { ...message, liked: !message.liked }; + if (updatedMessage.liked) { + setHeartCount((prevCount) => prevCount + 1); + } else { + setHeartCount((prevCount) => prevCount - 1); + } + return updatedMessage; + } + return message; + }); + }); + }; + + const setParticipantColor = (color) => { + setColor(color); + }; + + const participants = Array.from(new Set(chatMessages.map((message) => message.sender))); + + const headerTitle = participants.length === 1 ? participants[0] : `${participants[0]} and ${participants[1]}`; + return (
-

Application title

+

Say What

+

{headerTitle}

+
+

{heartCount} ❤️s

+
+
- {/* Wave 01: Render one ChatEntry component - Wave 02: Render ChatLog component */} +
); diff --git a/src/components/ChatEntry.css b/src/components/ChatEntry.css index 05c3baa44..b3c86b12f 100644 --- a/src/components/ChatEntry.css +++ b/src/components/ChatEntry.css @@ -1,59 +1,3 @@ -button { - background: none; - color: inherit; - border: none; - padding: 10px; - font: inherit; - cursor: pointer; - outline: inherit; -} - -.chat-entry { - margin: 1rem; -} - -.chat-entry:last-child { - margin-bottom: 0; -} - -.chat-entry .entry-bubble { - background-color: #ffffe0; - border-radius: 30px; - max-width: 50rem; - min-width: 10rem; - padding: 1rem 1rem 0.1rem 1rem; - position: relative; - width: fit-content; -} - -.chat-entry .entry-bubble:hover { - background-color: #fefea2; -} - -.chat-entry .entry-name { - font-size: medium; - margin-bottom: 0.5rem; -} - -.chat-entry .entry-time { - color: #bbb; - font-size: x-small; - margin-bottom: 0.1rem; - margin-right: 0.5rem; -} - -/* Chat bubble arrow styling */ -.chat-entry .entry-bubble::before { - content: ''; - height: 22px; - width: 44px; - clip-path: polygon(100% 0, 0 0, 50% 100%); - - position: absolute; - top: 0; -} - -/* "local" messages are shown on the left side */ .chat-entry.local { text-align: left; } @@ -62,39 +6,56 @@ button { text-align: right; } +.chat-entry.local .entry-bubble { + background-color: #ffffe0; + border-radius: 20px; + display: inline-block; + padding: 8px 12px; + position: relative; +} + .chat-entry.local .entry-bubble::before { background-color: #ffffe0; + content: ""; + height: 20px; + position: absolute; + bottom: -10px; left: -18px; + transform: rotate(45deg); + width: 20px; } .chat-entry.local .entry-bubble:hover::before { background-color: #fefea2; } -/* "remote" messages are shown on the right side, in blue */ .chat-entry.remote { text-align: right; } -.chat-entry.remote .entry-bubble { - background-color: #e0ffff; - margin-left: auto; - margin-right: 0; -} - -.chat-entry.remote .entry-bubble:hover { - background-color: #a9f6f6; -} - .chat-entry.remote .entry-time { text-align: left; } +.chat-entry.remote .entry-bubble { + background-color: #e0ffff; + border-radius: 20px; + display: inline-block; + padding: 8px 12px; + position: relative; +} + .chat-entry.remote .entry-bubble::before { background-color: #e0ffff; + content: ""; + height: 20px; + position: absolute; + bottom: -10px; right: -18px; + transform: rotate(45deg); + width: 20px; } .chat-entry.remote .entry-bubble:hover::before { background-color: #a9f6f6; -} \ No newline at end of file +} diff --git a/src/components/ChatEntry.js b/src/components/ChatEntry.js index b92f0b7b2..7cbe1a5f9 100644 --- a/src/components/ChatEntry.js +++ b/src/components/ChatEntry.js @@ -1,22 +1,36 @@ import React from 'react'; import './ChatEntry.css'; import PropTypes from 'prop-types'; +import TimeStamp from './TimeStamp'; -const ChatEntry = (props) => { +const ChatEntry = ({id, sender, body, timeStamp, liked, type, color, onLike}) => { + const entryClass = type === 'local' ? 'local' : 'remote'; + const bubbleClass = type === 'local' ? 'local' : 'remote'; return ( -
-

Replace with name of sender

-
-

Replace with body of ChatEntry

-

Replace with TimeStamp component

- +
+

+ {sender} +

+
+

{body}

+ +
); }; ChatEntry.propTypes = { - //Fill with correct proptypes + sender: PropTypes.string.isRequired, + body: PropTypes.string.isRequired, + timeStamp: PropTypes.string.isRequired, + liked: PropTypes.bool, + id: PropTypes.number.isRequired, + onLike: PropTypes.func.isRequired, + type: PropTypes.string.isRequired, + color: PropTypes.string.isRequired, }; export default ChatEntry; diff --git a/src/components/ChatLog.js b/src/components/ChatLog.js new file mode 100644 index 000000000..4309c1e18 --- /dev/null +++ b/src/components/ChatLog.js @@ -0,0 +1,25 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import ChatEntry from './ChatEntry'; + +const ChatLog = ({ entries, color, onLike }) => { + const chatComponents = entries.map((entry, i) => ( + + )); + + return
{chatComponents}
; +}; + +ChatLog.propTypes = { + entries: PropTypes.arrayOf(PropTypes.object).isRequired, + color: PropTypes.string.isRequired, + onLike: PropTypes.func.isRequired, +}; + +export default ChatLog; diff --git a/src/components/ColorChoice.js b/src/components/ColorChoice.js new file mode 100644 index 000000000..10c84ca25 --- /dev/null +++ b/src/components/ColorChoice.js @@ -0,0 +1,24 @@ +import React, { useState } from 'react'; + +const ColorChoice = (props) => { + const [color, setColor] = useState('#000000'); + + const handleColorChange = (e) => { + const selectedColor = e.target.value; + setColor(selectedColor); + props.setColorCallback(selectedColor); + }; + + return ( +
+

Select Color:

+ +
+ ); +}; + +export default ColorChoice;