✨(frontend) add open source section homepage
We decided to add the open source section on the homepage of Docs.
This commit is contained in:
@@ -12,6 +12,7 @@ and this project adheres to
|
|||||||
|
|
||||||
- 💄(frontend) add error pages #643
|
- 💄(frontend) add error pages #643
|
||||||
- ✨(frontend) Custom block quote with export #646
|
- ✨(frontend) Custom block quote with export #646
|
||||||
|
- ✨(frontend) add open source section homepage #666
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ test.describe('Home page', () => {
|
|||||||
|
|
||||||
// Check the titles
|
// Check the titles
|
||||||
const h2 = page.locator('h2');
|
const h2 = page.locator('h2');
|
||||||
|
await expect(h2.getByText('Govs ❤️ Open Source.')).toBeVisible();
|
||||||
await expect(
|
await expect(
|
||||||
h2.getByText('Collaborative writing, Simplified.'),
|
h2.getByText('Collaborative writing, Simplified.'),
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { Button } from '@openfun/cunningham-react';
|
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { css } from 'styled-components';
|
|
||||||
|
|
||||||
import DocLogo from '@/assets/icons/icon-docs.svg?url';
|
import DocLogo from '@/assets/icons/icon-docs.svg?url';
|
||||||
import { Box, Text } from '@/components';
|
import { Box, Text } from '@/components';
|
||||||
@@ -10,137 +8,15 @@ import { ProConnectButton } from '@/features/auth';
|
|||||||
import { Title } from '@/features/header';
|
import { Title } from '@/features/header';
|
||||||
import { useResponsiveStore } from '@/stores';
|
import { useResponsiveStore } from '@/stores';
|
||||||
|
|
||||||
import SC5 from '../assets/SC5.png';
|
|
||||||
import GithubIcon from '../assets/github.svg';
|
|
||||||
|
|
||||||
import { HomeSection } from './HomeSection';
|
|
||||||
|
|
||||||
export function HomeBottom() {
|
export function HomeBottom() {
|
||||||
const { componentTokens } = useCunninghamTheme();
|
const { componentTokens } = useCunninghamTheme();
|
||||||
const withProConnect = componentTokens()['home-proconnect'].activated;
|
const withProConnect = componentTokens()['home-proconnect'].activated;
|
||||||
|
|
||||||
if (withProConnect) {
|
if (!withProConnect) {
|
||||||
return <HomeProConnect />;
|
return null;
|
||||||
} else {
|
|
||||||
return <HomeOpenSource />;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function HomeOpenSource() {
|
return <HomeProConnect />;
|
||||||
const { t } = useTranslation();
|
|
||||||
const { colorsTokens } = useCunninghamTheme();
|
|
||||||
const { isTablet } = useResponsiveStore();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<HomeSection
|
|
||||||
isColumn={false}
|
|
||||||
isSmallDevice={isTablet}
|
|
||||||
illustration={SC5}
|
|
||||||
title={t('Govs ❤️ Open Source.')}
|
|
||||||
tag={t('Open Source')}
|
|
||||||
textWidth="60%"
|
|
||||||
description={
|
|
||||||
<Box
|
|
||||||
$css={css`
|
|
||||||
& a {
|
|
||||||
color: ${colorsTokens()['primary-600']};
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
>
|
|
||||||
<Text as="p" $display="inline">
|
|
||||||
<Trans t={t} i18nKey="home-content-open-source-part1">
|
|
||||||
Docs is built on top of{' '}
|
|
||||||
<a href="https://www.django-rest-framework.org/" target="_blank">
|
|
||||||
Django Rest Framework
|
|
||||||
</a>
|
|
||||||
,{' '}
|
|
||||||
<a href="https://nextjs.org/" target="_blank">
|
|
||||||
Next.js
|
|
||||||
</a>
|
|
||||||
, and{' '}
|
|
||||||
<a href="https://min.io/" target="_blank">
|
|
||||||
MinIO
|
|
||||||
</a>
|
|
||||||
. We also use{' '}
|
|
||||||
<a href="https://github.com/yjs" target="_blank">
|
|
||||||
Yjs
|
|
||||||
</a>{' '}
|
|
||||||
and{' '}
|
|
||||||
<a href="https://www.blocknotejs.org/" target="_blank">
|
|
||||||
BlockNote.js
|
|
||||||
</a>{' '}
|
|
||||||
of which we are proud sponsors.
|
|
||||||
</Trans>
|
|
||||||
</Text>
|
|
||||||
<Text as="p" $display="inline">
|
|
||||||
<Trans t={t} i18nKey="home-content-open-source-part2">
|
|
||||||
You can easily self-hosted Docs (check our installation{' '}
|
|
||||||
<a
|
|
||||||
href="https://github.com/suitenumerique/docs/tree/main/docs"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
documentation
|
|
||||||
</a>{' '}
|
|
||||||
with production-ready examples).
|
|
||||||
<br />
|
|
||||||
Docs uses an innovation and business friendly{' '}
|
|
||||||
<a
|
|
||||||
href="https://github.com/suitenumerique/docs/blob/main/LICENSE"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
licence
|
|
||||||
</a>
|
|
||||||
.<br />
|
|
||||||
Contributions are welcome (see our roadmap{' '}
|
|
||||||
<a
|
|
||||||
href="https://github.com/orgs/numerique-gouv/projects/13/views/11"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
here
|
|
||||||
</a>
|
|
||||||
).
|
|
||||||
</Trans>
|
|
||||||
</Text>
|
|
||||||
<Text as="p" $display="inline">
|
|
||||||
<Trans t={t} i18nKey="home-content-open-source-part3">
|
|
||||||
Docs is the result of a joint effort lead by the French 🇫🇷🥖
|
|
||||||
<a href="https://www.numerique.gouv.fr/dinum/" target="_blank">
|
|
||||||
(DINUM)
|
|
||||||
</a>{' '}
|
|
||||||
and German 🇩🇪🥨 governments{' '}
|
|
||||||
<a href="https://zendis.de/" target="_blank">
|
|
||||||
(ZenDiS)
|
|
||||||
</a>
|
|
||||||
. We are always looking for new public partners (we are currently
|
|
||||||
onboarding the Netherlands 🇳🇱🧀). Feel free to reach out if you
|
|
||||||
are interested in using or contributing to docs.
|
|
||||||
</Trans>
|
|
||||||
</Text>
|
|
||||||
<Box $direction="row" $gap="1rem" $margin={{ top: 'small' }}>
|
|
||||||
<Button
|
|
||||||
icon={
|
|
||||||
<Text $isMaterialIcon $color="white">
|
|
||||||
chat
|
|
||||||
</Text>
|
|
||||||
}
|
|
||||||
href="https://matrix.to/#/#docs-official:matrix.org"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<Text $color="white">Matrix</Text>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
color="secondary"
|
|
||||||
icon={<GithubIcon />}
|
|
||||||
href="https://github.com/suitenumerique/docs"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
Github
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function HomeProConnect() {
|
function HomeProConnect() {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { Button } from '@openfun/cunningham-react';
|
||||||
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import { css } from 'styled-components';
|
import { css } from 'styled-components';
|
||||||
|
|
||||||
import { Box } from '@/components';
|
import { Box, Text } from '@/components';
|
||||||
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
import { Footer } from '@/features/footer';
|
import { Footer } from '@/features/footer';
|
||||||
import { LeftPanel } from '@/features/left-panel';
|
import { LeftPanel } from '@/features/left-panel';
|
||||||
import { useLanguage } from '@/i18n/hooks/useLanguage';
|
import { useLanguage } from '@/i18n/hooks/useLanguage';
|
||||||
@@ -17,6 +19,8 @@ import SC4En from '../assets/SC4-en.png';
|
|||||||
import SC4Fr from '../assets/SC4-fr.png';
|
import SC4Fr from '../assets/SC4-fr.png';
|
||||||
import SC4ResponsiveEn from '../assets/SC4-responsive-en.png';
|
import SC4ResponsiveEn from '../assets/SC4-responsive-en.png';
|
||||||
import SC4ResponsiveFr from '../assets/SC4-responsive-fr.png';
|
import SC4ResponsiveFr from '../assets/SC4-responsive-fr.png';
|
||||||
|
import SC5 from '../assets/SC5.png';
|
||||||
|
import GithubIcon from '../assets/github.svg';
|
||||||
|
|
||||||
import HomeBanner from './HomeBanner';
|
import HomeBanner from './HomeBanner';
|
||||||
import { HomeBottom } from './HomeBottom';
|
import { HomeBottom } from './HomeBottom';
|
||||||
@@ -25,7 +29,8 @@ import { HomeSection } from './HomeSection';
|
|||||||
|
|
||||||
export function HomeContent() {
|
export function HomeContent() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { isMobile, isSmallMobile } = useResponsiveStore();
|
const { colorsTokens } = useCunninghamTheme();
|
||||||
|
const { isMobile, isSmallMobile, isTablet } = useResponsiveStore();
|
||||||
const lang = useLanguage();
|
const lang = useLanguage();
|
||||||
const isFrLanguage = lang.language === 'fr';
|
const isFrLanguage = lang.language === 'fr';
|
||||||
|
|
||||||
@@ -58,19 +63,142 @@ export function HomeContent() {
|
|||||||
$gap={isMobile ? '115px' : '230px'}
|
$gap={isMobile ? '115px' : '230px'}
|
||||||
$padding={{ bottom: '3rem' }}
|
$padding={{ bottom: '3rem' }}
|
||||||
>
|
>
|
||||||
<HomeSection
|
<Box $gap="30px">
|
||||||
isColumn={true}
|
<HomeSection
|
||||||
isSmallDevice={isMobile}
|
isColumn={false}
|
||||||
illustration={isFrLanguage ? SC1ResponsiveFr : SC1ResponsiveEn}
|
isSmallDevice={isTablet}
|
||||||
video={
|
illustration={SC5}
|
||||||
isFrLanguage ? `/assets/SC1-fr.webm` : `/assets/SC1-en.webm`
|
title={t('Govs ❤️ Open Source.')}
|
||||||
}
|
tag={t('Open Source')}
|
||||||
title={t('An uncompromising writing experience.')}
|
textWidth="60%"
|
||||||
tag={t('Write')}
|
$css={`min-height: calc(100vh - ${getHeaderHeight(isSmallMobile)}px);`}
|
||||||
description={t(
|
description={
|
||||||
'Docs offers an intuitive writing experience. Its minimalist interface favors content over layout, while offering the essentials: media import, offline mode and keyboard shortcuts for greater efficiency.',
|
<Box
|
||||||
)}
|
$css={css`
|
||||||
/>
|
& a {
|
||||||
|
color: ${colorsTokens()['primary-600']};
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<Text as="p" $display="inline">
|
||||||
|
<Trans t={t} i18nKey="home-content-open-source-part1">
|
||||||
|
Docs is built on top of{' '}
|
||||||
|
<a
|
||||||
|
href="https://www.django-rest-framework.org/"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Django Rest Framework
|
||||||
|
</a>
|
||||||
|
,{' '}
|
||||||
|
<a href="https://nextjs.org/" target="_blank">
|
||||||
|
Next.js
|
||||||
|
</a>
|
||||||
|
, and{' '}
|
||||||
|
<a href="https://min.io/" target="_blank">
|
||||||
|
MinIO
|
||||||
|
</a>
|
||||||
|
. We also use{' '}
|
||||||
|
<a href="https://github.com/yjs" target="_blank">
|
||||||
|
Yjs
|
||||||
|
</a>{' '}
|
||||||
|
and{' '}
|
||||||
|
<a href="https://www.blocknotejs.org/" target="_blank">
|
||||||
|
BlockNote.js
|
||||||
|
</a>{' '}
|
||||||
|
of which we are proud sponsors.
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
<Text as="p" $display="inline">
|
||||||
|
<Trans t={t} i18nKey="home-content-open-source-part2">
|
||||||
|
You can easily self-hosted Docs (check our installation{' '}
|
||||||
|
<a
|
||||||
|
href="https://github.com/suitenumerique/docs/tree/main/docs"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
documentation
|
||||||
|
</a>{' '}
|
||||||
|
with production-ready examples).
|
||||||
|
<br />
|
||||||
|
Docs uses an innovation and business friendly{' '}
|
||||||
|
<a
|
||||||
|
href="https://github.com/suitenumerique/docs/blob/main/LICENSE"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
licence
|
||||||
|
</a>
|
||||||
|
.<br />
|
||||||
|
Contributions are welcome (see our roadmap{' '}
|
||||||
|
<a
|
||||||
|
href="https://github.com/orgs/numerique-gouv/projects/13/views/11"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
here
|
||||||
|
</a>
|
||||||
|
).
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
<Text as="p" $display="inline">
|
||||||
|
<Trans t={t} i18nKey="home-content-open-source-part3">
|
||||||
|
Docs is the result of a joint effort lead by the French
|
||||||
|
🇫🇷🥖
|
||||||
|
<a
|
||||||
|
href="https://www.numerique.gouv.fr/dinum/"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
(DINUM)
|
||||||
|
</a>{' '}
|
||||||
|
and German 🇩🇪🥨 governments{' '}
|
||||||
|
<a href="https://zendis.de/" target="_blank">
|
||||||
|
(ZenDiS)
|
||||||
|
</a>
|
||||||
|
. We are always looking for new public partners (we are
|
||||||
|
currently onboarding the Netherlands 🇳🇱🧀). Feel free to
|
||||||
|
reach out if you are interested in using or contributing
|
||||||
|
to docs.
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
<Box
|
||||||
|
$direction="row"
|
||||||
|
$gap="1rem"
|
||||||
|
$margin={{ top: 'small' }}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
icon={
|
||||||
|
<Text $isMaterialIcon $color="white">
|
||||||
|
chat
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
href="https://matrix.to/#/#docs-official:matrix.org"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<Text $color="white">Matrix</Text>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
color="secondary"
|
||||||
|
icon={<GithubIcon />}
|
||||||
|
href="https://github.com/suitenumerique/docs"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Github
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<HomeSection
|
||||||
|
isColumn={true}
|
||||||
|
isSmallDevice={isMobile}
|
||||||
|
illustration={isFrLanguage ? SC1ResponsiveFr : SC1ResponsiveEn}
|
||||||
|
video={
|
||||||
|
isFrLanguage ? `/assets/SC1-fr.webm` : `/assets/SC1-en.webm`
|
||||||
|
}
|
||||||
|
title={t('An uncompromising writing experience.')}
|
||||||
|
tag={t('Write')}
|
||||||
|
description={t(
|
||||||
|
'Docs offers an intuitive writing experience. Its minimalist interface favors content over layout, while offering the essentials: media import, offline mode and keyboard shortcuts for greater efficiency.',
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
<HomeSection
|
<HomeSection
|
||||||
isColumn={false}
|
isColumn={false}
|
||||||
isSmallDevice={isMobile}
|
isSmallDevice={isMobile}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { css } from 'styled-components';
|
import { css } from 'styled-components';
|
||||||
|
|
||||||
import { Box, Text } from '@/components';
|
import { Box, BoxType, Text } from '@/components';
|
||||||
import { useCunninghamTheme } from '@/cunningham';
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
import { useResponsiveStore } from '@/stores';
|
import { useResponsiveStore } from '@/stores';
|
||||||
|
|
||||||
@@ -18,10 +18,12 @@ export type HomeSectionProps = {
|
|||||||
reverse?: boolean;
|
reverse?: boolean;
|
||||||
textWidth?: string;
|
textWidth?: string;
|
||||||
video?: string;
|
video?: string;
|
||||||
|
$css?: BoxType['$css'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const HomeSection = ({
|
export const HomeSection = ({
|
||||||
availableSoon = false,
|
availableSoon = false,
|
||||||
|
$css,
|
||||||
description,
|
description,
|
||||||
illustration,
|
illustration,
|
||||||
isSmallDevice,
|
isSmallDevice,
|
||||||
@@ -89,6 +91,7 @@ export const HomeSection = ({
|
|||||||
$hasTransition="slow"
|
$hasTransition="slow"
|
||||||
$css={css`
|
$css={css`
|
||||||
opacity: ${isVisible ? 1 : 0};
|
opacity: ${isVisible ? 1 : 0};
|
||||||
|
${$css}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
@@ -122,7 +125,11 @@ export const HomeSection = ({
|
|||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
<Text $variation="700" $weight="400" $size="md">
|
<Text
|
||||||
|
$variation="700"
|
||||||
|
$weight="400"
|
||||||
|
$size={isSmallMobile ? 'ml' : 'md'}
|
||||||
|
>
|
||||||
{description}
|
{description}
|
||||||
</Text>
|
</Text>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Reference in New Issue
Block a user