Skip to content

Commit 6252227

Browse files
committed
♻️(frontend) get theme from config endpoint
We centralized the configuration on the backend side, it is easier to manage and we can change the configuration without having to rebuild the frontend. We now use the config endpoint to get the theme, we refacto to remove the frontend env occurences and to adapt with the new way to get the theme.
1 parent e9ac393 commit 6252227

File tree

11 files changed

+55
-26
lines changed

11 files changed

+55
-26
lines changed

src/frontend/Dockerfile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ FROM impress AS impress-builder
6161

6262
WORKDIR /home/frontend/apps/impress
6363

64-
ARG FRONTEND_THEME
65-
ENV NEXT_PUBLIC_THEME=${FRONTEND_THEME}
66-
6764
ARG Y_PROVIDER_URL
6865
ENV NEXT_PUBLIC_Y_PROVIDER_URL=${Y_PROVIDER_URL}
6966

src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,25 @@ test.describe('Config', () => {
5656

5757
expect((await consoleMessage).text()).toContain(invalidMsg);
5858
});
59+
60+
test('it checks that theme is configured from config endpoint', async ({
61+
page,
62+
}) => {
63+
const responsePromise = page.waitForResponse(
64+
(response) =>
65+
response.url().includes('/config/') && response.status() === 200,
66+
);
67+
68+
await page.goto('/');
69+
70+
const response = await responsePromise;
71+
expect(response.ok()).toBeTruthy();
72+
73+
const jsonResponse = await response.json();
74+
expect(jsonResponse.FRONTEND_THEME).toStrictEqual('dsfr');
75+
76+
const footer = page.locator('footer').first();
77+
// alt 'Gouvernement Logo' comes from the theme
78+
await expect(footer.getByAltText('Gouvernement Logo')).toBeVisible();
79+
});
5980
});

src/frontend/apps/impress/.env

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
NEXT_PUBLIC_API_ORIGIN=
22
NEXT_PUBLIC_Y_PROVIDER_URL=
33
NEXT_PUBLIC_MEDIA_URL=
4-
NEXT_PUBLIC_THEME=dsfr
54
NEXT_PUBLIC_SW_DEACTIVATED=
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
NEXT_PUBLIC_API_ORIGIN=http://test.jest
2-
NEXT_PUBLIC_THEME=test-theme

src/frontend/apps/impress/src/core/config/ConfigProvider.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1+
import { Loader } from '@openfun/cunningham-react';
12
import { PropsWithChildren, useEffect } from 'react';
23

4+
import { Box } from '@/components';
5+
import { useCunninghamTheme } from '@/cunningham';
36
import { useSentryStore } from '@/stores/useSentryStore';
47

58
import { useConfig } from './api/useConfig';
69

710
export const ConfigProvider = ({ children }: PropsWithChildren) => {
811
const { data: conf } = useConfig();
912
const { setSentry } = useSentryStore();
13+
const { setTheme } = useCunninghamTheme();
1014

1115
useEffect(() => {
1216
if (!conf?.SENTRY_DSN) {
@@ -16,5 +20,21 @@ export const ConfigProvider = ({ children }: PropsWithChildren) => {
1620
setSentry(conf.SENTRY_DSN, conf.ENVIRONMENT);
1721
}, [conf?.SENTRY_DSN, conf?.ENVIRONMENT, setSentry]);
1822

23+
useEffect(() => {
24+
if (!conf?.FRONTEND_THEME) {
25+
return;
26+
}
27+
28+
setTheme(conf.FRONTEND_THEME);
29+
}, [conf?.FRONTEND_THEME, setTheme]);
30+
31+
if (!conf) {
32+
return (
33+
<Box $height="100vh" $width="100vw" $align="center" $justify="center">
34+
<Loader />
35+
</Box>
36+
);
37+
}
38+
1939
return children;
2040
};

src/frontend/apps/impress/src/core/config/api/useConfig.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { useQuery } from '@tanstack/react-query';
22

33
import { APIError, errorCauses, fetchAPI } from '@/api';
4+
import { Theme } from '@/cunningham/';
45

56
interface ConfigResponse {
67
SENTRY_DSN: string;
78
COLLABORATION_SERVER_URL: string;
89
ENVIRONMENT: string;
9-
FRONTEND_THEME: string;
10+
FRONTEND_THEME: Theme;
1011
LANGUAGES: [string, string][];
1112
LANGUAGE_CODE: string;
1213
MEDIA_BASE_URL: string;

src/frontend/apps/impress/src/cunningham/__tests__/useCunninghamTheme.spec.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
import useCunninghamTheme from '../useCunninghamTheme';
1+
import { useCunninghamTheme } from '../useCunninghamTheme';
22

33
describe('<useCunninghamTheme />', () => {
4-
it('has the theme from NEXT_PUBLIC_THEME', () => {
5-
const { theme } = useCunninghamTheme.getState();
6-
7-
expect(theme).toBe('test-theme');
8-
});
9-
104
it('has the dsfr logo correctly set', () => {
115
const { themeTokens, setTheme } = useCunninghamTheme.getState();
126
setTheme('dsfr');
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
1-
import { tokens } from './cunningham-tokens';
2-
import useCunninghamTheme from './useCunninghamTheme';
3-
4-
export { tokens, useCunninghamTheme };
1+
export * from './cunningham-tokens';
2+
export * from './useCunninghamTheme';

src/frontend/apps/impress/src/cunningham/useCunninghamTheme.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,25 @@ import { tokens } from './cunningham-tokens';
66
type Tokens = typeof tokens.themes.default & Partial<typeof tokens.themes.dsfr>;
77
type ColorsTokens = Tokens['theme']['colors'];
88
type ComponentTokens = Tokens['components'];
9-
type Theme = 'default' | 'dsfr';
9+
export type Theme = keyof typeof tokens.themes;
1010

1111
interface AuthStore {
12-
theme: Theme;
12+
theme: string;
1313
setTheme: (theme: Theme) => void;
1414
themeTokens: () => Partial<Tokens['theme']>;
1515
colorsTokens: () => Partial<ColorsTokens>;
1616
componentTokens: () => ComponentTokens;
1717
}
1818

19-
const useCunninghamTheme = create<AuthStore>((set, get) => {
19+
export const useCunninghamTheme = create<AuthStore>((set, get) => {
2020
const currentTheme = () =>
21-
merge(tokens.themes['default'], tokens.themes[get().theme]) as Tokens;
21+
merge(
22+
tokens.themes['default'],
23+
tokens.themes[get().theme as keyof typeof tokens.themes],
24+
) as Tokens;
2225

2326
return {
24-
theme: (process.env.NEXT_PUBLIC_THEME as Theme) || 'dsfr',
27+
theme: 'dsfr',
2528
themeTokens: () => currentTheme().theme,
2629
colorsTokens: () => currentTheme().theme.colors,
2730
componentTokens: () => currentTheme().components,
@@ -30,5 +33,3 @@ const useCunninghamTheme = create<AuthStore>((set, get) => {
3033
},
3134
};
3235
});
33-
34-
export default useCunninghamTheme;

src/frontend/apps/impress/src/custom-next.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,5 @@ namespace NodeJS {
2323
NEXT_PUBLIC_MEDIA_URL?: string;
2424
NEXT_PUBLIC_Y_PROVIDER_URL?: string;
2525
NEXT_PUBLIC_SW_DEACTIVATED?: string;
26-
NEXT_PUBLIC_THEME?: string;
2726
}
2827
}

0 commit comments

Comments
 (0)