diff --git a/packages/twenty-front/src/modules/accounts/types/BlockedEmail.ts b/packages/twenty-front/src/modules/accounts/types/BlockedEmail.ts
new file mode 100644
index 000000000..65958c0bf
--- /dev/null
+++ b/packages/twenty-front/src/modules/accounts/types/BlockedEmail.ts
@@ -0,0 +1,5 @@
+export type BlockedEmail = {
+ id: string;
+ email: string;
+ blocked_at: string;
+};
diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistInput.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistInput.tsx
new file mode 100644
index 000000000..bfc8ca7cb
--- /dev/null
+++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistInput.tsx
@@ -0,0 +1,54 @@
+import { useState } from 'react';
+import styled from '@emotion/styled';
+
+import { Button } from '@/ui/input/button/components/Button';
+import { TextInput } from '@/ui/input/components/TextInput';
+
+const StyledContainer = styled.div`
+ display: flex;
+ flex-direction: row;
+ margin-bottom: 16px;
+`;
+
+const StyledLinkContainer = styled.div`
+ flex: 1;
+ margin-right: ${({ theme }) => theme.spacing(2)};
+`;
+
+type SettingsAccountsEmailsBlocklistInputProps = {
+ updateBlockedEmailList: (email: string) => void;
+};
+
+export const SettingsAccountsEmailsBlocklistInput = ({
+ updateBlockedEmailList,
+}: SettingsAccountsEmailsBlocklistInputProps) => {
+ const [formValues, setFormValues] = useState<{
+ email: string;
+ }>({
+ email: '',
+ });
+ return (
+
+
+ {
+ setFormValues((prevState) => ({
+ ...prevState,
+ email: value,
+ }));
+ }}
+ fullWidth
+ />
+
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistSection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistSection.tsx
new file mode 100644
index 000000000..53272743e
--- /dev/null
+++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistSection.tsx
@@ -0,0 +1,45 @@
+import { useState } from 'react';
+import { v4 } from 'uuid';
+
+import { SettingsAccountsEmailsBlocklistInput } from '@/settings/accounts/components/SettingsAccountsEmailsBlocklistInput';
+import { SettingsAccountsEmailsBlocklistTable } from '@/settings/accounts/components/SettingsAccountsEmailsBlocklistTable';
+import { H2Title } from '@/ui/display/typography/components/H2Title';
+import { Section } from '@/ui/layout/section/components/Section';
+import { mockedBlockedEmailList } from '~/testing/mock-data/accounts';
+import { formatDate } from '~/utils/date-utils';
+
+export const SettingsAccountsEmailsBlocklistSection = () => {
+ const [blockedEmailList, setBlockedEmailList] = useState(
+ mockedBlockedEmailList,
+ );
+
+ const handleBlockedEmailRemove = (id: string) =>
+ setBlockedEmailList((previousBlockedEmailList) =>
+ previousBlockedEmailList.filter((blockedEmail) => blockedEmail.id !== id),
+ );
+
+ const updateBlockedEmailList = (email: string) =>
+ setBlockedEmailList((prevState) => [
+ ...prevState,
+ {
+ id: v4(),
+ email: email,
+ blocked_at: formatDate(new Date(), 'dd/LL/yyyy'),
+ },
+ ]);
+ return (
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistTable.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistTable.tsx
new file mode 100644
index 000000000..0278fa55f
--- /dev/null
+++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistTable.tsx
@@ -0,0 +1,40 @@
+import styled from '@emotion/styled';
+
+import { BlockedEmail } from '@/accounts/types/BlockedEmail';
+import { SettingsAccountsEmailsBlocklistTableRow } from '@/settings/accounts/components/SettingsAccountsEmailsBlocklistTableRow';
+import { Table } from '@/ui/layout/table/components/Table';
+import { TableBody } from '@/ui/layout/table/components/TableBody';
+import { TableHeader } from '@/ui/layout/table/components/TableHeader';
+import { TableRow } from '@/ui/layout/table/components/TableRow';
+
+type SettingsAccountsEmailsBlocklistTableProps = {
+ blockedEmailList: BlockedEmail[];
+ handleBlockedEmailRemove: (id: string) => void;
+};
+const StyledTableBody = styled(TableBody)`
+ border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
+`;
+
+export const SettingsAccountsEmailsBlocklistTable = ({
+ blockedEmailList,
+ handleBlockedEmailRemove,
+}: SettingsAccountsEmailsBlocklistTableProps) => {
+ return (
+
+
+ Email/Domain
+ Added to blocklist
+
+
+
+ {blockedEmailList.map((blockedEmail) => (
+
+ ))}
+
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistTableRow.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistTableRow.tsx
new file mode 100644
index 000000000..dac56fa65
--- /dev/null
+++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsBlocklistTableRow.tsx
@@ -0,0 +1,32 @@
+import { BlockedEmail } from '@/accounts/types/BlockedEmail';
+import { IconX } from '@/ui/display/icon';
+import { IconButton } from '@/ui/input/button/components/IconButton';
+import { TableCell } from '@/ui/layout/table/components/TableCell';
+import { TableRow } from '@/ui/layout/table/components/TableRow';
+
+type SettingsAccountsEmailsBlocklistTableRowProps = {
+ blockedEmail: BlockedEmail;
+ onRemove: (id: string) => void;
+};
+
+export const SettingsAccountsEmailsBlocklistTableRow = ({
+ blockedEmail,
+ onRemove,
+}: SettingsAccountsEmailsBlocklistTableRowProps) => {
+ return (
+
+ {blockedEmail.email}
+ {blockedEmail.blocked_at}
+
+ {
+ onRemove(blockedEmail.id);
+ }}
+ variant="tertiary"
+ size="small"
+ Icon={IconX}
+ />
+
+
+ );
+};
diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmails.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmails.tsx
index f46dc331e..507f9c39d 100644
--- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmails.tsx
+++ b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmails.tsx
@@ -1,3 +1,4 @@
+import { SettingsAccountsEmailsBlocklistSection } from '@/settings/accounts/components/SettingsAccountsEmailsBlocklistSection';
import { SettingsAccountsEmailsSyncSection } from '@/settings/accounts/components/SettingsAccountsEmailsSyncSection';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { IconSettings } from '@/ui/display/icon';
@@ -14,6 +15,7 @@ export const SettingsAccountsEmails = () => (
]}
/>
+
);
diff --git a/packages/twenty-front/src/testing/mock-data/accounts.ts b/packages/twenty-front/src/testing/mock-data/accounts.ts
index aa6c7de18..87a816f24 100644
--- a/packages/twenty-front/src/testing/mock-data/accounts.ts
+++ b/packages/twenty-front/src/testing/mock-data/accounts.ts
@@ -1,4 +1,5 @@
import { Account } from '@/accounts/types/Account';
+import { BlockedEmail } from '@/accounts/types/BlockedEmail';
import { InboxSettingsVisibilityValue } from '@/settings/accounts/components/SettingsAccountsInboxSettingsVisibilitySection';
export const mockedAccounts: Account[] = [
@@ -15,3 +16,21 @@ export const mockedAccounts: Account[] = [
visibility: InboxSettingsVisibilityValue.Metadata,
},
];
+
+export const mockedBlockedEmailList: BlockedEmail[] = [
+ {
+ email: 'thomas@twenty.com',
+ id: '9594b782-232e-48c3-977e-b0f57f90de24',
+ blocked_at: '12/06/2023',
+ },
+ {
+ email: 'tim@apple.com',
+ id: 'ac64a7ec-76b2-325b-a8e8-28ff0396c3aa',
+ blocked_at: '11/06/2023',
+ },
+ {
+ email: '@microsoft.com',
+ id: 'ac6445ec-76b2-325b-58e8-28340396c3ff',
+ blocked_at: '04/06/2023',
+ },
+];
diff --git a/packages/twenty-front/src/utils/date-utils.ts b/packages/twenty-front/src/utils/date-utils.ts
index 57fbf67a9..acdaedc73 100644
--- a/packages/twenty-front/src/utils/date-utils.ts
+++ b/packages/twenty-front/src/utils/date-utils.ts
@@ -33,7 +33,10 @@ export const parseDate = (dateToParse: Date | string | number) => {
const isSameDay = (a: DateTime, b: DateTime): boolean =>
a.hasSame(b, 'day') && a.hasSame(b, 'month') && a.hasSame(b, 'year');
-const formatDate = (dateToFormat: Date | string | number, format: string) => {
+export const formatDate = (
+ dateToFormat: Date | string | number,
+ format: string,
+) => {
try {
const parsedDate = parseDate(dateToFormat);
return parsedDate.toFormat(format);