(app-desk) create mails feature

Create the archi to handle the mails feature.
It has a different layout than the other features,
we don't display the sidebar to keep the
user focused on the mail content.
This commit is contained in:
Anthony LC
2024-04-08 14:42:56 +02:00
committed by Anthony LC
parent ebf58f42c9
commit 45a3e7936d
10 changed files with 126 additions and 1 deletions
@@ -1,8 +1,10 @@
import { PropsWithChildren } from 'react';
import { Box } from '@/components';
import { HEADER_HEIGHT, Header } from '@/features/header';
import { Menu } from '@/features/menu';
export function MainLayout({ children }: { children: React.ReactNode }) {
export function MainLayout({ children }: PropsWithChildren) {
return (
<Box $height="100vh" $css="overflow:hidden;">
<Header />
@@ -0,0 +1,51 @@
import { DataGrid } from '@openfun/cunningham-react';
import { useTranslation } from 'react-i18next';
import { Card } from '@/components';
export function MailContent() {
const { t } = useTranslation();
const dataset = [
{
id: '1',
name: 'John Doe',
email: '[email protected]',
state: 'Active',
lastConnection: '2021-09-01',
},
{
id: '2',
name: 'Jane Doe',
email: '[email protected]',
state: 'Inactive',
lastConnection: '2021-09-02',
},
];
return (
<Card className="m-l p-s">
<DataGrid
columns={[
{
headerName: t('Names'),
field: 'name',
},
{
field: 'email',
headerName: t('Emails'),
},
{
field: 'state',
headerName: t('State'),
},
{
field: 'lastConnection',
headerName: t('Last Connecttion'),
},
]}
rows={dataset}
/>
</Card>
);
}
@@ -0,0 +1,23 @@
import { PropsWithChildren } from 'react';
import { Box } from '@/components';
import { MainLayout } from '@/core';
import { useCunninghamTheme } from '@/cunningham';
export function MailLayout({ children }: PropsWithChildren) {
const { colorsTokens } = useCunninghamTheme();
return (
<MainLayout>
<Box $height="inherit" $direction="row">
<Box
$background={colorsTokens()['primary-bg']}
$width="100%"
$height="inherit"
>
{children}
</Box>
</Box>
</MainLayout>
);
}
@@ -0,0 +1,2 @@
export * from './MailContent';
export * from './MailLayout';
@@ -0,0 +1 @@
export * from './components/';
@@ -8,6 +8,7 @@ import useCunninghamTheme from '@/cunningham/useCunninghamTheme';
import MenuItem from './MenuItems';
import IconRecent from './assets/icon-clock.svg';
import IconContacts from './assets/icon-contacts.svg';
import IconMail from './assets/icon-mails.svg';
import IconSearch from './assets/icon-search.svg';
import IconFavorite from './assets/icon-stars.svg';
@@ -25,6 +26,7 @@ export const Menu = () => {
>
<Box className="pt-l" $direction="column" $gap="0.8rem">
<MenuItem Icon={IconSearch} label={t('Search')} href="/" />
<MenuItem Icon={IconMail} label={t('Mails')} href="/mails" />
<MenuItem Icon={IconFavorite} label={t('Favorite')} href="/favorite" />
<MenuItem Icon={IconRecent} label={t('Recent')} href="/recent" />
<MenuItem Icon={IconContacts} label={t('Contacts')} href="/contacts" />
@@ -0,0 +1,13 @@
<svg viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_879_8339)">
<path
d="M18 3C9.72 3 3 9.72 3 18C3 26.28 9.72 33 18 33H25.5V30H18C11.49 30 6 24.51 6 18C6 11.49 11.49 6 18 6C24.51 6 30 11.49 30 18V20.145C30 21.33 28.935 22.5 27.75 22.5C26.565 22.5 25.5 21.33 25.5 20.145V18C25.5 13.86 22.14 10.5 18 10.5C13.86 10.5 10.5 13.86 10.5 18C10.5 22.14 13.86 25.5 18 25.5C20.07 25.5 21.96 24.66 23.31 23.295C24.285 24.63 25.965 25.5 27.75 25.5C30.705 25.5 33 23.1 33 20.145V18C33 9.72 26.28 3 18 3ZM18 22.5C15.51 22.5 13.5 20.49 13.5 18C13.5 15.51 15.51 13.5 18 13.5C20.49 13.5 22.5 15.51 22.5 18C22.5 20.49 20.49 22.5 18 22.5Z"
fill="currentColor"
/>
</g>
<defs>
<clipPath id="clip0_879_8339">
<rect width="36" height="36" fill="currentColor" />
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 854 B

@@ -0,0 +1,14 @@
import { ReactElement } from 'react';
import { MailContent, MailLayout } from '@/features/mails';
import { NextPageWithLayout } from '@/types/next';
const Page: NextPageWithLayout = () => {
return <MailContent />;
};
Page.getLayout = function getLayout(page: ReactElement) {
return <MailLayout>{page}</MailLayout>;
};
export default Page;
@@ -0,0 +1,16 @@
import { expect, test } from '@playwright/test';
import { keyCloakSignIn } from './common';
test.beforeEach(async ({ page, browserName }) => {
await page.goto('/');
await keyCloakSignIn(page, browserName);
});
test.describe('Mails', () => {
test('checks all the elements are visible', async ({ page }) => {
await page.locator('menu').first().getByLabel(`Mails button`).click();
await expect(page.getByText('[email protected]')).toBeVisible();
await expect(page.getByText('[email protected]')).toBeVisible();
});
});
@@ -10,6 +10,7 @@ test.beforeEach(async ({ page, browserName }) => {
test.describe('Menu', () => {
const menuItems = [
{ name: 'Search', isDefault: true },
{ name: 'Mails', isDefault: false },
{ name: 'Favorite', isDefault: false },
{ name: 'Recent', isDefault: false },
{ name: 'Contacts', isDefault: false },