Skip to content
This repository was archived by the owner on Nov 10, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'reflect-metadata';
import React, { ReactElement, useState } from 'react';
import { ReactElement, useState } from 'react';
import { AppProps } from 'next/app';
import Head from 'next/head';
import { enableStaticRendering } from 'mobx-react-lite';
Expand Down
12 changes: 12 additions & 0 deletions src/pages/long-sync.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import createPage from 'presentation/pageBuilder/createPage';
import TestPage from 'presentation/component/page/test';

export default createPage(TestPage, {
getInitialProps: async () => {
console.log('getInitialProps start');
await new Promise((resolve) => {
setTimeout(resolve, 3500)
})
console.log('getInitialProps finish');
},
});
4 changes: 4 additions & 0 deletions src/pages/static.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import Controller from 'presentation/component/page/static/Controller';
export default createSSGPage(StaticPage);

export const getStaticProps = createSSGAction(async (container) => {
await new Promise((resolve) => {
setTimeout(resolve, 3500)
})

await container.get(Controller).initialAction();
});

Expand Down
Empty file.
22 changes: 22 additions & 0 deletions src/presentation/component/common/block/LoadSpinner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { FC, HTMLAttributes } from 'react';
import { Wrapper, WrapperPropsT, Spinner, LoaderCssPropsT } from './styles';

export type LoadSpinnerPropsT = HTMLAttributes<HTMLDivElement> &
Partial<LoaderCssPropsT> &
WrapperPropsT;

const LoadSpinner: FC<LoadSpinnerPropsT> = (props) => {
const { size = 160, sizeXl, sizeMd, sizeSm, color, ...restProps } = props;

return (
<Wrapper {...restProps}>
<Spinner size={size} sizeXl={sizeXl} sizeMd={sizeMd} sizeSm={sizeSm} color={color}>
<span />
<span />
<span />
</Spinner>
</Wrapper>
);
};

export default LoadSpinner;
85 changes: 85 additions & 0 deletions src/presentation/component/common/block/LoadSpinner/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import styled from '@emotion/styled';
import { ColorKeyT } from 'presentation/context/Theme/keys';
import { mq } from 'presentation/mediaquery';

export type WrapperPropsT = {
isVisible: boolean;
};

export const Wrapper = styled('div', {
shouldForwardProp(propName: PropertyKey): boolean {
return propName !== 'isVisible';
},
})<WrapperPropsT>`
display: grid;
place-items: center;
width: 100%;
height: 100%;
opacity: ${({ isVisible }) => (isVisible ? 1 : 0)};
transition: opacity ${({ theme }) => theme.transition.fast};
`;

export type LoaderCssPropsT = {
size: number;
sizeXl?: number;
sizeMd?: number;
sizeSm?: number;
color?: ColorKeyT;
};

export const Spinner = styled.div<LoaderCssPropsT>`
--loader-size: ${({ size }) => size}px;
--loader-width: 8px;

position: relative;
display: inline-block;
width: var(--loader-size);
height: var(--loader-size);

${mq.lowerLg} {
--loader-size: ${({ size, sizeXl }) => sizeXl ?? size}px;
}

${mq.lowerMd} {
--loader-size: ${({ size, sizeXl, sizeMd }) => sizeMd ?? sizeXl ?? size}px;
--loader-width: 6px;
}

${mq.lowerSm} {
--loader-size: ${({ size, sizeXl, sizeMd, sizeSm }) =>
sizeSm ?? sizeMd ?? sizeXl ?? size}px;
}

& span {
position: absolute;
display: block;
width: calc(var(--loader-size) * 0.9);
height: calc(var(--loader-size) * 0.9);
margin: 8px;
border: var(--loader-width) solid transparent;
border-radius: 50%;
border-left-color: ${({ theme, color }) => theme.colors[color || 'text']};
animation: round-wrap 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}

& span:nth-of-type(1) {
animation-delay: -0.45s;
}

& span:nth-of-type(2) {
animation-delay: -0.3s;
}

& span:nth-of-type(3) {
animation-delay: -0.15s;
}

@keyframes round-wrap {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FC } from 'react';
import LoadSpinner, { LoadSpinnerPropsT } from 'presentation/component/common/block/LoadSpinner';
import { Wrapper } from './styles';

type PropsT = LoadSpinnerPropsT;

const PageBlockingLoadSpinner: FC<PropsT> = (props) => {
const { isVisible } = props;

return (
<Wrapper isVisible={isVisible}>
<LoadSpinner {...props} />
</Wrapper>
);
};

export default PageBlockingLoadSpinner;
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import styled from '@emotion/styled';
import { keyframes } from '@emotion/react';
import { rgba } from 'polished';

type WrapperPropsT = {
isVisible: boolean;
};

const show = keyframes`
0% {
opacity: 0;
z-index: -1;
}
1% {
z-index: 1000000;
}
100% {
opacity: 1;
z-index: 1000000;
}
`;

const hide = keyframes`
0% {
opacity: 1;
z-index: 1000000;
}
99% {
z-index: 1000000;
}
100% {
opacity: 0;
z-index: -1;
}
`;

// eslint-disable-next-line import/prefer-default-export
export const Wrapper = styled.div<WrapperPropsT>`
position: fixed;
background-color: ${({ theme }) => rgba(theme.colors.text, 0.1)};
inset: 0;
transition: opacity ${({ theme }) => theme.transition.normal};

