From a8b6daa7f71b034a0ab380055ee7d604d2957962 Mon Sep 17 00:00:00 2001 From: Rafa Date: Wed, 10 Jan 2024 12:12:19 +0100 Subject: [PATCH 01/37] feat: mocks for components --- src/components/mail/mocks/index.ts | 309 +++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 src/components/mail/mocks/index.ts diff --git a/src/components/mail/mocks/index.ts b/src/components/mail/mocks/index.ts new file mode 100644 index 0000000..ba370da --- /dev/null +++ b/src/components/mail/mocks/index.ts @@ -0,0 +1,309 @@ +import { v4 as uuidv4 } from 'uuid'; + +type EmailAttachment = { + filename: string; + mimeType: string; + size: number; +}; + +type Recipient = { + email: string; + name: string; + avatar?: string; +}; + +export type EmailProps = { + id: string; + from: { + email: string; + name: string; + avatar?: string; + }; + to: Recipient[]; + cc?: Recipient[]; + bcc?: Recipient[]; + subject: string; + body: string; + attachments: EmailAttachment[]; + isHtml?: boolean; + timestamp?: string; + read: boolean; +}; + +const randomEmail = (): string => { + const domain = 'internxt.com'; + return `user${Math.floor(Math.random() * 1000)}@${domain}`; +}; + +const randomName = (): string => { + const names = [ + 'John Doe', + 'Jane Smith', + 'Alice Johnson', + 'Bob Brown', + 'Charlie Davis', + 'Diana Evans', + 'Edward Wilson', + 'Fiona White', + 'George Clark', + 'Hannah Scott', + ]; + return names[Math.floor(Math.random() * names.length)]; +}; + +const randomAvatar = (): string | undefined => { + return Math.random() < 0.5 ? `https://picsum.photos/seed/${Math.random()}/200` : undefined; +}; + +const randomSubject = (): string => { + const subjects = [ + 'Meeting Reminder', + 'Project Update', + 'Invoice Attached', + 'Welcome to the Team', + 'Your Subscription Details', + 'Password Reset Request', + 'Special Offer Just for You', + 'Upcoming Webinar Details', + 'Happy Birthday!', + 'Security Alert', + ]; + return subjects[Math.floor(Math.random() * subjects.length)]; +}; + +const randomBody = (): string => { + const bodies = [ + 'This is a reminder for your upcoming meeting.', + 'Please find the attached document for your review.', + 'Your subscription will expire soon. Renew now!', + 'Welcome aboard! We are excited to have you on our team.', + 'Here are the details of your recent purchase.', + 'Click the link below to reset your password.', + 'Do not miss this exclusive offer, valid only for today.', + 'Join us for an exciting webinar on the latest trends.', + 'Happy Birthday! We hope you have a wonderful day.', + 'We detected an unusual login attempt on your account.', + ]; + return bodies[Math.floor(Math.random() * bodies.length)]; +}; + +const randomReadStatus = (): boolean => Math.random() < 0.5; + +const generateRandomRecipients = (count: number): Recipient[] => { + return Array.from({ length: count }, () => ({ + email: randomEmail(), + name: randomName(), + avatar: randomAvatar(), + })); +}; + +const generateMocks = (): Record => { + const mocks: Record = { + basicEmails: [], + emailsWithAttachments: [], + emailsWithMultipleRecipients: [], + invalidEmails: [], + emailsWithHTML: [], + notificationEmails: [], + emailsWithLongBody: [], + }; + + for (let i = 0; i < 10; i++) { + mocks.basicEmails.push({ + id: uuidv4(), + from: { + email: randomEmail(), + name: randomName(), + avatar: randomAvatar(), + }, + to: generateRandomRecipients(1), + subject: randomSubject(), + body: randomBody(), + attachments: [], + timestamp: new Date( + Math.floor(Math.random() * (2023 - 2021 + 1) + 2021), + Math.floor(Math.random() * 12), + Math.floor(Math.random() * 28), + Math.floor(Math.random() * 24), + Math.floor(Math.random() * 60), + ).toISOString(), + read: randomReadStatus(), + }); + + mocks.emailsWithAttachments.push({ + id: uuidv4(), + from: { + email: randomEmail(), + name: randomName(), + avatar: randomAvatar(), + }, + to: generateRandomRecipients(2), + subject: randomSubject(), + body: randomBody(), + attachments: [ + { + filename: `file${Math.floor(Math.random() * 5)}.pdf`, + mimeType: 'application/pdf', + size: Math.floor(Math.random() * 20480 + 1024), + }, + { + filename: `image${Math.floor(Math.random() * 5)}.png`, + mimeType: 'image/png', + size: Math.floor(Math.random() * 10240 + 2048), + }, + ], + read: randomReadStatus(), + }); + + mocks.emailsWithMultipleRecipients.push({ + id: uuidv4(), + from: { + email: randomEmail(), + name: randomName(), + avatar: randomAvatar(), + }, + to: generateRandomRecipients(3), + cc: generateRandomRecipients(3), + bcc: generateRandomRecipients(1), + subject: randomSubject(), + timestamp: new Date( + Math.floor(Math.random() * (2023 - 2021 + 1) + 2021), + Math.floor(Math.random() * 12), + Math.floor(Math.random() * 28), + Math.floor(Math.random() * 24), + Math.floor(Math.random() * 60), + ).toISOString(), + body: randomBody(), + attachments: [], + read: randomReadStatus(), + }); + + mocks.invalidEmails.push({ + id: uuidv4(), + from: { + email: 'invalid-email', + name: randomName(), + avatar: randomAvatar(), + }, + to: [], + subject: '', + body: '', + attachments: [], + read: randomReadStatus(), + }); + + mocks.emailsWithHTML.push({ + id: uuidv4(), + from: { + email: randomEmail(), + name: randomName(), + avatar: randomAvatar(), + }, + to: generateRandomRecipients(1), + subject: randomSubject(), + body: `

${randomSubject()}

${randomBody()}

`, + isHtml: true, + attachments: [], + read: randomReadStatus(), + }); + + mocks.notificationEmails.push({ + id: uuidv4(), + from: { + email: 'no-reply@system.com', + name: randomName(), + avatar: randomAvatar(), + }, + to: generateRandomRecipients(2), + subject: randomSubject(), + body: randomBody(), + timestamp: new Date( + Math.floor(Math.random() * (2023 - 2021 + 1) + 2021), + Math.floor(Math.random() * 12), + Math.floor(Math.random() * 28), + Math.floor(Math.random() * 24), + Math.floor(Math.random() * 60), + ).toISOString(), + attachments: [], + read: randomReadStatus(), + }); + + mocks.emailsWithLongBody.push({ + id: uuidv4(), + from: { + email: randomEmail(), + name: randomName(), + avatar: randomAvatar(), + }, + to: generateRandomRecipients(3), + subject: randomSubject(), + body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. '.repeat(50), + attachments: [], + read: randomReadStatus(), + }); + } + + return mocks; +}; + +export const emailMocks = generateMocks(); + +/** + * Updates the 'read' status of an email by its ID. + * @param mocks - The collection of email mocks. + * @param id - The ID of the email to update. + * @param newReadStatus - The new value for the 'read' field. + * @returns The updated email, or null if not found. + */ +export const updateEmailReadStatus = ( + mocks: Record, + id: string, + newReadStatus: boolean, +): EmailProps | null => { + for (const category in mocks) { + const email = mocks[category].find((email) => email.id === id); + if (email) { + email.read = newReadStatus; + return email; + } + } + return null; +}; + +export function formatTimestamp(timestamp: string): string { + const date = new Date(timestamp); + + const today = new Date(); + const isToday = + date.getDate() === today.getDate() && + date.getMonth() === today.getMonth() && + date.getFullYear() === today.getFullYear(); + + const isYesterday = + date.getDate() === today.getDate() - 1 && + date.getMonth() === today.getMonth() && + date.getFullYear() === today.getFullYear(); + + if (isToday) { + const options: Intl.DateTimeFormatOptions = { + hour: '2-digit', + minute: '2-digit', + }; + return date.toLocaleTimeString('en-US', options); + } else if (isYesterday) { + const options: Intl.DateTimeFormatOptions = { + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + }; + return date.toLocaleString('en-US', options); + } else { + const options: Intl.DateTimeFormatOptions = { + month: 'short', + day: 'numeric', + year: 'numeric', + }; + return date.toLocaleDateString('en-US', options); + } +} From bf968ed49457e99270a83fe9a9adf048a1ac771e Mon Sep 17 00:00:00 2001 From: Rafa Date: Thu, 18 Jan 2024 10:12:00 +0100 Subject: [PATCH 02/37] feat: sidenav component --- src/components/mail/sidenav/Sidenav.tsx | 167 ++++++++++++++++++ .../mail/sidenav/Sidenav.stories.tsx | 29 +++ 2 files changed, 196 insertions(+) create mode 100644 src/components/mail/sidenav/Sidenav.tsx create mode 100644 src/stories/components/mail/sidenav/Sidenav.stories.tsx diff --git a/src/components/mail/sidenav/Sidenav.tsx b/src/components/mail/sidenav/Sidenav.tsx new file mode 100644 index 0000000..d28bb4f --- /dev/null +++ b/src/components/mail/sidenav/Sidenav.tsx @@ -0,0 +1,167 @@ +import { + DotsNine, + NotePencil, + Tray, + File, + PaperPlaneTilt, + Trash, + CaretRight, + WarningDiamond, + Archive, + IconWeight, + CaretDown, +} from '@phosphor-icons/react'; +import { Button } from '../../button/Button'; +import { useState } from 'react'; + +const MAIL_OPTIONS = [ + { + id: 0, + title: 'Inbox', + icon: Tray, + notifications: 2, + }, + { + id: 1, + title: 'Drafts', + icon: File, + notifications: 1, + }, + { + id: 2, + title: 'Sent', + icon: PaperPlaneTilt, + }, + { + id: 3, + title: 'Trash', + icon: Trash, + }, + { + id: 4, + title: 'More', + icon: CaretRight, + activeIcon: CaretDown, + iconSize: 14, + weight: 'fill' as IconWeight, + }, + { + id: 5, + title: 'Archive', + icon: Archive, + notifications: 10, + iconSize: 20, + subsection: true, + }, + { + id: 6, + title: 'Spam', + icon: WarningDiamond, + notifications: 3, + weight: 'regular' as IconWeight, + subsection: true, + }, +]; + +export const Sidenav = () => { + const [active, setActive] = useState(0); + const [showSubsections, setShowSubsections] = useState(false); // Controls subsection visibility + + const handleClick = (optionId: number, isSubsection: boolean) => { + if (isSubsection) { + setActive(optionId); + return; // Prevent hiding subsections on click + } + + // Toggle subsection visibility when 'More' is clicked + if (optionId === 4) { + setShowSubsections(!showSubsections); + } else { + setShowSubsections(false); + } + + setActive(optionId); + }; + + // !TODO: Remove max-h + return ( +
+
+
+
+ +

Mail

+
+ +
+
+ +
+ {MAIL_OPTIONS.map((option) => { + if (option.subsection && !showSubsections) { + return null; + } + + return ( + + ); + })} +
+
+
+
+
+
+

2.8 GB

+

/

+

4 GB

+
+ +
+
+
+
+
+
+ ); +}; diff --git a/src/stories/components/mail/sidenav/Sidenav.stories.tsx b/src/stories/components/mail/sidenav/Sidenav.stories.tsx new file mode 100644 index 0000000..e3a1248 --- /dev/null +++ b/src/stories/components/mail/sidenav/Sidenav.stories.tsx @@ -0,0 +1,29 @@ +import type { Decorator, Meta, StoryObj } from '@storybook/react'; +import { Sidenav } from '../../../../components/mail/sidenav/Sidenav'; + +const overlay: Decorator = (Story) => ( +
+ +
+); + +const meta: Meta = { + title: 'Components(Email)/Sidenav', + component: Sidenav, + parameters: { + layout: 'fullscreen', + }, + decorators: [overlay], + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: (args) => ( +
+ +
+ ), +}; From cdd92815cc749c67ebb4543aab4d01c9b9c08b2b Mon Sep 17 00:00:00 2001 From: Rafa Date: Thu, 18 Jan 2024 10:32:00 +0100 Subject: [PATCH 03/37] fix: remove comments and complete the TODO in Sidenav --- src/components/mail/sidenav/Sidenav.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/mail/sidenav/Sidenav.tsx b/src/components/mail/sidenav/Sidenav.tsx index d28bb4f..523fda6 100644 --- a/src/components/mail/sidenav/Sidenav.tsx +++ b/src/components/mail/sidenav/Sidenav.tsx @@ -65,15 +65,14 @@ const MAIL_OPTIONS = [ export const Sidenav = () => { const [active, setActive] = useState(0); - const [showSubsections, setShowSubsections] = useState(false); // Controls subsection visibility + const [showSubsections, setShowSubsections] = useState(false); const handleClick = (optionId: number, isSubsection: boolean) => { if (isSubsection) { setActive(optionId); - return; // Prevent hiding subsections on click + return; } - // Toggle subsection visibility when 'More' is clicked if (optionId === 4) { setShowSubsections(!showSubsections); } else { @@ -83,7 +82,6 @@ export const Sidenav = () => { setActive(optionId); }; - // !TODO: Remove max-h return (
From a314c8c6be6a48852b6226dc665e91d30700d20d Mon Sep 17 00:00:00 2001 From: Rafa Date: Sat, 3 Feb 2024 14:33:00 +0100 Subject: [PATCH 04/37] feat: Tray component --- src/components/mail/tray/Tray.tsx | 57 +++++++++++++++++++ .../mail/tray/components/Message.tsx | 36 ++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 src/components/mail/tray/Tray.tsx create mode 100644 src/components/mail/tray/components/Message.tsx diff --git a/src/components/mail/tray/Tray.tsx b/src/components/mail/tray/Tray.tsx new file mode 100644 index 0000000..50dd823 --- /dev/null +++ b/src/components/mail/tray/Tray.tsx @@ -0,0 +1,57 @@ +import { CaretDown, DotsThreeVertical, FunnelSimple } from '@phosphor-icons/react'; +import Checkbox from '../../checkbox/Checkbox'; +import Input from '../../input/Input'; +import { Message } from './components/Message'; +import { emailMocks, EmailProps } from '../mocks'; + +export const Tray = ({ + mails, + handleSelectAll, + checked, + selectedEmails, + activeEmail, + onMailSelected, +}: { + mails: EmailProps[]; + selectedEmails: string[]; + checked: boolean; + activeEmail: string; + handleSelectAll: () => void; + onMailSelected: (id: string) => void; +}) => { + return ( +
+
+ +
+
+
+ 0 && selectedEmails.length < emailMocks.basicEmails.length} + checked={checked} + onClick={handleSelectAll} + /> + +
+

Inbox

+
+
+ + +
+
+
+
+
+ {mails.map((email) => ( +
+ +
+
+
+
+ ))} +
+
+ ); +}; diff --git a/src/components/mail/tray/components/Message.tsx b/src/components/mail/tray/components/Message.tsx new file mode 100644 index 0000000..c582dfb --- /dev/null +++ b/src/components/mail/tray/components/Message.tsx @@ -0,0 +1,36 @@ +import { Avatar } from '../../../avatar/Avatar'; +import { EmailProps, formatTimestamp } from '../../mocks'; + +interface MessageProps { + email: Pick; + onClick: (id: string) => void; + active?: boolean; +} + +export const Message = ({ email, active, onClick }: MessageProps) => { + return ( + + ); +}; From c73e9bd8cae53de519c5997ebbf667901734e8ec Mon Sep 17 00:00:00 2001 From: Rafa Date: Sat, 3 Feb 2024 14:37:00 +0100 Subject: [PATCH 05/37] fix: extract props to an interface in Tray component --- src/components/mail/tray/Tray.tsx | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/components/mail/tray/Tray.tsx b/src/components/mail/tray/Tray.tsx index 50dd823..7346407 100644 --- a/src/components/mail/tray/Tray.tsx +++ b/src/components/mail/tray/Tray.tsx @@ -4,21 +4,16 @@ import Input from '../../input/Input'; import { Message } from './components/Message'; import { emailMocks, EmailProps } from '../mocks'; -export const Tray = ({ - mails, - handleSelectAll, - checked, - selectedEmails, - activeEmail, - onMailSelected, -}: { +interface TrayProps { mails: EmailProps[]; selectedEmails: string[]; checked: boolean; activeEmail: string; handleSelectAll: () => void; onMailSelected: (id: string) => void; -}) => { +} + +export const Tray = ({ mails, handleSelectAll, checked, selectedEmails, activeEmail, onMailSelected }: TrayProps) => { return (
From 460fb4be45c5f89f36f59dc3cba882196fe73633 Mon Sep 17 00:00:00 2001 From: Rafa Date: Tue, 6 Feb 2024 12:07:00 +0100 Subject: [PATCH 06/37] feat: Action bar for Preview component --- .../mail/preview/components/ActionBar.tsx | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/components/mail/preview/components/ActionBar.tsx diff --git a/src/components/mail/preview/components/ActionBar.tsx b/src/components/mail/preview/components/ActionBar.tsx new file mode 100644 index 0000000..468ee2e --- /dev/null +++ b/src/components/mail/preview/components/ActionBar.tsx @@ -0,0 +1,93 @@ +import { + ArrowBendUpRight, + Archive, + ArrowBendDoubleUpLeft, + ArrowBendUpLeft, + EnvelopeSimple, + Flag, + FolderSimple, + Trash, + Gear, + DotsThreeVertical, + Printer, + Info, + WarningDiamond, + WarningOctagon, +} from '@phosphor-icons/react'; +import { Button } from '../../../button/Button'; +import { Avatar } from '../../../avatar/Avatar'; +import Dropdown from '../../../dropdown/Dropdown'; + +export const ActionBar = () => { + const dropdownActions = [ + { + name: 'Print', + icon: Printer, + }, + { + name: 'View source', + icon: Info, + }, + { + separator: true, + }, + { + name: 'Move to Spam', + icon: WarningDiamond, + }, + { + name: 'Report phishing', + icon: WarningOctagon, + }, + ]; + + return ( +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ } + classButton="flex items-center hover:bg-gray-5 p-2 rounded-lg" + classMenuItems="relative" + dropdownActionsContext={dropdownActions} + openDirection="right" + /> +
+
+ + +
+
+ ); +}; From 6cb2f5239c62ead4ea99e3b3286d06aa24db7cb1 Mon Sep 17 00:00:00 2001 From: Rafa Date: Tue, 6 Feb 2024 15:14:00 +0100 Subject: [PATCH 07/37] feat: Header for Preview component --- .../mail/preview/components/Header.tsx | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/components/mail/preview/components/Header.tsx diff --git a/src/components/mail/preview/components/Header.tsx b/src/components/mail/preview/components/Header.tsx new file mode 100644 index 0000000..cc71532 --- /dev/null +++ b/src/components/mail/preview/components/Header.tsx @@ -0,0 +1,62 @@ +import { useState } from 'react'; +import { Avatar } from '../../../avatar/Avatar'; +import { EmailProps, formatTimestamp } from '../../mocks'; +import { UserCheap } from '../../userCheap/UserCheap'; + +export const Header = ({ from, to, cc, timestamp }: Pick) => { + const [hoveredIndex, setHoveredIndex] = useState(null); + + return ( +
+
+ +
+

{from.name}

+
+

To:

+
+ {to.map((email, index) => ( +
setHoveredIndex(index)} + onMouseLeave={() => setHoveredIndex(null)} + > +

{email.name.split(' ')[0]}

+ {hoveredIndex === index && ( +
+ +
+ )} +
+ ))} +
+
+
+

Cc:

+
+ {cc?.map((email, index) => ( +
setHoveredIndex(index + to.length)} + onMouseLeave={() => setHoveredIndex(null)} + > +

{email.name.split(' ')[0]}

+ {hoveredIndex === index + to.length && ( +
+ +
+ )} +
+ ))} +
+
+
+
+
+

{formatTimestamp(timestamp as string)}

+
+
+ ); +}; From a63230cecc670191a5c0e7a27df164114d62bd5b Mon Sep 17 00:00:00 2001 From: Rafa Date: Tue, 6 Feb 2024 16:54:00 +0100 Subject: [PATCH 08/37] feat: Message Inbox for Preview component --- .../mail/preview/components/MessageInbox.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/components/mail/preview/components/MessageInbox.tsx diff --git a/src/components/mail/preview/components/MessageInbox.tsx b/src/components/mail/preview/components/MessageInbox.tsx new file mode 100644 index 0000000..d7b32d2 --- /dev/null +++ b/src/components/mail/preview/components/MessageInbox.tsx @@ -0,0 +1,10 @@ +import { EmailProps } from '../../mocks'; + +export const MessageInbox = ({ subject, body }: Pick) => { + return ( +
+

{subject}

+

{body}

+
+ ); +}; From eb6ee86fbace9c7e4910affd997223929b99d6fa Mon Sep 17 00:00:00 2001 From: Rafa Date: Sat, 17 Feb 2024 16:47:00 +0100 Subject: [PATCH 09/37] feat: Inbox preview component --- src/components/mail/preview/Preview.tsx | 22 +++++++++++++ .../mail/preview/Preview.stories.tsx | 33 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/components/mail/preview/Preview.tsx create mode 100644 src/stories/components/mail/preview/Preview.stories.tsx diff --git a/src/components/mail/preview/Preview.tsx b/src/components/mail/preview/Preview.tsx new file mode 100644 index 0000000..32c5c95 --- /dev/null +++ b/src/components/mail/preview/Preview.tsx @@ -0,0 +1,22 @@ +import { EmailProps } from '../mocks'; +import { ActionBar } from './components/ActionBar'; +import { Header } from './components/Header'; +import { MessageInbox } from './components/MessageInbox'; + +interface PreviewProps { + email: EmailProps; +} + +export const Preview = ({ email }: PreviewProps) => { + const { from, to, cc, timestamp, body, subject } = email; + return ( +
+
+ +
+
+
+ +
+ ); +}; diff --git a/src/stories/components/mail/preview/Preview.stories.tsx b/src/stories/components/mail/preview/Preview.stories.tsx new file mode 100644 index 0000000..a29ce80 --- /dev/null +++ b/src/stories/components/mail/preview/Preview.stories.tsx @@ -0,0 +1,33 @@ +import type { Decorator, Meta, StoryObj } from '@storybook/react'; +import { Preview } from '../../../../components/mail/preview/Preview'; +import { emailMocks } from '../../../../components/mail/mocks'; + +const overlay: Decorator = (Story) => ( +
+ +
+); + +const meta: Meta = { + title: 'Components(Email)/Preview', + component: Preview, + parameters: { + layout: 'fullscreen', + }, + decorators: [overlay], + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + email: emailMocks.emailsWithMultipleRecipients[0], + }, + render: (args) => ( +
+ +
+ ), +}; From 83b989fcb107df6a6e57425e6d158f0a32e8a53f Mon Sep 17 00:00:00 2001 From: Rafa Date: Tue, 5 Mar 2024 11:30:00 +0100 Subject: [PATCH 10/37] feat: UserCheap component --- src/components/mail/userCheap/UserCheap.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/components/mail/userCheap/UserCheap.tsx diff --git a/src/components/mail/userCheap/UserCheap.tsx b/src/components/mail/userCheap/UserCheap.tsx new file mode 100644 index 0000000..98240a8 --- /dev/null +++ b/src/components/mail/userCheap/UserCheap.tsx @@ -0,0 +1,14 @@ +import { Avatar } from '../../avatar/Avatar'; +import { EmailProps } from '../mocks'; + +export const UserCheap = ({ to }: Pick) => { + return ( +
+ +
+

{to[0].name}

+

{to[0].email}

+
+
+ ); +}; From 531b631e8239628c1ac49b1f4f51747021f4c43b Mon Sep 17 00:00:00 2001 From: Rafa Date: Sun, 10 Mar 2024 14:30:00 +0100 Subject: [PATCH 11/37] feat: Tray story component --- .../components/mail/tray/Tray.stories.tsx | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/stories/components/mail/tray/Tray.stories.tsx diff --git a/src/stories/components/mail/tray/Tray.stories.tsx b/src/stories/components/mail/tray/Tray.stories.tsx new file mode 100644 index 0000000..eb34162 --- /dev/null +++ b/src/stories/components/mail/tray/Tray.stories.tsx @@ -0,0 +1,69 @@ +import { useState } from 'react'; +import type { Decorator, Meta, StoryObj } from '@storybook/react'; +import { Tray } from '../../../../components/mail/tray/Tray'; +import { emailMocks } from '../../../../components/mail/mocks'; + +const overlay: Decorator = (Story) => ( +
+ +
+); + +const meta: Meta = { + title: 'Components(Email)/Tray', + component: Tray, + parameters: { + layout: 'fullscreen', + }, + decorators: [overlay], + tags: ['autodocs'], +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + render: () => { + const [checked, setChecked] = useState(false); + const [selectedEmails, setSelectedEmails] = useState([]); + const [activeEmail, setActiveEmail] = useState(''); + + const handleSelectAll = () => { + if (checked) { + // Unselect all emails + setSelectedEmails([]); + } else { + // Select all emails + setSelectedEmails(emailMocks.emailsWithMultipleRecipients.map((email) => email.id)); + } + setChecked(!checked); + }; + + const handleMailSelected = (id: string) => { + if (selectedEmails.includes(id)) { + // Deselect the email + setSelectedEmails(selectedEmails.filter((emailId) => emailId !== id)); + } else { + // Select the email + setSelectedEmails([...selectedEmails, id]); + } + }; + + return ( +
+ { + setActiveEmail(id); + handleMailSelected(id); + }} + /> +
+ ); + }, +}; From f8cd511e4bb4a18d245b6729a45f1eb315cf86b8 Mon Sep 17 00:00:00 2001 From: Rafa Date: Mon, 18 Mar 2024 15:25:00 +0100 Subject: [PATCH 12/37] feat: mail view component --- src/components/mail/mailView/MailView.tsx | 46 +++++++++++++++++++ .../mail/inboxView/InboxView.stories.tsx | 33 +++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/components/mail/mailView/MailView.tsx create mode 100644 src/stories/components/mail/inboxView/InboxView.stories.tsx diff --git a/src/components/mail/mailView/MailView.tsx b/src/components/mail/mailView/MailView.tsx new file mode 100644 index 0000000..f8d5e2b --- /dev/null +++ b/src/components/mail/mailView/MailView.tsx @@ -0,0 +1,46 @@ +import { useState } from 'react'; +import { emailMocks, EmailProps, updateEmailReadStatus } from '../mocks'; +import { Preview } from '../preview/Preview'; +import { Sidenav } from '../sidenav/Sidenav'; +import { Tray } from '../tray/Tray'; + +export const MailView = () => { + const mails = emailMocks.emailsWithMultipleRecipients; + const [mailSelected, setMailSelected] = useState(); + const [checked, setChecked] = useState(false); + const [activeEmail, setActiveEmail] = useState(); + const [selectedEmails, setSelectedEmails] = useState([]); + + const handleOnMessageClicked = (id: string) => { + const selectedMail = mails.filter((mail) => id === mail.id)[0]; + updateEmailReadStatus(emailMocks, id, false); + setMailSelected(selectedMail); + setActiveEmail(id); + setSelectedEmails([id]); + }; + + const handleSelectAll = () => { + if (checked) { + setSelectedEmails([]); + } else { + const allEmailIds = emailMocks.basicEmails.map((email) => email.id); + setSelectedEmails(allEmailIds); + } + setChecked(!checked); + }; + + return ( +
+ + + {mailSelected && } +
+ ); +}; diff --git a/src/stories/components/mail/inboxView/InboxView.stories.tsx b/src/stories/components/mail/inboxView/InboxView.stories.tsx new file mode 100644 index 0000000..d19f8ee --- /dev/null +++ b/src/stories/components/mail/inboxView/InboxView.stories.tsx @@ -0,0 +1,33 @@ +import type { Decorator, Meta, StoryObj } from '@storybook/react'; +import { emailMocks } from '../../../../components/mail/mocks'; +import { MailView } from '../../../../components/mail/mailView/MailView'; + +const overlay: Decorator = (Story) => ( +
+ +
+); + +const meta: Meta = { + title: 'Components(Email)/MailView', + component: MailView, + parameters: { + layout: 'fullscreen', + }, + decorators: [overlay], + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + email: emailMocks.emailsWithMultipleRecipients[0], + }, + render: (args) => ( +
+ +
+ ), +}; From 15d0053eb06dc7e0cd60b6665c74c7b14b3ffefa Mon Sep 17 00:00:00 2001 From: Rafa Date: Thu, 4 Apr 2024 13:25:00 +0200 Subject: [PATCH 13/37] feat: Message skeleton --- .../mail/tray/components/MessageSkeleton.tsx | 28 ++++++++++++++++ .../MessageSkeleton.stories.tsx | 33 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/components/mail/tray/components/MessageSkeleton.tsx create mode 100644 src/stories/components/mail/messageSkeleton/MessageSkeleton.stories.tsx diff --git a/src/components/mail/tray/components/MessageSkeleton.tsx b/src/components/mail/tray/components/MessageSkeleton.tsx new file mode 100644 index 0000000..1d5992e --- /dev/null +++ b/src/components/mail/tray/components/MessageSkeleton.tsx @@ -0,0 +1,28 @@ +import { EmailProps } from '../../mocks'; + +interface MessageSkeletonProps { + email: Pick; + onClick: (id: string) => void; + active?: boolean; +} + +export const MessageSkeleton = ({ email, active, onClick }: MessageSkeletonProps) => { + return ( + + ); +}; diff --git a/src/stories/components/mail/messageSkeleton/MessageSkeleton.stories.tsx b/src/stories/components/mail/messageSkeleton/MessageSkeleton.stories.tsx new file mode 100644 index 0000000..9dc03df --- /dev/null +++ b/src/stories/components/mail/messageSkeleton/MessageSkeleton.stories.tsx @@ -0,0 +1,33 @@ +import type { Decorator, Meta, StoryObj } from '@storybook/react'; +import { emailMocks } from '../../../../components/mail/mocks'; +import { MessageSkeleton } from '../../../../components/mail/tray/components/MessageSkeleton'; + +const overlay: Decorator = (Story) => ( +
+ +
+); + +const meta: Meta = { + title: 'Components(Email)/MessageSkeleton', + component: MessageSkeleton, + parameters: { + layout: 'fullscreen', + }, + decorators: [overlay], + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + email: emailMocks.emailsWithMultipleRecipients[0], + }, + render: (args) => ( +
+ +
+ ), +}; From 222da8d0a5499c1e67e1699e797edc327e1cf38a Mon Sep 17 00:00:00 2001 From: Rafa Date: Sat, 13 Apr 2024 09:13:00 +0200 Subject: [PATCH 14/37] feat: update MessageSkeleton style --- .../mail/tray/components/MessageSkeleton.tsx | 39 +++++++------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/components/mail/tray/components/MessageSkeleton.tsx b/src/components/mail/tray/components/MessageSkeleton.tsx index 1d5992e..9cfdbda 100644 --- a/src/components/mail/tray/components/MessageSkeleton.tsx +++ b/src/components/mail/tray/components/MessageSkeleton.tsx @@ -1,28 +1,15 @@ -import { EmailProps } from '../../mocks'; - -interface MessageSkeletonProps { - email: Pick; - onClick: (id: string) => void; - active?: boolean; -} - -export const MessageSkeleton = ({ email, active, onClick }: MessageSkeletonProps) => { - return ( - - ); -}; +
+ +); From f01e1a156ac20ab9feda4d71897bfbff68f9dec6 Mon Sep 17 00:00:00 2001 From: Rafa Date: Sat, 13 Apr 2024 11:43:00 +0200 Subject: [PATCH 15/37] feat: use MessageSkeleton in Tray component --- src/components/mail/tray/Tray.tsx | 42 ++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/components/mail/tray/Tray.tsx b/src/components/mail/tray/Tray.tsx index 7346407..e5b0933 100644 --- a/src/components/mail/tray/Tray.tsx +++ b/src/components/mail/tray/Tray.tsx @@ -3,17 +3,27 @@ import Checkbox from '../../checkbox/Checkbox'; import Input from '../../input/Input'; import { Message } from './components/Message'; import { emailMocks, EmailProps } from '../mocks'; +import { MessageSkeleton } from './components/MessageSkeleton'; interface TrayProps { mails: EmailProps[]; selectedEmails: string[]; + loading: boolean; checked: boolean; activeEmail: string; handleSelectAll: () => void; onMailSelected: (id: string) => void; } -export const Tray = ({ mails, handleSelectAll, checked, selectedEmails, activeEmail, onMailSelected }: TrayProps) => { +export const Tray = ({ + mails, + loading, + checked, + selectedEmails, + activeEmail, + handleSelectAll, + onMailSelected, +}: TrayProps) => { return (
@@ -38,14 +48,28 @@ export const Tray = ({ mails, handleSelectAll, checked, selectedEmails, activeEm
- {mails.map((email) => ( -
- -
-
-
-
- ))} + {loading ? ( + <> + {Array(8) + .fill(0) + .map((_, index) => ( +
+ +
+ ))} + + ) : ( + <> + {mails.map((email) => ( +
+ +
+
+
+
+ ))} + + )}
); From 937bf13b1e06617cb0d65605bf5a5fee4a72453e Mon Sep 17 00:00:00 2001 From: Rafa Date: Tue, 23 Apr 2024 15:43:00 +0200 Subject: [PATCH 16/37] feat: add timeout in MailView to mock the API call --- src/components/mail/mailView/MailView.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/mail/mailView/MailView.tsx b/src/components/mail/mailView/MailView.tsx index f8d5e2b..0fb3b64 100644 --- a/src/components/mail/mailView/MailView.tsx +++ b/src/components/mail/mailView/MailView.tsx @@ -1,16 +1,26 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { emailMocks, EmailProps, updateEmailReadStatus } from '../mocks'; import { Preview } from '../preview/Preview'; import { Sidenav } from '../sidenav/Sidenav'; import { Tray } from '../tray/Tray'; export const MailView = () => { - const mails = emailMocks.emailsWithMultipleRecipients; + const mockedMails = emailMocks.emailsWithMultipleRecipients; + const [mails, setMails] = useState([]); + const [isFetchingMails, setIsFetchingMails] = useState(false); const [mailSelected, setMailSelected] = useState(); const [checked, setChecked] = useState(false); const [activeEmail, setActiveEmail] = useState(); const [selectedEmails, setSelectedEmails] = useState([]); + useEffect(() => { + setIsFetchingMails(true); + setTimeout(() => { + setMails(mockedMails); + setIsFetchingMails(false); + }, 1500); + }, []); + const handleOnMessageClicked = (id: string) => { const selectedMail = mails.filter((mail) => id === mail.id)[0]; updateEmailReadStatus(emailMocks, id, false); @@ -35,6 +45,7 @@ export const MailView = () => { Date: Sun, 12 May 2024 11:21:00 +0200 Subject: [PATCH 17/37] feat: UserCheap story --- .../mail/userCheap/UserCheap.stories.tsx | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/stories/components/mail/userCheap/UserCheap.stories.tsx diff --git a/src/stories/components/mail/userCheap/UserCheap.stories.tsx b/src/stories/components/mail/userCheap/UserCheap.stories.tsx new file mode 100644 index 0000000..d308255 --- /dev/null +++ b/src/stories/components/mail/userCheap/UserCheap.stories.tsx @@ -0,0 +1,33 @@ +import type { Decorator, Meta, StoryObj } from '@storybook/react'; +import { emailMocks } from '../../../../components/mail/mocks'; +import { UserCheap } from '../../../../components/mail/userCheap/UserCheap'; + +const overlay: Decorator = (Story) => ( +
+ +
+); + +const meta: Meta = { + title: 'Components(Email)/UserCheap', + component: UserCheap, + parameters: { + layout: 'fullscreen', + }, + decorators: [overlay], + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + to: emailMocks.emailsWithMultipleRecipients[0].to, + }, + render: (args) => ( +
+ +
+ ), +}; From 80ebe7f0f5b6e9d5ebda274140cbde2b7f227fdf Mon Sep 17 00:00:00 2001 From: Rafa Date: Wed, 15 May 2024 12:01:00 +0200 Subject: [PATCH 18/37] feat: updating UserCheap style --- src/components/mail/preview/components/Header.tsx | 4 ++-- src/components/mail/userCheap/UserCheap.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/mail/preview/components/Header.tsx b/src/components/mail/preview/components/Header.tsx index cc71532..bbf353e 100644 --- a/src/components/mail/preview/components/Header.tsx +++ b/src/components/mail/preview/components/Header.tsx @@ -24,7 +24,7 @@ export const Header = ({ from, to, cc, timestamp }: Pick

{email.name.split(' ')[0]}

{hoveredIndex === index && ( -
+
)} @@ -44,7 +44,7 @@ export const Header = ({ from, to, cc, timestamp }: Pick

{email.name.split(' ')[0]}

{hoveredIndex === index + to.length && ( -
+
)} diff --git a/src/components/mail/userCheap/UserCheap.tsx b/src/components/mail/userCheap/UserCheap.tsx index 98240a8..a813c46 100644 --- a/src/components/mail/userCheap/UserCheap.tsx +++ b/src/components/mail/userCheap/UserCheap.tsx @@ -3,7 +3,7 @@ import { EmailProps } from '../mocks'; export const UserCheap = ({ to }: Pick) => { return ( -
+

{to[0].name}

From 2b7ebef3bc41327a42f09fdc7d3c77961382a982 Mon Sep 17 00:00:00 2001 From: Rafa Date: Wed, 29 May 2024 17:01:00 +0200 Subject: [PATCH 19/37] feat:new messages state for Preview component --- src/assets/icons/mail/new-message.svg | 201 ++++++++++++++++++ .../preview/components/states/NewMessages.tsx | 19 ++ 2 files changed, 220 insertions(+) create mode 100644 src/assets/icons/mail/new-message.svg create mode 100644 src/components/mail/preview/components/states/NewMessages.tsx diff --git a/src/assets/icons/mail/new-message.svg b/src/assets/icons/mail/new-message.svg new file mode 100644 index 0000000..b415a02 --- /dev/null +++ b/src/assets/icons/mail/new-message.svg @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/mail/preview/components/states/NewMessages.tsx b/src/components/mail/preview/components/states/NewMessages.tsx new file mode 100644 index 0000000..440cf00 --- /dev/null +++ b/src/components/mail/preview/components/states/NewMessages.tsx @@ -0,0 +1,19 @@ +export const NewMessages = ({ newMessagesCount }: { newMessagesCount: number }) => { + return ( +
+
+ New messages icon +
+

{newMessagesCount}

+
+

Unread messages

+

Click any email to preview

+
+
+ ); +}; From 3bc832ae23c5edec3c5201ffa8710929ab9c1f1b Mon Sep 17 00:00:00 2001 From: Rafa Date: Mon, 3 Jun 2024 12:01:00 +0200 Subject: [PATCH 20/37] feat: managing new messages state --- src/components/mail/mailView/MailView.tsx | 2 +- src/components/mail/preview/Preview.tsx | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/components/mail/mailView/MailView.tsx b/src/components/mail/mailView/MailView.tsx index 0fb3b64..360432d 100644 --- a/src/components/mail/mailView/MailView.tsx +++ b/src/components/mail/mailView/MailView.tsx @@ -51,7 +51,7 @@ export const MailView = () => { selectedEmails={selectedEmails} onMailSelected={handleOnMessageClicked} /> - {mailSelected && } + mail.read).length} />
); }; diff --git a/src/components/mail/preview/Preview.tsx b/src/components/mail/preview/Preview.tsx index 32c5c95..be3307c 100644 --- a/src/components/mail/preview/Preview.tsx +++ b/src/components/mail/preview/Preview.tsx @@ -2,21 +2,30 @@ import { EmailProps } from '../mocks'; import { ActionBar } from './components/ActionBar'; import { Header } from './components/Header'; import { MessageInbox } from './components/MessageInbox'; +import { NewMessages } from './components/states/NewMessages'; interface PreviewProps { - email: EmailProps; + mailSelected?: EmailProps; + newMessagesCount?: number; } -export const Preview = ({ email }: PreviewProps) => { - const { from, to, cc, timestamp, body, subject } = email; +export const Preview = ({ mailSelected, newMessagesCount }: PreviewProps) => { return (
-
+ {mailSelected && ( +
+ )}
- + {!mailSelected && newMessagesCount && newMessagesCount > 0 && } + {mailSelected && }
); }; From 46b53a4a85c0530be3255a3ae7063874a95ed336 Mon Sep 17 00:00:00 2001 From: Rafa Date: Thu, 13 Jun 2024 09:22:00 +0200 Subject: [PATCH 21/37] feat:managing empty state for Preview component --- src/assets/icons/mail/no-messages.svg | 52 +++++++++++++++++++ src/components/mail/preview/Preview.tsx | 2 + .../preview/components/states/NoMessages.tsx | 16 ++++++ 3 files changed, 70 insertions(+) create mode 100644 src/assets/icons/mail/no-messages.svg create mode 100644 src/components/mail/preview/components/states/NoMessages.tsx diff --git a/src/assets/icons/mail/no-messages.svg b/src/assets/icons/mail/no-messages.svg new file mode 100644 index 0000000..f2cf5f0 --- /dev/null +++ b/src/assets/icons/mail/no-messages.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/components/mail/preview/Preview.tsx b/src/components/mail/preview/Preview.tsx index be3307c..1aa9adb 100644 --- a/src/components/mail/preview/Preview.tsx +++ b/src/components/mail/preview/Preview.tsx @@ -3,6 +3,7 @@ import { ActionBar } from './components/ActionBar'; import { Header } from './components/Header'; import { MessageInbox } from './components/MessageInbox'; import { NewMessages } from './components/states/NewMessages'; +import { EmptyMessages } from './components/states/NoMessages'; interface PreviewProps { mailSelected?: EmailProps; @@ -25,6 +26,7 @@ export const Preview = ({ mailSelected, newMessagesCount }: PreviewProps) => {
{!mailSelected && newMessagesCount && newMessagesCount > 0 && } + {!mailSelected && newMessagesCount && newMessagesCount === 0 && } {mailSelected && }
); diff --git a/src/components/mail/preview/components/states/NoMessages.tsx b/src/components/mail/preview/components/states/NoMessages.tsx new file mode 100644 index 0000000..6ce043d --- /dev/null +++ b/src/components/mail/preview/components/states/NoMessages.tsx @@ -0,0 +1,16 @@ +export const EmptyMessages = () => { + return ( +
+
+ New messages icon +

You’re all set!

+

There are no unread messages

+
+
+ ); +}; From 2de035045c84b8a75d27f383d37d2442ada4bf8a Mon Sep 17 00:00:00 2001 From: Rafa Date: Thu, 13 Jun 2024 10:02:00 +0200 Subject: [PATCH 22/37] feat:handle no new messages state --- .../mail/preview/components/states/NewMessages.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/mail/preview/components/states/NewMessages.tsx b/src/components/mail/preview/components/states/NewMessages.tsx index 440cf00..28ae620 100644 --- a/src/components/mail/preview/components/states/NewMessages.tsx +++ b/src/components/mail/preview/components/states/NewMessages.tsx @@ -1,4 +1,8 @@ -export const NewMessages = ({ newMessagesCount }: { newMessagesCount: number }) => { +interface NewMessagesProps { + newMessagesCount: number; +} + +export const NewMessages = ({ newMessagesCount }: NewMessagesProps) => { return (
From 771268590a4fc84ab4c3d80fe952a39adf3b2cb5 Mon Sep 17 00:00:00 2001 From: Rafa Date: Thu, 13 Jun 2024 10:13:00 +0200 Subject: [PATCH 23/37] styles: NewMessages component --- src/components/mail/preview/components/states/NewMessages.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/mail/preview/components/states/NewMessages.tsx b/src/components/mail/preview/components/states/NewMessages.tsx index 28ae620..55f6030 100644 --- a/src/components/mail/preview/components/states/NewMessages.tsx +++ b/src/components/mail/preview/components/states/NewMessages.tsx @@ -5,14 +5,14 @@ interface NewMessagesProps { export const NewMessages = ({ newMessagesCount }: NewMessagesProps) => { return (
-
+
New messages icon -
+

{newMessagesCount}

Unread messages

From 3a993f76c4649e84738ebb39fc58d979984a1b58 Mon Sep 17 00:00:00 2001 From: Rafa Date: Thu, 25 Jul 2024 11:25:00 +0200 Subject: [PATCH 24/37] WIP (new mail dialog) --- .../mail/newMailDialog/NewMailDialog.tsx | 82 +++++++++++++++++++ .../newMailDialog/components/ActionBar.tsx | 14 ++++ .../newMailDialog/NewMailDialog.stories.tsx | 32 ++++++++ 3 files changed, 128 insertions(+) create mode 100644 src/components/mail/newMailDialog/NewMailDialog.tsx create mode 100644 src/components/mail/newMailDialog/components/ActionBar.tsx create mode 100644 src/stories/components/mail/newMailDialog/NewMailDialog.stories.tsx diff --git a/src/components/mail/newMailDialog/NewMailDialog.tsx b/src/components/mail/newMailDialog/NewMailDialog.tsx new file mode 100644 index 0000000..c2613e3 --- /dev/null +++ b/src/components/mail/newMailDialog/NewMailDialog.tsx @@ -0,0 +1,82 @@ +import { Paperclip, X } from '@phosphor-icons/react'; +import { Button } from '../../button/Button'; +import Input from '../../input/Input'; + +interface NewMailDialogProps { + isOpen: boolean; + onClose: () => void; + title: string; + subtitle: string; + onPrimaryAction: () => void; + onSecondaryAction: () => void; + isLoading: boolean; + primaryActionColor?: string; +} + +export const NewMailDialog = ({ + isOpen, + title, + isLoading, + primaryActionColor = 'primary', + onClose, + onPrimaryAction, + onSecondaryAction, +}: NewMailDialogProps) => { + return ( +
+
+ +
+
+
+

{title}

+ +
+
+

To

+ +
+
+

Subject

+ +
+
+
+ +
+ + +
+
+
+ ); +}; diff --git a/src/components/mail/newMailDialog/components/ActionBar.tsx b/src/components/mail/newMailDialog/components/ActionBar.tsx new file mode 100644 index 0000000..0702976 --- /dev/null +++ b/src/components/mail/newMailDialog/components/ActionBar.tsx @@ -0,0 +1,14 @@ +import { PaintBucket } from '@phosphor-icons/react'; + +export const ActionBar = () => { + return ( +
+

Arial

+

14px

+
+ +
+
+
+ ); +}; diff --git a/src/stories/components/mail/newMailDialog/NewMailDialog.stories.tsx b/src/stories/components/mail/newMailDialog/NewMailDialog.stories.tsx new file mode 100644 index 0000000..3ce83eb --- /dev/null +++ b/src/stories/components/mail/newMailDialog/NewMailDialog.stories.tsx @@ -0,0 +1,32 @@ +import type { Decorator, Meta, StoryObj } from '@storybook/react'; +import { NewMailDialog } from '../../../../components/mail/newMailDialog/NewMailDialog'; + +const overlay: Decorator = (Story) => ( +
+ +
+); + +const meta: Meta = { + title: 'Components(Email)/NewMailDialog', + component: NewMailDialog, + parameters: { + layout: 'fullscreen', + }, + decorators: [overlay], + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + title: 'New message', + }, + render: (args) => ( +
+ +
+ ), +}; From 26e93d15bcbd722937a076a76444ae1dc8612711 Mon Sep 17 00:00:00 2001 From: Rafa Date: Sat, 3 Aug 2024 16:28:00 +0200 Subject: [PATCH 25/37] WIP (new mail dialog) --- .../mail/newMailDialog/NewMailDialog.tsx | 5 +- .../newMailDialog/components/ActionBar.tsx | 87 +++++++++++++++++-- src/components/textArea/TextArea.tsx | 5 +- 3 files changed, 88 insertions(+), 9 deletions(-) diff --git a/src/components/mail/newMailDialog/NewMailDialog.tsx b/src/components/mail/newMailDialog/NewMailDialog.tsx index c2613e3..7e4fe3d 100644 --- a/src/components/mail/newMailDialog/NewMailDialog.tsx +++ b/src/components/mail/newMailDialog/NewMailDialog.tsx @@ -1,6 +1,8 @@ import { Paperclip, X } from '@phosphor-icons/react'; import { Button } from '../../button/Button'; import Input from '../../input/Input'; +import { ActionBar } from './components/ActionBar'; +import TextArea from '../../textArea/TextArea'; interface NewMailDialogProps { isOpen: boolean; @@ -62,8 +64,9 @@ export const NewMailDialog = ({
+
- +