diff --git a/images/chatLog-components.png b/images/chatLog-components.png new file mode 100644 index 000000000..95c0542cd Binary files /dev/null and b/images/chatLog-components.png differ diff --git a/src/App.css b/src/App.css index d97beb4e6..8e7e6085b 100644 --- a/src/App.css +++ b/src/App.css @@ -1,11 +1,10 @@ #App { - background-color: #87cefa; + background-color: #3d4852; } #App header { - background-color: #222; - color: #fff; - padding-bottom: 0.5rem; + background-color: #f7f8fa; + color: #3d4852; position: fixed; width: 100%; z-index: 100; @@ -27,7 +26,12 @@ } #App header section { - background-color: #e0ffff; + color: #3d4852; + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + border: 3px solid #3d4852; } #App .widget { @@ -49,6 +53,10 @@ display: inline-block } +.black { + color:#222 +} + .red { color: #b22222 } @@ -57,8 +65,8 @@ color: #e6ac00 } -.yellow { - color: #e6e600 +.brown { + color: #735711 } .green { diff --git a/src/App.jsx b/src/App.jsx index 14a7f684d..3383b43df 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,14 +1,65 @@ import './App.css'; +import ChatLog from './components/ChatLog'; +import ColorChoice from './components/ColorChoice'; +import DATA from './data/messages.json'; +import { useState } from 'react'; const App = () => { + const [entryData, setEntryData] = useState(DATA); + const [localColor, setLocalColor] = useState('green'); + const [remoteColor, setRemoteColor] = useState('blue'); + + const LOCAL_SENDER = entryData[0].sender; + const REMOTE_SENDER = entryData[1].sender; + + const handleColorChange = (sender, color) => { + if (sender === LOCAL_SENDER){ + setLocalColor(color); + } else if (sender === REMOTE_SENDER) { + setRemoteColor(color); + } + }; + + const updateEntryLikedState = (entryId) => { + setEntryData(entries => { + return entries.map(entry => { + if (entry.id === entryId) { + return { ...entry, liked: !entry.liked }; + } else { + return entry; + } + }); + }); + }; + + const totalLikes = entryData.reduce((sum, entry) => { + return entry.liked ? sum + 1 : sum; + }, 0); + return (
-

Application title

+

Chat Between{' '} + {LOCAL_SENDER}{' '} + and{' '} + {REMOTE_SENDER} +

+ +
+ + {totalLikes} ❤️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..f7a074473 100644 --- a/src/components/ChatEntry.css +++ b/src/components/ChatEntry.css @@ -10,6 +10,7 @@ button { .chat-entry { margin: 1rem; + font-size: 1.1rem; } .chat-entry:last-child { @@ -31,13 +32,14 @@ button { } .chat-entry .entry-name { - font-size: medium; + font-size: 1.1rem; margin-bottom: 0.5rem; + color: whitesmoke; } .chat-entry .entry-time { color: #bbb; - font-size: x-small; + font-size: small; margin-bottom: 0.1rem; margin-right: 0.5rem; } diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 15c56f96b..bf5f42393 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,20 +1,36 @@ import './ChatEntry.css'; +import TimeStamp from './TimeStamp'; +import PropTypes from 'prop-types'; + +const ChatEntry = ({ id, sender, body, timeStamp, liked, onToggleLike, isLocal, chatColor }) => { + const entryClass = `chat-entry ${isLocal ? 'local' : 'remote'}`; -const ChatEntry = () => { return ( -
-

Replace with name of sender

+
+

{sender}

-

Replace with body of ChatEntry

-

Replace with TimeStamp component

- +

{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, + onToggleLike: PropTypes.func.isRequired, + isLocal: PropTypes.bool.isRequired, + chatColor: PropTypes.string.isRequired }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx new file mode 100644 index 000000000..7162adbdd --- /dev/null +++ b/src/components/ChatLog.jsx @@ -0,0 +1,47 @@ +import ChatEntry from './ChatEntry'; +import './ChatLog.css'; +import PropTypes from 'prop-types'; + +const ChatLog = ({ entries, onToggleHeart, chatLocalColor, chatRemoteColor, localSender}) => { + const chatEntryComponents = entries.map((entry) => { + const isLocal = entry.sender === localSender; + const chatColor = isLocal ? chatLocalColor : chatRemoteColor; + return ( + + ); + }); + + return ( +
+ {chatEntryComponents} +
+ ); +}; + +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, + }) + ), + onToggleHeart: PropTypes.func.isRequired, + chatLocalColor: PropTypes.string.isRequired, + chatRemoteColor: PropTypes.string.isRequired, + localSender: PropTypes.string.isRequired +}; + +export default ChatLog; \ No newline at end of file diff --git a/src/components/ColorChoice.css b/src/components/ColorChoice.css new file mode 100644 index 000000000..0ba42cb4f --- /dev/null +++ b/src/components/ColorChoice.css @@ -0,0 +1,11 @@ +label { + font-size: 1.1rem; + font-weight: 600; +} +select { + margin-left: 1rem; + cursor: pointer; + border-radius: 10px; + font-size: 1rem; + padding: 0.5rem; +} diff --git a/src/components/ColorChoice.jsx b/src/components/ColorChoice.jsx new file mode 100644 index 000000000..dee854a43 --- /dev/null +++ b/src/components/ColorChoice.jsx @@ -0,0 +1,30 @@ +import PropTypes from 'prop-types'; +import './ColorChoice.css'; + +const ColorChoice = ({sender, chatColor, setColorCallback}) => { + const handleColorChange = (event) => { + setColorCallback(sender, event.target.value); + }; + + return ( + + ); +}; + +ColorChoice.propTypes = { + sender: PropTypes.string.isRequired, + chatColor: PropTypes.string.isRequired, + setColorCallback: PropTypes.func.isRequired +}; +export default ColorChoice; \ No newline at end of file