animation-name: ${({ isVisible }) => (isVisible ? show : hide)};
animation-duration: ${({ theme }) => theme.transition.normal};
animation-timing-function: linear;
animation-fill-mode: forwards;
`;
6 changes: 5 additions & 1 deletion src/presentation/component/layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import React, { FC } from 'react';
import { FC } from 'react';
import { Global } from '@emotion/react';
import { observer } from 'mobx-react-lite';
import { useService } from 'presentation/context/Container';
import UiGlobalController from 'presentation/controller/UiGlobalController';
import globalCss from 'presentation/component/layout/common/globalCss';
import PageBlockingLoadSpinner from 'presentation/component/common/block/PageBlockingLoadSpinner';
import useRouterSwitchState from "presentation/hook/useRouterSwitchState";
import { LayoutWrapper, Main } from './styles';

const Layout: FC = observer((props) => {
const { children } = props;
const { mainBlockConfig } = useService(UiGlobalController);
const routerSwitchState = useRouterSwitchState();

return (
<>
<LayoutWrapper>
{/* Header */}
<Main {...mainBlockConfig}>{children}</Main>
{/* Footer */}
<PageBlockingLoadSpinner isVisible={routerSwitchState}/>
</LayoutWrapper>
<Global styles={globalCss} />
</>
Expand Down
17 changes: 16 additions & 1 deletion src/presentation/component/page/home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
import { FC } from 'react';
import Link from "presentation/component/common/typography/Link";

const HomePage: FC = () => {
return <div>Home page</div>;
return (
<div>
<h1>Home page</h1>
<br />
<br />
<Link href="/long-sync" >
to long action page
</Link>
<br />
<br />
<Link href="/static">
to static
</Link>
</div>
);
};

export default HomePage;
17 changes: 16 additions & 1 deletion src/presentation/component/page/static/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,26 @@ import { FC } from 'react';
import { observer } from 'mobx-react-lite';
import { useService } from 'presentation/context/Container';
import Controller from './Controller';
import Link from "presentation/component/common/typography/Link";

const StaticPage: FC = observer(() => {
const { title } = useService(Controller);

return <div>{title}</div>;
return (
<div>
{title}
<br />
<br />
<Link href="/">
back home
</Link>
<br />
<br />
<Link href="/long-sync" >
to long action page
</Link>
</div>
);
});

export default StaticPage;
23 changes: 23 additions & 0 deletions src/presentation/component/page/test/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FC } from 'react';
import Link from "presentation/component/common/typography/Link";
import { Wrapper } from './styles';

const TestPage: FC = () => {
return (
<Wrapper>
test
<br />
<br />
<Link href="/">
back home
</Link>
<br />
<br />
<Link href="/static">
to static
</Link>
</Wrapper>
);
};

export default TestPage;
5 changes: 5 additions & 0 deletions src/presentation/component/page/test/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import styled from '@emotion/styled';

export const Wrapper = styled.div();

export const Item = styled.div();
30 changes: 30 additions & 0 deletions src/presentation/hook/useRouterSwitchState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import isServer from 'helper/common/isServer';


export default function useRouterSwitchState() {
const router = useRouter();
const [state, setState] = useState(false);

useEffect(() => {
const handleRouteChangeStart = () => setState(true);
const handleRouteChangeComplete = () => setState(false);

router.events.on('routeChangeStart', handleRouteChangeStart);
router.events.on('routeChangeComplete', handleRouteChangeComplete);
router.events.on('routeChangeError', handleRouteChangeComplete);

return () => {
router.events.off('routeChangeStart', handleRouteChangeStart);
router.events.off('routeChangeComplete', handleRouteChangeComplete);
router.events.off('routeChangeError', handleRouteChangeComplete);
};
}, []);

if (isServer()) {
return false;
}

return state;
}
2 changes: 1 addition & 1 deletion src/presentation/pageBuilder/createPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default function createPage<Q extends ParsedUrlQuery = ParsedUrlQuery>(
if (getInitialProps || withInitialProps) {
Page.getInitialProps = async (ctx: PageContextT<Q>) => {
if (getInitialProps) {
await getInitialProps(container, ctx);
await getInitialProps(container, ctx);
}

if (!isServer()) {
Expand Down