diff --git a/images/gmail-email-view-intro.png b/images/gmail-email-view-intro.png
new file mode 100644
index 0000000..7817237
Binary files /dev/null and b/images/gmail-email-view-intro.png differ
diff --git a/images/write-email-component.png b/images/write-email-component.png
new file mode 100644
index 0000000..cacb0f4
Binary files /dev/null and b/images/write-email-component.png differ
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..7d0d724 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,6 +1,8 @@
import { useState } from 'react'
import initialEmails from './data/emails'
+import Emails from './components/Emails'
+import ViewEmail from './components/ViewEmail'
import './styles/App.css'
@@ -9,9 +11,10 @@ const getReadEmails = emails => emails.filter(email => !email.read)
const getStarredEmails = emails => emails.filter(email => email.starred)
function App() {
- const [emails, setEmails] = useState(initialEmails)
+ const [emails, setEmails] = useState(initialEmails || [])
const [hideRead, setHideRead] = useState(false)
const [currentTab, setCurrentTab] = useState('inbox')
+ const [selectedEmail, setSelectedEmail] = useState(null);
const unreadEmails = emails.filter(email => !email.read)
const starredEmails = emails.filter(email => email.starred)
@@ -41,10 +44,13 @@ function App() {
if (currentTab === 'starred')
filteredEmails = getStarredEmails(filteredEmails)
+ // left-menu Gmail logo make inbox/index button
return (
-
+
console.log('Div clicked!')}>
@@ -87,37 +93,23 @@ function App() {
-
-
-
+
+ {selectedEmail ? (
+ setSelectedEmail(null)}
+ />
+ ) : (
+
+ )}
+
)
}
-export default App
+export default App;
\ No newline at end of file
diff --git a/src/assets/icons/back-arrow.png b/src/assets/icons/back-arrow.png
new file mode 100644
index 0000000..77bf292
Binary files /dev/null and b/src/assets/icons/back-arrow.png differ
diff --git a/src/assets/icons/download-button.png b/src/assets/icons/download-button.png
new file mode 100644
index 0000000..ddb5a11
Binary files /dev/null and b/src/assets/icons/download-button.png differ
diff --git a/src/assets/icons/rate-star-button.png b/src/assets/icons/rate-star-button.png
new file mode 100644
index 0000000..16d6722
Binary files /dev/null and b/src/assets/icons/rate-star-button.png differ
diff --git a/src/assets/icons/rubbish-bin-delete-button.png b/src/assets/icons/rubbish-bin-delete-button.png
new file mode 100644
index 0000000..7090fb1
Binary files /dev/null and b/src/assets/icons/rubbish-bin-delete-button.png differ
diff --git a/src/assets/images/flaticon-welcome-image.png b/src/assets/images/flaticon-welcome-image.png
new file mode 100644
index 0000000..698c431
Binary files /dev/null and b/src/assets/images/flaticon-welcome-image.png differ
diff --git a/src/components/Email.jsx b/src/components/Email.jsx
new file mode 100644
index 0000000..00335bd
--- /dev/null
+++ b/src/components/Email.jsx
@@ -0,0 +1,34 @@
+function Email({ index, email, toggleRead, toggleStar, viewEmail }) {
+
+ 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..a65a08f
--- /dev/null
+++ b/src/components/Emails.jsx
@@ -0,0 +1,22 @@
+import Email from './Email'
+
+function Emails({ emails = [], toggleRead, toggleStar, viewEmail }) {
+ return (
+ <>
+
+
+ {emails.map((email, index) => (
+ viewEmail(email)} />
+ ))}
+
+
+ >
+ )
+}
+
+export default Emails;
\ No newline at end of file
diff --git a/src/components/ViewEmail.jsx b/src/components/ViewEmail.jsx
new file mode 100644
index 0000000..1430c88
--- /dev/null
+++ b/src/components/ViewEmail.jsx
@@ -0,0 +1,95 @@
+import flaticonWelcomeImage from '../assets/images/flaticon-welcome-image.png'
+import backArrow from '../assets/icons/back-arrow.png'
+import downloadButton from '../assets/icons/download-button.png'
+import rateStarButton from '../assets/icons/rate-star-button.png'
+import rubbishButton from '../assets/icons/rubbish-bin-delete-button.png'
+
+import '../styles/Mail.css'
+
+function ViewEmail({ email, goBack }) {
+
+ return (
+ <>
+
+
+
+
+
{email.title}
+
+
+
+
+

+
+
+
+
+
+ >
+ );
+}
+
+export default ViewEmail;
\ No newline at end of file
diff --git a/src/main.jsx b/src/main.jsx
index fce89a2..ef85956 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -1,7 +1,7 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
-import './styles/index.css'
+import './styles/App.css'
ReactDOM.createRoot(document.getElementById('root')).render(
diff --git a/src/styles/App.css b/src/styles/App.css
index da375b1..9b1158b 100644
--- a/src/styles/App.css
+++ b/src/styles/App.css
@@ -1,3 +1,10 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ font-family: sans-serif;
+}
+
.app {
height: 100vh;
diff --git a/src/styles/Mail.css b/src/styles/Mail.css
new file mode 100644
index 0000000..b5e0b07
--- /dev/null
+++ b/src/styles/Mail.css
@@ -0,0 +1,203 @@
+/* from the gmail-react-intro repository! */
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ font-family: sans-serif;
+}
+
+.app {
+ height: 100vh;
+
+ display: grid;
+ grid-template:
+ 'header header' 50px
+ 'left-menu emails' 1fr /
+ 180px 1fr;
+}
+
+.app > .header {
+ grid-area: header;
+
+ display: grid;
+ grid-template-columns: 180px 1fr;
+
+ border-bottom: solid 1px #00000020;
+}
+
+.app > .header > .left-menu {
+ display: grid;
+ grid-auto-flow: column;
+ align-items: center;
+ justify-content: left;
+}
+
+.app > .header > .left-menu .menu-icon {
+ width: 25px;
+ height: 25px;
+ margin: 10px;
+}
+
+.app > .header > .search {
+ display: grid;
+ padding: 6px;
+}
+
+.app > .header > .search .search-bar {
+ border: none;
+ border-radius: 5px;
+ background-color: rgb(240, 240, 240);
+ padding: 0 10px;
+ font-size: 1rem;
+}
+
+.app > .left-menu {
+ grid-area: left-menu;
+ padding: 10px;
+ padding-left: 0;
+}
+
+.app > .left-menu .inbox-list {
+ display: grid;
+ grid-gap: 10px;
+}
+
+.app > .left-menu .inbox-list .item {
+ padding: 5px 10px;
+ display: grid;
+ grid-auto-flow: column;
+ justify-content: space-between;
+ align-items: center;
+
+ border-top-right-radius: 20px;
+ border-bottom-right-radius: 20px;
+}
+
+.app > .left-menu .inbox-list .item.active {
+ background-color: #ff000050;
+}
+
+.app > .left-menu .inbox-list .item.toggle {
+ background-color: transparent;
+}
+
+.email-toolbar {
+ padding: 0.5rem 2rem;
+
+ display: grid;
+ grid-template-columns: auto 1fr auto;
+
+ border-bottom: 1px solid #eee;
+}
+
+.email-toolbar > * {
+ display: grid;
+ grid-auto-flow: column;
+ align-items: center;
+ gap: 1rem;
+}
+
+.email-toolbar > ul {
+ list-style-type: none;
+}
+
+.email-toolbar .icon {
+ width: 24px;
+ height: 24px;
+}
+
+.email-toolbar button {
+ padding: 0.25rem 0.5rem 0.4rem;
+
+ border-radius: 0.5rem;
+ border: 1px solid #a1a1a1;
+ background-color: transparent;
+
+ font-weight: bold;
+}
+
+.title {
+ padding: 1rem;
+}
+
+.title h1 {
+ padding-left: 56px;
+
+ font-weight: normal;
+}
+
+.email-content--header {
+ padding: 0.5rem 1rem;
+
+ display: grid;
+ grid-template-columns: auto 1fr auto auto;
+ gap: 1rem;
+}
+
+.email-content--header .avatar {
+ width: 56px;
+ height: 56px;
+
+ border-radius: 100%;
+ background-color: #eee;
+}
+
+.email-info {
+ padding: 0.25rem 0;
+}
+
+.email-info .sender-info h2 {
+ margin-right: 1rem;
+
+ display: inline-block;
+
+ font-size: 0.925rem;
+}
+
+.email-info .user-info {
+ margin-top: 0.5rem;
+}
+
+.email-info .user-info p {
+ font-size: 0.825rem;
+}
+
+.email-action-icons ul {
+ padding: 0;
+ margin: 0;
+
+ display: grid;
+ grid-auto-flow: column;
+ gap: 0.25rem;
+
+ list-style-type: none;
+}
+
+.email-action-icons .icon {
+ width: 20px;
+ height: 20px;
+}
+
+.email-body .content {
+ max-width: 600px;
+ margin: 0 auto;
+}
+
+.email-body .content img {
+ width: 100%;
+}
+
+.email-actions {
+ padding: 1rem 0.5rem;
+}
+
+.email-actions button {
+ padding: 0.5rem 1rem;
+ margin-right: 0.5rem;
+
+ border-radius: 0.5rem;
+ border: 1px solid #a1a1a1;
+ background-color: transparent;
+
+ font-weight: bold;
+}
diff --git a/src/styles/index.css b/src/styles/index.css
deleted file mode 100644
index 48ed51c..0000000
--- a/src/styles/index.css
+++ /dev/null
@@ -1,6 +0,0 @@
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- font-family: sans-serif;
-}