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';