diff --git a/CHANGELOG.md b/CHANGELOG.md index 1367bc1e..f02bbfa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to - ✨(backend) integrate maleware_detection from django-lasuite #936 - 🏗️(frontend) Footer configurable #959 - 🩺(CI) add lint spell mistakes #954 +- ✨(frontend) create generic theme #792 - 🛂(frontend) block edition to not connected users #945 - 🚸 Let loader during upload analyze #984 diff --git a/env.d/development/common.dist b/env.d/development/common.dist index 4b1389bf..bf1b4553 100644 --- a/env.d/development/common.dist +++ b/env.d/development/common.dist @@ -61,6 +61,3 @@ COLLABORATION_BACKEND_BASE_URL=http://app-dev:8000 COLLABORATION_SERVER_ORIGIN=http://localhost:3000 COLLABORATION_SERVER_SECRET=my-secret COLLABORATION_WS_URL=ws://localhost:4444/collaboration/ws/ - -# Frontend -FRONTEND_THEME=default diff --git a/src/frontend/apps/e2e/__tests__/app-impress/404.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/404.spec.ts index 83b9b823..e55acfe5 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/404.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/404.spec.ts @@ -10,8 +10,6 @@ test.beforeEach(async ({ page }) => { test.describe('404', () => { test('Checks all the elements are visible', async ({ page }) => { - await expect(page.getByLabel('Image 404')).toBeVisible(); - await expect(page.getByText('Ouch')).toBeVisible(); await expect( page.getByText( 'It seems that the page you are looking for does not exist or cannot be displayed correctly.', diff --git a/src/frontend/apps/e2e/__tests__/app-impress/common.ts b/src/frontend/apps/e2e/__tests__/app-impress/common.ts index eadb609f..ee5f24de 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/common.ts @@ -7,7 +7,7 @@ export const CONFIG = { ENVIRONMENT: 'development', FRONTEND_CSS_URL: null, FRONTEND_HOMEPAGE_FEATURE_ENABLED: true, - FRONTEND_THEME: 'default', + FRONTEND_THEME: null, MEDIA_BASE_URL: 'http://localhost:8083', LANGUAGES: [ ['en-us', 'English'], @@ -20,7 +20,7 @@ export const CONFIG = { POSTHOG_KEY: {}, SENTRY_DSN: null, theme_customization: {}, -}; +} as const; export const overrideConfig = async ( page: Page, @@ -46,10 +46,7 @@ export const keyCloakSignIn = async ( fromHome: boolean = true, ) => { if (fromHome) { - await page - .getByRole('button', { name: 'Proconnect Login' }) - .first() - .click(); + await page.getByRole('button', { name: 'Start Writing' }).first().click(); } const login = `user-e2e-${browserName}`; @@ -109,9 +106,16 @@ export const createDoc = async ( }; export const verifyDocName = async (page: Page, docName: string) => { - const input = page.getByRole('textbox', { name: 'doc title input' }); + await expect( + page.getByLabel('It is the card information about the document.'), + ).toBeVisible({ + timeout: 10000, + }); + try { - await expect(input).toHaveText(docName); + await expect( + page.getByRole('textbox', { name: 'doc title input' }), + ).toHaveText(docName); } catch { await expect(page.getByRole('heading', { name: docName })).toBeVisible(); } diff --git a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts index 28379315..21bb085e 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts @@ -5,25 +5,6 @@ import { expect, test } from '@playwright/test'; import { CONFIG, createDoc, overrideConfig } from './common'; test.describe('Config', () => { - test('it checks the config api is called', async ({ page }) => { - const responsePromise = page.waitForResponse( - (response) => - response.url().includes('/config/') && response.status() === 200, - ); - - await page.goto('/'); - - const response = await responsePromise; - expect(response.ok()).toBeTruthy(); - - const json = (await response.json()) as typeof CONFIG; - const { theme_customization, ...configApi } = json; - expect(theme_customization).toBeDefined(); - const { theme_customization: _, ...CONFIG_LEFT } = CONFIG; - - expect(configApi).toStrictEqual(CONFIG_LEFT); - }); - test('it checks that sentry is trying to init from config endpoint', async ({ page, }) => { @@ -143,9 +124,7 @@ test.describe('Config', () => { test.describe('Config: Not loggued', () => { test.use({ storageState: { cookies: [], origins: [] } }); - test('it checks that theme is configured from config endpoint', async ({ - page, - }) => { + test('it checks the config api is called', async ({ page }) => { const responsePromise = page.waitForResponse( (response) => response.url().includes('/config/') && response.status() === 200, @@ -156,8 +135,22 @@ test.describe('Config: Not loggued', () => { const response = await responsePromise; expect(response.ok()).toBeTruthy(); - const jsonResponse = await response.json(); - expect(jsonResponse.FRONTEND_THEME).toStrictEqual('default'); + const json = (await response.json()) as typeof CONFIG; + const { theme_customization, ...configApi } = json; + expect(theme_customization).toBeDefined(); + const { theme_customization: _, ...CONFIG_LEFT } = CONFIG; + + expect(configApi).toStrictEqual(CONFIG_LEFT); + }); + + test('it checks that theme is configured from config endpoint', async ({ + page, + }) => { + await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', + }); + + await page.goto('/'); const header = page.locator('header').first(); // alt 'Gouvernement Logo' comes from the theme diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts index 758c8712..12be84ce 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts @@ -208,7 +208,6 @@ test.describe('Documents filters', () => { // Initial state await expect(allDocs).toBeVisible(); - await expect(allDocs).toHaveCSS('background-color', 'rgb(238, 238, 238)'); await expect(allDocs).toHaveAttribute('aria-selected', 'true'); await expect(myDocs).toBeVisible(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts index a28200b0..f28fb38d 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts @@ -101,6 +101,8 @@ test.describe('Doc Visibility: Restricted', () => { page, browserName, }) => { + test.slow(); + await page.goto('/'); await keyCloakSignIn(page, browserName); @@ -121,14 +123,16 @@ test.describe('Doc Visibility: Restricted', () => { await keyCloakSignIn(page, otherBrowser!); await expect( - page.getByRole('link', { name: 'Docs Logo Docs BETA' }), + page.getByRole('link', { name: 'Docs Logo Docs' }), ).toBeVisible(); await page.goto(urlDoc); await expect( page.getByText('You do not have permission to view this document.'), - ).toBeVisible(); + ).toBeVisible({ + timeout: 10000, + }); }); test('A doc is accessible when member.', async ({ page, browserName }) => { @@ -173,7 +177,7 @@ test.describe('Doc Visibility: Restricted', () => { await keyCloakSignIn(page, otherBrowser!); await expect( - page.getByRole('link', { name: 'Docs Logo Docs BETA' }), + page.getByRole('link', { name: 'Docs Logo Docs' }), ).toBeVisible(); await page.goto(urlDoc); @@ -430,7 +434,7 @@ test.describe('Doc Visibility: Authenticated', () => { await keyCloakSignIn(page, otherBrowser!); await expect( - page.getByRole('link', { name: 'Docs Logo Docs BETA' }), + page.getByRole('link', { name: 'Docs Logo Docs' }), ).toBeVisible(); await page.goto(urlDoc); @@ -490,7 +494,7 @@ test.describe('Doc Visibility: Authenticated', () => { await keyCloakSignIn(page, otherBrowser!); await expect( - page.getByRole('link', { name: 'Docs Logo Docs BETA' }), + page.getByRole('link', { name: 'Docs Logo Docs' }), ).toBeVisible(); await page.goto(urlDoc); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts index 93405911..221fbf82 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/footer.spec.ts @@ -20,7 +20,6 @@ test.describe('Footer', () => { await expect(footer.getByAltText('Docs Logo')).toBeVisible(); await expect(footer.getByRole('heading', { name: 'Docs' })).toBeVisible(); - await expect(footer.getByText('BETA')).toBeVisible(); await expect(footer.getByRole('link', { name: 'Github' })).toBeVisible(); await expect(footer.getByRole('link', { name: 'DINUM' })).toBeVisible(); @@ -57,6 +56,7 @@ test.describe('Footer', () => { test('checks the footer is correctly overrided', async ({ page }) => { await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', theme_customization: { footer: { default: { diff --git a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts index 7234b1fd..1abca24b 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts @@ -1,20 +1,39 @@ import { expect, test } from '@playwright/test'; -import { expectLoginPage, keyCloakSignIn } from './common'; +import { expectLoginPage, keyCloakSignIn, overrideConfig } from './common'; test.describe('Header', () => { - test.beforeEach(async ({ page }) => { - await page.goto('/'); - }); - test('checks all the elements are visible', async ({ page }) => { + await page.goto('/'); + const header = page.locator('header').first(); await expect(header.getByLabel('Docs Logo')).toBeVisible(); await expect(header.locator('h2').getByText('Docs')).toHaveCSS( - 'color', - 'rgb(0, 0, 145)', + 'font-family', + /Roboto/i, ); + + await expect( + header.getByRole('button', { + name: 'Logout', + }), + ).toBeVisible(); + + await expect(header.getByText('English')).toBeVisible(); + }); + + test('checks all the elements are visible with DSFR theme', async ({ + page, + }) => { + await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', + }); + await page.goto('/'); + + const header = page.locator('header').first(); + + await expect(header.getByLabel('Docs Logo')).toBeVisible(); await expect(header.locator('h2').getByText('Docs')).toHaveCSS( 'font-family', /Marianne/i, @@ -36,6 +55,11 @@ test.describe('Header', () => { }); test('checks La Gauffre interaction', async ({ page }) => { + await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', + }); + await page.goto('/'); + const header = page.locator('header').first(); await expect( @@ -68,11 +92,13 @@ test.describe('Header', () => { test.describe('Header mobile', () => { test.use({ viewport: { width: 500, height: 1200 } }); - test.beforeEach(async ({ page }) => { - await page.goto('/'); - }); + test('it checks the header when mobile with DSFR theme', async ({ page }) => { + await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', + }); + + await page.goto('/'); - test('it checks the header when mobile', async ({ page }) => { const header = page.locator('header').first(); await expect(header.getByLabel('Open the header menu')).toBeVisible(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts index b3c7be40..63b74fae 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts @@ -9,6 +9,62 @@ test.beforeEach(async ({ page }) => { test.describe('Home page', () => { test.use({ storageState: { cookies: [], origins: [] } }); test('checks all the elements are visible', async ({ page }) => { + await page.goto('/docs/'); + + // Check header content + const header = page.locator('header').first(); + const footer = page.locator('footer').first(); + await expect(header).toBeVisible(); + await expect( + header.getByRole('button', { name: /Language/ }), + ).toBeVisible(); + await expect(header.getByRole('img', { name: 'Docs logo' })).toBeVisible(); + await expect(header.getByRole('heading', { name: 'Docs' })).toBeVisible(); + + // Check the titles + const h2 = page.locator('h2'); + await expect(h2.getByText('Govs ❤️ Open Source.')).toBeVisible(); + await expect( + h2.getByText('Collaborative writing, Simplified.'), + ).toBeVisible(); + await expect( + h2.getByText('An uncompromising writing experience.'), + ).toBeVisible(); + await expect( + h2.getByText('Simple and secure collaboration.'), + ).toBeVisible(); + await expect(h2.getByText('Flexible export.')).toBeVisible(); + await expect( + h2.getByText('A new way to organize knowledge.'), + ).toBeVisible(); + await expect( + page.getByRole('button', { name: 'Start Writing' }), + ).toBeVisible(); + + await expect(footer).toBeVisible(); + }); + + test('checks all the elements are visible with dsfr theme', async ({ + page, + }) => { + await overrideConfig(page, { + FRONTEND_THEME: 'dsfr', + theme_customization: { + footer: { + default: { + externalLinks: [ + { + label: 'legifrance.gouv.fr', + href: '#', + }, + ], + }, + }, + }, + }); + + await page.goto('/docs/'); + // Check header content const header = page.locator('header').first(); const footer = page.locator('footer').first(); diff --git a/src/frontend/apps/impress/cunningham.ts b/src/frontend/apps/impress/cunningham.ts index 988d39f3..1bccd00e 100644 --- a/src/frontend/apps/impress/cunningham.ts +++ b/src/frontend/apps/impress/cunningham.ts @@ -3,6 +3,8 @@ import { cunninghamConfig as tokens } from '@gouvfr-lasuite/ui-kit'; const customColors = { 'primary-action': '#1212FF', 'primary-bg': '#FAFAFA', + 'primary-focus': '#0A76F6', + 'secondary-icon': 'var(--c--theme--colors--primary-text)', 'blue-400': '#7AB1E8', 'blue-500': '#417DC4', 'blue-600': '#3558A2', @@ -34,7 +36,6 @@ const customColors = { 'yellow-500': '#B7A73F', 'yellow-600': '#66673D', }; - tokens.themes.default.theme.colors = { ...tokens.themes.default.theme.colors, ...customColors, @@ -44,10 +45,10 @@ tokens.themes.default.theme = { ...tokens.themes.default.theme, ...{ logo: { - src: '/assets/logo-gouv.svg', - widthHeader: '110px', - widthFooter: '220px', - alt: 'Gouvernement Logo', + src: '', + alt: '', + widthHeader: '', + widthFooter: '', }, }, }; @@ -55,13 +56,189 @@ tokens.themes.default.theme = { tokens.themes.default.components = { ...tokens.themes.default.components, ...{ - 'la-gauffre': { - activated: true, + 'la-gaufre': false, + 'home-proconnect': false, + beta: false, + }, +}; + +const dsfrTheme = { + dsfr: { + theme: { + colors: { + 'secondary-icon': '#C9191E', + }, + logo: { + src: '/assets/logo-gouv.svg', + widthHeader: '110px', + widthFooter: '220px', + alt: 'Gouvernement Logo', + }, }, - 'home-proconnect': { - activated: true, + components: { + 'la-gaufre': true, + 'home-proconnect': true, + beta: true, }, }, }; -export default tokens; +const genericTheme = { + generic: { + theme: { + colors: { + 'primary-action': '#206EBD', + 'primary-focus': '#1E64BF', + 'primary-text': '#2E2C28', + 'primary-050': '#F8F8F7', + 'primary-100': '#F0EFEC', + 'primary-150': '#F4F4FD', + 'primary-200': '#E8E7E4', + 'primary-300': '#CFCDC9', + 'primary-400': '#979592', + 'primary-500': '#82807D', + 'primary-600': '#3F3D39', + 'primary-700': '#2E2C28', + 'primary-800': '#302E29', + 'primary-900': '#282622', + 'primary-950': '#201F1C', + 'secondary-text': '#fff', + 'secondary-50': '#F4F7FA', + 'secondary-100': '#D7E3EE', + 'secondary-200': '#B8CCE1', + 'secondary-300': '#99B4D3', + 'secondary-400': '#7595BE', + 'secondary-500': '#5874A0', + 'secondary-600': '#3A5383', + 'secondary-700': '#1E3462', + 'secondary-800': '#091B41', + 'secondary-900': '#08183B', + 'secondary-950': '#071636', + 'greyscale-text': '#3C3B38', + 'greyscale-000': '#fff', + 'greyscale-050': '#F8F7F7', + 'greyscale-100': '#F3F3F2', + 'greyscale-200': '#ECEBEA', + 'greyscale-250': '#E4E3E2', + 'greyscale-300': '#D3D2CF', + 'greyscale-350': '#eee', + 'greyscale-400': '#96948E', + 'greyscale-500': '#817E77', + 'greyscale-600': '#6A6862', + 'greyscale-700': '#3C3B38', + 'greyscale-750': '#383632', + 'greyscale-800': '#2D2B27', + 'greyscale-900': '#262522', + 'greyscale-950': '#201F1C', + 'greyscale-1000': '#181714', + 'success-text': '#234935', + 'success-50': '#F3FBF5', + 'success-100': '#E4F7EA', + 'success-200': '#CAEED4', + 'success-300': '#A0E0B5', + 'success-400': '#6CC88C', + 'success-500': '#6CC88C', + 'success-600': '#358D5C', + 'success-700': '#2D704B', + 'success-800': '#28583F', + 'success-900': '#234935', + 'success-950': '#0F281B', + 'info-text': '#212445', + 'info-50': '#F2F6FB', + 'info-100': '#E2E9F5', + 'info-200': '#CCD8EE', + 'info-300': '#A9C0E3', + 'info-400': '#809DD4', + 'info-500': '#617BC7', + 'info-600': '#4A5CBF', + 'info-700': '#3E49B2', + 'info-800': '#353C8F', + 'info-900': '#303771', + 'info-950': '#212445', + 'warning-text': '#D97C3A', + 'warning-50': '#FDF7F1', + 'warning-100': '#FBEDDC', + 'warning-200': '#F5D9B9', + 'warning-300': '#EDBE8C', + 'warning-400': '#E2985C', + 'warning-500': '#D97C3A', + 'warning-600': '#C96330', + 'warning-700': '#A34B32', + 'warning-800': '#813B2C', + 'warning-900': '#693327', + 'warning-950': '#381713', + 'danger-action': '#C0182A', + 'danger-text': '#FFF', + 'danger-050': '#FDF5F4', + 'danger-100': '#FBEBE8', + 'danger-200': '#F9E0DC', + 'danger-300': '#F3C3BD', + 'danger-400': '#E26552', + 'danger-500': '#C91F00', + 'danger-600': '#A71901', + 'danger-700': '#562C2B', + 'danger-800': '#392425', + 'danger-900': '#311F20', + 'danger-950': '#2A191A', + 'blue-400': '#8BAECC', + 'blue-500': '#567AA2', + 'blue-600': '#455784', + 'brown-400': '#E4C090', + 'brown-500': '#BA9977', + 'brown-600': '#735C45', + 'cyan-400': '#5CBEC9', + 'cyan-500': '#43A1B3', + 'cyan-600': '#39809B', + 'gold-400': '#ECBF50', + 'gold-500': '#DFA038', + 'gold-600': '#C17B31', + 'green-400': '#5DBD9A', + 'green-500': '#3AA183', + 'green-600': '#2A816D', + 'olive-400': '#AFD662', + 'olive-500': '#90BB4B', + 'olive-600': '#6E9441', + 'orange-400': '#E2985C', + 'orange-500': '#D97C3A', + 'orange-600': '#C96330', + 'pink-400': '#BE8FC8', + 'pink-500': '#A563B1', + 'pink-600': '#8B44A5', + 'purple-400': '#BE8FC8', + 'purple-500': '#A563B1', + 'purple-600': '#8B44A5', + 'yellow-400': '#EDC947', + 'yellow-500': '#DBB13A', + 'yellow-600': '#B88A34', + }, + font: { + families: { + base: 'Inter, Roboto Flex Variable, sans-serif', + accent: 'Inter, Roboto Flex Variable, sans-serif', + }, + }, + }, + components: { + button: { + primary: { + background: { + 'color-hover': 'var(--c--theme--colors--primary-focus)', + 'color-active': 'var(--c--theme--colors--primary-focus)', + 'color-focus': 'var(--c--theme--colors--primary-focus)', + }, + }, + }, + }, + }, +}; + +const docsTokens = { + ...tokens, + themes: { + ...tokens.themes, + ...dsfrTheme, + ...genericTheme, + }, +}; + +export default docsTokens; diff --git a/src/frontend/apps/impress/package.json b/src/frontend/apps/impress/package.json index dc1d0c59..416510f1 100644 --- a/src/frontend/apps/impress/package.json +++ b/src/frontend/apps/impress/package.json @@ -6,7 +6,7 @@ "dev": "next dev", "build": "prettier --check . && yarn stylelint && next build", "build:ci": "cp .env.development .env.local && yarn build", - "build-theme": "cunningham -g css,ts -o src/cunningham --utility-classes && yarn prettier", + "build-theme": "cunningham -g css,ts -o src/cunningham --utility-classes && yarn prettier && yarn stylelint --fix", "start": "npx -y serve@latest out", "lint": "tsc --noEmit && next lint", "prettier": "prettier --write .", diff --git a/src/frontend/apps/impress/src/assets/icons/icon-docs.svg b/src/frontend/apps/impress/src/assets/icons/icon-docs.svg index 05cf0436..882e92ef 100644 --- a/src/frontend/apps/impress/src/assets/icons/icon-docs.svg +++ b/src/frontend/apps/impress/src/assets/icons/icon-docs.svg @@ -1,12 +1,12 @@ diff --git a/src/frontend/apps/impress/src/components/DropButton.tsx b/src/frontend/apps/impress/src/components/DropButton.tsx index 5dfc1054..22f18f67 100644 --- a/src/frontend/apps/impress/src/components/DropButton.tsx +++ b/src/frontend/apps/impress/src/components/DropButton.tsx @@ -6,7 +6,9 @@ import { useState, } from 'react'; import { Button, Popover } from 'react-aria-components'; -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; + +import { useCunninghamTheme } from '@/cunningham'; import { BoxProps } from './Box'; @@ -27,11 +29,9 @@ const StyledButton = styled(Button)` background: none; outline: none; transition: all 0.2s ease-in-out; - font-family: Marianne, Arial, serif; font-weight: 500; font-size: 0.938rem; padding: 0; - text-wrap: nowrap; ${({ $css }) => $css}; `; @@ -51,6 +51,8 @@ export const DropButton = ({ children, label, }: PropsWithChildren) => { + const { themeTokens } = useCunninghamTheme(); + const font = themeTokens['font']?.['families']['base']; const [isLocalOpen, setIsLocalOpen] = useState(isOpen); const triggerRef = useRef(null); @@ -70,7 +72,10 @@ export const DropButton = ({ ref={triggerRef} onPress={() => onOpenChangeHandler(true)} aria-label={label} - $css={buttonCss} + $css={css` + font-family: ${font}; + ${buttonCss}; + `} className="--docs--drop-button" > {button} diff --git a/src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx b/src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx index 425781d6..208d8942 100644 --- a/src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx +++ b/src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx @@ -2,8 +2,12 @@ import { useCunninghamTheme } from '../useCunninghamTheme'; describe('', () => { it('has the logo correctly set', () => { - const { themeTokens, setTheme } = useCunninghamTheme.getState(); - setTheme('default'); + expect(useCunninghamTheme.getState().themeTokens.logo?.src).toBe(''); + + // Change theme + useCunninghamTheme.getState().setTheme('dsfr'); + + const { themeTokens } = useCunninghamTheme.getState(); const logo = themeTokens.logo; expect(logo?.src).toBe('/assets/logo-gouv.svg'); expect(logo?.widthHeader).toBe('110px'); diff --git a/src/frontend/apps/impress/src/cunningham/cunningham-style.css b/src/frontend/apps/impress/src/cunningham/cunningham-style.css index f3d42853..b98989ac 100644 --- a/src/frontend/apps/impress/src/cunningham/cunningham-style.css +++ b/src/frontend/apps/impress/src/cunningham/cunningham-style.css @@ -43,3 +43,29 @@ .c__tooltip { padding: 4px 6px; } + +@font-face { + font-family: Inter; + font-style: italic; + font-weight: 100 900; + font-display: swap; + src: url('https://fonts.gstatic.com/s/inter/v18/UcCm3FwrK3iLTcvnUwQT9g.woff2') + format('woff2'); + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, + U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, + U+2215, U+FEFF, U+FFFD; +} + +@font-face { + font-family: Inter; + font-style: normal; + font-weight: 100 900; + font-display: swap; + src: url('https://fonts.gstatic.com/s/inter/v18/UcCo3FwrK3iLTcviYwY.woff2') + format('woff2'); + unicode-range: + U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, + U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, + U+2215, U+FEFF, U+FFFD; +} diff --git a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css index c48bc4b1..f16f85fc 100644 --- a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css +++ b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css @@ -92,6 +92,8 @@ --c--theme--colors--rose-500: #e18b76; --c--theme--colors--primary-action: #1212ff; --c--theme--colors--primary-bg: #fafafa; + --c--theme--colors--primary-focus: #0a76f6; + --c--theme--colors--secondary-icon: var(--c--theme--colors--primary-text); --c--theme--colors--blue-400: #7ab1e8; --c--theme--colors--blue-600: #3558a2; --c--theme--colors--brown-400: #e6be92; @@ -190,10 +192,10 @@ --c--theme--breakpoints--xxs: 320px; --c--theme--breakpoints--mobile: 768px; --c--theme--breakpoints--tablet: 1024px; - --c--theme--logo--src: /assets/logo-gouv.svg; - --c--theme--logo--widthheader: 110px; - --c--theme--logo--widthfooter: 220px; - --c--theme--logo--alt: gouvernement logo; + --c--theme--logo--src: ; + --c--theme--logo--alt: ; + --c--theme--logo--widthheader: ; + --c--theme--logo--widthfooter: ; --c--components--modal--width-small: 342px; --c--components--tooltip--padding: 4px 8px; --c--components--tooltip--background-color: var( @@ -485,8 +487,9 @@ --c--theme--colors--info-100 ); --c--components--badge--info--color: var(--c--theme--colors--info-600); - --c--components--la-gauffre--activated: true; - --c--components--home-proconnect--activated: true; + --c--components--la-gaufre: false; + --c--components--home-proconnect: false; + --c--components--beta: false; } .cunningham-theme--dark { @@ -538,6 +541,154 @@ --c--theme--colors--danger-900: #9d6666; } +.cunningham-theme--dsfr { + --c--theme--colors--secondary-icon: #c9191e; + --c--theme--logo--src: /assets/logo-gouv.svg; + --c--theme--logo--widthHeader: 110px; + --c--theme--logo--widthFooter: 220px; + --c--theme--logo--alt: gouvernement logo; + --c--components--la-gaufre: true; + --c--components--home-proconnect: true; + --c--components--beta: true; +} + +.cunningham-theme--generic { + --c--theme--colors--primary-action: #206ebd; + --c--theme--colors--primary-focus: #1e64bf; + --c--theme--colors--primary-text: #2e2c28; + --c--theme--colors--primary-050: #f8f8f7; + --c--theme--colors--primary-100: #f0efec; + --c--theme--colors--primary-150: #f4f4fd; + --c--theme--colors--primary-200: #e8e7e4; + --c--theme--colors--primary-300: #cfcdc9; + --c--theme--colors--primary-400: #979592; + --c--theme--colors--primary-500: #82807d; + --c--theme--colors--primary-600: #3f3d39; + --c--theme--colors--primary-700: #2e2c28; + --c--theme--colors--primary-800: #302e29; + --c--theme--colors--primary-900: #282622; + --c--theme--colors--primary-950: #201f1c; + --c--theme--colors--secondary-text: #fff; + --c--theme--colors--secondary-50: #f4f7fa; + --c--theme--colors--secondary-100: #d7e3ee; + --c--theme--colors--secondary-200: #b8cce1; + --c--theme--colors--secondary-300: #99b4d3; + --c--theme--colors--secondary-400: #7595be; + --c--theme--colors--secondary-500: #5874a0; + --c--theme--colors--secondary-600: #3a5383; + --c--theme--colors--secondary-700: #1e3462; + --c--theme--colors--secondary-800: #091b41; + --c--theme--colors--secondary-900: #08183b; + --c--theme--colors--secondary-950: #071636; + --c--theme--colors--greyscale-text: #3c3b38; + --c--theme--colors--greyscale-000: #fff; + --c--theme--colors--greyscale-050: #f8f7f7; + --c--theme--colors--greyscale-100: #f3f3f2; + --c--theme--colors--greyscale-200: #ecebea; + --c--theme--colors--greyscale-250: #e4e3e2; + --c--theme--colors--greyscale-300: #d3d2cf; + --c--theme--colors--greyscale-350: #eee; + --c--theme--colors--greyscale-400: #96948e; + --c--theme--colors--greyscale-500: #817e77; + --c--theme--colors--greyscale-600: #6a6862; + --c--theme--colors--greyscale-700: #3c3b38; + --c--theme--colors--greyscale-750: #383632; + --c--theme--colors--greyscale-800: #2d2b27; + --c--theme--colors--greyscale-900: #262522; + --c--theme--colors--greyscale-950: #201f1c; + --c--theme--colors--greyscale-1000: #181714; + --c--theme--colors--success-text: #234935; + --c--theme--colors--success-50: #f3fbf5; + --c--theme--colors--success-100: #e4f7ea; + --c--theme--colors--success-200: #caeed4; + --c--theme--colors--success-300: #a0e0b5; + --c--theme--colors--success-400: #6cc88c; + --c--theme--colors--success-500: #6cc88c; + --c--theme--colors--success-600: #358d5c; + --c--theme--colors--success-700: #2d704b; + --c--theme--colors--success-800: #28583f; + --c--theme--colors--success-900: #234935; + --c--theme--colors--success-950: #0f281b; + --c--theme--colors--info-text: #212445; + --c--theme--colors--info-50: #f2f6fb; + --c--theme--colors--info-100: #e2e9f5; + --c--theme--colors--info-200: #ccd8ee; + --c--theme--colors--info-300: #a9c0e3; + --c--theme--colors--info-400: #809dd4; + --c--theme--colors--info-500: #617bc7; + --c--theme--colors--info-600: #4a5cbf; + --c--theme--colors--info-700: #3e49b2; + --c--theme--colors--info-800: #353c8f; + --c--theme--colors--info-900: #303771; + --c--theme--colors--info-950: #212445; + --c--theme--colors--warning-text: #d97c3a; + --c--theme--colors--warning-50: #fdf7f1; + --c--theme--colors--warning-100: #fbeddc; + --c--theme--colors--warning-200: #f5d9b9; + --c--theme--colors--warning-300: #edbe8c; + --c--theme--colors--warning-400: #e2985c; + --c--theme--colors--warning-500: #d97c3a; + --c--theme--colors--warning-600: #c96330; + --c--theme--colors--warning-700: #a34b32; + --c--theme--colors--warning-800: #813b2c; + --c--theme--colors--warning-900: #693327; + --c--theme--colors--warning-950: #381713; + --c--theme--colors--danger-action: #c0182a; + --c--theme--colors--danger-text: #fff; + --c--theme--colors--danger-050: #fdf5f4; + --c--theme--colors--danger-100: #fbebe8; + --c--theme--colors--danger-200: #f9e0dc; + --c--theme--colors--danger-300: #f3c3bd; + --c--theme--colors--danger-400: #e26552; + --c--theme--colors--danger-500: #c91f00; + --c--theme--colors--danger-600: #a71901; + --c--theme--colors--danger-700: #562c2b; + --c--theme--colors--danger-800: #392425; + --c--theme--colors--danger-900: #311f20; + --c--theme--colors--danger-950: #2a191a; + --c--theme--colors--blue-400: #8baecc; + --c--theme--colors--blue-500: #567aa2; + --c--theme--colors--blue-600: #455784; + --c--theme--colors--brown-400: #e4c090; + --c--theme--colors--brown-500: #ba9977; + --c--theme--colors--brown-600: #735c45; + --c--theme--colors--cyan-400: #5cbec9; + --c--theme--colors--cyan-500: #43a1b3; + --c--theme--colors--cyan-600: #39809b; + --c--theme--colors--gold-400: #ecbf50; + --c--theme--colors--gold-500: #dfa038; + --c--theme--colors--gold-600: #c17b31; + --c--theme--colors--green-400: #5dbd9a; + --c--theme--colors--green-500: #3aa183; + --c--theme--colors--green-600: #2a816d; + --c--theme--colors--olive-400: #afd662; + --c--theme--colors--olive-500: #90bb4b; + --c--theme--colors--olive-600: #6e9441; + --c--theme--colors--orange-400: #e2985c; + --c--theme--colors--orange-500: #d97c3a; + --c--theme--colors--orange-600: #c96330; + --c--theme--colors--pink-400: #be8fc8; + --c--theme--colors--pink-500: #a563b1; + --c--theme--colors--pink-600: #8b44a5; + --c--theme--colors--purple-400: #be8fc8; + --c--theme--colors--purple-500: #a563b1; + --c--theme--colors--purple-600: #8b44a5; + --c--theme--colors--yellow-400: #edc947; + --c--theme--colors--yellow-500: #dbb13a; + --c--theme--colors--yellow-600: #b88a34; + --c--theme--font--families--base: inter, roboto flex variable, sans-serif; + --c--theme--font--families--accent: inter, roboto flex variable, sans-serif; + --c--components--button--primary--background--color-hover: var( + --c--theme--colors--primary-focus + ); + --c--components--button--primary--background--color-active: var( + --c--theme--colors--primary-focus + ); + --c--components--button--primary--background--color-focus: var( + --c--theme--colors--primary-focus + ); +} + .clr-secondary-text { color: var(--c--theme--colors--secondary-text); } @@ -910,6 +1061,14 @@ color: var(--c--theme--colors--primary-bg); } +.clr-primary-focus { + color: var(--c--theme--colors--primary-focus); +} + +.clr-secondary-icon { + color: var(--c--theme--colors--secondary-icon); +} + .clr-blue-400 { color: var(--c--theme--colors--blue-400); } @@ -1366,6 +1525,14 @@ background-color: var(--c--theme--colors--primary-bg); } +.bg-primary-focus { + background-color: var(--c--theme--colors--primary-focus); +} + +.bg-secondary-icon { + background-color: var(--c--theme--colors--secondary-icon); +} + .bg-blue-400 { background-color: var(--c--theme--colors--blue-400); } diff --git a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts index 1687edf4..27d06644 100644 --- a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts +++ b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts @@ -96,6 +96,8 @@ export const tokens = { 'rose-500': '#E18B76', 'primary-action': '#1212FF', 'primary-bg': '#FAFAFA', + 'primary-focus': '#0A76F6', + 'secondary-icon': 'var(--c--theme--colors--primary-text)', 'blue-400': '#7AB1E8', 'blue-600': '#3558A2', 'brown-400': '#E6BE92', @@ -208,12 +210,7 @@ export const tokens = { mobile: '768px', tablet: '1024px', }, - logo: { - src: '/assets/logo-gouv.svg', - widthHeader: '110px', - widthFooter: '220px', - alt: 'Gouvernement Logo', - }, + logo: { src: '', alt: '', widthHeader: '', widthFooter: '' }, }, components: { modal: { 'width-small': '342px' }, @@ -366,8 +363,9 @@ export const tokens = { warning: { 'background-color': '#fff4f3', color: '#b34000' }, info: { 'background-color': '#E8EDFF', color: '#0063CB' }, }, - 'la-gauffre': { activated: true }, - 'home-proconnect': { activated: true }, + 'la-gaufre': false, + 'home-proconnect': false, + beta: false, }, }, dark: { @@ -422,5 +420,163 @@ export const tokens = { }, }, }, + dsfr: { + theme: { + colors: { 'secondary-icon': '#C9191E' }, + logo: { + src: '/assets/logo-gouv.svg', + widthHeader: '110px', + widthFooter: '220px', + alt: 'Gouvernement Logo', + }, + }, + components: { 'la-gaufre': true, 'home-proconnect': true, beta: true }, + }, + generic: { + theme: { + colors: { + 'primary-action': '#206EBD', + 'primary-focus': '#1E64BF', + 'primary-text': '#2E2C28', + 'primary-050': '#F8F8F7', + 'primary-100': '#F0EFEC', + 'primary-150': '#F4F4FD', + 'primary-200': '#E8E7E4', + 'primary-300': '#CFCDC9', + 'primary-400': '#979592', + 'primary-500': '#82807D', + 'primary-600': '#3F3D39', + 'primary-700': '#2E2C28', + 'primary-800': '#302E29', + 'primary-900': '#282622', + 'primary-950': '#201F1C', + 'secondary-text': '#fff', + 'secondary-50': '#F4F7FA', + 'secondary-100': '#D7E3EE', + 'secondary-200': '#B8CCE1', + 'secondary-300': '#99B4D3', + 'secondary-400': '#7595BE', + 'secondary-500': '#5874A0', + 'secondary-600': '#3A5383', + 'secondary-700': '#1E3462', + 'secondary-800': '#091B41', + 'secondary-900': '#08183B', + 'secondary-950': '#071636', + 'greyscale-text': '#3C3B38', + 'greyscale-000': '#fff', + 'greyscale-050': '#F8F7F7', + 'greyscale-100': '#F3F3F2', + 'greyscale-200': '#ECEBEA', + 'greyscale-250': '#E4E3E2', + 'greyscale-300': '#D3D2CF', + 'greyscale-350': '#eee', + 'greyscale-400': '#96948E', + 'greyscale-500': '#817E77', + 'greyscale-600': '#6A6862', + 'greyscale-700': '#3C3B38', + 'greyscale-750': '#383632', + 'greyscale-800': '#2D2B27', + 'greyscale-900': '#262522', + 'greyscale-950': '#201F1C', + 'greyscale-1000': '#181714', + 'success-text': '#234935', + 'success-50': '#F3FBF5', + 'success-100': '#E4F7EA', + 'success-200': '#CAEED4', + 'success-300': '#A0E0B5', + 'success-400': '#6CC88C', + 'success-500': '#6CC88C', + 'success-600': '#358D5C', + 'success-700': '#2D704B', + 'success-800': '#28583F', + 'success-900': '#234935', + 'success-950': '#0F281B', + 'info-text': '#212445', + 'info-50': '#F2F6FB', + 'info-100': '#E2E9F5', + 'info-200': '#CCD8EE', + 'info-300': '#A9C0E3', + 'info-400': '#809DD4', + 'info-500': '#617BC7', + 'info-600': '#4A5CBF', + 'info-700': '#3E49B2', + 'info-800': '#353C8F', + 'info-900': '#303771', + 'info-950': '#212445', + 'warning-text': '#D97C3A', + 'warning-50': '#FDF7F1', + 'warning-100': '#FBEDDC', + 'warning-200': '#F5D9B9', + 'warning-300': '#EDBE8C', + 'warning-400': '#E2985C', + 'warning-500': '#D97C3A', + 'warning-600': '#C96330', + 'warning-700': '#A34B32', + 'warning-800': '#813B2C', + 'warning-900': '#693327', + 'warning-950': '#381713', + 'danger-action': '#C0182A', + 'danger-text': '#FFF', + 'danger-050': '#FDF5F4', + 'danger-100': '#FBEBE8', + 'danger-200': '#F9E0DC', + 'danger-300': '#F3C3BD', + 'danger-400': '#E26552', + 'danger-500': '#C91F00', + 'danger-600': '#A71901', + 'danger-700': '#562C2B', + 'danger-800': '#392425', + 'danger-900': '#311F20', + 'danger-950': '#2A191A', + 'blue-400': '#8BAECC', + 'blue-500': '#567AA2', + 'blue-600': '#455784', + 'brown-400': '#E4C090', + 'brown-500': '#BA9977', + 'brown-600': '#735C45', + 'cyan-400': '#5CBEC9', + 'cyan-500': '#43A1B3', + 'cyan-600': '#39809B', + 'gold-400': '#ECBF50', + 'gold-500': '#DFA038', + 'gold-600': '#C17B31', + 'green-400': '#5DBD9A', + 'green-500': '#3AA183', + 'green-600': '#2A816D', + 'olive-400': '#AFD662', + 'olive-500': '#90BB4B', + 'olive-600': '#6E9441', + 'orange-400': '#E2985C', + 'orange-500': '#D97C3A', + 'orange-600': '#C96330', + 'pink-400': '#BE8FC8', + 'pink-500': '#A563B1', + 'pink-600': '#8B44A5', + 'purple-400': '#BE8FC8', + 'purple-500': '#A563B1', + 'purple-600': '#8B44A5', + 'yellow-400': '#EDC947', + 'yellow-500': '#DBB13A', + 'yellow-600': '#B88A34', + }, + font: { + families: { + base: 'Inter, Roboto Flex Variable, sans-serif', + accent: 'Inter, Roboto Flex Variable, sans-serif', + }, + }, + }, + components: { + button: { + primary: { + background: { + 'color-hover': 'var(--c--theme--colors--primary-focus)', + 'color-active': 'var(--c--theme--colors--primary-focus)', + 'color-focus': 'var(--c--theme--colors--primary-focus)', + }, + }, + }, + }, + }, }, }; diff --git a/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx b/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx index 7cc5e662..0e266199 100644 --- a/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx +++ b/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx @@ -12,30 +12,32 @@ type ComponentTokens = Tokens['components']; export type Theme = keyof typeof tokens.themes; interface ThemeStore { - theme: Theme; - setTheme: (theme: Theme) => void; - themeTokens: Partial; colorsTokens: Partial; - fontSizesTokens: Partial; - spacingsTokens: Partial; componentTokens: ComponentTokens; + currentTokens: Partial; + fontSizesTokens: Partial; + setTheme: (theme: Theme) => void; + spacingsTokens: Partial; + theme: Theme; + themeTokens: Partial; } const getMergedTokens = (theme: Theme) => { return merge({}, tokens.themes['default'], tokens.themes[theme]); }; -const DEFAULT_THEME: Theme = 'default'; +const DEFAULT_THEME: Theme = 'generic'; const defaultTokens = getMergedTokens(DEFAULT_THEME); const initialState: ThemeStore = { - theme: DEFAULT_THEME, - setTheme: () => {}, - themeTokens: defaultTokens.theme, colorsTokens: defaultTokens.theme.colors, componentTokens: defaultTokens.components, - spacingsTokens: defaultTokens.theme.spacings, + currentTokens: tokens.themes[DEFAULT_THEME] as Partial, fontSizesTokens: defaultTokens.theme.font.sizes, + setTheme: () => {}, + spacingsTokens: defaultTokens.theme.spacings, + theme: DEFAULT_THEME, + themeTokens: defaultTokens.theme, }; export const useCunninghamTheme = create((set) => ({ @@ -44,12 +46,13 @@ export const useCunninghamTheme = create((set) => ({ const newTokens = getMergedTokens(theme); set({ - theme, - themeTokens: newTokens.theme, colorsTokens: newTokens.theme.colors, componentTokens: newTokens.components, - spacingsTokens: newTokens.theme.spacings, + currentTokens: tokens.themes[theme] as Partial, fontSizesTokens: newTokens.theme.font.sizes, + spacingsTokens: newTokens.theme.spacings, + theme, + themeTokens: newTokens.theme, }); }, })); diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/assets/pinned-document.svg b/src/frontend/apps/impress/src/features/docs/docs-grid/assets/pinned-document.svg index af34c0b0..027fb33b 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/assets/pinned-document.svg +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/assets/pinned-document.svg @@ -1,51 +1,138 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/assets/simple-document.svg b/src/frontend/apps/impress/src/features/docs/docs-grid/assets/simple-document.svg index 817cf203..ee656f0d 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/assets/simple-document.svg +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/assets/simple-document.svg @@ -1,37 +1,117 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/components/SimpleDocItem.tsx b/src/frontend/apps/impress/src/features/docs/docs-grid/components/SimpleDocItem.tsx index 1a02d87a..e4d13834 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/components/SimpleDocItem.tsx +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/components/SimpleDocItem.tsx @@ -32,7 +32,7 @@ export const SimpleDocItem = ({ showAccesses = false, }: SimpleDocItemProps) => { const { t } = useTranslation(); - const { spacingsTokens } = useCunninghamTheme(); + const { spacingsTokens, colorsTokens } = useCunninghamTheme(); const { isDesktop } = useResponsiveStore(); const { untitledDocument } = useTrans(); @@ -52,9 +52,15 @@ export const SimpleDocItem = ({ `} > {isPinned ? ( - + ) : ( - + )} diff --git a/src/frontend/apps/impress/src/features/header/assets/icon-cells.svg b/src/frontend/apps/impress/src/features/header/assets/icon-cells.svg deleted file mode 100644 index 15329758..00000000 --- a/src/frontend/apps/impress/src/features/header/assets/icon-cells.svg +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - diff --git a/src/frontend/apps/impress/src/features/header/components/Header.tsx b/src/frontend/apps/impress/src/features/header/components/Header.tsx index 73b15d7e..39f3ce63 100644 --- a/src/frontend/apps/impress/src/features/header/components/Header.tsx +++ b/src/frontend/apps/impress/src/features/header/components/Header.tsx @@ -48,7 +48,11 @@ export const Header = () => { $height="fit-content" $margin={{ top: 'auto' }} > - + </Box> </StyledLink> diff --git a/src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx b/src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx index 8f99198d..39c4f1ea 100644 --- a/src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx +++ b/src/frontend/apps/impress/src/features/header/components/LaGaufre.tsx @@ -15,7 +15,7 @@ const GaufreStyle = createGlobalStyle` export const LaGaufre = () => { const { componentTokens } = useCunninghamTheme(); - if (!componentTokens['la-gauffre'].activated) { + if (!componentTokens['la-gaufre']) { return null; } diff --git a/src/frontend/apps/impress/src/features/header/components/Title.tsx b/src/frontend/apps/impress/src/features/header/components/Title.tsx index be3b2706..9c328e4f 100644 --- a/src/frontend/apps/impress/src/features/header/components/Title.tsx +++ b/src/frontend/apps/impress/src/features/header/components/Title.tsx @@ -6,7 +6,9 @@ import { useCunninghamTheme } from '@/cunningham'; export const Title = () => { const { t } = useTranslation(); - const { spacingsTokens } = useCunninghamTheme(); + const { spacingsTokens, colorsTokens, componentTokens } = + useCunninghamTheme(); + const isBeta = componentTokens['beta']; return ( <Box @@ -18,32 +20,34 @@ export const Title = () => { <Text $margin="none" as="h2" - $color="#000091" + $color={colorsTokens['primary-text']} $zIndex={1} $size="1.375rem" > {t('Docs')} </Text> - <Text - $padding={{ - horizontal: '6px', - vertical: '4px', - }} - $size="11px" - $theme="primary" - $variation="500" - $weight="bold" - $radius="12px" - $css={css` - line-height: 9px; - `} - $width="40px" - $height="16px" - $background="#ECECFF" - $color="#5958D3" - > - BETA - </Text> + {isBeta && ( + <Text + $padding={{ + horizontal: '6px', + vertical: '4px', + }} + $size="11px" + $theme="primary" + $variation="500" + $weight="bold" + $radius="12px" + $css={css` + line-height: 9px; + `} + $width="40px" + $height="16px" + $background="#ECECFF" + $color="#5958D3" + > + BETA + </Text> + )} </Box> ); }; diff --git a/src/frontend/apps/impress/src/features/home/components/HomeBanner.tsx b/src/frontend/apps/impress/src/features/home/components/HomeBanner.tsx index e6c2d03c..03d92cb3 100644 --- a/src/frontend/apps/impress/src/features/home/components/HomeBanner.tsx +++ b/src/frontend/apps/impress/src/features/home/components/HomeBanner.tsx @@ -3,7 +3,7 @@ import Image from 'next/image'; import { useTranslation } from 'react-i18next'; import { css } from 'styled-components'; -import DocLogo from '@/assets/icons/icon-docs.svg?url'; +import IconDocs from '@/assets/icons/icon-docs.svg'; import { Box, Icon, Text } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; import { ProConnectButton, gotoLogin } from '@/features/auth'; @@ -15,9 +15,10 @@ import { getHeaderHeight } from './HomeHeader'; export default function HomeBanner() { const { t } = useTranslation(); - const { componentTokens, spacingsTokens } = useCunninghamTheme(); + const { componentTokens, spacingsTokens, colorsTokens } = + useCunninghamTheme(); const { isMobile, isSmallMobile } = useResponsiveStore(); - const withProConnect = componentTokens['home-proconnect'].activated; + const withProConnect = componentTokens['home-proconnect']; return ( <Box @@ -46,7 +47,11 @@ export default function HomeBanner() { $align="center" $gap={spacingsTokens['sm']} > - <Image src={DocLogo} alt="DocLogo" width={64} /> + <IconDocs + aria-label={t('Docs Logo')} + width={64} + color={colorsTokens['primary-text']} + /> <Text as="h2" $size={!isMobile ? 'xs-alt' : '2.3rem'} diff --git a/src/frontend/apps/impress/src/features/home/components/HomeBottom.tsx b/src/frontend/apps/impress/src/features/home/components/HomeBottom.tsx index fcf6f7b9..0c498347 100644 --- a/src/frontend/apps/impress/src/features/home/components/HomeBottom.tsx +++ b/src/frontend/apps/impress/src/features/home/components/HomeBottom.tsx @@ -1,7 +1,6 @@ -import Image from 'next/image'; import { useTranslation } from 'react-i18next'; -import DocLogo from '@/assets/icons/icon-docs.svg?url'; +import IconDocs from '@/assets/icons/icon-docs.svg'; import { Box, Text } from '@/components'; import { useCunninghamTheme } from '@/cunningham'; import { ProConnectButton } from '@/features/auth'; @@ -10,7 +9,7 @@ import { useResponsiveStore } from '@/stores'; export function HomeBottom() { const { componentTokens } = useCunninghamTheme(); - const withProConnect = componentTokens['home-proconnect'].activated; + const withProConnect = componentTokens['home-proconnect']; if (!withProConnect) { return null; @@ -21,7 +20,7 @@ export function HomeBottom() { function HomeProConnect() { const { t } = useTranslation(); - const { spacingsTokens } = useCunninghamTheme(); + const { spacingsTokens, colorsTokens } = useCunninghamTheme(); const { isMobile } = useResponsiveStore(); const parentGap = '230px'; @@ -45,7 +44,11 @@ function HomeProConnect() { $height="fit-content" $css="zoom: 1.9;" > - <Image src={DocLogo} alt="DocLogo" /> + <IconDocs + aria-label={t('Docs Logo')} + width={34} + color={colorsTokens['primary-text']} + /> <Title /> </Box> <Text $size="md" $variation="1000" $textAlign="center"> diff --git a/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx b/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx index 39390c25..ae4cdc9a 100644 --- a/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx +++ b/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx @@ -61,7 +61,7 @@ export function HomeContent() { $gap={isMobile ? '115px' : '230px'} $padding={{ bottom: '3rem' }} > - <Box $gap="30px"> + <Box $gap={isMobile ? '115px' : '30px'}> <HomeSection isColumn={false} isSmallDevice={isTablet} diff --git a/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx b/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx index 2c285d14..4837b7f9 100644 --- a/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx +++ b/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx @@ -17,7 +17,7 @@ export const getHeaderHeight = (isSmallMobile: boolean) => export const HomeHeader = () => { const { t } = useTranslation(); - const { themeTokens, spacingsTokens } = useCunninghamTheme(); + const { themeTokens, spacingsTokens, colorsTokens } = useCunninghamTheme(); const logo = themeTokens.logo; const { isSmallMobile } = useResponsiveStore(); @@ -44,7 +44,7 @@ export const HomeHeader = () => { <ButtonTogglePanel /> </Box> )} - {!isSmallMobile && logo && ( + {!isSmallMobile && logo?.src && ( <Image priority src={logo.src} @@ -61,7 +61,11 @@ export const HomeHeader = () => { $position="relative" $height="fit-content" > - <IconDocs aria-label={t('Docs Logo')} width={32} /> + <IconDocs + aria-label={t('Docs Logo')} + width={32} + color={colorsTokens['primary-text']} + /> <Title /> </Box> </Box> diff --git a/src/frontend/apps/impress/src/pages/404.tsx b/src/frontend/apps/impress/src/pages/404.tsx index 6bd66271..f4d008ed 100644 --- a/src/frontend/apps/impress/src/pages/404.tsx +++ b/src/frontend/apps/impress/src/pages/404.tsx @@ -1,37 +1,44 @@ import { Button } from '@openfun/cunningham-react'; +import Image from 'next/image'; import { ReactElement } from 'react'; import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; -import Icon404 from '@/assets/icons/icon-404.svg'; +import img403 from '@/assets/icons/icon-403.png'; import { Box, Icon, StyledLink, Text } from '@/components'; import { PageLayout } from '@/layouts'; import { NextPageWithLayout } from '@/types/next'; const StyledButton = styled(Button)` width: fit-content; - padding-left: 2rem; - padding-right: 2rem; `; const Page: NextPageWithLayout = () => { const { t } = useTranslation(); return ( - <Box $align="center" $margin="auto" $height="70vh" $gap="2rem"> - <Icon404 aria-label="Image 404" role="img" /> + <Box + $align="center" + $margin="auto" + $gap="1rem" + $padding={{ bottom: '2rem' }} + > + <Image + src={img403} + alt={t('Image 403')} + style={{ + maxWidth: '100%', + height: 'auto', + }} + /> - <Text $size="h2" $weight="700" $theme="greyscale" $variation="900"> - {t('Ouch !')} - </Text> + <Box $align="center" $gap="0.8rem"> + <Text as="p" $textAlign="center" $maxWidth="350px" $theme="primary"> + {t( + 'It seems that the page you are looking for does not exist or cannot be displayed correctly.', + )} + </Text> - <Text as="p" $textAlign="center" $maxWidth="400px" $size="m"> - {t( - 'It seems that the page you are looking for does not exist or cannot be displayed correctly.', - )} - </Text> - - <Box $margin={{ top: 'large' }}> <StyledLink href="/"> <StyledButton icon={<Icon iconName="house" $color="white" />}> {t('Home')}