diff --git a/front/src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx b/front/src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
new file mode 100644
index 000000000..3c5337e65
--- /dev/null
+++ b/front/src/modules/settings/accounts/components/SettingsAccountsSettingsSection.tsx
@@ -0,0 +1,43 @@
+import { useNavigate } from 'react-router-dom';
+import styled from '@emotion/styled';
+
+import { SettingsNavigationCard } from '@/settings/components/SettingsNavigationCard';
+import { IconCalendarEvent, IconMailCog } from '@/ui/display/icon';
+import { H2Title } from '@/ui/display/typography/components/H2Title';
+import { Section } from '@/ui/layout/section/components/Section';
+
+const StyledCardsContainer = styled.div`
+ display: flex;
+ gap: ${({ theme }) => theme.spacing(4)};
+ margin-top: ${({ theme }) => theme.spacing(6)};
+`;
+
+export const SettingsAccountsSettingsSection = () => {
+ const navigate = useNavigate();
+
+ return (
+
+
+
+ navigate('/settings/accounts/emails')}
+ >
+ Set email visibility, manage your blocklist and more.
+
+
+ Configure and customize your calendar preferences.
+
+
+
+ );
+};
diff --git a/front/src/modules/settings/components/SettingsNavigationCard.tsx b/front/src/modules/settings/components/SettingsNavigationCard.tsx
new file mode 100644
index 000000000..0ec1dcf9b
--- /dev/null
+++ b/front/src/modules/settings/components/SettingsNavigationCard.tsx
@@ -0,0 +1,79 @@
+import { ReactNode } from 'react';
+import { useTheme } from '@emotion/react';
+import styled from '@emotion/styled';
+
+import { IconChevronRight } from '@/ui/display/icon';
+import { IconComponent } from '@/ui/display/icon/types/IconComponent';
+import { SoonPill } from '@/ui/display/pill/components/SoonPill';
+import { Card } from '@/ui/layout/card/components/Card';
+
+type SettingsNavigationCardProps = {
+ children: ReactNode;
+ disabled?: boolean;
+ hasSoonPill?: boolean;
+ Icon: IconComponent;
+ onClick?: () => void;
+ title: string;
+};
+
+const StyledCard = styled(Card)<{
+ disabled?: boolean;
+ onClick?: () => void;
+}>`
+ color: ${({ theme }) => theme.font.color.tertiary};
+ cursor: ${({ disabled, onClick }) =>
+ disabled ? 'not-allowed' : onClick ? 'pointer' : 'default'};
+ display: flex;
+ flex-direction: column;
+ gap: ${({ theme }) => theme.spacing(2)};
+ padding-bottom: ${({ theme }) => theme.spacing(4)};
+ padding-top: ${({ theme }) => theme.spacing(4)};
+`;
+
+const StyledHeader = styled.div`
+ align-items: center;
+ display: flex;
+ gap: ${({ theme }) => theme.spacing(3)};
+`;
+
+const StyledTitle = styled.div`
+ color: ${({ theme }) => theme.font.color.secondary};
+ display: flex;
+ flex: 1 0 auto;
+ font-weight: ${({ theme }) => theme.font.weight.medium};
+ gap: ${({ theme }) => theme.spacing(2)};
+ justify-content: flex-start;
+`;
+
+const StyledIconChevronRight = styled(IconChevronRight)`
+ color: ${({ theme }) => theme.font.color.light};
+`;
+
+const StyledDescription = styled.div`
+ padding-left: ${({ theme }) => theme.spacing(8)};
+`;
+
+export const SettingsNavigationCard = ({
+ children,
+ disabled,
+ hasSoonPill,
+ Icon,
+ onClick,
+ title,
+}: SettingsNavigationCardProps) => {
+ const theme = useTheme();
+
+ return (
+
+
+
+
+ {title}
+ {hasSoonPill && }
+
+
+
+ {children}
+
+ );
+};
diff --git a/front/src/modules/settings/data-model/components/SettingsObjectFieldTypeCard.tsx b/front/src/modules/settings/data-model/components/SettingsObjectFieldTypeCard.tsx
index c70d26b87..8bfeba2de 100644
--- a/front/src/modules/settings/data-model/components/SettingsObjectFieldTypeCard.tsx
+++ b/front/src/modules/settings/data-model/components/SettingsObjectFieldTypeCard.tsx
@@ -1,16 +1,16 @@
import { ReactNode } from 'react';
import styled from '@emotion/styled';
+import { Card } from '@/ui/layout/card/components/Card';
+
type SettingsObjectFieldTypeCardProps = {
className?: string;
preview: ReactNode;
form?: ReactNode;
};
-const StyledPreviewContainer = styled.div`
+const StyledPreviewContainer = styled(Card)`
background-color: ${({ theme }) => theme.background.transparent.lighter};
- border: 1px solid ${({ theme }) => theme.border.color.medium};
- border-radius: ${({ theme }) => theme.border.radius.sm};
padding: ${({ theme }) => theme.spacing(4)};
&:not(:last-child) {
@@ -32,14 +32,12 @@ const StyledPreviewContent = styled.div`
gap: 6px;
`;
-const StyledFormContainer = styled.div`
- background-color: ${({ theme }) => theme.background.secondary};
- border: 1px solid ${({ theme }) => theme.border.color.medium};
- border-radius: ${({ theme }) => theme.border.radius.sm};
+const StyledFormContainer = styled(Card)`
border-top: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
overflow: hidden;
+ padding: 0;
`;
export const SettingsObjectFieldTypeCard = ({
diff --git a/front/src/modules/settings/data-model/new-object/components/SettingsObjectTypeCard.tsx b/front/src/modules/settings/data-model/new-object/components/SettingsObjectTypeCard.tsx
index c2ddf18c7..e31e8b48f 100644
--- a/front/src/modules/settings/data-model/new-object/components/SettingsObjectTypeCard.tsx
+++ b/front/src/modules/settings/data-model/new-object/components/SettingsObjectTypeCard.tsx
@@ -37,6 +37,10 @@ const StyledIconCheck = styled(IconCheck)`
margin-left: auto;
`;
+const StyledSoonPill = styled(SoonPill)`
+ margin-left: auto;
+`;
+
type SettingsObjectTypeCardProps = {
prefixIcon?: React.ReactNode;
title: string;
@@ -68,7 +72,7 @@ export const SettingsObjectTypeCard = ({
>
{prefixIcon}
- {soon && }
+ {soon && }
{!disabled && selected && }
);
diff --git a/front/src/modules/settings/data-model/object-details/components/SettingsObjectAboutSection.tsx b/front/src/modules/settings/data-model/object-details/components/SettingsObjectAboutSection.tsx
index 3e29adb18..6275782fb 100644
--- a/front/src/modules/settings/data-model/object-details/components/SettingsObjectAboutSection.tsx
+++ b/front/src/modules/settings/data-model/object-details/components/SettingsObjectAboutSection.tsx
@@ -6,6 +6,7 @@ import { Tag } from '@/ui/display/tag/components/Tag';
import { H2Title } from '@/ui/display/typography/components/H2Title';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
+import { Card } from '@/ui/layout/card/components/Card';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
@@ -22,11 +23,8 @@ type SettingsAboutSectionProps = {
onEdit: () => void;
};
-const StyledCard = styled.div`
+const StyledCard = styled(Card)`
align-items: center;
- background-color: ${({ theme }) => theme.background.secondary};
- border: ${({ theme }) => `1px solid ${theme.border.color.medium}`};
- border-radius: ${({ theme }) => theme.border.radius.sm};
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(2)};
diff --git a/front/src/modules/ui/display/icon/index.ts b/front/src/modules/ui/display/icon/index.ts
index 226df9746..09482ee94 100644
--- a/front/src/modules/ui/display/icon/index.ts
+++ b/front/src/modules/ui/display/icon/index.ts
@@ -60,6 +60,7 @@ export {
IconList,
IconLogout,
IconMail,
+ IconMailCog,
IconMap,
IconMinus,
IconMoneybag,
diff --git a/front/src/modules/ui/display/pill/components/SoonPill.tsx b/front/src/modules/ui/display/pill/components/SoonPill.tsx
index 2a6b43408..8e1393436 100644
--- a/front/src/modules/ui/display/pill/components/SoonPill.tsx
+++ b/front/src/modules/ui/display/pill/components/SoonPill.tsx
@@ -1,5 +1,9 @@
import styled from '@emotion/styled';
+type SoonPillProps = {
+ className?: string;
+};
+
const StyledSoonPill = styled.span`
align-items: center;
background: ${({ theme }) => theme.background.transparent.light};
@@ -13,8 +17,9 @@ const StyledSoonPill = styled.span`
height: ${({ theme }) => theme.spacing(4)};
justify-content: flex-end;
line-height: ${({ theme }) => theme.text.lineHeight.lg};
- margin-left: auto;
padding: ${({ theme }) => `0 ${theme.spacing(2)}`};
`;
-export const SoonPill = () => Soon;
+export const SoonPill = ({ className }: SoonPillProps) => (
+ Soon
+);
diff --git a/front/src/modules/ui/input/button/components/Button.tsx b/front/src/modules/ui/input/button/components/Button.tsx
index 1eddaba13..b42157269 100644
--- a/front/src/modules/ui/input/button/components/Button.tsx
+++ b/front/src/modules/ui/input/button/components/Button.tsx
@@ -277,6 +277,10 @@ const StyledButton = styled.button<
}
`;
+const StyledSoonPill = styled(SoonPill)`
+ margin-left: auto;
+`;
+
export const Button = ({
className,
Icon,
@@ -307,7 +311,7 @@ export const Button = ({
>
{Icon && }
{title}
- {soon && }
+ {soon && }
);
};
diff --git a/front/src/modules/ui/layout/card/components/Card.tsx b/front/src/modules/ui/layout/card/components/Card.tsx
new file mode 100644
index 000000000..745bdc678
--- /dev/null
+++ b/front/src/modules/ui/layout/card/components/Card.tsx
@@ -0,0 +1,10 @@
+import styled from '@emotion/styled';
+
+const StyledCard = styled.div`
+ background-color: ${({ theme }) => theme.background.secondary};
+ border: 1px solid ${({ theme }) => theme.border.color.medium};
+ border-radius: ${({ theme }) => theme.border.radius.sm};
+ padding: ${({ theme }) => theme.spacing(3)};
+`;
+
+export { StyledCard as Card };
diff --git a/front/src/modules/ui/layout/card/components/__stories__/Card.stories.tsx b/front/src/modules/ui/layout/card/components/__stories__/Card.stories.tsx
new file mode 100644
index 000000000..ecff673a6
--- /dev/null
+++ b/front/src/modules/ui/layout/card/components/__stories__/Card.stories.tsx
@@ -0,0 +1,13 @@
+import { Meta, StoryObj } from '@storybook/react';
+
+import { Card } from '../Card';
+
+const meta: Meta = {
+ title: 'UI/Layout/Card/Card',
+ component: Card,
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/front/src/pages/settings/accounts/SettingsAccounts.tsx b/front/src/pages/settings/accounts/SettingsAccounts.tsx
index aca1c0706..101089050 100644
--- a/front/src/pages/settings/accounts/SettingsAccounts.tsx
+++ b/front/src/pages/settings/accounts/SettingsAccounts.tsx
@@ -1,3 +1,4 @@
+import { SettingsAccountsSettingsSection } from '@/settings/accounts/components/SettingsAccountsSettingsSection';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { IconSettings } from '@/ui/display/icon';
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
@@ -7,6 +8,7 @@ export const SettingsAccounts = () => (
+
);