Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 31 additions & 46 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useState } from 'react'

import initialEmails from './data/emails'

import './styles/App.css'
import Emails from './Components/Emails'
import EmailView from './Components/EmailView'
import Header from './Components/Header'

const getReadEmails = emails => emails.filter(email => !email.read)

Expand All @@ -12,10 +13,22 @@ function App() {
const [emails, setEmails] = useState(initialEmails)
const [hideRead, setHideRead] = useState(false)
const [currentTab, setCurrentTab] = useState('inbox')
const [openedEmail, setOpenedEmail] = useState(null)
const [searchTerm, setSearchTerm] = useState('')

const unreadEmails = emails.filter(email => !email.read)
const starredEmails = emails.filter(email => email.starred)

const openEmail = (email) => {
if (!email.read) {
setEmails(emails =>
emails.map(e =>
e.id === email.id ? { ...e, read: true } : e
)
)
}
setOpenedEmail(email)
}
const toggleStar = targetEmail => {
const updatedEmails = emails =>
emails.map(email =>
Expand All @@ -40,25 +53,14 @@ function App() {

if (currentTab === 'starred')
filteredEmails = getStarredEmails(filteredEmails)

if (searchTerm) {
filteredEmails = filteredEmails.filter(email =>
email.title.toLowerCase().includes(searchTerm.toLowerCase())
)
}
return (
<div className="app">
<header className="header">
<div className="left-menu">
<svg className="menu-icon" focusable="false" viewBox="0 0 24 24">
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path>
</svg>

<img
src="https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_1x_r2.png"
alt="gmail logo"
/>
</div>

<div className="search">
<input className="search-bar" placeholder="Search mail" />
</div>
</header>
<Header searchTerm={searchTerm} setSearchTerm={setSearchTerm} />
<nav className="left-menu">
<ul className="inbox-list">
<li
Expand Down Expand Up @@ -88,33 +90,16 @@ function App() {
</ul>
</nav>
<main className="emails">
<ul>
{filteredEmails.map((email, index) => (
<li
key={index}
className={`email ${email.read ? 'read' : 'unread'}`}
>
<div className="select">
<input
className="select-checkbox"
type="checkbox"
checked={email.read}
onChange={() => toggleRead(email)}
/>
</div>
<div className="star">
<input
className="star-checkbox"
type="checkbox"
checked={email.starred}
onChange={() => toggleStar(email)}
/>
</div>
<div className="sender">{email.sender}</div>
<div className="title">{email.title}</div>
</li>
))}
</ul>
{openedEmail ? (
<EmailView email={openedEmail} onClose={() => setOpenedEmail(null)} />
) : (
<Emails
emails={filteredEmails}
toggleRead={toggleRead}
toggleStar={toggleStar}
openEmail={openEmail}
/>
)}
</main>
</div>
)
Expand Down
31 changes: 31 additions & 0 deletions src/Components/Email.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

function Email({ email, toggleRead, toggleStar, openEmail }) {
return (
<li
className={`email ${email.read ? 'read' : 'unread'}`}
onClick={() => openEmail(email)}
style={{ cursor: 'pointer' }}
>
<div className="select">
<input
className="select-checkbox"
type="checkbox"
checked={email.read}
onChange={() => toggleRead(email)}
/>
</div>
<div className="star">
<input
className="star-checkbox"
type="checkbox"
checked={email.starred}
onChange={() => toggleStar(email)}
/>
</div>
<div className="sender">{email.sender}</div>
<div className="title">{email.title}</div>
</li>
)
}

export default Email
14 changes: 14 additions & 0 deletions src/Components/EmailView.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import '../styles/EmailView.css'

function EmailView({ email, onClose }) {
return (
<div className="email-view">
<button onClick={onClose}>Back</button>
<h2>{email.title}</h2>
<h4>From: {email.sender}</h4>
<p>{email.description}</p>
</div>
)
}

export default EmailView
20 changes: 20 additions & 0 deletions src/Components/Emails.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

import Email from './Email'

function Emails({ emails, toggleRead, toggleStar, openEmail }) {
return (
<ul>
{emails.map((email) => (
<Email
key={email.id}
email={email}
toggleRead={toggleRead}
toggleStar={toggleStar}
openEmail={openEmail}
/>
))}
</ul>
)
}

export default Emails
25 changes: 25 additions & 0 deletions src/Components/Header.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function Header({ searchTerm, setSearchTerm }) {
return (
<header className="header">
<div className="left-menu">
<svg className="menu-icon" focusable="false" viewBox="0 0 24 24">
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path>
</svg>
<img
src="https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_1x_r2.png"
alt="gmail logo"
/>
</div>
<div className="search">
<input
className="search-bar"
placeholder="Search mail"
value={searchTerm}
onChange={e => setSearchTerm(e.target.value)}
/>
</div>
</header>
)
}

export default Header
7 changes: 6 additions & 1 deletion src/data/emails.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,40 @@ export default [
id: 1,
sender: `Zoom`,
title: `Cloud Recording - Nicolas Marcora's Personal Meeting Room is now available`,
description: `Your cloud recording for Nicolas Marcora's Personal Meeting Room is now available. Click the link to view or download your recording.`,
starred: false,
read: true
},
{
id: 2,
sender: `Zoom`,
title: `Sean Davison has joined your Personal Meeting Room`,
description: `Sean Davison has just joined your Zoom Personal Meeting Room. You can now start your meeting.`,
starred: false,
read: false
},
{
id: 3,
sender: `Notion`,
title: `1 update in Boolean`,
description: `There is 1 new update in your Boolean workspace on Notion. Check it out to stay up to date.`,
starred: true,
read: true
},
{
id: 4,
sender: `The Calendly Team`,
title: `Use more than one calendar?`,
description: `Calendly now supports connecting multiple calendars. Manage your events more efficiently by linking all your calendars.`,
starred: false,
read: false
},
{
id: 5,
sender: `Patrick`,
title: `Updated invitation: Coding chat with Nico`,
description: `Patrick has updated the invitation for your coding chat with Nico. Please review the new details and confirm your attendance.`,
starred: true,
read: false
}
]
]
28 changes: 28 additions & 0 deletions src/styles/Emailview.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.email-view {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px #0001;
padding: 1.5rem 2rem;
max-width: 90%;
margin: 2rem auto;
}

.email-view button {
background: #f5f5f5;
border: none;
border-radius: 4px;
padding: 0.4rem 1rem;
margin-bottom: 1rem;
}

.email-view h4 {
margin: 0 0 1rem 0;
color: #555;
font-weight: 400;
}

.email-view p {
font-size: 1rem;
color: #222;
line-height: 1.5;
}