diff --git a/CHANGELOG.md b/CHANGELOG.md
index e7b8e01a..0e07df1f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,7 +10,10 @@ and this project adheres to
## [Unreleased]
## Added
+
- 📝(doc) Add security.md and codeofconduct.md #604
+- ✨(frontend) add home page #553
+
## Fixed
diff --git a/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts
new file mode 100644
index 00000000..5299d017
--- /dev/null
+++ b/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts
@@ -0,0 +1,49 @@
+import { expect, test } from '@playwright/test';
+
+test.beforeEach(async ({ page }) => {
+ await page.goto('/docs/');
+});
+
+test.describe('Home page', () => {
+ test.use({ storageState: { cookies: [], origins: [] } });
+ test('checks all the elements are visible', async ({ page }) => {
+ // Check header content
+ const header = page.locator('header').first();
+ const footer = page.locator('footer').first();
+ await expect(header).toBeVisible();
+ await expect(
+ header.getByRole('combobox', { name: 'Language' }),
+ ).toBeVisible();
+ await expect(
+ header.getByRole('button', { name: 'Les services de La Suite numé' }),
+ ).toBeVisible();
+ await expect(
+ header.getByRole('img', { name: 'Gouvernement Logo' }),
+ ).toBeVisible();
+ await expect(
+ header.getByRole('img', { name: 'Docs app logo' }),
+ ).toBeVisible();
+ await expect(header.getByRole('heading', { name: 'Docs' })).toBeVisible();
+ await expect(header.getByText('BETA')).toBeVisible();
+
+ // Check the ttile and subtitle are visible
+ await expect(page.getByText('Collaborative writing made')).toBeVisible();
+ await expect(page.getByText('Collaborate and write in real')).toBeVisible();
+ await expect(page.getByText('An uncompromising writing')).toBeVisible();
+ await expect(page.getByText('Docs offers an intuitive')).toBeVisible();
+ await expect(page.getByText('Simple and secure')).toBeVisible();
+ await expect(page.getByText('Docs makes real-time')).toBeVisible();
+ await expect(page.getByText('Flexible export.')).toBeVisible();
+ await expect(page.getByText('To facilitate the circulation')).toBeVisible();
+ await expect(page.getByText('A new way to organize')).toBeVisible();
+ await expect(page.getByText('Docs transforms your')).toBeVisible();
+
+ await expect(page.getByTestId('proconnect-button')).toHaveCount(2);
+
+ // Footer - The footer is already tested in its entirety in the footer.spec.ts file
+ await expect(footer).toBeVisible();
+ await expect(
+ page.getByRole('link', { name: 'expand_more See more' }),
+ ).toBeVisible();
+ });
+});
diff --git a/src/frontend/apps/impress/cunningham.ts b/src/frontend/apps/impress/cunningham.ts
index a324b170..633e2db9 100644
--- a/src/frontend/apps/impress/cunningham.ts
+++ b/src/frontend/apps/impress/cunningham.ts
@@ -5,6 +5,7 @@ const config = {
colors: {
'card-border': '#ededed',
'primary-bg': '#FAFAFA',
+ 'primary-action': '#1212FF',
'primary-050': '#F5F5FE',
'primary-100': '#EDF5FA',
'primary-150': '#E5EEFA',
@@ -59,6 +60,11 @@ const config = {
h4: '1.375rem',
h5: '1.25rem',
h6: '1.125rem',
+ 'xl-alt': '5rem',
+ 'lg-alt': '4.5rem',
+ 'md-alt': '4rem',
+ 'sm-alt': '3.5rem',
+ 'xs-alt': '3rem',
},
weights: {
thin: 100,
@@ -224,7 +230,7 @@ const config = {
'color-hover': 'var(--c--theme--colors--primary-700)',
},
border: {
- color: 'var(--c--theme--colors--primary-200)',
+ color: 'var(--c--theme--colors--greyscale-300)',
},
},
tertiary: {
@@ -379,8 +385,8 @@ const config = {
'color-active': '#EDEDED',
},
border: {
- color: 'var(--c--theme--colors--primary-600)',
- 'color-hover': 'var(--c--theme--colors--primary-600)',
+ color: 'var(--c--theme--colors--greyscale-300)',
+ 'color-hover': 'var(--c--theme--colors--greyscale-300)',
},
color: 'var(--c--theme--colors--primary-text)',
},
diff --git a/src/frontend/apps/impress/public/assets/SC1-en.webm b/src/frontend/apps/impress/public/assets/SC1-en.webm
new file mode 100644
index 00000000..ff1dc284
Binary files /dev/null and b/src/frontend/apps/impress/public/assets/SC1-en.webm differ
diff --git a/src/frontend/apps/impress/public/assets/SC1-fr.webm b/src/frontend/apps/impress/public/assets/SC1-fr.webm
new file mode 100644
index 00000000..1ebc7bef
Binary files /dev/null and b/src/frontend/apps/impress/public/assets/SC1-fr.webm differ
diff --git a/src/frontend/apps/impress/src/assets/icons/icon-docs.svg b/src/frontend/apps/impress/src/assets/icons/icon-docs.svg
new file mode 100644
index 00000000..430eb0e0
--- /dev/null
+++ b/src/frontend/apps/impress/src/assets/icons/icon-docs.svg
@@ -0,0 +1,18 @@
+
diff --git a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css
index 3357c29c..c0572eb0 100644
--- a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css
+++ b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.css
@@ -71,6 +71,7 @@
--c--theme--colors--danger-text: var(--c--theme--colors--greyscale-000);
--c--theme--colors--card-border: #ededed;
--c--theme--colors--primary-bg: #fafafa;
+ --c--theme--colors--primary-action: #1212ff;
--c--theme--colors--primary-050: #f5f5fe;
--c--theme--colors--primary-150: #e5eefa;
--c--theme--colors--primary-950: #1b1b35;
@@ -122,6 +123,11 @@
--c--theme--font--sizes--ml: 0.938rem;
--c--theme--font--sizes--xl: 1.25rem;
--c--theme--font--sizes--t: 0.6875rem;
+ --c--theme--font--sizes--xl-alt: 5rem;
+ --c--theme--font--sizes--lg-alt: 4.5rem;
+ --c--theme--font--sizes--md-alt: 4rem;
+ --c--theme--font--sizes--sm-alt: 3.5rem;
+ --c--theme--font--sizes--xs-alt: 3rem;
--c--theme--font--weights--thin: 100;
--c--theme--font--weights--light: 300;
--c--theme--font--weights--regular: 400;
@@ -316,7 +322,7 @@
--c--theme--colors--primary-700
);
--c--components--button--secondary--border--color: var(
- --c--theme--colors--primary-200
+ --c--theme--colors--greyscale-300
);
--c--components--button--tertiary--color: var(
--c--theme--colors--primary-text
@@ -501,10 +507,10 @@
--c--components--button--secondary--background--color-hover: #f6f6f6;
--c--components--button--secondary--background--color-active: #ededed;
--c--components--button--secondary--border--color: var(
- --c--theme--colors--primary-600
+ --c--theme--colors--greyscale-300
);
--c--components--button--secondary--border--color-hover: var(
- --c--theme--colors--primary-600
+ --c--theme--colors--greyscale-300
);
--c--components--button--secondary--color: var(
--c--theme--colors--primary-text
@@ -874,6 +880,10 @@
color: var(--c--theme--colors--primary-bg);
}
+.clr-primary-action {
+ color: var(--c--theme--colors--primary-action);
+}
+
.clr-primary-050 {
color: var(--c--theme--colors--primary-050);
}
@@ -1302,6 +1312,10 @@
background-color: var(--c--theme--colors--primary-bg);
}
+.bg-primary-action {
+ background-color: var(--c--theme--colors--primary-action);
+}
+
.bg-primary-050 {
background-color: var(--c--theme--colors--primary-050);
}
@@ -1550,6 +1564,31 @@
letter-spacing: var(--c--theme--font--letterspacings--t);
}
+.fs-xl-alt {
+ font-size: var(--c--theme--font--sizes--xl-alt);
+ letter-spacing: var(--c--theme--font--letterspacings--xl-alt);
+}
+
+.fs-lg-alt {
+ font-size: var(--c--theme--font--sizes--lg-alt);
+ letter-spacing: var(--c--theme--font--letterspacings--lg-alt);
+}
+
+.fs-md-alt {
+ font-size: var(--c--theme--font--sizes--md-alt);
+ letter-spacing: var(--c--theme--font--letterspacings--md-alt);
+}
+
+.fs-sm-alt {
+ font-size: var(--c--theme--font--sizes--sm-alt);
+ letter-spacing: var(--c--theme--font--letterspacings--sm-alt);
+}
+
+.fs-xs-alt {
+ font-size: var(--c--theme--font--sizes--xs-alt);
+ letter-spacing: var(--c--theme--font--letterspacings--xs-alt);
+}
+
.f-base {
font-family: var(--c--theme--font--families--base);
}
diff --git a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts
index 521094f4..b63ef0bf 100644
--- a/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts
+++ b/src/frontend/apps/impress/src/cunningham/cunningham-tokens.ts
@@ -75,6 +75,7 @@ export const tokens = {
'danger-text': '#fff',
'card-border': '#ededed',
'primary-bg': '#FAFAFA',
+ 'primary-action': '#1212FF',
'primary-050': '#F5F5FE',
'primary-150': '#E5EEFA',
'primary-950': '#1B1B35',
@@ -129,6 +130,11 @@ export const tokens = {
ml: '0.938rem',
xl: '1.25rem',
t: '0.6875rem',
+ 'xl-alt': '5rem',
+ 'lg-alt': '4.5rem',
+ 'md-alt': '4rem',
+ 'sm-alt': '3.5rem',
+ 'xs-alt': '3rem',
},
weights: {
thin: 100,
@@ -315,7 +321,7 @@ export const tokens = {
color: 'white',
'color-hover': 'var(--c--theme--colors--primary-700)',
},
- border: { color: 'var(--c--theme--colors--primary-200)' },
+ border: { color: 'var(--c--theme--colors--greyscale-300)' },
},
tertiary: {
color: 'var(--c--theme--colors--primary-text)',
@@ -502,8 +508,8 @@ export const tokens = {
secondary: {
background: { 'color-hover': '#F6F6F6', 'color-active': '#EDEDED' },
border: {
- color: 'var(--c--theme--colors--primary-600)',
- 'color-hover': 'var(--c--theme--colors--primary-600)',
+ color: 'var(--c--theme--colors--greyscale-300)',
+ 'color-hover': 'var(--c--theme--colors--greyscale-300)',
},
color: 'var(--c--theme--colors--primary-text)',
},
diff --git a/src/frontend/apps/impress/src/features/auth/components/Auth.tsx b/src/frontend/apps/impress/src/features/auth/components/Auth.tsx
index 714ef86f..73728786 100644
--- a/src/frontend/apps/impress/src/features/auth/components/Auth.tsx
+++ b/src/frontend/apps/impress/src/features/auth/components/Auth.tsx
@@ -1,23 +1,41 @@
import { Loader } from '@openfun/cunningham-react';
+import { useRouter } from 'next/router';
import { PropsWithChildren } from 'react';
import { Box } from '@/components';
-import HomeContent from '@/features/home/components/HomeContent';
import { useAuth } from '../hooks';
-/**
- * TODO: Remove this restriction when we will have a homepage design for non-authenticated users.
- *
- * We define the paths that are not allowed without authentication.
- * Actually, only the home page and the docs page are not allowed without authentication.
- * When we will have a homepage design for non-authenticated users, we will remove this restriction to have
- * the full website accessible without authentication.
- */
export const Auth = ({ children }: PropsWithChildren) => {
- const { user, isLoading, pathAllowed } = useAuth();
+ const { isLoading, pathAllowed, isFetchedAfterMount, authenticated } =
+ useAuth();
+ const { replace, pathname } = useRouter();
- if (isLoading) {
+ if (isLoading && !isFetchedAfterMount) {
+ return (
+
+
+
+ );
+ }
+
+ /**
+ * If the user is not authenticated and the path is not allowed, we redirect to the login page.
+ */
+ if (!authenticated && !pathAllowed) {
+ void replace('/login');
+ return (
+
+
+
+ );
+ }
+
+ /**
+ * If the user is authenticated and the path is the login page, we redirect to the home page.
+ */
+ if (pathname === '/login' && authenticated) {
+ void replace('/');
return (
diff --git a/src/frontend/apps/impress/src/features/header/assets/icon-docs.svg b/src/frontend/apps/impress/src/features/header/assets/icon-docs.svg
deleted file mode 100644
index 4f26ae3b..00000000
--- a/src/frontend/apps/impress/src/features/header/assets/icon-docs.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/src/frontend/apps/impress/src/features/header/components/ButtonTogglePanel.tsx b/src/frontend/apps/impress/src/features/header/components/ButtonTogglePanel.tsx
new file mode 100644
index 00000000..8504674e
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/header/components/ButtonTogglePanel.tsx
@@ -0,0 +1,26 @@
+import { Button } from '@openfun/cunningham-react';
+import { useTranslation } from 'react-i18next';
+
+import { Icon } from '@/components/';
+import { useLeftPanelStore } from '@/features/left-panel';
+
+export const ButtonTogglePanel = () => {
+ const { t } = useTranslation();
+ const { isPanelOpen, togglePanel } = useLeftPanelStore();
+
+ return (
+
+ );
+}
diff --git a/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx b/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx
new file mode 100644
index 00000000..903bae0b
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/home/components/HomeContent.tsx
@@ -0,0 +1,120 @@
+import { useTranslation } from 'react-i18next';
+import { css } from 'styled-components';
+
+import { Box } from '@/components';
+import { Footer } from '@/features/footer';
+import { LeftPanel } from '@/features/left-panel';
+import { useLanguage } from '@/i18n/hooks/useLanguage';
+import { useResponsiveStore } from '@/stores';
+
+import SC1ResponsiveEn from '../assets/SC1-responsive-en.png';
+import SC1ResponsiveFr from '../assets/SC1-responsive-fr.png';
+import SC2En from '../assets/SC2-en.png';
+import SC2Fr from '../assets/SC2-fr.png';
+import SC3En from '../assets/SC3-en.png';
+import SC3Fr from '../assets/SC3-fr.png';
+import SC4En from '../assets/SC4-en.png';
+import SC4Fr from '../assets/SC4-fr.png';
+import SC4ResponsiveEn from '../assets/SC4-responsive-en.png';
+import SC4ResponsiveFr from '../assets/SC4-responsive-fr.png';
+
+import HomeBanner from './HomeBanner';
+import { HomeOpenSource } from './HomeOpenSource';
+import { HomeHeader, getHeaderHeight } from './HomeHeader';
+import { HomeSection } from './HomeSection';
+
+export function HomeContent() {
+ const { t } = useTranslation();
+ const { isMobile, isSmallMobile } = useResponsiveStore();
+ const lang = useLanguage();
+ const isFrLanguage = lang.language === 'fr';
+
+ return (
+
+
+ {isSmallMobile && (
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx b/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx
new file mode 100644
index 00000000..8e7a331d
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/home/components/HomeHeader.tsx
@@ -0,0 +1,76 @@
+import Image from 'next/image';
+import { useTranslation } from 'react-i18next';
+
+import { default as IconDocs } from '@/assets/icons/icon-docs.svg?url';
+import { Box } from '@/components';
+import { useCunninghamTheme } from '@/cunningham';
+import { ButtonTogglePanel, Title } from '@/features/header/';
+import { LaGaufre } from '@/features/header/components/LaGaufre';
+import { LanguagePicker } from '@/features/language';
+import { useResponsiveStore } from '@/stores';
+
+export const HEADER_HEIGHT = 91;
+export const HEADER_HEIGHT_MOBILE = 52;
+
+export const getHeaderHeight = (isSmallMobile: boolean) =>
+ isSmallMobile ? HEADER_HEIGHT_MOBILE : HEADER_HEIGHT;
+
+export const HomeHeader = () => {
+ const { t } = useTranslation();
+ const { themeTokens, spacingsTokens } = useCunninghamTheme();
+ const spacings = spacingsTokens();
+ const logo = themeTokens().logo;
+ const { isSmallMobile } = useResponsiveStore();
+
+ return (
+
+
+ {isSmallMobile && (
+
+
+
+ )}
+ {!isSmallMobile && logo && (
+
+ )}
+
+
+
+
+
+ {!isSmallMobile && (
+
+
+
+
+ )}
+
+ );
+};
diff --git a/src/frontend/apps/impress/src/features/home/components/HomeOpenSource.tsx b/src/frontend/apps/impress/src/features/home/components/HomeOpenSource.tsx
new file mode 100644
index 00000000..151a71a3
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/home/components/HomeOpenSource.tsx
@@ -0,0 +1,103 @@
+import { Trans, useTranslation } from 'react-i18next';
+import { css } from 'styled-components';
+
+import { Box, Text } from '@/components';
+import { useCunninghamTheme } from '@/cunningham';
+
+import SC5 from '../assets/SC5.png';
+
+import { HomeSection } from './HomeSection';
+
+export function HomeOpenSource() {
+ const { t } = useTranslation();
+ const { colorsTokens } = useCunninghamTheme();
+
+ return (
+
+
+
+ Docs is built on top of{' '}
+
+ Django Rest Framework
+
+ ,{' '}
+
+ Next.js
+
+ , and{' '}
+
+ MinIO
+
+ . We also use{' '}
+
+ Yjs
+ {' '}
+ and{' '}
+
+ BlockNote.js
+ {' '}
+ of which we are proud sponsors.
+
+
+
+
+ You can easily self-host Docs (check our installation{' '}
+
+ documentation
+ {' '}
+ with production-ready examples).
+
+ Docs uses an innovation and business friendly{' '}
+
+ licence
+
+ .
+ Contributions are welcome (see our roadmap{' '}
+
+ here
+
+ ).
+
+
+
+
+ Docs is the result of a joint effort lead by the French 🇫🇷🥖
+
+ (DINUM)
+ {' '}
+ and German 🇩🇪🥨 governments{' '}
+
+ (ZenDiS)
+
+ . 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.
+
+
+
+ }
+ />
+ );
+}
diff --git a/src/frontend/apps/impress/src/features/home/components/HomeSection.tsx b/src/frontend/apps/impress/src/features/home/components/HomeSection.tsx
new file mode 100644
index 00000000..956acd4c
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/home/components/HomeSection.tsx
@@ -0,0 +1,218 @@
+import Image, { ImageProps } from 'next/image';
+import React, { useEffect, useMemo, useRef, useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { css } from 'styled-components';
+
+import { Box, Text } from '@/components';
+import { useCunninghamTheme } from '@/cunningham';
+import { useResponsiveStore } from '@/stores';
+
+export type HomeSectionProps = {
+ description: React.ReactNode;
+ tag: string;
+ title: string;
+ availableSoon?: boolean;
+ illustration?: ImageProps['src'];
+ isColumn?: boolean;
+ isSmallDevice?: boolean;
+ reverse?: boolean;
+ textWidth?: string;
+ video?: string;
+};
+
+export const HomeSection = ({
+ availableSoon = false,
+ description,
+ illustration,
+ isSmallDevice,
+ isColumn = true,
+ reverse = false,
+ tag,
+ textWidth = '50%',
+ title,
+ video,
+}: HomeSectionProps) => {
+ const { t } = useTranslation();
+ const { spacingsTokens } = useCunninghamTheme();
+ const spacings = spacingsTokens();
+
+ const { isSmallMobile } = useResponsiveStore();
+
+ const direction = useMemo(() => {
+ if (isSmallDevice) {
+ return 'column';
+ } else if (isColumn) {
+ return reverse ? 'column-reverse' : 'column';
+ }
+
+ return reverse ? 'row-reverse' : 'row';
+ }, [isColumn, isSmallDevice, reverse]);
+
+ const [isVisible, setIsVisible] = useState(false);
+ const sectionRef = useRef(null);
+
+ /**
+ * Intersection Observer to trigger animation when the section is in the viewport
+ */
+ useEffect(() => {
+ const currentSection = sectionRef.current;
+
+ const observer = new IntersectionObserver(
+ (entries) => {
+ entries.forEach((entry) => {
+ if (entry.isIntersecting) {
+ setIsVisible(true);
+ observer.disconnect();
+ }
+ });
+ },
+ { threshold: 0.1 },
+ );
+
+ if (currentSection) {
+ observer.observe(currentSection);
+ }
+
+ return () => {
+ if (currentSection) {
+ observer.unobserve(currentSection);
+ }
+ };
+ }, []);
+
+ return (
+
+
+
+
+
+ {availableSoon && (
+
+ )}
+
+
+ {title}
+
+
+ {description}
+
+
+
+ {video && !isSmallDevice && (
+
+ as="video"
+ preload="none"
+ loop
+ muted
+ autoPlay
+ src={video}
+ $css={css`
+ width: 100%;
+ max-width: ${isSmallDevice ? 'calc(100dvw - 50px)' : '1200px'};
+ height: auto;
+ overflow: auto;
+ margin: auto;
+ `}
+ onPlay={(e) => {
+ const videoElement = e.currentTarget;
+ const observer = new IntersectionObserver(
+ (entries) => {
+ entries.forEach((entry) => {
+ if (!entry.isIntersecting) {
+ videoElement.pause();
+ } else {
+ setTimeout(() => {
+ void videoElement.play();
+ }, 500);
+ }
+ });
+ },
+ { threshold: 0.1 },
+ );
+ observer.observe(videoElement);
+ }}
+ >
+
+
+ )}
+
+ {illustration && (isSmallDevice || !video) && (
+
+ )}
+
+
+ );
+};
+
+const SectionTag = ({
+ tag,
+ availableSoon,
+}: {
+ tag: string;
+ availableSoon?: boolean;
+}) => {
+ const { colorsTokens, spacingsTokens } = useCunninghamTheme();
+ const spacings = spacingsTokens();
+ const colors = colorsTokens();
+ return (
+
+
+ {tag}
+
+
+ );
+};
diff --git a/src/frontend/apps/impress/src/features/home/components/index.ts b/src/frontend/apps/impress/src/features/home/components/index.ts
new file mode 100644
index 00000000..73b53e00
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/home/components/index.ts
@@ -0,0 +1 @@
+export * from './HomeContent';
diff --git a/src/frontend/apps/impress/src/features/home/index.ts b/src/frontend/apps/impress/src/features/home/index.ts
new file mode 100644
index 00000000..07635cbb
--- /dev/null
+++ b/src/frontend/apps/impress/src/features/home/index.ts
@@ -0,0 +1 @@
+export * from './components';
diff --git a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelHeader.tsx b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelHeader.tsx
index 640a731a..ccc20bea 100644
--- a/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelHeader.tsx
+++ b/src/frontend/apps/impress/src/features/left-panel/components/LeftPanelHeader.tsx
@@ -36,7 +36,7 @@ export const LeftPanelHeader = ({ children }: PropsWithChildren) => {
return (
<>
-
+
) {
const { isDesktop } = useResponsiveStore();
const { colorsTokens } = useCunninghamTheme();
@@ -57,7 +54,6 @@ export function MainLayout({
{children}
- {!withoutFooter && }
);
}
diff --git a/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx b/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx
index a748ebe8..fdd26602 100644
--- a/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx
+++ b/src/frontend/apps/impress/src/pages/docs/[id]/index.tsx
@@ -33,7 +33,7 @@ export function DocLayout() {
-
+
>
diff --git a/src/frontend/apps/impress/src/pages/login/index.tsx b/src/frontend/apps/impress/src/pages/login/index.tsx
new file mode 100644
index 00000000..dca21233
--- /dev/null
+++ b/src/frontend/apps/impress/src/pages/login/index.tsx
@@ -0,0 +1,8 @@
+import { HomeContent } from '@/features/home';
+import { NextPageWithLayout } from '@/types/next';
+
+const Page: NextPageWithLayout = () => {
+ return ;
+};
+
+export default Page;
diff --git a/src/frontend/apps/impress/src/stores/useResponsiveStore.tsx b/src/frontend/apps/impress/src/stores/useResponsiveStore.tsx
index 4b202161..7da3133c 100644
--- a/src/frontend/apps/impress/src/stores/useResponsiveStore.tsx
+++ b/src/frontend/apps/impress/src/stores/useResponsiveStore.tsx
@@ -23,13 +23,13 @@ const initialState = {
};
export const useResponsiveStore = create((set) => ({
+ isDesktop: initialState.isDesktop,
isMobile: initialState.isMobile,
- isTablet: initialState.isTablet,
isSmallMobile: initialState.isSmallMobile,
+ isTablet: initialState.isTablet,
screenSize: initialState.screenSize,
screenWidth: initialState.screenWidth,
setScreenSize: (size: ScreenSize) => set(() => ({ screenSize: size })),
- isDesktop: initialState.isDesktop,
initializeResizeListener: () => {
const resizeHandler = () => {
const width = window.innerWidth;
@@ -38,14 +38,14 @@ export const useResponsiveStore = create((set) => ({
isDesktop: false,
screenSize: 'small-mobile',
isMobile: true,
- isTablet: false,
+ isTablet: true,
isSmallMobile: true,
});
} else if (width < 768) {
set({
isDesktop: false,
screenSize: 'mobile',
- isTablet: false,
+ isTablet: true,
isMobile: true,
isSmallMobile: false,
});