From 0efcd2a5e8a9686d9dd60bbb8a6eb41a194e0c50 Mon Sep 17 00:00:00 2001 From: lucasholter00 Date: Thu, 28 Aug 2025 15:02:50 +0200 Subject: [PATCH 1/3] Core and extension 1 --- src/App.jsx | 72 +++++++++++------------------- src/components/Email/index.jsx | 34 ++++++++++++++ src/components/EmailList/index.jsx | 39 ++++++++++++++++ src/data/emails.js | 5 +++ 4 files changed, 104 insertions(+), 46 deletions(-) create mode 100644 src/components/Email/index.jsx create mode 100644 src/components/EmailList/index.jsx diff --git a/src/App.jsx b/src/App.jsx index c902699..a1610ad 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,5 +1,7 @@ import { useState } from 'react' +import EmailList from './components/EmailList' + import initialEmails from './data/emails' import './styles/App.css' @@ -12,27 +14,12 @@ function App() { const [emails, setEmails] = useState(initialEmails) const [hideRead, setHideRead] = useState(false) const [currentTab, setCurrentTab] = useState('inbox') + const [selectedIndex, setSelectedIndex] = useState(-1) const unreadEmails = emails.filter(email => !email.read) const starredEmails = emails.filter(email => email.starred) - const toggleStar = targetEmail => { - const updatedEmails = emails => - emails.map(email => - email.id === targetEmail.id - ? { ...email, starred: !email.starred } - : email - ) - setEmails(updatedEmails) - } - - const toggleRead = targetEmail => { - const updatedEmails = emails => - emails.map(email => - email.id === targetEmail.id ? { ...email, read: !email.read } : email - ) - setEmails(updatedEmails) - } + let filteredEmails = emails @@ -63,14 +50,20 @@ function App() {
- + { selectedIndex >= 0 && filteredEmails[selectedIndex] ?( + <> +

{ filteredEmails[selectedIndex].title }

+

Sender: { filteredEmails[selectedIndex].sender }

+

-----------------------------------------------

+

{ filteredEmails[selectedIndex].content }

+ + ) : ( + + ) + } +
+ + ) } diff --git a/src/components/Email/index.jsx b/src/components/Email/index.jsx new file mode 100644 index 0000000..02a8e91 --- /dev/null +++ b/src/components/Email/index.jsx @@ -0,0 +1,34 @@ + +function Email({ email, toggleRead, toggleStar, onClick }){ + + return( +
  • +
    + { + toggleRead(email) + }} + /> +
    +
    + { + toggleStar(email) + }} + /> +
    +
    {email.sender}
    +
    {email.title}
    +
  • + ) +} + +export default Email diff --git a/src/components/EmailList/index.jsx b/src/components/EmailList/index.jsx new file mode 100644 index 0000000..f443e80 --- /dev/null +++ b/src/components/EmailList/index.jsx @@ -0,0 +1,39 @@ +import Email from "../Email" + +function EmailList({ filteredEmails, setEmails, setSelectedIndex }){ + + const toggleStar = targetEmail => { + const updatedEmails = emails => + emails.map(email => + email.id === targetEmail.id + ? { ...email, starred: !email.starred } + : email + ) + setEmails(updatedEmails) + } + + const toggleRead = targetEmail => { + const updatedEmails = emails => + emails.map(email => + email.id === targetEmail.id ? { ...email, read: !email.read } : email + ) + setEmails(updatedEmails) + } + +return ( + <> + + + +) + +} + + + + +export default EmailList diff --git a/src/data/emails.js b/src/data/emails.js index 68fb1fc..99a4a38 100644 --- a/src/data/emails.js +++ b/src/data/emails.js @@ -3,6 +3,7 @@ export default [ id: 1, sender: `Zoom`, title: `Cloud Recording - Nicolas Marcora's Personal Meeting Room is now available`, + content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras mi mi, gravida sit amet odio eget, consectetur hendrerit ante. Proin a dui justo. Fusce turpis dolor, gravida ac sapien id, malesuada auctor diam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam mollis, orci nec ornare ultrices, lorem ipsum tincidunt purus, id tincidunt turpis purus in nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Pellentesque dapibus odio nibh, eu bibendum sem euismod sit amet. Sed et nibh quis enim faucibus mattis venenatis eget tortor. Suspendisse et odio faucibus, bibendum quam in, volutpat tellus. Vivamus tempor condimentum purus, ac auctor enim elementum et. Vivamus blandit, est sagittis vulputate lacinia, mauris ante dapibus sapien, sed convallis nulla felis a eros. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum dictum, neque eget aliquet imperdiet, nisi dui feugiat libero, id pulvinar massa risus sed erat. Vivamus in turpis placerat tortor maximus vulputate ut ac mi. Lorem ipsum dolor sit amet, consectetur adipiscing elit." , starred: false, read: true }, @@ -10,6 +11,7 @@ export default [ id: 2, sender: `Zoom`, title: `Sean Davison has joined your Personal Meeting Room`, + content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras mi mi, gravida sit amet odio eget, consectetur hendrerit ante. Proin a dui justo. Fusce turpis dolor, gravida ac sapien id, malesuada auctor diam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam mollis, orci nec ornare ultrices, lorem ipsum tincidunt purus, id tincidunt turpis purus in nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Pellentesque dapibus odio nibh, eu bibendum sem euismod sit amet. Sed et nibh quis enim faucibus mattis venenatis eget tortor. Suspendisse et odio faucibus, bibendum quam in, volutpat tellus. Vivamus tempor condimentum purus, ac auctor enim elementum et. Vivamus blandit, est sagittis vulputate lacinia, mauris ante dapibus sapien, sed convallis nulla felis a eros. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum dictum, neque eget aliquet imperdiet, nisi dui feugiat libero, id pulvinar massa risus sed erat. Vivamus in turpis placerat tortor maximus vulputate ut ac mi. Lorem ipsum dolor sit amet, consectetur adipiscing elit." , starred: false, read: false }, @@ -17,6 +19,7 @@ export default [ id: 3, sender: `Notion`, title: `1 update in Boolean`, + content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras mi mi, gravida sit amet odio eget, consectetur hendrerit ante. Proin a dui justo. Fusce turpis dolor, gravida ac sapien id, malesuada auctor diam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam mollis, orci nec ornare ultrices, lorem ipsum tincidunt purus, id tincidunt turpis purus in nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Pellentesque dapibus odio nibh, eu bibendum sem euismod sit amet. Sed et nibh quis enim faucibus mattis venenatis eget tortor. Suspendisse et odio faucibus, bibendum quam in, volutpat tellus. Vivamus tempor condimentum purus, ac auctor enim elementum et. Vivamus blandit, est sagittis vulputate lacinia, mauris ante dapibus sapien, sed convallis nulla felis a eros. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum dictum, neque eget aliquet imperdiet, nisi dui feugiat libero, id pulvinar massa risus sed erat. Vivamus in turpis placerat tortor maximus vulputate ut ac mi. Lorem ipsum dolor sit amet, consectetur adipiscing elit." , starred: true, read: true }, @@ -24,6 +27,7 @@ export default [ id: 4, sender: `The Calendly Team`, title: `Use more than one calendar?`, + content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras mi mi, gravida sit amet odio eget, consectetur hendrerit ante. Proin a dui justo. Fusce turpis dolor, gravida ac sapien id, malesuada auctor diam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam mollis, orci nec ornare ultrices, lorem ipsum tincidunt purus, id tincidunt turpis purus in nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Pellentesque dapibus odio nibh, eu bibendum sem euismod sit amet. Sed et nibh quis enim faucibus mattis venenatis eget tortor. Suspendisse et odio faucibus, bibendum quam in, volutpat tellus. Vivamus tempor condimentum purus, ac auctor enim elementum et. Vivamus blandit, est sagittis vulputate lacinia, mauris ante dapibus sapien, sed convallis nulla felis a eros. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum dictum, neque eget aliquet imperdiet, nisi dui feugiat libero, id pulvinar massa risus sed erat. Vivamus in turpis placerat tortor maximus vulputate ut ac mi. Lorem ipsum dolor sit amet, consectetur adipiscing elit." , starred: false, read: false }, @@ -31,6 +35,7 @@ export default [ id: 5, sender: `Patrick`, title: `Updated invitation: Coding chat with Nico`, + content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras mi mi, gravida sit amet odio eget, consectetur hendrerit ante. Proin a dui justo. Fusce turpis dolor, gravida ac sapien id, malesuada auctor diam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam mollis, orci nec ornare ultrices, lorem ipsum tincidunt purus, id tincidunt turpis purus in nisl. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Pellentesque dapibus odio nibh, eu bibendum sem euismod sit amet. Sed et nibh quis enim faucibus mattis venenatis eget tortor. Suspendisse et odio faucibus, bibendum quam in, volutpat tellus. Vivamus tempor condimentum purus, ac auctor enim elementum et. Vivamus blandit, est sagittis vulputate lacinia, mauris ante dapibus sapien, sed convallis nulla felis a eros. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum dictum, neque eget aliquet imperdiet, nisi dui feugiat libero, id pulvinar massa risus sed erat. Vivamus in turpis placerat tortor maximus vulputate ut ac mi. Lorem ipsum dolor sit amet, consectetur adipiscing elit." , starred: true, read: false } From a45afed5d78764395aab6a685ad60d025c38e349 Mon Sep 17 00:00:00 2001 From: lucasholter00 Date: Thu, 28 Aug 2025 15:10:04 +0200 Subject: [PATCH 2/3] Extension 2 --- src/App.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/App.jsx b/src/App.jsx index a1610ad..6eadd25 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -14,6 +14,7 @@ function App() { const [emails, setEmails] = useState(initialEmails) const [hideRead, setHideRead] = useState(false) const [currentTab, setCurrentTab] = useState('inbox') + const [search, setSearch] = useState("") const [selectedIndex, setSelectedIndex] = useState(-1) const unreadEmails = emails.filter(email => !email.read) @@ -28,6 +29,11 @@ function App() { if (currentTab === 'starred') filteredEmails = getStarredEmails(filteredEmails) + if (search != "" && selectedIndex < 0) + filteredEmails = filteredEmails.filter((item) => { + return item.title.toLowerCase().includes(search); + }) + return (
    @@ -43,7 +49,7 @@ function App() {
    - + setSearch(e.target.value)} className="search-bar" placeholder="Search mail" />
    { selectedIndex >= 0 && filteredEmails[selectedIndex] ?( - <> -

    { filteredEmails[selectedIndex].title }

    -

    Sender: { filteredEmails[selectedIndex].sender }

    -

    -----------------------------------------------

    -

    { filteredEmails[selectedIndex].content }

    - + ) : ( ) diff --git a/src/components/Content/index.jsx b/src/components/Content/index.jsx new file mode 100644 index 0000000..86ef4c0 --- /dev/null +++ b/src/components/Content/index.jsx @@ -0,0 +1,16 @@ +function Content({ email, setSelectedIndex }){ + +return( + <> + +

    { email.title }

    +

    Sender: { email.sender }

    +

    -----------------------------------------------

    +

    { email.content }

    + +) + + +} + +export default Content