diff --git a/src/frontend/Dockerfile b/src/frontend/Dockerfile index de961185..c10ce231 100644 --- a/src/frontend/Dockerfile +++ b/src/frontend/Dockerfile @@ -61,9 +61,6 @@ FROM impress AS impress-builder WORKDIR /home/frontend/apps/impress -ARG FRONTEND_THEME -ENV NEXT_PUBLIC_THEME=${FRONTEND_THEME} - ARG Y_PROVIDER_URL ENV NEXT_PUBLIC_Y_PROVIDER_URL=${Y_PROVIDER_URL} 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 3a6f8c94..c0a2c4c4 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts @@ -56,4 +56,25 @@ test.describe('Config', () => { expect((await consoleMessage).text()).toContain(invalidMsg); }); + + test('it checks that theme is configured from config endpoint', 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 jsonResponse = await response.json(); + expect(jsonResponse.FRONTEND_THEME).toStrictEqual('dsfr'); + + const footer = page.locator('footer').first(); + // alt 'Gouvernement Logo' comes from the theme + await expect(footer.getByAltText('Gouvernement Logo')).toBeVisible(); + }); }); diff --git a/src/frontend/apps/impress/.env b/src/frontend/apps/impress/.env index 393b6b3c..051e4595 100644 --- a/src/frontend/apps/impress/.env +++ b/src/frontend/apps/impress/.env @@ -1,5 +1,4 @@ NEXT_PUBLIC_API_ORIGIN= NEXT_PUBLIC_Y_PROVIDER_URL= NEXT_PUBLIC_MEDIA_URL= -NEXT_PUBLIC_THEME=dsfr NEXT_PUBLIC_SW_DEACTIVATED= diff --git a/src/frontend/apps/impress/.env.test b/src/frontend/apps/impress/.env.test index 6d5094f8..9a4d5142 100644 --- a/src/frontend/apps/impress/.env.test +++ b/src/frontend/apps/impress/.env.test @@ -1,2 +1 @@ NEXT_PUBLIC_API_ORIGIN=http://test.jest -NEXT_PUBLIC_THEME=test-theme diff --git a/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx b/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx index faa46de2..217866e9 100644 --- a/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx +++ b/src/frontend/apps/impress/src/core/config/ConfigProvider.tsx @@ -1,5 +1,8 @@ +import { Loader } from '@openfun/cunningham-react'; import { PropsWithChildren, useEffect } from 'react'; +import { Box } from '@/components'; +import { useCunninghamTheme } from '@/cunningham'; import { useSentryStore } from '@/stores/useSentryStore'; import { useConfig } from './api/useConfig'; @@ -7,6 +10,7 @@ import { useConfig } from './api/useConfig'; export const ConfigProvider = ({ children }: PropsWithChildren) => { const { data: conf } = useConfig(); const { setSentry } = useSentryStore(); + const { setTheme } = useCunninghamTheme(); useEffect(() => { if (!conf?.SENTRY_DSN) { @@ -16,5 +20,21 @@ export const ConfigProvider = ({ children }: PropsWithChildren) => { setSentry(conf.SENTRY_DSN, conf.ENVIRONMENT); }, [conf?.SENTRY_DSN, conf?.ENVIRONMENT, setSentry]); + useEffect(() => { + if (!conf?.FRONTEND_THEME) { + return; + } + + setTheme(conf.FRONTEND_THEME); + }, [conf?.FRONTEND_THEME, setTheme]); + + if (!conf) { + return ( + + + + ); + } + return children; }; diff --git a/src/frontend/apps/impress/src/core/config/api/useConfig.tsx b/src/frontend/apps/impress/src/core/config/api/useConfig.tsx index f4b4ef7a..8717c56b 100644 --- a/src/frontend/apps/impress/src/core/config/api/useConfig.tsx +++ b/src/frontend/apps/impress/src/core/config/api/useConfig.tsx @@ -1,12 +1,13 @@ import { useQuery } from '@tanstack/react-query'; import { APIError, errorCauses, fetchAPI } from '@/api'; +import { Theme } from '@/cunningham/'; interface ConfigResponse { SENTRY_DSN: string; COLLABORATION_SERVER_URL: string; ENVIRONMENT: string; - FRONTEND_THEME: string; + FRONTEND_THEME: Theme; LANGUAGES: [string, string][]; LANGUAGE_CODE: string; MEDIA_BASE_URL: string; 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 f6a32fff..69f1dff2 100644 --- a/src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx +++ b/src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx @@ -1,12 +1,6 @@ -import useCunninghamTheme from '../useCunninghamTheme'; +import { useCunninghamTheme } from '../useCunninghamTheme'; describe('', () => { - it('has the theme from NEXT_PUBLIC_THEME', () => { - const { theme } = useCunninghamTheme.getState(); - - expect(theme).toBe('test-theme'); - }); - it('has the dsfr logo correctly set', () => { const { themeTokens, setTheme } = useCunninghamTheme.getState(); setTheme('dsfr'); diff --git a/src/frontend/apps/impress/src/cunningham/index.ts b/src/frontend/apps/impress/src/cunningham/index.ts index e955768b..1e5bd52d 100644 --- a/src/frontend/apps/impress/src/cunningham/index.ts +++ b/src/frontend/apps/impress/src/cunningham/index.ts @@ -1,4 +1,2 @@ -import { tokens } from './cunningham-tokens'; -import useCunninghamTheme from './useCunninghamTheme'; - -export { tokens, useCunninghamTheme }; +export * from './cunningham-tokens'; +export * from './useCunninghamTheme'; diff --git a/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx b/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx index a951a830..26ea5975 100644 --- a/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx +++ b/src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx @@ -6,22 +6,25 @@ import { tokens } from './cunningham-tokens'; type Tokens = typeof tokens.themes.default & Partial; type ColorsTokens = Tokens['theme']['colors']; type ComponentTokens = Tokens['components']; -type Theme = 'default' | 'dsfr'; +export type Theme = keyof typeof tokens.themes; interface AuthStore { - theme: Theme; + theme: string; setTheme: (theme: Theme) => void; themeTokens: () => Partial; colorsTokens: () => Partial; componentTokens: () => ComponentTokens; } -const useCunninghamTheme = create((set, get) => { +export const useCunninghamTheme = create((set, get) => { const currentTheme = () => - merge(tokens.themes['default'], tokens.themes[get().theme]) as Tokens; + merge( + tokens.themes['default'], + tokens.themes[get().theme as keyof typeof tokens.themes], + ) as Tokens; return { - theme: (process.env.NEXT_PUBLIC_THEME as Theme) || 'dsfr', + theme: 'dsfr', themeTokens: () => currentTheme().theme, colorsTokens: () => currentTheme().theme.colors, componentTokens: () => currentTheme().components, @@ -30,5 +33,3 @@ const useCunninghamTheme = create((set, get) => { }, }; }); - -export default useCunninghamTheme; diff --git a/src/frontend/apps/impress/src/custom-next.d.ts b/src/frontend/apps/impress/src/custom-next.d.ts index ff3906c6..ec8d7d06 100644 --- a/src/frontend/apps/impress/src/custom-next.d.ts +++ b/src/frontend/apps/impress/src/custom-next.d.ts @@ -23,6 +23,5 @@ namespace NodeJS { NEXT_PUBLIC_MEDIA_URL?: string; NEXT_PUBLIC_Y_PROVIDER_URL?: string; NEXT_PUBLIC_SW_DEACTIVATED?: string; - NEXT_PUBLIC_THEME?: string; } } diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalRemoveDoc.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalRemoveDoc.tsx index f2600b3c..6b341b70 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalRemoveDoc.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/components/ModalRemoveDoc.tsx @@ -10,7 +10,7 @@ import { t } from 'i18next'; import { useRouter } from 'next/router'; import { Box, Text, TextErrors } from '@/components'; -import useCunninghamTheme from '@/cunningham/useCunninghamTheme'; +import { useCunninghamTheme } from '@/cunningham/'; import { useRemoveDoc } from '../api/useRemoveDoc'; import IconDoc from '../assets/icon-doc.svg';