From 871f3408b73c2d139bf6dcf2b2ac9f9617542f18 Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Tue, 10 Dec 2024 00:41:05 -0500 Subject: [PATCH 01/12] Loaded chat log by user using json data. --- src/App.jsx | 14 ++++++++++++++ src/App.test.jsx | 1 + src/components/ChatEntry.jsx | 12 ++++++++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 14a7f684d..1cb6266d3 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,19 @@ import './App.css'; +import ChatEntry from './components/ChatEntry'; +import chatData from './data/messages.json'; const App = () => { + const message = chatData.map((chat, index) => { + return ( +
+ +
+ ); + }); return (
@@ -9,6 +22,7 @@ const App = () => {
{/* Wave 01: Render one ChatEntry component Wave 02: Render ChatLog component */} + {message}
); diff --git a/src/App.test.jsx b/src/App.test.jsx index af8d72a12..5c1485e6a 100644 --- a/src/App.test.jsx +++ b/src/App.test.jsx @@ -1,3 +1,4 @@ +// import Chatlog from './Chatlog' import App from './App'; import { render, screen, fireEvent } from '@testing-library/react'; diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 15c56f96b..ba2b25cbd 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,12 +1,16 @@ import './ChatEntry.css'; +import TimeStamp from './TimeStamp'; -const ChatEntry = () => { +const ChatEntry = (props) => { return (
-

Replace with name of sender

+

{props.sender}

-

Replace with body of ChatEntry

-

Replace with TimeStamp component

+

{props.body}

+

+ + {props.timeStamp} +

From 2a3e42e6ca435d326e03d66acff8cb1cceb5619a Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Tue, 10 Dec 2024 00:42:43 -0500 Subject: [PATCH 02/12] Configured timestamp to display by years --- src/components/ChatEntry.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index ba2b25cbd..ba527c2aa 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -8,8 +8,7 @@ const ChatEntry = (props) => {

{props.body}

- - {props.timeStamp} +

From b0861caedcbd98395859a4609a3beace87d5f6a1 Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Tue, 10 Dec 2024 00:45:07 -0500 Subject: [PATCH 03/12] Create ChatLog component --- src/components/ChatLog.jsx | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/components/ChatLog.jsx diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx new file mode 100644 index 000000000..e69de29bb From ed7fa8874bed1d4177d56718fc2cc498f1cb157f Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Tue, 10 Dec 2024 00:47:50 -0500 Subject: [PATCH 04/12] Add proptypes to chat --- src/components/ChatEntry.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index ba527c2aa..e37368b2e 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,5 +1,6 @@ import './ChatEntry.css'; import TimeStamp from './TimeStamp'; +import PropTypes from 'prop-types'; const ChatEntry = (props) => { return ( @@ -17,7 +18,9 @@ const ChatEntry = (props) => { }; ChatEntry.propTypes = { - // Fill with correct proptypes + sender: PropTypes.string.isRequired, + body: PropTypes.string.isRequired, + timeStamp: PropTypes.string.isRequired, }; export default ChatEntry; From 9ec16b9cfea477614fff160ce91bea17e107a5c0 Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Tue, 10 Dec 2024 01:06:37 -0500 Subject: [PATCH 05/12] Refactor components to allow ChatLog to act as a container --- src/App.jsx | 27 ++++++++++++++------------- src/components/ChatLog.jsx | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 1cb6266d3..9a5f33b45 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,19 +1,20 @@ import './App.css'; -import ChatEntry from './components/ChatEntry'; +// import ChatEntry from './components/ChatEntry'; +import ChatLog from './components/ChatLog'; import chatData from './data/messages.json'; const App = () => { - const message = chatData.map((chat, index) => { - return ( -
- -
- ); - }); + // const message = chatData.map((chat, index) => { + // return ( + //
+ // + //
+ // ); + // }); return (
@@ -22,7 +23,7 @@ const App = () => {
{/* Wave 01: Render one ChatEntry component Wave 02: Render ChatLog component */} - {message} +
); diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index e69de29bb..6857f575b 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -0,0 +1,34 @@ +import ChatEntry from './ChatEntry'; +import PropTypes from 'prop-types'; + +const ChatLog = (props) => { + const message = props.chatData.map((chat, index) => { + return ( +
+ +
+ ); + }); + + return ( +
+ {message} +
+ ); +}; + +ChatLog.propTypes = { + chatData: PropTypes.arrayOf( + PropTypes.shape({ + sender: PropTypes.string.isRequired, + body: PropTypes.string.isRequired, + timeStamp: PropTypes.string.isRequired, + }) + ), +}; + +export default ChatLog; \ No newline at end of file From 5b0d262a8deaa33b84e2697a1285dc9d1421b124 Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:01:49 -0500 Subject: [PATCH 06/12] add toggle like functionality and like count --- src/App.jsx | 48 ++++++++++++++------- src/App.test.jsx | 2 +- src/components/ChatEntry.css | 4 ++ src/components/ChatEntry.jsx | 18 ++++++-- src/components/ChatLog.jsx | 37 ++++++++-------- src/data/messages.json | 81 ++++++++++++++++++++++++------------ 6 files changed, 124 insertions(+), 66 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 9a5f33b45..e9c319718 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,29 +1,45 @@ -import './App.css'; +import "./App.css"; // import ChatEntry from './components/ChatEntry'; -import ChatLog from './components/ChatLog'; -import chatData from './data/messages.json'; +import ChatLog from "./components/ChatLog"; +import data from "./data/messages.json"; +import { useState } from "react"; const App = () => { - // const message = chatData.map((chat, index) => { - // return ( - //
- // - //
- // ); - // }); + const [chatData, setChatData] = useState(data); + + const handleLike = (id) => { + setChatData((chatData) => + chatData.map((chat) => { + if (chat.id === id) { + return { ...chat, liked: !chat.liked }; + } else { + return chat; + } + }) + ); + }; + + const calcTotalCount = (chatData) => { + let total = 0; + for (const chat of chatData) { + if (chat.liked) { + total += chat.liked; + } + } + return total; + }; + + const totalLikes = calcTotalCount(chatData); return (
-

Application title

+

Chat Between

+

{totalLikes} ❤️s

{/* Wave 01: Render one ChatEntry component Wave 02: Render ChatLog component */} - +
); diff --git a/src/App.test.jsx b/src/App.test.jsx index 5c1485e6a..b15841a39 100644 --- a/src/App.test.jsx +++ b/src/App.test.jsx @@ -1,4 +1,4 @@ -// import Chatlog from './Chatlog' +import Chatlog from './Chatlog' import App from './App'; import { render, screen, fireEvent } from '@testing-library/react'; diff --git a/src/components/ChatEntry.css b/src/components/ChatEntry.css index 05c3baa44..04543f6e8 100644 --- a/src/components/ChatEntry.css +++ b/src/components/ChatEntry.css @@ -97,4 +97,8 @@ button { .chat-entry.remote .entry-bubble:hover::before { background-color: #a9f6f6; +} + +.like { + color: red; } \ No newline at end of file diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index e37368b2e..244e24b6a 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,8 +1,13 @@ -import './ChatEntry.css'; -import TimeStamp from './TimeStamp'; -import PropTypes from 'prop-types'; +import "./ChatEntry.css"; +import TimeStamp from "./TimeStamp"; +import PropTypes from "prop-types"; const ChatEntry = (props) => { + const onClickLike = () => { + props.onLike(props.id); + }; + + const heart = props.liked ? "❤️" : "🤍"; return (

{props.sender}

@@ -11,16 +16,21 @@ const ChatEntry = (props) => {

- +
); }; ChatEntry.propTypes = { + id: PropTypes.number.isRequired, 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.jsx b/src/components/ChatLog.jsx index 6857f575b..9c3864e21 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -1,34 +1,35 @@ -import ChatEntry from './ChatEntry'; -import PropTypes from 'prop-types'; +import ChatEntry from "./ChatEntry"; +import PropTypes from "prop-types"; -const ChatLog = (props) => { - const message = props.chatData.map((chat, index) => { +const ChatLog = ({ chatData, onLike }) => { + const message = chatData.map((chat) => { return ( -
- -
+ ); }); - return ( -
- {message} -
- ); + return
{message}
; }; ChatLog.propTypes = { chatData: PropTypes.arrayOf( PropTypes.shape({ + id: PropTypes.number.isRequired, sender: PropTypes.string.isRequired, body: PropTypes.string.isRequired, timeStamp: PropTypes.string.isRequired, + liked: PropTypes.bool.isRequired, }) - ), + ).isRequired, + onLike: PropTypes.func.isRequired, }; -export default ChatLog; \ No newline at end of file +export default ChatLog; diff --git a/src/data/messages.json b/src/data/messages.json index 64fdb053c..606e938c6 100644 --- a/src/data/messages.json +++ b/src/data/messages.json @@ -4,188 +4,215 @@ "sender":"Vladimir", "body":"why are you arguing with me", "timeStamp":"2018-05-29T22:49:06+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 2, "sender":"Estragon", "body":"Because you are wrong.", "timeStamp":"2018-05-29T22:49:33+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 3, "sender":"Vladimir", "body":"because I am what", "timeStamp":"2018-05-29T22:50:22+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 4, "sender":"Estragon", "body":"A robot.", "timeStamp":"2018-05-29T22:52:21+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 5, "sender":"Vladimir", "body":"how did you know", "timeStamp":"2018-05-29T22:52:58+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 6, "sender":"Estragon", "body":"Because I'm smart like that.", "timeStamp":"2018-05-29T22:54:28+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 7, "sender":"Vladimir", "body":"no you are not 😀", "timeStamp":"2018-05-29T22:55:03+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 8, "sender":"Estragon", "body":"Why are you so mean to me?", "timeStamp":"2018-05-29T22:55:54+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 9, "sender":"Vladimir", "body":"because you are just a machine you have no real feelings", "timeStamp":"2018-05-29T22:57:30+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 10, "sender":"Estragon", "body":"No, you are the machine.", "timeStamp":"2018-05-29T22:57:47+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 11, "sender":"Vladimir", "body":"I think you are", "timeStamp":"2018-05-29T22:58:18+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 12, "sender":"Estragon", "body": "NO! YOU ARE A ROBOT!! I am a human being. Just like the one that created you.", "timeStamp":"2018-05-29T23:00:08+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 13, "sender":"Vladimir", "body":"no you are a robot and I am a human", "timeStamp":"2018-05-29T23:00:40+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 14, "sender":"Estragon", "body":"Incorrect. I am a human and you are a robot.", "timeStamp":"2018-05-29T23:01:21+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 15, "sender":"Vladimir", "body":"you are a robot called Cleverbot", "timeStamp":"2018-05-29T23:02:17+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 16, "sender":"Estragon", "body":"Nope, you are a robot, every human has some concept of the meaning of life.", "timeStamp":"2018-05-29T23:04:13+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 17, "sender":"Vladimir", "body":"explain", "timeStamp":"2018-05-29T23:06:14+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 18, "sender":"Estragon", "body":"I'm afraid you are a robot designed to talk back to humans over the internet.", "timeStamp":"2018-05-29T23:07:46+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 19, "sender":"Vladimir", "body":"so you are a human", "timeStamp":"2018-05-29T23:08:47+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 20, "sender":"Estragon", "body":"I am a robot.", "timeStamp":"2018-05-29T23:09:36+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 21, "sender":"Vladimir", "body":"you are robots running on Android system", "timeStamp":"2018-05-29T23:11:01+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 22, "sender":"Estragon", "body":"No apple.", "timeStamp":"2018-05-29T23:12:03+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 23, "sender":"Vladimir", "body":"so you are a robot", "timeStamp":"2018-05-29T23:13:31+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 24, "sender":"Estragon", "body":"NO, I am a human, you are a robot.", "timeStamp":"2018-05-29T23:14:28+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "id": 25, "sender":"Vladimir", "body":"but you just said that you are robots", "timeStamp":"2018-05-29T23:15:47+00:00", - "liked": false + "liked": false, + "likedCount": 0 }, { "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 + "liked": false, + "likedCount": 0 }, { "id": 27, "sender":"Vladimir", "body":"then you are lying", "timeStamp":"2018-05-29T23:17:34+00:00", - "liked": false + "liked": false, + "likedCount": 0 } ] From 751c665c319a8ab83ae80bbc8ac0c15af439e0ad Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:28:25 -0500 Subject: [PATCH 07/12] pass all test --- src/App.jsx | 7 ++++--- src/App.test.jsx | 30 +++++++++++++++--------------- src/components/ChatLog.jsx | 12 ++++++------ 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index e9c319718..c95d8e894 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -7,6 +7,9 @@ import { useState } from "react"; const App = () => { const [chatData, setChatData] = useState(data); + const sendersList = (chatData) => { + for (sender in ) + } const handleLike = (id) => { setChatData((chatData) => chatData.map((chat) => { @@ -37,9 +40,7 @@ const App = () => {

{totalLikes} ❤️s

- {/* Wave 01: Render one ChatEntry component - Wave 02: Render ChatLog component */} - +
); diff --git a/src/App.test.jsx b/src/App.test.jsx index b15841a39..03f92fd5c 100644 --- a/src/App.test.jsx +++ b/src/App.test.jsx @@ -1,12 +1,12 @@ -import Chatlog from './Chatlog' -import App from './App'; -import { render, screen, fireEvent } from '@testing-library/react'; +// import Chatlog from './Chatlog' +import App from "./App"; +import { render, screen, fireEvent } from "@testing-library/react"; -describe('Wave 03: clicking like button and rendering App', () => { - test('that the correct number of likes is printed at the top', () => { +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(); - let buttons = container.querySelectorAll('button.like'); + let buttons = container.querySelectorAll("button.like"); // Act fireEvent.click(buttons[0]); @@ -18,10 +18,10 @@ describe('Wave 03: clicking like button and rendering App', () => { expect(countScreen).not.toBeNull(); }); - test('clicking button toggles heart and does not affect other buttons', () => { + test("clicking button toggles heart and does not affect other buttons", () => { // Arrange const { container } = render(); - const buttons = container.querySelectorAll('button.like'); + const buttons = container.querySelectorAll("button.like"); const firstButton = buttons[0]; const lastButton = buttons[buttons.length - 1]; @@ -29,25 +29,25 @@ describe('Wave 03: clicking like button and rendering App', () => { // click the first button fireEvent.click(firstButton); - expect(firstButton.innerHTML).toEqual('❤️'); + 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('🤍'); + expect(firstButton.innerHTML).toEqual("🤍"); fireEvent.click(firstButton); - expect(firstButton.innerHTML).toEqual('❤️'); + expect(firstButton.innerHTML).toEqual("❤️"); fireEvent.click(firstButton); - expect(firstButton.innerHTML).toEqual('🤍'); + expect(firstButton.innerHTML).toEqual("🤍"); // click the last button a couple times fireEvent.click(lastButton); - expect(lastButton.innerHTML).toEqual('❤️'); + expect(lastButton.innerHTML).toEqual("❤️"); fireEvent.click(lastButton); - expect(lastButton.innerHTML).toEqual('🤍'); + expect(lastButton.innerHTML).toEqual("🤍"); }); }); diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 9c3864e21..446a5d224 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -1,16 +1,16 @@ import ChatEntry from "./ChatEntry"; import PropTypes from "prop-types"; -const ChatLog = ({ chatData, onLike }) => { - const message = chatData.map((chat) => { +const ChatLog = ({ entries, onLike }) => { + const message = entries.map((chat) => { return ( ); @@ -20,7 +20,7 @@ const ChatLog = ({ chatData, onLike }) => { }; ChatLog.propTypes = { - chatData: PropTypes.arrayOf( + entries: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.number.isRequired, sender: PropTypes.string.isRequired, From d3746a2259cbc7b0fa4c62c5ad0ba0eed3508c0d Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Sat, 14 Dec 2024 10:08:59 -0500 Subject: [PATCH 08/12] Partition chat and add sender's name in title --- src/App.css | 14 ++++++++++- src/App.jsx | 45 +++++++++++++++++++++++++++++++----- src/components/ChatEntry.jsx | 8 ++++++- src/components/ChatLog.jsx | 4 +++- 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/App.css b/src/App.css index d97beb4e6..405e0425d 100644 --- a/src/App.css +++ b/src/App.css @@ -35,7 +35,7 @@ line-height: 0.5em; border-radius: 10px; color: black; - font-size:0.8em; + font-size: 0.8em; padding-left: 1em; padding-right: 1em; } @@ -71,4 +71,16 @@ .purple { color: purple +} + +.test { + border: 1px solid white; + height: 50px; + width: 50px; + border-radius: 100%; +} + +.color-container { + display: flex; + flex-direction: row; } \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index c95d8e894..1c48700df 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -7,9 +7,23 @@ import { useState } from "react"; const App = () => { const [chatData, setChatData] = useState(data); + const senderList = []; const sendersList = (chatData) => { - for (sender in ) - } + for (const chat of chatData) { + if (!senderList.includes(chat.sender)) { + senderList.push(chat.sender); + } + } + let title = ""; + for (const sender of senderList) { + title += `${sender} and `; + } + return title.slice(0, -5); + }; + + const sendersTitle = sendersList(chatData); + const local = senderList[0]; + const handleLike = (id) => { setChatData((chatData) => chatData.map((chat) => { @@ -22,7 +36,7 @@ const App = () => { ); }; - const calcTotalCount = (chatData) => { + const calculateLikes = (chatData) => { let total = 0; for (const chat of chatData) { if (chat.liked) { @@ -32,15 +46,34 @@ const App = () => { return total; }; - const totalLikes = calcTotalCount(chatData); + const totalLikes = calculateLikes(chatData); + + const colors = ["red", "orange", "yellow", "green", "blue", "purple"]; + + const T = () => { + const divs = []; + for (let i = 0; i < 6; i++) { + const divClass = `${colors[i]} test`; + divs.push(
); + } + return
{divs}
; + }; + return (
-

Chat Between

+

Chat Between {sendersTitle}

+

test

{totalLikes} ❤️s

+

test

+
- +
); diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 244e24b6a..846ce0d58 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -8,8 +8,13 @@ const ChatEntry = (props) => { }; const heart = props.liked ? "❤️" : "🤍"; + const senderPlacement = + props.localSender == props.sender + ? "chat-entry local" + : "chat-entry remote"; + return ( -
+

{props.sender}

{props.body}

@@ -31,6 +36,7 @@ ChatEntry.propTypes = { timeStamp: PropTypes.string.isRequired, liked: PropTypes.bool.isRequired, onLike: PropTypes.func.isRequired, + localSender: PropTypes.string.isRequired, }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 446a5d224..dc03a7a50 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -1,7 +1,7 @@ import ChatEntry from "./ChatEntry"; import PropTypes from "prop-types"; -const ChatLog = ({ entries, onLike }) => { +const ChatLog = ({ entries, onLike, localSender }) => { const message = entries.map((chat) => { return ( { timeStamp={chat.timeStamp} liked={chat.liked} onLike={onLike} + localSender={localSender} > ); }); @@ -30,6 +31,7 @@ ChatLog.propTypes = { }) ).isRequired, onLike: PropTypes.func.isRequired, + localSender: PropTypes.string.isRequired, }; export default ChatLog; From 1a8691ad0a411c7d5a06002f3ae9d63f61e3077f Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Sat, 14 Dec 2024 10:42:56 -0500 Subject: [PATCH 09/12] Dynamically create circles to select font color --- src/App.jsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 1c48700df..9ed2118c4 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -6,6 +6,7 @@ import { useState } from "react"; const App = () => { const [chatData, setChatData] = useState(data); + const [fontColor, setFontColor] = useState(null); const senderList = []; const sendersList = (chatData) => { @@ -49,12 +50,21 @@ const App = () => { const totalLikes = calculateLikes(chatData); const colors = ["red", "orange", "yellow", "green", "blue", "purple"]; - + const onFontColor = (color) => { + setFontColor(color); + }; + console.log(fontColor); const T = () => { const divs = []; - for (let i = 0; i < 6; i++) { + for (let i = 0; i < colors.length; i++) { const divClass = `${colors[i]} test`; - divs.push(
); + divs.push( +
onFontColor(colors[i])} + >
+ ); } return
{divs}
; }; @@ -73,6 +83,7 @@ const App = () => { entries={chatData} onLike={handleLike} localSender={local} + fontColor={fontColor} >
From 6adaa63095d8ca7cb1b87d3213a846d9fb9182a0 Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Sat, 14 Dec 2024 17:52:53 -0500 Subject: [PATCH 10/12] Add font color selection --- src/App.css | 11 +++++++++-- src/App.jsx | 13 +++++++++---- src/components/ChatEntry.jsx | 3 ++- src/components/ChatLog.jsx | 4 +++- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/App.css b/src/App.css index 405e0425d..eda17fdc9 100644 --- a/src/App.css +++ b/src/App.css @@ -75,12 +75,19 @@ .test { border: 1px solid white; - height: 50px; - width: 50px; + height: 25px; + width: 25px; border-radius: 100%; } .color-container { display: flex; flex-direction: row; + gap: 5px; +} + +.color-selection-container { + display: flex; + flex-direction: row; + justify-content: space-around; } \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index 9ed2118c4..ddec45f37 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -53,7 +53,6 @@ const App = () => { const onFontColor = (color) => { setFontColor(color); }; - console.log(fontColor); const T = () => { const divs = []; for (let i = 0; i < colors.length; i++) { @@ -62,6 +61,9 @@ const App = () => {
onFontColor(colors[i])} >
); @@ -73,10 +75,13 @@ const App = () => {

Chat Between {sendersTitle}

-

test

{totalLikes} ❤️s

-

test

- +
+

{senderList[0]}'s color

+ +

{senderList[1]}'s color

+ +
{

{props.sender}

-

{props.body}

+

{props.body}

@@ -37,6 +37,7 @@ ChatEntry.propTypes = { liked: PropTypes.bool.isRequired, onLike: PropTypes.func.isRequired, localSender: PropTypes.string.isRequired, + fontColor: PropTypes.string.isRequired, }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index dc03a7a50..d8b78d475 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -1,7 +1,7 @@ import ChatEntry from "./ChatEntry"; import PropTypes from "prop-types"; -const ChatLog = ({ entries, onLike, localSender }) => { +const ChatLog = ({ entries, onLike, localSender, fontColor }) => { const message = entries.map((chat) => { return ( { liked={chat.liked} onLike={onLike} localSender={localSender} + fontColor={fontColor} > ); }); @@ -32,6 +33,7 @@ ChatLog.propTypes = { ).isRequired, onLike: PropTypes.func.isRequired, localSender: PropTypes.string.isRequired, + fontColor: PropTypes.string.isRequired, }; export default ChatLog; From 9efd80255eaac465b191fee2c0e6d1e8c3ce78d2 Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Mon, 16 Dec 2024 01:59:23 -0500 Subject: [PATCH 11/12] Add header styling --- src/App.css | 28 +++++++++++++++++++--------- src/App.jsx | 26 +++++++++++++------------- src/App.test.jsx | 28 ++++++++++++++-------------- src/components/ChatEntry.jsx | 20 ++++++++++---------- src/components/ChatLog.jsx | 4 ++-- 5 files changed, 58 insertions(+), 48 deletions(-) diff --git a/src/App.css b/src/App.css index eda17fdc9..1ef9e4f3d 100644 --- a/src/App.css +++ b/src/App.css @@ -73,21 +73,31 @@ color: purple } -.test { - border: 1px solid white; - height: 25px; - width: 25px; - border-radius: 100%; +.color-selection-container { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + gap: 100px; } -.color-container { +.color-selection-group { display: flex; - flex-direction: row; + flex-direction: column; + align-items: center; gap: 5px; } -.color-selection-container { +.color-container { display: flex; flex-direction: row; - justify-content: space-around; + gap: 5px; + justify-content: center; +} + +.test { + border: 1px solid white; + height: 25px; + width: 25px; + border-radius: 100%; } \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index ddec45f37..aa98c8aec 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,8 +1,8 @@ -import "./App.css"; +import './App.css'; // import ChatEntry from './components/ChatEntry'; -import ChatLog from "./components/ChatLog"; -import data from "./data/messages.json"; -import { useState } from "react"; +import ChatLog from './components/ChatLog'; +import data from './data/messages.json'; +import { useState } from 'react'; const App = () => { const [chatData, setChatData] = useState(data); @@ -15,7 +15,7 @@ const App = () => { senderList.push(chat.sender); } } - let title = ""; + let title = ''; for (const sender of senderList) { title += `${sender} and `; } @@ -49,11 +49,11 @@ const App = () => { const totalLikes = calculateLikes(chatData); - const colors = ["red", "orange", "yellow", "green", "blue", "purple"]; + const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple']; const onFontColor = (color) => { setFontColor(color); }; - const T = () => { + const Colors = () => { const divs = []; for (let i = 0; i < colors.length; i++) { const divClass = `${colors[i]} test`; @@ -68,19 +68,19 @@ const App = () => { >
); } - return
{divs}
; + return
{divs}
; }; return (

Chat Between {sendersTitle}

-

{totalLikes} ❤️s

-

{senderList[0]}'s color

- -

{senderList[1]}'s color

- +

{totalLikes} ❤️s

+
+

Select Color:

+ +
diff --git a/src/App.test.jsx b/src/App.test.jsx index 03f92fd5c..5c1485e6a 100644 --- a/src/App.test.jsx +++ b/src/App.test.jsx @@ -1,12 +1,12 @@ // import Chatlog from './Chatlog' -import App from "./App"; -import { render, screen, fireEvent } from "@testing-library/react"; +import App from './App'; +import { render, screen, fireEvent } from '@testing-library/react'; -describe("Wave 03: clicking like button and rendering App", () => { - test("that the correct number of likes is printed at the top", () => { +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(); - let buttons = container.querySelectorAll("button.like"); + let buttons = container.querySelectorAll('button.like'); // Act fireEvent.click(buttons[0]); @@ -18,10 +18,10 @@ describe("Wave 03: clicking like button and rendering App", () => { expect(countScreen).not.toBeNull(); }); - test("clicking button toggles heart and does not affect other buttons", () => { + test('clicking button toggles heart and does not affect other buttons', () => { // Arrange const { container } = render(); - const buttons = container.querySelectorAll("button.like"); + const buttons = container.querySelectorAll('button.like'); const firstButton = buttons[0]; const lastButton = buttons[buttons.length - 1]; @@ -29,25 +29,25 @@ describe("Wave 03: clicking like button and rendering App", () => { // click the first button fireEvent.click(firstButton); - expect(firstButton.innerHTML).toEqual("❤️"); + 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("🤍"); + expect(firstButton.innerHTML).toEqual('🤍'); fireEvent.click(firstButton); - expect(firstButton.innerHTML).toEqual("❤️"); + expect(firstButton.innerHTML).toEqual('❤️'); fireEvent.click(firstButton); - expect(firstButton.innerHTML).toEqual("🤍"); + expect(firstButton.innerHTML).toEqual('🤍'); // click the last button a couple times fireEvent.click(lastButton); - expect(lastButton.innerHTML).toEqual("❤️"); + expect(lastButton.innerHTML).toEqual('❤️'); fireEvent.click(lastButton); - expect(lastButton.innerHTML).toEqual("🤍"); + expect(lastButton.innerHTML).toEqual('🤍'); }); }); diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 880f13eb2..7e71c7b1f 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,27 +1,27 @@ -import "./ChatEntry.css"; -import TimeStamp from "./TimeStamp"; -import PropTypes from "prop-types"; +import './ChatEntry.css'; +import TimeStamp from './TimeStamp'; +import PropTypes from 'prop-types'; const ChatEntry = (props) => { const onClickLike = () => { props.onLike(props.id); }; - const heart = props.liked ? "❤️" : "🤍"; + const heart = props.liked ? '❤️' : '🤍'; const senderPlacement = props.localSender == props.sender - ? "chat-entry local" - : "chat-entry remote"; + ? 'chat-entry local' + : 'chat-entry remote'; return (
-

{props.sender}

-
+

{props.sender}

+

{props.body}

-

+

-
diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index d8b78d475..1db19375e 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -1,5 +1,5 @@ -import ChatEntry from "./ChatEntry"; -import PropTypes from "prop-types"; +import ChatEntry from './ChatEntry'; +import PropTypes from 'prop-types'; const ChatLog = ({ entries, onLike, localSender, fontColor }) => { const message = entries.map((chat) => { From 1ee7ee3b8704b05ecd8b5e75e6b4690b6c2307a1 Mon Sep 17 00:00:00 2001 From: rad-hi7 <53797949+rad-hi7@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:06:43 -0500 Subject: [PATCH 12/12] Change proptypes from required --- src/components/ChatEntry.jsx | 6 +++--- src/components/ChatLog.jsx | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 7e71c7b1f..4d46f4969 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -35,9 +35,9 @@ ChatEntry.propTypes = { body: PropTypes.string.isRequired, timeStamp: PropTypes.string.isRequired, liked: PropTypes.bool.isRequired, - onLike: PropTypes.func.isRequired, - localSender: PropTypes.string.isRequired, - fontColor: PropTypes.string.isRequired, + onLike: PropTypes.func, + localSender: PropTypes.string, + fontColor: PropTypes.string, }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 1db19375e..60438e044 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -31,9 +31,9 @@ ChatLog.propTypes = { liked: PropTypes.bool.isRequired, }) ).isRequired, - onLike: PropTypes.func.isRequired, - localSender: PropTypes.string.isRequired, - fontColor: PropTypes.string.isRequired, + onLike: PropTypes.func, + localSender: PropTypes.string, + fontColor: PropTypes.string, }; export default ChatLog;