From 15747c6eae32ab8cc5db8a2d9f1587818b94e12f Mon Sep 17 00:00:00 2001 From: olive Date: Mon, 20 Jun 2022 19:28:43 -0500 Subject: [PATCH 1/7] destructured props --- src/App.js | 5 +-- src/App.test.js | 62 +++++++++++++++++----------------- src/components/ChatEntry.js | 16 ++++++--- src/components/ChatLog.js | 28 +++++++++++++++ src/components/ChatLog.test.js | 48 +++++++++++++------------- 5 files changed, 97 insertions(+), 62 deletions(-) create mode 100644 src/components/ChatLog.js diff --git a/src/App.js b/src/App.js index c10859093..edf008b4f 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,7 @@ import React from 'react'; import './App.css'; +import ChatEntry from './components/ChatEntry'; +import ChatLog from './components/ChatLog'; import chatMessages from './data/messages.json'; const App = () => { @@ -9,8 +11,7 @@ const App = () => {

Application title

- {/* Wave 01: Render one ChatEntry component - Wave 02: Render ChatLog component */} +
); diff --git a/src/App.test.js b/src/App.test.js index ca75c71dd..ca5281135 100644 --- a/src/App.test.js +++ b/src/App.test.js @@ -1,53 +1,53 @@ -import React from 'react' -import App from './App' -import { render, screen, fireEvent } from '@testing-library/react' +import React from 'react'; +import App from './App'; +import { render, screen, fireEvent } from '@testing-library/react'; -describe('Wave 03: clicking like button and rendering App', () => { +describe.skip('Wave 03: clicking like button and rendering App', () => { test('that the correct number of likes is printed at the top', () => { // Arrange - const { container } = render() - let buttons = container.querySelectorAll('button.like') + const { container } = render(); + let buttons = container.querySelectorAll('button.like'); // Act - fireEvent.click(buttons[0]) - fireEvent.click(buttons[1]) - fireEvent.click(buttons[10]) + fireEvent.click(buttons[0]); + fireEvent.click(buttons[1]); + fireEvent.click(buttons[10]); // Assert - const countScreen = screen.getByText(/3 ❤️s/) - expect(countScreen).not.toBeNull() - }) + const countScreen = screen.getByText(/3 ❤️s/); + expect(countScreen).not.toBeNull(); + }); test('clicking button toggles heart and does not affect other buttons', () => { // Arrange - const { container } = render() - const buttons = container.querySelectorAll('button.like') - const firstButton = buttons[0] - const lastButton = buttons[buttons.length - 1] + const { container } = render(); + const buttons = container.querySelectorAll('button.like'); + const firstButton = buttons[0]; + const lastButton = buttons[buttons.length - 1]; // Act-Assert // click the first button - fireEvent.click(firstButton) - expect(firstButton.innerHTML).toEqual('❤️') + fireEvent.click(firstButton); + expect(firstButton.innerHTML).toEqual('❤️'); // check that all other buttons haven't changed for (let i = 1; i < buttons.length; i++) { - expect(buttons[i].innerHTML).toEqual('🤍') + expect(buttons[i].innerHTML).toEqual('🤍'); } // click the first button a few more times - fireEvent.click(firstButton) - expect(firstButton.innerHTML).toEqual('🤍') - fireEvent.click(firstButton) - expect(firstButton.innerHTML).toEqual('❤️') - fireEvent.click(firstButton) - expect(firstButton.innerHTML).toEqual('🤍') + fireEvent.click(firstButton); + expect(firstButton.innerHTML).toEqual('🤍'); + fireEvent.click(firstButton); + expect(firstButton.innerHTML).toEqual('❤️'); + fireEvent.click(firstButton); + expect(firstButton.innerHTML).toEqual('🤍'); // click the last button a couple times - fireEvent.click(lastButton) - expect(lastButton.innerHTML).toEqual('❤️') - fireEvent.click(lastButton) - expect(lastButton.innerHTML).toEqual('🤍') - }) -}) + fireEvent.click(lastButton); + expect(lastButton.innerHTML).toEqual('❤️'); + fireEvent.click(lastButton); + expect(lastButton.innerHTML).toEqual('🤍'); + }); +}); diff --git a/src/components/ChatEntry.js b/src/components/ChatEntry.js index b92f0b7b2..267753f9c 100644 --- a/src/components/ChatEntry.js +++ b/src/components/ChatEntry.js @@ -1,14 +1,17 @@ import React from 'react'; import './ChatEntry.css'; import PropTypes from 'prop-types'; +import TimeStamp from './TimeStamp'; -const ChatEntry = (props) => { +const ChatEntry = ({ sender, body, timeStamp }) => { return (
-

Replace with name of sender

+

{sender}

-

Replace with body of ChatEntry

-

Replace with TimeStamp component

+

{body}

+

+ +

@@ -16,7 +19,10 @@ const ChatEntry = (props) => { }; ChatEntry.propTypes = { - //Fill with correct proptypes + id: PropTypes.number.isRequired, + sender: PropTypes.string.isRequired, + body: PropTypes.string.isRequired, + timeStamp: PropTypes.string.isRequired, }; export default ChatEntry; diff --git a/src/components/ChatLog.js b/src/components/ChatLog.js new file mode 100644 index 000000000..3fceb757d --- /dev/null +++ b/src/components/ChatLog.js @@ -0,0 +1,28 @@ +import React from 'react'; +import './ChatLog.css'; +import ChatEntry from './ChatEntry'; +import PropTypes from 'prop-types'; + +const ChatLog = ({ entries }) => { + const chatComponents = entries.map((chat) => { + return ( + + ); + }); + + return ( +
+
    {chatComponents}
; +
+ ); +}; + +ChatLog.propTypes = { + entries: PropTypes.arrayOf(PropTypes.object).isRequired, +}; + +export default ChatLog; diff --git a/src/components/ChatLog.test.js b/src/components/ChatLog.test.js index 96f89ebc3..5bafee291 100644 --- a/src/components/ChatLog.test.js +++ b/src/components/ChatLog.test.js @@ -1,49 +1,49 @@ -import React from "react"; -import "@testing-library/jest-dom/extend-expect"; -import ChatLog from "./ChatLog"; -import { render, screen } from "@testing-library/react"; +import React from 'react'; +import '@testing-library/jest-dom/extend-expect'; +import ChatLog from './ChatLog'; +import { render, screen } from '@testing-library/react'; const LOG = [ { - sender: "Vladimir", - body: "why are you arguing with me", - timeStamp: "2018-05-29T22:49:06+00:00", + sender: 'Vladimir', + body: 'why are you arguing with me', + timeStamp: '2018-05-29T22:49:06+00:00', }, { - sender: "Estragon", - body: "Because you are wrong.", - timeStamp: "2018-05-29T22:49:33+00:00", + sender: 'Estragon', + body: 'Because you are wrong.', + timeStamp: '2018-05-29T22:49:33+00:00', }, { - sender: "Vladimir", - body: "because I am what", - timeStamp: "2018-05-29T22:50:22+00:00", + sender: 'Vladimir', + body: 'because I am what', + timeStamp: '2018-05-29T22:50:22+00:00', }, { - sender: "Estragon", - body: "A robot.", - timeStamp: "2018-05-29T22:52:21+00:00", + sender: 'Estragon', + body: 'A robot.', + timeStamp: '2018-05-29T22:52:21+00:00', }, { - sender: "Vladimir", - body: "Notabot", - timeStamp: "2019-07-23T22:52:21+00:00", + sender: 'Vladimir', + body: 'Notabot', + timeStamp: '2019-07-23T22:52:21+00:00', }, ]; -describe("Wave 02: ChatLog", () => { +describe('Wave 02: ChatLog', () => { beforeEach(() => { render(); }); - test("renders without crashing and shows all the names", () => { + test('renders without crashing and shows all the names', () => { [ { - name: "Vladimir", + name: 'Vladimir', numChats: 3, }, { - name: "Estragon", + name: 'Estragon', numChats: 2, }, ].forEach((person) => { @@ -56,7 +56,7 @@ describe("Wave 02: ChatLog", () => { }); }); - test("renders an empty list without crashing", () => { + test('renders an empty list without crashing', () => { const element = render(); expect(element).not.toBeNull(); }); From 0d81594ef7a162ec0c86e29ba023f6e9d9c63615 Mon Sep 17 00:00:00 2001 From: olive Date: Mon, 20 Jun 2022 19:38:47 -0500 Subject: [PATCH 2/7] added id key to chat log --- src/App.js | 2 +- src/components/ChatEntry.js | 2 +- src/components/ChatLog.js | 12 +++++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/App.js b/src/App.js index edf008b4f..d95adfb96 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,6 @@ import React from 'react'; import './App.css'; -import ChatEntry from './components/ChatEntry'; +// import ChatEntry from './components/ChatEntry'; import ChatLog from './components/ChatLog'; import chatMessages from './data/messages.json'; diff --git a/src/components/ChatEntry.js b/src/components/ChatEntry.js index 267753f9c..306cf8ae2 100644 --- a/src/components/ChatEntry.js +++ b/src/components/ChatEntry.js @@ -3,7 +3,7 @@ import './ChatEntry.css'; import PropTypes from 'prop-types'; import TimeStamp from './TimeStamp'; -const ChatEntry = ({ sender, body, timeStamp }) => { +const ChatEntry = ({ id, sender, body, timeStamp }) => { return (

{sender}

diff --git a/src/components/ChatLog.js b/src/components/ChatLog.js index 3fceb757d..bc1d4052c 100644 --- a/src/components/ChatLog.js +++ b/src/components/ChatLog.js @@ -6,11 +6,13 @@ import PropTypes from 'prop-types'; const ChatLog = ({ entries }) => { const chatComponents = entries.map((chat) => { return ( - +
  • + +
  • ); }); From a16273399f2ec9ebc9a05c813cbe4f4be209e336 Mon Sep 17 00:00:00 2001 From: olive Date: Mon, 20 Jun 2022 22:25:52 -0500 Subject: [PATCH 3/7] started wave 3 --- src/App.js | 20 ++++++++++++++++++-- src/components/ChatEntry.css | 4 +++- src/components/ChatEntry.js | 27 ++++++++++++++++++++++----- src/components/ChatLog.js | 16 ++++++++++------ 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/App.js b/src/App.js index d95adfb96..95aee1d50 100644 --- a/src/App.js +++ b/src/App.js @@ -1,17 +1,33 @@ -import React from 'react'; +import React, { useState } from 'react'; import './App.css'; // import ChatEntry from './components/ChatEntry'; import ChatLog from './components/ChatLog'; import chatMessages from './data/messages.json'; const App = () => { + const [chatEntries, setChatEntries] = useState(chatMessages); + const [likeCount, setLikeCount] = useState(0); + + const updateChatEntry = (updatedEntry) => { + const entries = chatEntries.map((entry) => { + if (entry.id === updatedEntry.id) { + setLikeCount(likeCount + 1); + return updatedEntry; + } else { + return entry; + } + }); + setChatEntries(entries); + }; + return (

    Application title

    +

    {likeCount} ❤️

    - +
    ); diff --git a/src/components/ChatEntry.css b/src/components/ChatEntry.css index 05c3baa44..5e092aeb7 100644 --- a/src/components/ChatEntry.css +++ b/src/components/ChatEntry.css @@ -97,4 +97,6 @@ button { .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 306cf8ae2..a38063ff4 100644 --- a/src/components/ChatEntry.js +++ b/src/components/ChatEntry.js @@ -3,16 +3,31 @@ import './ChatEntry.css'; import PropTypes from 'prop-types'; import TimeStamp from './TimeStamp'; -const ChatEntry = ({ id, sender, body, timeStamp }) => { +const ChatEntry = (props) => { + const onLikeButtonClick = () => { + const updatedChatEntry = { + id: props.id, + sender: props.sender, + body: props.body, + timeStamp: props.timeStamp, + liked: !props.liked, + }; + props.onLike(updatedChatEntry); + }; + + // const heartColor = liked ? 'full' : 'empty'; + return (
    -

    {sender}

    +

    {props.sender}

    -

    {body}

    +

    {props.body}

    - +

    - +
    ); @@ -23,6 +38,8 @@ ChatEntry.propTypes = { sender: PropTypes.string.isRequired, body: PropTypes.string.isRequired, timeStamp: PropTypes.string.isRequired, + liked: PropTypes.bool.isRequired, + onLike: PropTypes.func.isRequired, }; export default ChatEntry; diff --git a/src/components/ChatLog.js b/src/components/ChatLog.js index bc1d4052c..c4fe238d9 100644 --- a/src/components/ChatLog.js +++ b/src/components/ChatLog.js @@ -3,14 +3,17 @@ import './ChatLog.css'; import ChatEntry from './ChatEntry'; import PropTypes from 'prop-types'; -const ChatLog = ({ entries }) => { - const chatComponents = entries.map((chat) => { +const ChatLog = ({ entries, onLike }) => { + const chatComponents = entries.map((entry) => { return ( -
  • +
  • ); @@ -25,6 +28,7 @@ const ChatLog = ({ entries }) => { ChatLog.propTypes = { entries: PropTypes.arrayOf(PropTypes.object).isRequired, + onLike: PropTypes.func.isRequired, }; export default ChatLog; From 6002339d5896855c3217ac6dc84dcce13f3bc719 Mon Sep 17 00:00:00 2001 From: olive Date: Mon, 20 Jun 2022 23:02:27 -0500 Subject: [PATCH 4/7] passing wave 3 --- src/App.js | 8 ++++++-- src/App.test.js | 2 +- src/components/ChatEntry.js | 9 ++++----- src/components/ChatLog.js | 25 +++++++++++++------------ 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/App.js b/src/App.js index 95aee1d50..ebad15be4 100644 --- a/src/App.js +++ b/src/App.js @@ -11,7 +11,11 @@ const App = () => { const updateChatEntry = (updatedEntry) => { const entries = chatEntries.map((entry) => { if (entry.id === updatedEntry.id) { - setLikeCount(likeCount + 1); + if (entry.liked) { + setLikeCount(likeCount - 1); + } else { + setLikeCount(likeCount + 1); + } return updatedEntry; } else { return entry; @@ -24,7 +28,7 @@ const App = () => {

    Application title

    -

    {likeCount} ❤️

    +

    {likeCount} ❤️s

    diff --git a/src/App.test.js b/src/App.test.js index ca5281135..878148902 100644 --- a/src/App.test.js +++ b/src/App.test.js @@ -2,7 +2,7 @@ import React from 'react'; import App from './App'; import { render, screen, fireEvent } from '@testing-library/react'; -describe.skip('Wave 03: clicking like button and rendering App', () => { +describe('Wave 03: clicking like button and rendering App', () => { test('that the correct number of likes is printed at the top', () => { // Arrange const { container } = render(); diff --git a/src/components/ChatEntry.js b/src/components/ChatEntry.js index a38063ff4..5821c7233 100644 --- a/src/components/ChatEntry.js +++ b/src/components/ChatEntry.js @@ -15,7 +15,7 @@ const ChatEntry = (props) => { props.onLike(updatedChatEntry); }; - // const heartColor = liked ? 'full' : 'empty'; + const heart = props.liked ? '❤️' : '🤍'; return (
    @@ -26,7 +26,7 @@ const ChatEntry = (props) => {

    @@ -34,12 +34,11 @@ const ChatEntry = (props) => { }; ChatEntry.propTypes = { - id: PropTypes.number.isRequired, + // id: PropTypes.number.isRequired, sender: PropTypes.string.isRequired, body: PropTypes.string.isRequired, timeStamp: PropTypes.string.isRequired, - liked: PropTypes.bool.isRequired, - onLike: PropTypes.func.isRequired, + // liked: PropTypes.bool.isRequired, }; export default ChatEntry; diff --git a/src/components/ChatLog.js b/src/components/ChatLog.js index c4fe238d9..8d2baab38 100644 --- a/src/components/ChatLog.js +++ b/src/components/ChatLog.js @@ -3,19 +3,20 @@ import './ChatLog.css'; import ChatEntry from './ChatEntry'; import PropTypes from 'prop-types'; -const ChatLog = ({ entries, onLike }) => { - const chatComponents = entries.map((entry) => { +const ChatLog = (props) => { + const chatComponents = props.entries.map((entry) => { return ( -
  • - -
  • + //
  • + + //
  • ); }); From 5739cf6084edaf1a07e774219ee4d905036af1da Mon Sep 17 00:00:00 2001 From: olive Date: Mon, 20 Jun 2022 23:17:59 -0500 Subject: [PATCH 5/7] changed local v remote display appearance --- src/App.js | 2 +- src/components/ChatEntry.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/App.js b/src/App.js index ebad15be4..2fc9aa8b2 100644 --- a/src/App.js +++ b/src/App.js @@ -27,7 +27,7 @@ const App = () => { return (
    -

    Application title

    +

    Chat between Vladimir and Estragon

    {likeCount} ❤️s

    diff --git a/src/components/ChatEntry.js b/src/components/ChatEntry.js index 5821c7233..b470f4b60 100644 --- a/src/components/ChatEntry.js +++ b/src/components/ChatEntry.js @@ -16,9 +16,11 @@ const ChatEntry = (props) => { }; const heart = props.liked ? '❤️' : '🤍'; + const displaySide = + props.sender === 'Vladimir' ? 'chat-entry local' : 'chat-entry remote'; return ( -
    +

    {props.sender}

    {props.body}

    From 168866eb835070f7f7245df7099ed88f2e7c060f Mon Sep 17 00:00:00 2001 From: olive Date: Tue, 21 Jun 2022 15:09:13 -0500 Subject: [PATCH 6/7] updated like count and get participants to helper functions --- src/App.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/App.js b/src/App.js index 2fc9aa8b2..1bc39fdd0 100644 --- a/src/App.js +++ b/src/App.js @@ -1,21 +1,14 @@ import React, { useState } from 'react'; import './App.css'; -// import ChatEntry from './components/ChatEntry'; import ChatLog from './components/ChatLog'; import chatMessages from './data/messages.json'; const App = () => { const [chatEntries, setChatEntries] = useState(chatMessages); - const [likeCount, setLikeCount] = useState(0); const updateChatEntry = (updatedEntry) => { const entries = chatEntries.map((entry) => { if (entry.id === updatedEntry.id) { - if (entry.liked) { - setLikeCount(likeCount - 1); - } else { - setLikeCount(likeCount + 1); - } return updatedEntry; } else { return entry; @@ -24,11 +17,29 @@ const App = () => { setChatEntries(entries); }; + const getLikeCount = () => { + let likeCount = 0; + for (const entry of chatEntries) { + if (entry.liked === true) { + likeCount += 1; + } + } + return likeCount; + }; + + const getParticipants = () => { + const participants = new Set(); + for (const entry of chatEntries) { + participants.add(entry.sender); + } + return [...participants].join(' and '); + }; + return (
    -

    Chat between Vladimir and Estragon

    -

    {likeCount} ❤️s

    +

    Chat between {getParticipants()}

    +

    {getLikeCount()} ❤️s

    From c18b32955d036c210f35f92e2ae4292353fda782 Mon Sep 17 00:00:00 2001 From: olive Date: Wed, 22 Jun 2022 13:51:07 -0500 Subject: [PATCH 7/7] final edits --- src/components/ChatLog.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/ChatLog.js b/src/components/ChatLog.js index 8d2baab38..9186dc9be 100644 --- a/src/components/ChatLog.js +++ b/src/components/ChatLog.js @@ -6,17 +6,17 @@ import PropTypes from 'prop-types'; const ChatLog = (props) => { const chatComponents = props.entries.map((entry) => { return ( - //
  • - key={entry.id} - id={entry.id} - sender={entry.sender} - body={entry.body} - timeStamp={entry.timeStamp} - liked={entry.liked} - onLike={props.onLike} - /> - //
  • + + ); });