From 177c0931a6231402fa37303da6c4f44112751214 Mon Sep 17 00:00:00 2001 From: Shirley425 Date: Fri, 20 Jun 2025 03:21:56 -0700 Subject: [PATCH 1/4] finished wave02 --- .vscode/settings.json | 3 +++ package-lock.json | 12 +++++++++++- package.json | 3 ++- src/App.jsx | 12 ++++++++---- src/components/ChatEntry.jsx | 16 +++++++++++----- src/components/ChatLog.jsx | 36 ++++++++++++++++++++++++++++++++++++ src/data/messages.json | 4 ++-- 7 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/components/ChatLog.jsx diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..6f3a2913e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2a6ed1d5b..7a31e43c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "dependencies": { "luxon": "^2.5.2", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-icons": "^5.5.0" }, "devDependencies": { "@eslint/compat": "^1.2.0", @@ -4497,6 +4498,15 @@ "react": "^18.3.1" } }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", diff --git a/package.json b/package.json index 1a053dda4..84a3a1dcf 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "dependencies": { "luxon": "^2.5.2", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-icons": "^5.5.0" }, "devDependencies": { "@eslint/compat": "^1.2.0", diff --git a/src/App.jsx b/src/App.jsx index 14a7f684d..e488a9187 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,14 +1,18 @@ import './App.css'; +import ChatLog from './components/ChatLog'; +import messages from './data/messages.json'; const App = () => { return ( -
+
-

Application title

+

Chat Between Vladimir and Estragon

+

❤️s

- {/* Wave 01: Render one ChatEntry component - Wave 02: Render ChatLog component */} +
+ +
); diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 15c56f96b..deaa6a14a 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -1,12 +1,16 @@ import './ChatEntry.css'; +import TimeStamp from './TimeStamp'; +import PropTypes from 'prop-types'; -const ChatEntry = () => { +const ChatEntry = (props) => { return (
-

Replace with name of sender

+

{props.sender}

-

Replace with body of ChatEntry

-

Replace with TimeStamp component

+

{props.body}

+

+ +

@@ -14,7 +18,9 @@ const ChatEntry = () => { }; ChatEntry.propTypes = { - // Fill with correct proptypes + sender: PropTypes.string.isRequired, + body: PropTypes.string.isRequired, + timeStamp: PropTypes.string.isRequired }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx new file mode 100644 index 000000000..12387d5e5 --- /dev/null +++ b/src/components/ChatLog.jsx @@ -0,0 +1,36 @@ +import './ChatLog.css'; +import ChatEntry from './ChatEntry'; +import PropTypes from 'prop-types'; + + +const ChatLog = (props) => { + const getChatLog = (entries) => { + return entries.map((entry) => ( + + )); + }; + + return ( +
+
    {getChatLog(props.entries)}
+
+ ); +}; + +ChatLog.propTypes = { + entries: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.number.isRequired, + sender: PropTypes.string.isRequired, + body: PropTypes.string.isRequired, + timeStamp: PropTypes.string.isRequired + }) + ).isRequired, +}; + +export default ChatLog; \ No newline at end of file diff --git a/src/data/messages.json b/src/data/messages.json index 64fdb053c..048c0c735 100644 --- a/src/data/messages.json +++ b/src/data/messages.json @@ -1,5 +1,5 @@ -[ - { + [ + { "id": 1, "sender":"Vladimir", "body":"why are you arguing with me", From a14585973f24a60fd8e03e794e87b73185ea4a95 Mon Sep 17 00:00:00 2001 From: Shirley425 Date: Fri, 20 Jun 2025 11:35:33 -0700 Subject: [PATCH 2/4] finished all waves --- src/App.css | 4 ++++ src/App.jsx | 23 +++++++++++++++++++--- src/components/ChatEntry.jsx | 16 ++++++++++------ src/components/ChatLog.jsx | 37 +++++++++++++++++++----------------- 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/App.css b/src/App.css index d97beb4e6..a20a28e85 100644 --- a/src/App.css +++ b/src/App.css @@ -28,6 +28,10 @@ #App header section { background-color: #e0ffff; + font-size: 1.2em; + color: #222; + font-weight: bold; + padding: 1%; } #App .widget { diff --git a/src/App.jsx b/src/App.jsx index e488a9187..868ec460e 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,21 +1,38 @@ +import { useState } from 'react'; import './App.css'; import ChatLog from './components/ChatLog'; import messages from './data/messages.json'; const App = () => { + const [entries, setEntries] = useState( + messages.map((entry) => ({...entry})) + ); + + const toggleLike = (id) => { + const updatedEntries = entries.map((entry) => + entry.id === id ? { ...entry, liked: !entry.liked } : entry + ); + setEntries(updatedEntries); + }; + + const totalLikes = entries.filter((entry) => entry.liked).length; + return (

Chat Between Vladimir and Estragon

-

❤️s

+
{totalLikes} ❤️s
- +
); }; -export default App; +export default App; \ No newline at end of file diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index deaa6a14a..9e1c64c0a 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -4,23 +4,27 @@ import PropTypes from 'prop-types'; const ChatEntry = (props) => { return ( -
+

{props.sender}

{props.body}

-

- -

- +

{props.timeStamp}

+
); }; ChatEntry.propTypes = { + id: PropTypes.number.isRequired, sender: PropTypes.string.isRequired, body: PropTypes.string.isRequired, - timeStamp: PropTypes.string.isRequired + timeStamp: PropTypes.string.isRequired, + side: PropTypes.oneOf(['local', 'remote']).isRequired, + liked: PropTypes.bool.isRequired, + onLikeToggle: PropTypes.func.isRequired, }; export default ChatEntry; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index 12387d5e5..fafd26e7b 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -2,22 +2,23 @@ import './ChatLog.css'; import ChatEntry from './ChatEntry'; import PropTypes from 'prop-types'; - -const ChatLog = (props) => { - const getChatLog = (entries) => { - return entries.map((entry) => ( - - )); - }; - +const ChatLog = ({entries, onLikeToggle}) => { return ( -
-
    {getChatLog(props.entries)}
+
+
    + {entries.map((entry) => ( + + ))} +
); }; @@ -28,9 +29,11 @@ ChatLog.propTypes = { id: PropTypes.number.isRequired, sender: PropTypes.string.isRequired, body: PropTypes.string.isRequired, - timeStamp: PropTypes.string.isRequired + timeStamp: PropTypes.string.isRequired, + liked: PropTypes.bool.isRequired, }) ).isRequired, + onLikeToggle: PropTypes.func.isRequired, }; -export default ChatLog; \ No newline at end of file +export default ChatLog; From 6e785a2dad9bb3e377b61f51e17dd6d306f3a82d Mon Sep 17 00:00:00 2001 From: Shirley425 Date: Mon, 7 Jul 2025 01:52:58 -0700 Subject: [PATCH 3/4] updated --- src/components/ChatEntry.jsx | 6 +++--- src/components/ChatLog.jsx | 13 ++----------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/components/ChatEntry.jsx b/src/components/ChatEntry.jsx index 9e1c64c0a..87edf9c4d 100644 --- a/src/components/ChatEntry.jsx +++ b/src/components/ChatEntry.jsx @@ -3,12 +3,13 @@ import TimeStamp from './TimeStamp'; import PropTypes from 'prop-types'; const ChatEntry = (props) => { + const side = props.sender === 'Vladimir' ? 'local' : 'remote'; return ( -
+

{props.sender}

{props.body}

-

{props.timeStamp}

+ @@ -22,7 +23,6 @@ ChatEntry.propTypes = { sender: PropTypes.string.isRequired, body: PropTypes.string.isRequired, timeStamp: PropTypes.string.isRequired, - side: PropTypes.oneOf(['local', 'remote']).isRequired, liked: PropTypes.bool.isRequired, onLikeToggle: PropTypes.func.isRequired, }; diff --git a/src/components/ChatLog.jsx b/src/components/ChatLog.jsx index fafd26e7b..8c7433dda 100644 --- a/src/components/ChatLog.jsx +++ b/src/components/ChatLog.jsx @@ -2,21 +2,12 @@ import './ChatLog.css'; import ChatEntry from './ChatEntry'; import PropTypes from 'prop-types'; -const ChatLog = ({entries, onLikeToggle}) => { +const ChatLog = ({ entries, onLikeToggle }) => { return (
    {entries.map((entry) => ( - + ))}
From 22c6097903bc733ab63f466dc2f4044516e17357 Mon Sep 17 00:00:00 2001 From: Shirley425 Date: Mon, 7 Jul 2025 01:54:44 -0700 Subject: [PATCH 4/4] final --- src/App.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 868ec460e..2a91bb2cc 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,9 +4,7 @@ import ChatLog from './components/ChatLog'; import messages from './data/messages.json'; const App = () => { - const [entries, setEntries] = useState( - messages.map((entry) => ({...entry})) - ); + const [entries, setEntries] = useState(messages); const toggleLike = (id) => { const updatedEntries = entries.map((entry) =>