Compare commits

...

1 Commits

Author SHA1 Message Date
Cyril 46000bed33 ️(frontend) add contextual browser tab titles for docs routes
Each page sets its own tab title instead of generic "Docs"
2026-03-26 09:21:14 +01:00
6 changed files with 92 additions and 21 deletions
+1
View File
@@ -17,6 +17,7 @@ and this project adheres to
- ♿️(frontend) improve language picker accessibility #2069
- ♿️(frontend) add aria-hidden to decorative icons in dropdown menu #2093
- 🐛(backend) move lock table closer to the insert operation targeted
- ♿️(frontend) add contextual browser tab titles for docs routes #2120
### Fixed
@@ -1,6 +1,6 @@
import { useTranslation } from 'react-i18next';
import { Role } from '../types';
import { DocDefaultFilter, Role } from '../types';
export const useTrans = () => {
const { t } = useTranslation();
@@ -12,11 +12,22 @@ export const useTrans = () => {
[Role.OWNER]: t('Owner'),
};
const translatedFilters = {
[DocDefaultFilter.ALL_DOCS]: t('All docs'),
[DocDefaultFilter.MY_DOCS]: t('My docs'),
[DocDefaultFilter.SHARED_WITH_ME]: t('Shared with me'),
[DocDefaultFilter.TRASHBIN]: t('Trashbin'),
};
return {
transRole: (role: Role) => {
return translatedRoles[role];
},
transFilter: (filter: DocDefaultFilter) => {
return translatedFilters[filter];
},
untitledDocument: t('Untitled document'),
translatedRoles,
translatedFilters,
};
};
@@ -1,16 +1,35 @@
import Head from 'next/head';
import { useSearchParams } from 'next/navigation';
import type { ReactElement } from 'react';
import { useTranslation } from 'react-i18next';
import { DocDefaultFilter } from '@/docs/doc-management';
import { DocDefaultFilter, useTrans } from '@/docs/doc-management';
import { DocsGrid } from '@/docs/docs-grid';
import { MainLayout } from '@/layouts';
import { NextPageWithLayout } from '@/types/next';
const Page: NextPageWithLayout = () => {
const { t } = useTranslation();
const { transFilter } = useTrans();
const searchParams = useSearchParams();
const target = searchParams.get('target');
const target =
(searchParams.get('target') as DocDefaultFilter) ??
DocDefaultFilter.ALL_DOCS;
const pageTitle = transFilter(target);
return <DocsGrid target={target as DocDefaultFilter} />;
return (
<>
<Head>
<title>{`${pageTitle} - ${t('Docs')}`}</title>
<meta
property="og:title"
content={`${pageTitle} - ${t('Docs')}`}
key="title"
/>
</Head>
<DocsGrid target={target} />
</>
);
};
Page.getLayout = function getLayout(page: ReactElement) {
@@ -3,6 +3,7 @@ import Head from 'next/head';
import { useSearchParams } from 'next/navigation';
import { useRouter } from 'next/router';
import { ReactElement, useCallback, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { Loading } from '@/components';
import { LOGIN_URL, setAuthUrl, useAuth } from '@/features/auth';
@@ -17,6 +18,7 @@ import { MainLayout } from '@/layouts';
import { NextPageWithLayout } from '@/types/next';
const Page: NextPageWithLayout = () => {
const { t } = useTranslation();
const { setIsSkeletonVisible } = useSkeletonStore();
const router = useRouter();
const searchParams = useSearchParams();
@@ -96,7 +98,19 @@ const Page: NextPageWithLayout = () => {
updateDocLinkAsync,
]);
return <Loading />;
return (
<>
<Head>
<title>{`${t('New document')} - ${t('Docs')}`}</title>
<meta
property="og:title"
content={`${t('New document')} - ${t('Docs')}`}
key="title"
/>
</Head>
<Loading />
</>
);
};
Page.getLayout = function getLayout(page: ReactElement) {
@@ -1,5 +1,7 @@
import Head from 'next/head';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { Loading } from '@/components';
import { useAuth } from '@/features/auth';
@@ -7,6 +9,7 @@ import { HomeContent } from '@/features/home';
import { NextPageWithLayout } from '@/types/next';
const Page: NextPageWithLayout = () => {
const { t } = useTranslation();
const { authenticated } = useAuth();
const { replace } = useRouter();
@@ -25,7 +28,19 @@ const Page: NextPageWithLayout = () => {
return <Loading $height="100vh" $width="100vw" />;
}
return <HomeContent />;
return (
<>
<Head>
<title>{`${t('Home')} - ${t('Docs')}`}</title>
<meta
property="og:title"
content={`${t('Home')} - ${t('Docs')}`}
key="title"
/>
</Head>
<HomeContent />
</>
);
};
export default Page;
@@ -1,4 +1,5 @@
import { Button } from '@gouvfr-lasuite/cunningham-react';
import Head from 'next/head';
import { ReactElement } from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
@@ -18,25 +19,35 @@ const Page: NextPageWithLayout = () => {
const { t } = useTranslation();
return (
<Box $align="center" $margin="auto" $height="70vh" $gap="2rem">
<Icon404 aria-label="Image 404" role="img" />
<>
<Head>
<title>{`${t('Offline')} - ${t('Docs')}`}</title>
<meta
property="og:title"
content={`${t('Offline')} - ${t('Docs')}`}
key="title"
/>
</Head>
<Box $align="center" $margin="auto" $height="70vh" $gap="2rem">
<Icon404 aria-label="Image 404" role="img" />
<Text $size="h2" $weight="700">
{t('Offline ?!')}
</Text>
<Text $size="h2" $weight="700">
{t('Offline ?!')}
</Text>
<Text as="p" $textAlign="center" $maxWidth="400px" $size="m">
{t("Can't load this page, please check your internet connection.")}
</Text>
<Text as="p" $textAlign="center" $maxWidth="400px" $size="m">
{t("Can't load this page, please check your internet connection.")}
</Text>
<Box $margin={{ top: 'large' }}>
<StyledLink href="/">
<StyledButton icon={<Icon iconName="house" $color="white" />}>
{t('Home')}
</StyledButton>
</StyledLink>
<Box $margin={{ top: 'large' }}>
<StyledLink href="/">
<StyledButton icon={<Icon iconName="house" $color="white" />}>
{t('Home')}
</StyledButton>
</StyledLink>
</Box>
</Box>
</Box>
</>
);
};