diff --git a/package-lock.json b/package-lock.json index d603209..64d575b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "version": "0.0.0", "dependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^7.8.2" }, "devDependencies": { "@types/react": "^18.2.15", @@ -913,6 +914,15 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "dev": true, @@ -2561,6 +2571,44 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.8.2.tgz", + "integrity": "sha512-7M2fR1JbIZ/jFWqelpvSZx+7vd7UlBTfdZqf6OSdF9g6+sfdqJDAWcak6ervbHph200ePlu+7G8LdoiC3ReyAQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.8.2.tgz", + "integrity": "sha512-Z4VM5mKDipal2jQ385H6UBhiiEDlnJPx6jyWsTYoZQdl5TrjxEV2a9yl3Fi60NBJxYzOTGTTHXPi0pdizvTwow==", + "license": "MIT", + "dependencies": { + "react-router": "7.8.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.4", "dev": true, @@ -2725,6 +2773,12 @@ "semver": "bin/semver.js" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, "node_modules/set-function-length": { "version": "1.1.1", "dev": true, diff --git a/package.json b/package.json index b9d8385..af5239e 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ }, "dependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-router-dom": "^7.8.2" }, "devDependencies": { "@types/react": "^18.2.15", diff --git a/src/App.jsx b/src/App.jsx index c902699..3951a1b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,123 +1,83 @@ import { useState } from 'react' - +import './styles/App.css' +import Emails from './components/Emails' import initialEmails from './data/emails' +import Header from './components/Header' +import LeftMenu from './components/LeftMenu' +import DisplayEmail from './components/DisplayEmail' -import './styles/App.css' +function App() { -const getReadEmails = emails => emails.filter(email => !email.read) + const [emails, setEmails] = useState(initialEmails) -const getStarredEmails = emails => emails.filter(email => email.starred) + const [chosenEmail, setChosenEmail] = useState(null) + const [isClicked, setIsClicked] = useState(false) -function App() { - const [emails, setEmails] = useState(initialEmails) - const [hideRead, setHideRead] = useState(false) - const [currentTab, setCurrentTab] = useState('inbox') + const [input, setInput] = useState("") - const unreadEmails = emails.filter(email => !email.read) - const starredEmails = emails.filter(email => email.starred) + let filteredEmails = emails - const toggleStar = targetEmail => { - const updatedEmails = emails => - emails.map(email => - email.id === targetEmail.id - ? { ...email, starred: !email.starred } - : email - ) - setEmails(updatedEmails) - } + const toggleStar = targetEmail => { + const updatedEmails = emails.map(email => + email.id === targetEmail.id + ? { ...email, starred: !email.starred } + : email + ) + setEmails(updatedEmails) + } - const toggleRead = targetEmail => { - const updatedEmails = emails => - emails.map(email => + const toggleRead = targetEmail => { + const updatedEmails = emails.map(email => email.id === targetEmail.id ? { ...email, read: !email.read } : email ) - setEmails(updatedEmails) - } - - let filteredEmails = emails - - if (hideRead) filteredEmails = getReadEmails(filteredEmails) - - if (currentTab === 'starred') - filteredEmails = getStarredEmails(filteredEmails) - - return ( -
-
-
- - - - - gmail logo -
- -
- -
-
- -
- -
-
- ) + setEmails(updatedEmails) + } + + + const [currentTab, setCurrentTab] = useState('inbox') + const [hideRead, setHideRead] = useState(false) + + const getReadEmails = emails => emails.filter(email => !email.read) + const getStarredEmails = emails => emails.filter(email => email.starred) + const unreadEmails = emails.filter(email => !email.read) + const starredEmails = emails.filter(email => email.starred) + + if (currentTab === 'starred') + filteredEmails = getStarredEmails(filteredEmails) + + if (hideRead) filteredEmails = getReadEmails(filteredEmails) + + if (input !== "") filteredEmails = emails.filter(email => email.text.toLowerCase().includes(input.toLowerCase()) || email.title.toLowerCase().includes(input.toLowerCase()) || email.sender.toLowerCase().includes(input.toLowerCase())) + + + if (isClicked) { + return ( +
+
+
+
+ +
+ +
+ +
+ )} else { + return ( +
+
+
+
+ +
+ +
+
+ )} } export default App diff --git a/src/components/BackNav.jsx b/src/components/BackNav.jsx new file mode 100644 index 0000000..be47465 --- /dev/null +++ b/src/components/BackNav.jsx @@ -0,0 +1,15 @@ + + +function BackNav({setIsClicked}) { + + const handleBackClick = () => { + setIsClicked(false) + }; + + return ( + + ); +} + +export default BackNav + diff --git a/src/components/DisplayEmail.jsx b/src/components/DisplayEmail.jsx new file mode 100644 index 0000000..5f836b8 --- /dev/null +++ b/src/components/DisplayEmail.jsx @@ -0,0 +1,17 @@ +import BackNav from "./backNav" + +function DisplayEmail({emailText, emailSender, setIsClicked}){ + return ( + <> +
+ +
+
+

From: {emailSender}

+

{emailText}

+
+ + ) +} + +export default DisplayEmail \ No newline at end of file diff --git a/src/components/Email.jsx b/src/components/Email.jsx new file mode 100644 index 0000000..22785a3 --- /dev/null +++ b/src/components/Email.jsx @@ -0,0 +1,36 @@ + +function Email({email, index, toggleRead, toggleStar, setChosenEmail, setIsClicked}) { + + const onEmailClicked = () => { + setChosenEmail(email) + setIsClicked(true) + } + + // Display a single email + return ( + <> +
  • +
    + toggleRead(email)} + /> +
    +
    + toggleStar(email)} + /> +
    +
    {email.sender}
    +
    {email.title}
    +
  • + + ) +} + +export default Email \ No newline at end of file diff --git a/src/components/Emails.jsx b/src/components/Emails.jsx new file mode 100644 index 0000000..7ae1cd1 --- /dev/null +++ b/src/components/Emails.jsx @@ -0,0 +1,17 @@ +import Email from "./Email" + +function Emails({filteredEmails, toggleRead, toggleStar, setChosenEmail, setIsClicked}) { + + // Display all emails as an ul + return ( + <> + + + ) +} + +export default Emails \ No newline at end of file diff --git a/src/components/Header.jsx b/src/components/Header.jsx new file mode 100644 index 0000000..c59c577 --- /dev/null +++ b/src/components/Header.jsx @@ -0,0 +1,21 @@ +import SearchBar from "./SearchBar" + +function Header({input, setInput}){ + return ( + <> +
    + + + + + gmail logo +
    + + + ) +} + +export default Header \ No newline at end of file diff --git a/src/components/LeftMenu.jsx b/src/components/LeftMenu.jsx new file mode 100644 index 0000000..67805c7 --- /dev/null +++ b/src/components/LeftMenu.jsx @@ -0,0 +1,41 @@ + +function LeftMenu({currentTab, setCurrentTab, unreadEmails, starredEmails, hideRead, setHideRead, setIsClicked}){ + return ( + <> + + + ) +} + +export default LeftMenu \ No newline at end of file diff --git a/src/components/SearchBar.jsx b/src/components/SearchBar.jsx new file mode 100644 index 0000000..d5c0ebc --- /dev/null +++ b/src/components/SearchBar.jsx @@ -0,0 +1,18 @@ + +function SearchBar({input, setInput}) { + + const handleInput = (it) => { + setInput(it.target.value) + } + return ( + <> +
    + +
    + + ) +} + +export default SearchBar \ No newline at end of file diff --git a/src/data/emails.js b/src/data/emails.js index 68fb1fc..5a1736d 100644 --- a/src/data/emails.js +++ b/src/data/emails.js @@ -3,6 +3,8 @@ export default [ id: 1, sender: `Zoom`, title: `Cloud Recording - Nicolas Marcora's Personal Meeting Room is now available`, + text: `Hi Sarah, \n + I just wanted to give you a quick update on the marketing project. Weve completed the initial research phase and are moving into design next week. The timeline is still on track for our mid-October launch. Let me know if youd like me to share the draft report.`, starred: false, read: true }, @@ -10,6 +12,8 @@ export default [ id: 2, sender: `Zoom`, title: `Sean Davison has joined your Personal Meeting Room`, + text: `Hey Tom, \n + Its been ages since we last caught up! How have things been going for you? Id love to grab a coffee sometime soon and hear about your new job. Let me know when youre free.`, starred: false, read: false }, @@ -17,6 +21,8 @@ export default [ id: 3, sender: `Notion`, title: `1 update in Boolean`, + text: `Dear Anna, \n + This is a reminder that you have a dentist appointment scheduled for Tuesday, September 5th at 2:00 PM. Please arrive 10 minutes early to complete your check-in. If you need to reschedule, kindly call our office at least 24 hours in advance. We look forward to seeing you.`, starred: true, read: true }, @@ -24,6 +30,8 @@ export default [ id: 4, sender: `The Calendly Team`, title: `Use more than one calendar?`, + text: `Hello David, \n + Thank you for reaching out about your recent order. Weve checked our system and your package is currently in transit with an expected delivery date of Friday. Please let us know if it hasnt arrived by then, and well be happy to assist further. Thanks for shopping with us!`, starred: false, read: false }, @@ -31,6 +39,8 @@ export default [ id: 5, sender: `Patrick`, title: `Updated invitation: Coding chat with Nico`, + text: `Hi Emily, \n + It was such a pleasure meeting you at the conference yesterday. I really enjoyed our conversation about sustainable design and would love to continue the discussion. If youre open, maybe we could schedule a quick call next week. Looking forward to staying in touch.`, starred: true, read: false } diff --git a/src/main.jsx b/src/main.jsx index fce89a2..dae8d55 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -5,6 +5,6 @@ import './styles/index.css' ReactDOM.createRoot(document.getElementById('root')).render( - + , )