diff --git a/front/src/App.tsx b/front/src/App.tsx index f37dc28c3e..fa0843d05e 100644 --- a/front/src/App.tsx +++ b/front/src/App.tsx @@ -16,6 +16,7 @@ import { ImpersonateEffect } from '~/pages/impersonate/ImpersonateEffect'; import { NotFound } from '~/pages/not-found/NotFound'; import { Opportunities } from '~/pages/opportunities/Opportunities'; import { SettingsAccounts } from '~/pages/settings/accounts/SettingsAccounts'; +import { SettingsAccountsEmails } from '~/pages/settings/accounts/SettingsAccountsEmails'; import { SettingsNewObject } from '~/pages/settings/data-model/SettingsNewObject'; import { SettingsObjectDetail } from '~/pages/settings/data-model/SettingsObjectDetail'; import { SettingsObjectEdit } from '~/pages/settings/data-model/SettingsObjectEdit'; @@ -73,6 +74,10 @@ export const App = () => { path={SettingsPath.Accounts} element={} /> + } + /> } diff --git a/front/src/modules/favorites/components/Favorites.tsx b/front/src/modules/favorites/components/Favorites.tsx index ad16361ef3..c76f8efb67 100644 --- a/front/src/modules/favorites/components/Favorites.tsx +++ b/front/src/modules/favorites/components/Favorites.tsx @@ -3,14 +3,13 @@ import styled from '@emotion/styled'; import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem'; import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList'; import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; +import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection'; import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle'; import { Avatar } from '@/users/components/Avatar'; import { useFavorites } from '../hooks/useFavorites'; -const StyledContainer = styled.div` - display: flex; - flex-direction: column; +const StyledContainer = styled(NavigationDrawerSection)` overflow-x: auto; width: 100%; `; diff --git a/front/src/modules/navigation/components/MainNavigationDrawerItems.tsx b/front/src/modules/navigation/components/MainNavigationDrawerItems.tsx index df3688048f..3403b6ea0e 100644 --- a/front/src/modules/navigation/components/MainNavigationDrawerItems.tsx +++ b/front/src/modules/navigation/components/MainNavigationDrawerItems.tsx @@ -13,6 +13,7 @@ import { IconTargetArrow, } from '@/ui/display/icon'; import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; +import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection'; import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle'; import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; @@ -33,7 +34,7 @@ export const MainNavigationDrawerItems = () => { return ( <> {!isMobile && ( - <> + { Icon={IconCheckbox} count={currentUserDueTaskCount} /> - + )} - - - + + + + + ); }; diff --git a/front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx b/front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx index cc8d8c433d..9ba834ac3c 100644 --- a/front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx +++ b/front/src/modules/settings/components/SettingsNavigationDrawerItems.tsx @@ -5,15 +5,19 @@ import { useAuth } from '@/auth/hooks/useAuth'; import { AppPath } from '@/types/AppPath'; import { IconAt, + IconCalendarEvent, IconColorSwatch, IconHierarchy2, IconLogout, + IconMail, IconRobot, IconSettings, IconUserCircle, IconUsers, } from '@/ui/display/icon'; import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem'; +import { NavigationDrawerItemGroup } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItemGroup'; +import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection'; import { NavigationDrawerSectionTitle } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; @@ -27,97 +31,122 @@ export const SettingsNavigationDrawerItems = () => { }, [signOut, navigate]); const isMessagingEnabled = useIsFeatureEnabled('IS_MESSAGING_ENABLED'); - const isMessagingActive = !!useMatch({ + const isAccountsItemActive = !!useMatch({ path: useResolvedPath('/settings/accounts').pathname, end: true, }); + const isAccountsEmailsItemActive = !!useMatch({ + path: useResolvedPath('/settings/accounts/emails').pathname, + end: true, + }); return ( <> - - - - {isMessagingEnabled && ( + + - )} + + {isMessagingEnabled && ( + + + + + + )} + - - - - - + + + + + + + - - + + + + ); }; diff --git a/front/src/modules/types/SettingsPath.ts b/front/src/modules/types/SettingsPath.ts index 5bf414bf01..0c1e0cb27f 100644 --- a/front/src/modules/types/SettingsPath.ts +++ b/front/src/modules/types/SettingsPath.ts @@ -2,6 +2,7 @@ export enum SettingsPath { ProfilePage = 'profile', Appearance = 'profile/appearance', Accounts = 'accounts', + AccountsEmails = 'accounts/emails', Objects = 'objects', ObjectDetail = 'objects/:objectSlug', ObjectEdit = 'objects/:objectSlug/edit', diff --git a/front/src/modules/ui/layout/page/RightDrawerContainer.tsx b/front/src/modules/ui/layout/page/RightDrawerContainer.tsx index a30a5414c0..aaa6e49890 100644 --- a/front/src/modules/ui/layout/page/RightDrawerContainer.tsx +++ b/front/src/modules/ui/layout/page/RightDrawerContainer.tsx @@ -18,8 +18,7 @@ const StyledMainContainer = styled.div` flex-direction: row; gap: ${({ theme }) => theme.spacing(2)}; min-height: 0; - padding-bottom: ${({ theme }) => theme.spacing(4)}; - padding-right: ${({ theme }) => theme.spacing(3)}; + padding: ${({ theme }) => theme.spacing(0, 3)}; width: 100%; @media (max-width: ${MOBILE_VIEWPORT}px) { diff --git a/front/src/modules/ui/layout/page/SubMenuTopBarContainer.tsx b/front/src/modules/ui/layout/page/SubMenuTopBarContainer.tsx index e18b29ac3c..1e43bfdfc7 100644 --- a/front/src/modules/ui/layout/page/SubMenuTopBarContainer.tsx +++ b/front/src/modules/ui/layout/page/SubMenuTopBarContainer.tsx @@ -16,7 +16,7 @@ type SubMenuTopBarContainerProps = { const StyledContainer = styled.div<{ isMobile: boolean }>` display: flex; flex-direction: column; - padding-top: ${({ theme, isMobile }) => (!isMobile ? theme.spacing(4) : 0)}; + padding-top: ${({ theme, isMobile }) => (!isMobile ? theme.spacing(3) : 0)}; width: 100%; `; diff --git a/front/src/modules/ui/navigation/bread-crumb/components/Breadcrumb.tsx b/front/src/modules/ui/navigation/bread-crumb/components/Breadcrumb.tsx index bbf82999bd..463cc1faf9 100644 --- a/front/src/modules/ui/navigation/bread-crumb/components/Breadcrumb.tsx +++ b/front/src/modules/ui/navigation/bread-crumb/components/Breadcrumb.tsx @@ -14,7 +14,6 @@ const StyledWrapper = styled.nav` font-size: ${({ theme }) => theme.font.size.lg}; font-weight: ${({ theme }) => theme.font.weight.semiBold}; gap: ${({ theme }) => theme.spacing(2)}; - height: ${({ theme }) => theme.spacing(6)}; line-height: ${({ theme }) => theme.text.lineHeight.md}; `; diff --git a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawer.tsx b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawer.tsx index 4a6fc6667b..5311a16745 100644 --- a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawer.tsx +++ b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawer.tsx @@ -31,16 +31,16 @@ const StyledContainer = styled.div<{ isSubMenu?: boolean }>` box-sizing: border-box; display: flex; flex-direction: column; - gap: ${({ theme }) => theme.spacing(10)}; + gap: ${({ theme }) => theme.spacing(8)}; height: 100%; min-width: ${desktopNavDrawerWidths.menu}; - padding: ${({ theme }) => theme.spacing(2)}; - padding-bottom: ${({ theme }) => theme.spacing(4)}; + padding: ${({ theme }) => theme.spacing(3, 2, 4)}; ${({ isSubMenu, theme }) => isSubMenu ? css` - padding-top: ${theme.spacing(11)}; + padding-right: ${theme.spacing(8)}; + padding-top: 41px; ` : ''} @@ -52,6 +52,7 @@ const StyledContainer = styled.div<{ isSubMenu?: boolean }>` const StyledItemsContainer = styled.div` display: flex; flex-direction: column; + gap: ${({ theme }) => theme.spacing(8)}; margin-bottom: auto; `; diff --git a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx index dd2db01f16..30f478a933 100644 --- a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx +++ b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerBackButton.tsx @@ -1,4 +1,5 @@ import { useNavigate } from 'react-router-dom'; +import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { useRecoilValue } from 'recoil'; @@ -19,7 +20,8 @@ const StyledIconAndButtonContainer = styled.button` flex-direction: row; font-size: ${({ theme }) => theme.font.size.lg}; font-weight: ${({ theme }) => theme.font.weight.semiBold}; - gap: ${({ theme }) => theme.spacing(1)}; + gap: ${({ theme }) => theme.spacing(2)}; + line-height: ${({ theme }) => theme.text.lineHeight.md}; padding: ${({ theme }) => theme.spacing(1)}; width: 100%; `; @@ -33,6 +35,7 @@ const StyledContainer = styled.div` export const NavigationDrawerBackButton = ({ title, }: NavigationDrawerBackButtonProps) => { + const theme = useTheme(); const navigate = useNavigate(); const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState); @@ -43,7 +46,10 @@ export const NavigationDrawerBackButton = ({ navigate(navigationMemorizedUrl, { replace: true }); }} > - + {title} diff --git a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx index 61cd25cecf..568fbb4b6b 100644 --- a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx +++ b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerHeader.tsx @@ -8,9 +8,8 @@ const StyledContainer = styled.div` align-items: center; display: flex; gap: ${({ theme }) => theme.spacing(2)}; - height: 34px; + height: ${({ theme }) => theme.spacing(6)}; padding: ${({ theme }) => theme.spacing(1)}; - padding-bottom: ${({ theme }) => theme.spacing(2)}; user-select: none; `; diff --git a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx index 7c2981e439..122b394439 100644 --- a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx +++ b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerItem.tsx @@ -11,6 +11,7 @@ import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; type NavigationDrawerItemProps = { className?: string; label: string; + level?: 1 | 2; to?: string; onClick?: () => void; Icon: IconComponent; @@ -24,6 +25,7 @@ type NavigationDrawerItemProps = { type StyledItemProps = { active?: boolean; danger?: boolean; + level: 1 | 2; soon?: boolean; }; @@ -50,7 +52,7 @@ const StyledItem = styled.div` font-family: 'Inter'; font-size: ${({ theme }) => theme.font.size.md}; gap: ${({ theme }) => theme.spacing(2)}; - margin-bottom: calc(${({ theme }) => theme.spacing(1)} / 2); + margin-left: ${({ level, theme }) => theme.spacing((level - 1) * 4)}; padding-bottom: ${({ theme }) => theme.spacing(1)}; padding-left: ${({ theme }) => theme.spacing(1)}; padding-right: ${({ theme }) => theme.spacing(1)}; @@ -86,7 +88,6 @@ const StyledSoonPill = styled.div` font-size: ${({ theme }) => theme.font.size.xs}; height: 16px; justify-content: center; - margin-left: auto; padding-left: ${({ theme }) => theme.spacing(2)}; padding-right: ${({ theme }) => theme.spacing(2)}; `; @@ -120,6 +121,7 @@ const StyledKeyBoardShortcut = styled.div` export const NavigationDrawerItem = ({ className, label, + level = 1, Icon, to, onClick, @@ -152,6 +154,7 @@ export const NavigationDrawerItem = ({ return ( theme.spacing(0.5)}; +`; + +export { StyledGroup as NavigationDrawerItemGroup }; diff --git a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSection.tsx b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSection.tsx new file mode 100644 index 0000000000..7847ccaf10 --- /dev/null +++ b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSection.tsx @@ -0,0 +1,9 @@ +import styled from '@emotion/styled'; + +const StyledSection = styled.div` + display: flex; + flex-direction: column; + gap: ${({ theme }) => theme.spacing(1)}; +`; + +export { StyledSection as NavigationDrawerSection }; diff --git a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle.tsx b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle.tsx index c80b8eacb7..3f1efb117e 100644 --- a/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle.tsx +++ b/front/src/modules/ui/navigation/navigation-drawer/components/NavigationDrawerSectionTitle.tsx @@ -9,9 +9,8 @@ const StyledTitle = styled.div` display: flex; font-size: ${({ theme }) => theme.font.size.xs}; font-weight: ${({ theme }) => theme.font.weight.semiBold}; - padding-bottom: ${({ theme }) => theme.spacing(2)}; - padding-left: ${({ theme }) => theme.spacing(1)}; - padding-top: ${({ theme }) => theme.spacing(8)}; + padding: ${({ theme }) => theme.spacing(1)}; + padding-top: 0; text-transform: uppercase; `; diff --git a/front/src/modules/ui/navigation/navigation-drawer/components/__stories__/NavigationDrawer.stories.tsx b/front/src/modules/ui/navigation/navigation-drawer/components/__stories__/NavigationDrawer.stories.tsx index 2615a7936d..dd6dbd2e9c 100644 --- a/front/src/modules/ui/navigation/navigation-drawer/components/__stories__/NavigationDrawer.stories.tsx +++ b/front/src/modules/ui/navigation/navigation-drawer/components/__stories__/NavigationDrawer.stories.tsx @@ -2,11 +2,14 @@ import { Meta, StoryObj } from '@storybook/react'; import { Favorites } from '@/favorites/components/Favorites'; import { + IconAt, IconBell, IconBuildingSkyscraper, + IconCalendarEvent, IconCheckbox, IconColorSwatch, IconLogout, + IconMail, IconSearch, IconSettings, IconTargetArrow, @@ -21,6 +24,8 @@ import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator'; import { NavigationDrawer } from '../NavigationDrawer'; import { NavigationDrawerItem } from '../NavigationDrawerItem'; import { NavigationDrawerSectionTitle } from '../NavigationDrawerSectionTitle'; +import { NavigationDrawerSection } from '../NavigationDrawerSection'; +import { NavigationDrawerItemGroup } from '../NavigationDrawerItemGroup'; const meta: Meta = { title: 'UI/Navigation/NavigationDrawer/NavigationDrawer', @@ -37,33 +42,39 @@ export const Default: Story = { args: { children: ( <> - - - - + + + + + + + - - - - + + + + + + + ), footer: null, @@ -76,32 +87,58 @@ export const Submenu: Story = { title: 'Settings', children: ( <> - - - - - - + + + + + + + + + + - - + + + + + + + + + + ), footer: , diff --git a/front/src/modules/ui/theme/constants/theme.ts b/front/src/modules/ui/theme/constants/theme.ts index 4ed41a6c1c..ca51c46f8a 100644 --- a/front/src/modules/ui/theme/constants/theme.ts +++ b/front/src/modules/ui/theme/constants/theme.ts @@ -35,7 +35,8 @@ const common = { }, }, spacingMultiplicator: 4, - spacing: (multiplicator: number) => `${multiplicator * 4}px`, + spacing: (...args: number[]) => + args.map((multiplicator) => `${multiplicator * 4}px`).join(' '), betweenSiblingsGap: `2px`, table: { horizontalCellMargin: '8px', diff --git a/front/src/pages/settings/accounts/SettingsAccountsEmails.tsx b/front/src/pages/settings/accounts/SettingsAccountsEmails.tsx new file mode 100644 index 0000000000..384119e6ef --- /dev/null +++ b/front/src/pages/settings/accounts/SettingsAccountsEmails.tsx @@ -0,0 +1,17 @@ +import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; +import { IconSettings } from '@/ui/display/icon'; +import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'; +import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb'; + +export const SettingsAccountsEmails = () => ( + + + + + +); diff --git a/front/src/pages/settings/accounts/__stories__/SettingsAccounts.stories.tsx b/front/src/pages/settings/accounts/__stories__/SettingsAccounts.stories.tsx new file mode 100644 index 0000000000..25ed6a77f1 --- /dev/null +++ b/front/src/pages/settings/accounts/__stories__/SettingsAccounts.stories.tsx @@ -0,0 +1,28 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { + PageDecorator, + PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; +import { graphqlMocks } from '~/testing/graphqlMocks'; + +import { SettingsAccounts } from '../SettingsAccounts'; + +const meta: Meta = { + title: 'Pages/Settings/Accounts/SettingsAccounts', + component: SettingsAccounts, + decorators: [PageDecorator], + args: { + routePath: '/settings/accounts', + }, + parameters: { + layout: 'fullscreen', + msw: graphqlMocks, + }, +}; + +export default meta; + +export type Story = StoryObj; + +export const Default: Story = {}; diff --git a/front/src/pages/settings/accounts/__stories__/SettingsAccountsEmails.stories.tsx b/front/src/pages/settings/accounts/__stories__/SettingsAccountsEmails.stories.tsx new file mode 100644 index 0000000000..21bede0eb5 --- /dev/null +++ b/front/src/pages/settings/accounts/__stories__/SettingsAccountsEmails.stories.tsx @@ -0,0 +1,28 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { + PageDecorator, + PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; +import { graphqlMocks } from '~/testing/graphqlMocks'; + +import { SettingsAccountsEmails } from '../SettingsAccountsEmails'; + +const meta: Meta = { + title: 'Pages/Settings/Accounts/SettingsAccountsEmails', + component: SettingsAccountsEmails, + decorators: [PageDecorator], + args: { + routePath: '/settings/accounts/emails', + }, + parameters: { + layout: 'fullscreen', + msw: graphqlMocks, + }, +}; + +export default meta; + +export type Story = StoryObj; + +export const Default: Story = {};