From f5555a8487040fcdee8708e78462b5e4acb076b3 Mon Sep 17 00:00:00 2001 From: Anika Stephen Wilbur Date: Wed, 18 Jan 2023 23:15:14 -0800 Subject: [PATCH 1/3] Start building out App and ChatEntry components. --- src/App.js | 18 +++++++++++++++++- src/components/ChatEntry.js | 10 ++++++---- src/data/messages.json | 18 +++++++++--------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/App.js b/src/App.js index c10859093..5f50c5a3c 100644 --- a/src/App.js +++ b/src/App.js @@ -1,14 +1,30 @@ -import React from 'react'; +import React, { useState } from 'react'; +import ChatEntry from './components/ChatEntry'; import './App.css'; import chatMessages from './data/messages.json'; const App = () => { + // const [, setBoardsData] = useState([]); + + // const messageLog = () => { + // return ( + // chatMessages + // ) + // } return (

Application title

+
+ +
{/* Wave 01: Render one ChatEntry component Wave 02: Render ChatLog component */}
diff --git a/src/components/ChatEntry.js b/src/components/ChatEntry.js index b92f0b7b2..6d164ae10 100644 --- a/src/components/ChatEntry.js +++ b/src/components/ChatEntry.js @@ -5,10 +5,10 @@ import PropTypes from 'prop-types'; const ChatEntry = (props) => { return (
-

Replace with name of sender

+

{props.sender}

-

Replace with body of ChatEntry

-

Replace with TimeStamp component

+

{props.body}

+

{props.timeStamp}

@@ -16,7 +16,9 @@ const ChatEntry = (props) => { }; ChatEntry.propTypes = { - //Fill with correct proptypes + sender: PropTypes.string, + body: PropTypes.string, + timeStamp: PropTypes.string }; export default ChatEntry; diff --git a/src/data/messages.json b/src/data/messages.json index 64fdb053c..554b908ad 100644 --- a/src/data/messages.json +++ b/src/data/messages.json @@ -159,33 +159,33 @@ "body":"so you are a robot", "timeStamp":"2018-05-29T23:13:31+00:00", "liked": false - }, - { +}, +{ "id": 24, "sender":"Estragon", "body":"NO, I am a human, you are a robot.", "timeStamp":"2018-05-29T23:14:28+00:00", "liked": false - }, - { +}, +{ "id": 25, "sender":"Vladimir", "body":"but you just said that you are robots", "timeStamp":"2018-05-29T23:15:47+00:00", "liked": false - }, - { +}, +{ "id": 26, "sender":"Estragon", "body":"No, I said you are a person, I am a robot.", "timeStamp":"2018-05-29T23:16:53+00:00", "liked": false - }, - { +}, +{ "id": 27, "sender":"Vladimir", "body":"then you are lying", "timeStamp":"2018-05-29T23:17:34+00:00", "liked": false - } +} ] From 7962902fc7f54ecbb11656fba7e36c0676f3374c Mon Sep 17 00:00:00 2001 From: Anika Stephen Wilbur Date: Thu, 19 Jan 2023 23:41:49 -0800 Subject: [PATCH 2/3] Completes Wave 02 --- src/App.js | 38 ++++++++++++++++++------------------- src/components/ChatEntry.js | 18 +++++++++++------- src/components/ChatLog.js | 30 +++++++++++++++++++++++++++++ src/components/TimeStamp.js | 2 +- 4 files changed, 61 insertions(+), 27 deletions(-) create mode 100644 src/components/ChatLog.js diff --git a/src/App.js b/src/App.js index 5f50c5a3c..865d66d93 100644 --- a/src/App.js +++ b/src/App.js @@ -1,35 +1,35 @@ -import React, { useState } from 'react'; -import ChatEntry from './components/ChatEntry'; -import './App.css'; +import React, { useEffect, useState } from 'react'; +import ChatLog from './components/ChatLog'; import chatMessages from './data/messages.json'; +import './App.css'; const App = () => { - // const [, setBoardsData] = useState([]); + const [messageData, setMessageData] = useState([]); + + useEffect(() => { + setMessageData(chatMessages); + }, []); + + const entries = messageData.slice(0); - // const messageLog = () => { - // return ( - // chatMessages - // ) - // } return (
-

Application title

+

Rockin' React Chat Log!

- +
+
  • + +
  • +
    - {/* Wave 01: Render one ChatEntry component - Wave 02: Render ChatLog component */}
    ); }; -export default App; +export default App; \ No newline at end of file diff --git a/src/components/ChatEntry.js b/src/components/ChatEntry.js index 6d164ae10..4b27a2c2b 100644 --- a/src/components/ChatEntry.js +++ b/src/components/ChatEntry.js @@ -3,12 +3,13 @@ import './ChatEntry.css'; import PropTypes from 'prop-types'; const ChatEntry = (props) => { + console.log('this is props in ChatEntry', props) return (
    -

    {props.sender}

    +

    {props.entry.sender}

    -

    {props.body}

    -

    {props.timeStamp}

    +

    {props.entry.body}

    +

    {props.entry.timeStamp}

    @@ -16,9 +17,12 @@ const ChatEntry = (props) => { }; ChatEntry.propTypes = { - sender: PropTypes.string, - body: PropTypes.string, - timeStamp: PropTypes.string + entry: PropTypes.arrayOf(PropTypes.shape({ + id: PropTypes.number, + sender: PropTypes.string, + body: PropTypes.string, + timeStamp: PropTypes.string + })) }; -export default ChatEntry; +export default ChatEntry; \ No newline at end of file diff --git a/src/components/ChatLog.js b/src/components/ChatLog.js new file mode 100644 index 000000000..6cdd09488 --- /dev/null +++ b/src/components/ChatLog.js @@ -0,0 +1,30 @@ +import React, { useEffect, useState } from 'react'; +import ChatEntry from '../components/ChatEntry'; +import PropTypes from 'prop-types'; + +const ChatLog = (props) => { + const chatLog = props.entries.map((entry, index) => { + return ( +
      + +
    + ) + }); + return ( + chatLog + ); +}; + +ChatLog.propTypes = { + entries: PropTypes.arrayOf(PropTypes.shape({ + id: PropTypes.number, + sender: PropTypes.string, + body: PropTypes.string, + timeStamp: PropTypes.string, + // liked: PropTypes.bool + })), +}; + +export default ChatLog; \ No newline at end of file diff --git a/src/components/TimeStamp.js b/src/components/TimeStamp.js index 51232778b..251aeef64 100644 --- a/src/components/TimeStamp.js +++ b/src/components/TimeStamp.js @@ -8,4 +8,4 @@ const TimeStamp = (props) => { return {relative}; }; -export default TimeStamp; +export default TimeStamp; \ No newline at end of file From 2ba160811fd3effc3a062c7e7969da6a90e35cf0 Mon Sep 17 00:00:00 2001 From: Anika Stephen Wilbur Date: Fri, 20 Jan 2023 10:45:58 -0800 Subject: [PATCH 3/3] Finished Wave 03 and all tests passing --- src/App.css | 4 ++++ src/App.js | 41 +++++++++++++++++++++++++++++------- src/App.test.js | 2 +- src/components/ChatEntry.js | 42 ++++++++++++++++++++++++++----------- src/components/ChatLog.css | 4 ++++ src/components/ChatLog.js | 25 +++++++++++++++------- src/components/TimeStamp.js | 5 +++++ 7 files changed, 95 insertions(+), 28 deletions(-) diff --git a/src/App.css b/src/App.css index d97beb4e6..cdcdbb761 100644 --- a/src/App.css +++ b/src/App.css @@ -49,6 +49,10 @@ display: inline-block } +li { + list-style-type: none; +} + .red { color: #b22222 } diff --git a/src/App.js b/src/App.js index 865d66d93..1ea89c248 100644 --- a/src/App.js +++ b/src/App.js @@ -4,27 +4,54 @@ import chatMessages from './data/messages.json'; import './App.css'; const App = () => { - const [messageData, setMessageData] = useState([]); + + const [chatEntryData, setChatEntryData] = useState([ + { + id: 0, + sender: '', + body: '', + timeStamp: '', + liked: false + } + ]); useEffect(() => { - setMessageData(chatMessages); + setChatEntryData(chatMessages); }, []); + + const [likesCount, setLikesCount] = useState(0); - const entries = messageData.slice(0); + const updateChatEntryData = updatedEntry => { + const updatedEntries = chatEntryData.map(entry => { + if (entry.id === updatedEntry.id) { + if (updatedEntry.liked === true) { + setLikesCount((likesCount) => likesCount + 1); + return updatedEntry; + } else { + setLikesCount((likesCount) => likesCount - 1); + return updatedEntry; + } + } else { + return entry; + }}); + setChatEntryData(updatedEntries); + }; return (

    Rockin' React Chat Log!

    +

    {likesCount} ❤️

    -
    -
  • +
    +
      - +
  • diff --git a/src/App.test.js b/src/App.test.js index ca75c71dd..5296a141c 100644 --- a/src/App.test.js +++ b/src/App.test.js @@ -14,7 +14,7 @@ describe('Wave 03: clicking like button and rendering App', () => { fireEvent.click(buttons[10]) // Assert - const countScreen = screen.getByText(/3 ❤️s/) + const countScreen = screen.getByText(/3 ❤️/) expect(countScreen).not.toBeNull() }) diff --git a/src/components/ChatEntry.js b/src/components/ChatEntry.js index 4b27a2c2b..56f5b6be1 100644 --- a/src/components/ChatEntry.js +++ b/src/components/ChatEntry.js @@ -1,28 +1,46 @@ -import React from 'react'; +import React, { useState } from 'react'; +import TimeStamp from './TimeStamp'; import './ChatEntry.css'; import PropTypes from 'prop-types'; const ChatEntry = (props) => { - console.log('this is props in ChatEntry', props) + + const [isMessageLiked, setIsMessageLiked] = useState(false) + + + const toggleLikeButton = (event) => { + const updatedChatEntry = { + id: props.id, + sender: props.sender, + body: props.body, + timeStamp: props.timeStamp, + liked: !props.liked + } + setIsMessageLiked(!isMessageLiked); + props.onHandleLikes(updatedChatEntry); + }; + return (
    -

    {props.entry.sender}

    +

    {props.sender}

    -

    {props.entry.body}

    -

    {props.entry.timeStamp}

    - +

    {props.body}

    +

    +
    ); }; ChatEntry.propTypes = { - entry: PropTypes.arrayOf(PropTypes.shape({ - id: PropTypes.number, - sender: PropTypes.string, - body: PropTypes.string, - timeStamp: PropTypes.string - })) + id: PropTypes.number, + sender: PropTypes.string, + body: PropTypes.string, + timeStamp: PropTypes.string, + liked: PropTypes.bool, + onHandleLikes: PropTypes.func }; export default ChatEntry; \ No newline at end of file diff --git a/src/components/ChatLog.css b/src/components/ChatLog.css index 378848d1f..6fbac3452 100644 --- a/src/components/ChatLog.css +++ b/src/components/ChatLog.css @@ -2,3 +2,7 @@ margin: auto; max-width: 50rem; } + + + + diff --git a/src/components/ChatLog.js b/src/components/ChatLog.js index 6cdd09488..bfa26a82f 100644 --- a/src/components/ChatLog.js +++ b/src/components/ChatLog.js @@ -1,20 +1,28 @@ -import React, { useEffect, useState } from 'react'; import ChatEntry from '../components/ChatEntry'; import PropTypes from 'prop-types'; const ChatLog = (props) => { - const chatLog = props.entries.map((entry, index) => { + + const fullChatLog = props.entries.map((entry, index) => { return ( -
      +
    1. -
    + ) }); + return ( - chatLog - ); +
    + {fullChatLog} +
    + ) }; ChatLog.propTypes = { @@ -23,8 +31,9 @@ ChatLog.propTypes = { sender: PropTypes.string, body: PropTypes.string, timeStamp: PropTypes.string, - // liked: PropTypes.bool + liked: PropTypes.bool })), + onUpdateLikes: PropTypes.func }; export default ChatLog; \ No newline at end of file diff --git a/src/components/TimeStamp.js b/src/components/TimeStamp.js index 251aeef64..d059703da 100644 --- a/src/components/TimeStamp.js +++ b/src/components/TimeStamp.js @@ -1,4 +1,5 @@ import { DateTime } from 'luxon'; +import PropTypes from 'prop-types'; const TimeStamp = (props) => { const time = DateTime.fromISO(props.time); @@ -8,4 +9,8 @@ const TimeStamp = (props) => { return {relative}; }; +TimeStamp.propTypes = { + time: PropTypes.string +} + export default TimeStamp; \ No newline at end of file