diff --git a/packages/datasource/src/index.js b/packages/datasource/src/index.js
deleted file mode 100644
index c33a65188..000000000
--- a/packages/datasource/src/index.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import * as form from './form';
-import { defaultEnvDomains } from './config.domains';
-import { getData as getNavData } from './nav';
-
-export * as api from './api';
-export { useApiErrorListener } from './api/events';
-
-export const getFormData = () => form;
-
-export const getData = ({ domain, path, locale, env, envDomainConfig, meData, redDots = {} } = {}) => {
- const defaultEnv = (typeof process !== 'undefined' && process?.env?.NEXT_PUBLIC_RUNTIME_ENV) || 'production';
-
- env = env || defaultEnv;
- if (!['production', 'local'].includes(env)) {
- env = 'preview';
- }
-
- const domainConfig = (envDomainConfig || defaultEnvDomains)[env];
-
- return {
- nav: getNavData({
- domain,
- domainConfig,
- env,
- locale,
- path,
- meData,
- redDots,
- }),
- };
-};
diff --git a/packages/datasource/src/index.ts b/packages/datasource/src/index.ts
new file mode 100644
index 000000000..35f91231d
--- /dev/null
+++ b/packages/datasource/src/index.ts
@@ -0,0 +1,6 @@
+import * as form from './form';
+
+export * as api from './api';
+export { useApiErrorListener } from './api/events';
+
+export const getFormData = () => form;
diff --git a/src/components/errorPage/ErrorPage.component.js b/src/components/errorPage/ErrorPage.component.js
index f5a073782..e46834abd 100644
--- a/src/components/errorPage/ErrorPage.component.js
+++ b/src/components/errorPage/ErrorPage.component.js
@@ -2,43 +2,25 @@
// https://nextjs.org/docs/advanced-features/custom-error-page
// https://github.com/vercel/next.js/blob/canary/packages/next/pages/_error.tsx
-import * as R from 'ramda';
-import React, { useEffect } from 'react';
+import React, {useEffect, useState} from 'react';
import { ArrowLeftOutlined } from '@ant-design/icons';
import { Button } from 'antd';
import { useRouter } from 'next/router';
import * as Styled from './errorPage.styled';
-import Svg403 from './403.svg';
-import Svg404 from './404.svg';
-import Svg500 from './500.svg';
import { CommunityHead } from '~/components';
import { CoreLayout } from '~/layouts';
-
-const icons = {
- 403: Svg403,
- 404: Svg404,
- 500: Svg500,
-};
-
-const errorMsgs = {
- 403: '抱歉,您没有权限访问该页面',
- 404: '您访问的页面不存在',
- 500: '服务器异常,请稍后重试',
-};
+import ErrorStatus from "~/components/errorPage/ErrorStatus";
const ErrorPage = ({ statusCode, errorMsg, error = undefined }) => {
const router = useRouter();
- const Icon = R.propOr(icons[500], statusCode)(icons);
-
+ const [returnToHomepageLoading, setReturnToHomepageLoading] = useState(false)
useEffect(() => {
if (error) {
console.error(error);
}
}, [error]);
- errorMsg = errorMsg || R.propOr('未知错误,请稍后重试', statusCode)(errorMsgs);
-
const headProps = {
description: '',
keyword: '',
@@ -48,8 +30,11 @@ const ErrorPage = ({ statusCode, errorMsg, error = undefined }) => {
const buttonProps = {
type: 'primary',
icon: ,
- onClick: () => {
- router.push('/community', '/');
+ loading: returnToHomepageLoading,
+ onClick: async () => {
+ setReturnToHomepageLoading(true)
+ await router.push('/community', '/')
+ setReturnToHomepageLoading(false)
},
};
@@ -58,10 +43,7 @@ const ErrorPage = ({ statusCode, errorMsg, error = undefined }) => {
-
-
-
- {errorMsg}
+
>
diff --git a/src/components/errorPage/ErrorStatus.styled.ts b/src/components/errorPage/ErrorStatus.styled.ts
new file mode 100644
index 000000000..b4dc9c23e
--- /dev/null
+++ b/src/components/errorPage/ErrorStatus.styled.ts
@@ -0,0 +1,30 @@
+import styled from 'styled-components';
+import { mixins } from '@tidb-community/ui';
+
+export const Container = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 16px;
+`;
+
+export const Main = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ padding: 16px;
+`;
+
+export const IconWrapper = styled.div`
+ svg {
+ width: 30vw;
+ max-width: 280px;
+ min-width: 160px;
+ }
+`;
+
+export const Message = styled.div`
+ ${mixins.typography('p1')};
+ margin: 1.5rem 0 1rem;
+`;
diff --git a/src/components/errorPage/ErrorStatus.tsx b/src/components/errorPage/ErrorStatus.tsx
new file mode 100644
index 000000000..a1b471b17
--- /dev/null
+++ b/src/components/errorPage/ErrorStatus.tsx
@@ -0,0 +1,44 @@
+import * as React from "react"
+
+import * as Styled from './ErrorStatus.styled'
+import Svg403 from './403.svg';
+import Svg404 from './404.svg';
+import Svg500 from './500.svg';
+
+export interface IProps extends React.HTMLAttributes {
+ statusCode?: number
+ errorMsg?: React.ReactNode
+}
+
+const icons = {
+ 403: Svg403,
+ 404: Svg404,
+ 500: Svg500,
+};
+
+const errorMessages = {
+ 403: '抱歉,您没有权限访问该页面',
+ 404: '您访问的页面不存在',
+ 500: '服务器异常,请稍后重试',
+};
+
+const ErrorStatus: React.FC = (props) => {
+ const {statusCode, errorMsg, ...rest} = props
+
+ const statusCodeOutput = props.statusCode ?? 500
+ const errorMsgOutput = props.errorMsg ?? errorMessages[statusCodeOutput]
+ const Icon = icons[statusCodeOutput]
+
+ return (
+
+
+
+
+
+ {errorMsgOutput}
+
+
+ )
+}
+
+export default ErrorStatus
diff --git a/src/components/errorPage/errorPage.styled.js b/src/components/errorPage/errorPage.styled.js
index 6881ead43..c11b95cc8 100644
--- a/src/components/errorPage/errorPage.styled.js
+++ b/src/components/errorPage/errorPage.styled.js
@@ -8,16 +8,3 @@ export const Container = styled.div`
flex-direction: column;
flex: 1;
`;
-
-export const IconWrapper = styled.div`
- svg {
- width: 30vw;
- max-width: 280px;
- min-width: 160px;
- }
-`;
-
-export const Message = styled.div`
- ${mixins.typography('p1')};
- margin: 1.5rem 0 1rem;
-`;
diff --git a/src/hooks/account.ts b/src/hooks/account.ts
new file mode 100644
index 000000000..0a4647ac1
--- /dev/null
+++ b/src/hooks/account.ts
@@ -0,0 +1,63 @@
+import useSWR from "swr";
+import axios, {AxiosResponse} from "axios";
+import {useEffect} from "react";
+
+export type TMe = {
+ "detail": string // "成功",
+ "data": {
+ "id": number // 3699,
+ "openid": string // "",
+ "username": string // "cw1997",
+ "avatar_url": string // "https://asktug.com/letter_avatar_proxy/v4/letter/c/e5b9ba/50.png",
+ "is_staff": boolean // false
+ }
+}
+
+const accountsBaseUrl = process.env.NEXT_PUBLIC_ACCOUNTS_BASE_URL;
+//const homeUrl = process.env.NEXT_PUBLIC_HOME_URL;
+const loginUrl = `${accountsBaseUrl}/login`;
+//const logoutUrl = `${accountsBaseUrl}/logout`;
+
+export const login = (redirectUrl?: string) => {
+ const { location } = window;
+ location.href = `${loginUrl}?redirect_to=${encodeURIComponent(redirectUrl ?? window.location.href)}`;
+}
+
+/*export const logout = (redirectUrl?: string) => {
+ const { location } = window;
+ redirectUrl = redirectUrl ?? this.isAuthRequired ? homeUrl : location.href;
+ location.href = `${logoutUrl}?redirect_to=${encodeURIComponent(redirectUrl)}`;
+};*/
+
+const fetcher = async (): Promise> => {
+ const axiosInstance = axios.create({
+ baseURL: process.env.NEXT_PUBLIC_API_BASE_URL ?? '',
+ withCredentials: true,
+ })
+ const result = await axiosInstance.get('/api/me')
+ return result
+}
+
+export const useAccount = (requireAuth = true) => {
+ const swrResponse = useSWR(['account'], fetcher, {
+ revalidateOnReconnect: true,
+ revalidateOnFocus: true,
+ })
+ useEffect(() => {
+ if (requireAuth && !swrResponse.isValidating) {
+ if (swrResponse.data?.status !== 200 || swrResponse.error) {
+ login()
+ }
+ }
+ }, [requireAuth, swrResponse.isValidating, swrResponse.data?.status, swrResponse.error])
+ return swrResponse
+}
+
+export const useIsLoggedIn = (): null|boolean => {
+ const swrResponse = useSWR(['account'], fetcher, {
+ revalidateOnReconnect: true,
+ revalidateOnFocus: true,
+ })
+ if (swrResponse.isValidating) return null
+ return swrResponse.data?.status === 200
+}
diff --git a/src/layouts/CoreLayout/CoreLayout.tsx b/src/layouts/CoreLayout/CoreLayout.tsx
new file mode 100644
index 000000000..564885dc3
--- /dev/null
+++ b/src/layouts/CoreLayout/CoreLayout.tsx
@@ -0,0 +1,74 @@
+import React from 'react';
+import type { FC } from 'react';
+import Image from 'next/image'
+import { Footer, Header } from '@pingcap-inc/tidb-community-site-components';
+
+import * as Styled from './site.styled';
+import beianIconImage from './beian.png'
+import {ActivityBanner} from "../../../packages/ui";
+import * as bannerData from "~/data/banner";
+
+export interface IProps {
+ MainWrapper?: FC;
+ backgroundColor?: string;
+}
+
+const CoreLayout: FC = ({ MainWrapper = Styled.Main, backgroundColor, children }) => {
+ const currentYear = new Date().getFullYear();
+ return (
+
+
+
+ {children}
+
+ );
+};
+
+const ActivityBannerComponent = () => {
+ return (
+
+
+ {bannerData.text}
+ >
+ )}
+ // backgroundImage={'https://tidb.net/images/activity/banner.svg'}
+ // buttonImage={'https://tidb.net/images/activity/button.svg'}
+ link={bannerData.link}
+ onClick={undefined}
+ // onClick={() => onNavClick({ link: 'https://tidb.net/blog', target: '_blank' })}
+ />
+ );
+};
+
+export default CoreLayout;
diff --git a/public/images/beian.png b/src/layouts/CoreLayout/beian.png
similarity index 100%
rename from public/images/beian.png
rename to src/layouts/CoreLayout/beian.png
diff --git a/src/layouts/CoreLayout/index.ts b/src/layouts/CoreLayout/index.ts
new file mode 100644
index 000000000..6dcf4c6c5
--- /dev/null
+++ b/src/layouts/CoreLayout/index.ts
@@ -0,0 +1 @@
+export { default } from './CoreLayout';
diff --git a/src/layouts/site/site.styled.ts b/src/layouts/CoreLayout/site.styled.ts
similarity index 100%
rename from src/layouts/site/site.styled.ts
rename to src/layouts/CoreLayout/site.styled.ts
diff --git a/src/layouts/core/Core.component.js b/src/layouts/core/Core.component.js
deleted file mode 100644
index cfb8fd898..000000000
--- a/src/layouts/core/Core.component.js
+++ /dev/null
@@ -1,164 +0,0 @@
-import PropTypes from 'prop-types';
-import React, { useContext } from 'react';
-import useSWR from 'swr';
-import { ActivityBanner, UserProfile, utils } from '@tidb-community/ui';
-import { Footer, Header } from '@pingcap-inc/tidb-community-site-components';
-import { getData } from '@tidb-community/datasource';
-import { useRouter } from 'next/router';
-
-import * as Styled from './core.styled';
-import { AuthContext, MeContext, NavContext } from '~/context';
-import { link as linkUtils, redDots as redDotsUtils } from '~/utils';
-import { cdn } from '~/utils';
-import * as bannerData from '~/data/banner';
-
-// disabled for operation reasons
-// const renderActivityBanner = ({ meData, isMeValidating }, { link, ...data }, onNavClick, currentPathname) => {
-// // do not render if:
-// // - already in org
-// // - meData is validating
-// // - already at the page
-// if (meData?.org || isMeValidating || currentPathname === link) {
-// return undefined;
-// }
-//
-// return onNavClick({ link, target: '_blank' })} />;
-// };
-
-const ActivityBannerComponent = () => {
- return (
-
-
- {bannerData.text}
- >
- }
- // backgroundImage={'https://tidb.net/images/activity/banner.svg'}
- // buttonImage={'https://tidb.net/images/activity/button.svg'}
- link={bannerData.link}
- // onClick={() => onNavClick({ link: 'https://tidb.net/blog', target: '_blank' })}
- />
- );
-};
-
-const Core = ({
- MainWrapper = Styled.Main,
- children = undefined,
- domain = 'tidb.net',
- hasMargin,
- backgroundColor = undefined,
- style = undefined,
- props = {},
-}) => {
- const router = useRouter();
- const { login, logout, isLoggedIn } = useContext(AuthContext);
- const { meData /*isMeValidating*/ } = useContext(MeContext);
- const { data: redDotsResp } = useSWR(isLoggedIn && 'operation.fetchRedDots');
-
- const redDots = redDotsUtils.transformRespToMap(redDotsResp);
- const data = getData({
- domain,
- path: router.basePath,
- meData,
- redDots,
- }).nav;
- const { navItems: headerNavItems, userProfileNavItems } = data.header;
- const { navItems: footerNavItems, icons: footerIcons } = data.footer;
-
- const title = 'TiDB | COMMUNITY';
- const logo =
;
-
- const onNavClick = ({ link, browserLink, isSelected, target }) => {
- if (isSelected) return;
- linkUtils.handleRedirect(router, link, { as: browserLink, target });
- };
-
- const currentNav = utils.header.getCurrentNav(headerNavItems, router.asPath);
-
- const headerProps = {
- logo,
- title,
- onNavClick,
- navItems: headerNavItems,
- currentNav,
- onTitleClick: () => {
- document.location.href = process.env.NEXT_PUBLIC_HOME_URL;
- },
- };
-
- const footerProps = {
- logo,
- title,
- onNavClick: (link) => onNavClick({ link }),
- navItems: footerNavItems,
- icons: footerIcons,
- hasMargin,
- };
-
- const isBlogPage = router.pathname.startsWith('/blog');
-
- const currentYear = new Date().getFullYear();
-
- return (
-
-
- {/*{renderActivityBanner({ meData, isMeValidating }, data.activity, onNavClick, router.pathname)}*/}
- {!isBlogPage && }
- login()}
- onLogoutClick={() => logout()}
- currentNav={currentNav}
- items={userProfileNavItems}
- avatarUrl={meData?.avatar_url}
- />
- }
- />
- {children}
-
-
- );
-};
-
-Core.propTypes = {
- // It belongs to an object type if MainWrapper is a styled component
- MainWrapper: PropTypes.oneOfType([PropTypes.element, PropTypes.object]),
- children: PropTypes.node,
- domain: PropTypes.string,
- hasMargin: PropTypes.bool,
- locale: PropTypes.oneOf(['zh', 'en']),
-};
-
-export default Core;
diff --git a/src/layouts/core/core.styled.js b/src/layouts/core/core.styled.js
deleted file mode 100644
index d29b3acda..000000000
--- a/src/layouts/core/core.styled.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import styled from 'styled-components';
-
-export const Container = styled.div`
- display: flex;
- flex-direction: column;
- min-height: 100vh;
-`;
-
-export const Main = styled.div`
- flex: 1;
-`;
diff --git a/src/layouts/core/index.js b/src/layouts/core/index.js
deleted file mode 100644
index c70a59b32..000000000
--- a/src/layouts/core/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './Core.component';
diff --git a/src/layouts/index.js b/src/layouts/index.js
index ae7ce1a6c..794123033 100644
--- a/src/layouts/index.js
+++ b/src/layouts/index.js
@@ -1,2 +1 @@
-export { default as CoreLayout } from './core';
-export { default as SiteLayout } from './site';
+export { default as CoreLayout } from './CoreLayout';
diff --git a/src/layouts/site/Site.component.tsx b/src/layouts/site/Site.component.tsx
deleted file mode 100644
index b6ff52f61..000000000
--- a/src/layouts/site/Site.component.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Footer, Header } from '@pingcap-inc/tidb-community-site-components';
-import { FC, PropsWithChildren } from 'react';
-import { cdn } from '~/utils';
-import * as Styled from './site.styled';
-
-interface SiteLayoutProps {
- MainWrapper?: FC;
- backgroundColor?: string;
-}
-
-const SiteLayout = ({ MainWrapper = Styled.Main, backgroundColor, children }: PropsWithChildren) => {
- return (
-
-
- {children}
-
- );
-};
-
-export default SiteLayout;
diff --git a/src/layouts/site/index.ts b/src/layouts/site/index.ts
deleted file mode 100644
index c607a24dd..000000000
--- a/src/layouts/site/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './Site.component';
diff --git a/src/pages/_app.page.js b/src/pages/_app.page.tsx
similarity index 50%
rename from src/pages/_app.page.js
rename to src/pages/_app.page.tsx
index f0a1d4c23..d8106e6a9 100644
--- a/src/pages/_app.page.js
+++ b/src/pages/_app.page.tsx
@@ -1,42 +1,41 @@
-import '@formatjs/intl-numberformat/polyfill';
-import '@formatjs/intl-numberformat/locale-data/en';
-import '@pingcap-inc/tidb-community-ui/dist/antd.css';
-import 'dayjs/locale/zh';
import * as R from 'ramda';
-import React, { useEffect, useState } from 'react';
+import React, {useEffect} from 'react';
+import {SWRConfig} from 'swr';
+// import {Provider} from 'react-redux';
+import Link from 'next/link';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
-import useSWR, { SWRConfig } from 'swr';
-import { Provider } from 'react-redux';
-import { api, useApiErrorListener } from '@tidb-community/datasource';
-import { appWithTranslation } from 'next-i18next';
-import { constants, createAppGlobalStyle, utils } from '@tidb-community/ui';
-import { logPageView } from '@tidb-community/tracking-script';
-import { message } from 'antd';
-import { withLayout } from '@tidb-community/common';
-
-import '~/components/Button/Button.scss';
-import '~/components/Container/Container.scss';
-import '~/styles/globals.css';
-import ErrorPage from './_error.page';
-import nextI18NextConfig from '@/next-i18next.config';
-import { authContext, AuthContext, MeContext } from '~/context';
-import { isEmptyOrNil } from '~/utils/common.utils';
-import { store } from '~/redux';
+import 'dayjs/locale/zh';
-import '@fullcalendar/common/main.css';
-import '@fullcalendar/daygrid/main.css';
+import type {FC} from 'react'
+import type {AppProps} from 'next/app'
+import {api} from '@tidb-community/datasource';
+import {constants, createAppGlobalStyle} from '@tidb-community/ui';
+//@ts-ignore
+import {logPageView} from '@tidb-community/tracking-script';
+import {withLayout} from '@tidb-community/common';
import {
- SiteComponentsContext,
defineSiteComponentsConfig,
- Site,
Env,
+ Site,
+ // SiteComponentsContext,
} from '@pingcap-inc/tidb-community-site-components';
+
+import '@fullcalendar/common/main.css';
+import '@fullcalendar/daygrid/main.css';
+
+import '@formatjs/intl-numberformat/polyfill';
+import '@formatjs/intl-numberformat/locale-data/en';
+
import '@pingcap-inc/tidb-community-site-components/dist/index.css';
-import Link from 'next/link';
+import '@pingcap-inc/tidb-community-ui/dist/antd.css';
+
+import '~/components/Button/Button.scss';
+import '~/components/Container/Container.scss';
+import '~/styles/globals.css';
-import { fetcher as newFetcher } from '~/api';
+// import {fetcher as newFetcher} from '~/api';
dayjs.extend(relativeTime);
// TODO: Need to sync with NextJS locale value
@@ -79,35 +78,15 @@ defineSiteComponentsConfig({
},
});
-const siteFetchers = {
- fetchers: {
- accounts: newFetcher,
- blog: newFetcher,
- asktug: newFetcher,
- },
-};
-
-const App = ({ Component, pageProps, router }) => {
- const [errorStatus, setErrorStatus] = useState();
- const [errorMsg, setErrorMsg] = useState();
-
- useApiErrorListener((err) => {
- if (!err.status) {
- message.error(utils.errors.getErrorMessage(err));
- return;
- }
-
- const { status, statusText, data } = err;
- const errorMsg = data?.detail || statusText;
-
- if ([403, 404].includes(status)) {
- setErrorStatus(status);
- setErrorMsg(errorMsg);
- } else {
- message.error(`${errorMsg}`, 5);
- }
- });
+// const siteFetchers = {
+// fetchers: {
+// accounts: newFetcher,
+// blog: newFetcher,
+// asktug: newFetcher,
+// },
+// };
+const App: FC = ({ Component, pageProps, router }) => {
useEffect(() => {
const handleRouteChange = () => {
if (process.env.NEXT_PUBLIC_RUNTIME_ENV === 'production') {
@@ -126,53 +105,22 @@ const App = ({ Component, pageProps, router }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
- useEffect(() => {
- setErrorStatus();
- setErrorMsg();
- }, [router.pathname]);
-
- const {
- data: meResp,
- error: meError,
- isValidating: isMeValidating,
- mutate: mutateMe,
- } = useSWR('me', fetcher, {
- // Default configs could be found from
- // https://github.com/vercel/swr/blob/master/src/config.ts
- revalidateOnFocus: false,
- shouldRetryOnError: false,
- });
-
- const meData = meResp?.data;
-
- authContext.isAnonymous = !!meError;
- authContext.isLoggedIn = !isEmptyOrNil(meData);
-
- if (errorStatus) {
- return ;
- }
-
const WrappedComponent = withLayout(Component);
return (
-
+ {/**/}
-
-
-
-
-
-
-
-
+ {/**/}
+
+ {/**/}
+ {/**/}
);
};
-export default appWithTranslation(App, nextI18NextConfig);
+export default App;
diff --git a/src/pages/_document.page.js b/src/pages/_document.page.tsx
similarity index 84%
rename from src/pages/_document.page.js
rename to src/pages/_document.page.tsx
index 5041c929e..631816aae 100644
--- a/src/pages/_document.page.js
+++ b/src/pages/_document.page.tsx
@@ -2,10 +2,13 @@
// https://github.com/vercel/next.js/blob/master/examples/with-styled-components/pages/_document.js
import React from 'react';
// eslint-disable-next-line @next/next/no-document-import-in-page
-import Document from 'next/document';
+import Document from 'next/document'
+import type {DocumentInitialProps} from 'next/document'
+
import { ServerStyleSheet } from 'styled-components';
+
export default class MyDocument extends Document {
- static async getInitialProps(ctx) {
+ static async getInitialProps(ctx): Promise {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
diff --git a/src/pages/_error.page.js b/src/pages/_error.page.js
deleted file mode 100644
index 8e398bc9b..000000000
--- a/src/pages/_error.page.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import { createAppGlobalStyle } from '@tidb-community/ui';
-import { api } from '@tidb-community/datasource';
-
-import { ErrorPage } from '~/components';
-import { MeContext } from '~/context';
-
-const GlobalStyle = createAppGlobalStyle();
-
-const Error = (props) => {
- const [meData, setMeData] = useState(undefined);
-
- useEffect(() => {
- api
- .me()
- .then(({ data }) => setMeData(data))
- .catch(() => {});
- }, []);
-
- return (
- <>
-
-
-
-
- >
- );
-};
-
-Error.getInitialProps = ({ res, err }) => {
- const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
- return { statusCode };
-};
-
-export default Error;
diff --git a/src/pages/_error.page.tsx b/src/pages/_error.page.tsx
new file mode 100644
index 000000000..29da60754
--- /dev/null
+++ b/src/pages/_error.page.tsx
@@ -0,0 +1,17 @@
+import React from 'react';
+import {createAppGlobalStyle} from '@tidb-community/ui';
+
+import {ErrorPage} from '~/components';
+
+const GlobalStyle = createAppGlobalStyle();
+
+const Error = (props) => {
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default Error;
diff --git a/src/pages/my/company/index.page.js b/src/pages/my/company/index.page.js
index 71ba9d7e8..7a7efa592 100644
--- a/src/pages/my/company/index.page.js
+++ b/src/pages/my/company/index.page.js
@@ -1,9 +1,7 @@
-import React, { useContext, useEffect } from 'react';
+import React, { useEffect } from 'react';
import useSWR, { useSWRConfig } from 'swr';
import { api } from '@tidb-community/datasource';
-
-import { AuthContext, MeContext } from '~/context';
-import { CommunityHead, PageLoader } from '~/components';
+import { CommunityHead } from '~/components';
import { redDots as redDotsUtils } from '~/utils';
import * as Styled from './company.styled';
@@ -11,11 +9,11 @@ import Form from './form';
import Layout from '../layout';
import Verification from '../company/Verification.component';
import { Space } from 'antd';
+import { useIsLoggedIn } from '~/hooks/account';
const PageContent = ({ title }) => {
- const { login, isAnonymous, isLoggedIn } = useContext(AuthContext);
+ const isLoggedIn = useIsLoggedIn();
const { data: redDotsResp } = useSWR(isLoggedIn && 'operation.fetchRedDots');
- const { meData } = useContext(MeContext);
const { mutate } = useSWRConfig();
const redDots = redDotsUtils.transformRespToMap(redDotsResp);
@@ -24,20 +22,11 @@ const PageContent = ({ title }) => {
(async () => {
if (redDots.companyInfo) {
await api.operation.setRedDotRead('company-info');
- mutate('operation.fetchRedDots');
+ await mutate('operation.fetchRedDots');
}
})();
}, [redDots.companyInfo, mutate]);
- if (isAnonymous) {
- login();
- return null;
- }
-
- if (!meData) {
- return ;
- }
-
const titleNode = (
{title}
diff --git a/src/pages/my/layout/Layout.component.js b/src/pages/my/layout/Layout.component.js
index bc32d41ca..39084b914 100644
--- a/src/pages/my/layout/Layout.component.js
+++ b/src/pages/my/layout/Layout.component.js
@@ -1,34 +1,34 @@
-import React, { useEffect, useContext } from 'react';
-import { Col, Row } from 'antd';
+import React from 'react';
+import {Col, Row} from 'antd';
import * as Styled from './layout.styled';
import Menu from './menu';
-import { AuthContext } from '~/context';
-import { CoreLayout } from '~/layouts';
+import {CoreLayout} from '~/layouts';
+import {useAccount} from "~/hooks/account";
+import {PageLoader} from "~/components";
const Layout = ({ children, title }) => {
- const { setIsAuthRequired } = useContext(AuthContext);
-
- useEffect(() => {
- setIsAuthRequired(true);
- return () => setIsAuthRequired(false);
- }, [setIsAuthRequired]);
-
+ const account = useAccount()
+
return (
<>
-
-
-
-
-
-
- {title}
- {children}
-
-
-
+ {account.isValidating ? (
+
+ ): (
+
+
+
+
+
+
+ {title}
+ {children}
+
+
+
+ )}
>
diff --git a/src/pages/my/layout/menu/Menu.component.js b/src/pages/my/layout/menu/Menu.component.js
index 569e610f8..ee06c359d 100644
--- a/src/pages/my/layout/menu/Menu.component.js
+++ b/src/pages/my/layout/menu/Menu.component.js
@@ -1,15 +1,15 @@
-import React, { useContext } from 'react';
+import React from 'react';
import useSWR from 'swr';
-import { Badge } from 'antd';
-import { useRouter } from 'next/router';
+import {Badge} from 'antd';
+import {useRouter} from 'next/router';
import * as Styled from './menu.styled';
-import { AuthContext } from '~/context';
-import { redDots as redDotsUtils } from '~/utils';
+import {redDots as redDotsUtils} from '~/utils';
+import {useIsLoggedIn} from "~/hooks/account";
const Menu = () => {
const router = useRouter();
- const { isLoggedIn } = useContext(AuthContext);
+ const isLoggedIn = useIsLoggedIn()
const { data: redDotsResp } = useSWR(isLoggedIn && 'operation.fetchRedDots');
const redDots = redDotsUtils.transformRespToMap(redDotsResp);
@@ -20,8 +20,8 @@ const Menu = () => {
const companyPath = genPath('company');
const settingsPath = genPath('settings');
- const onClick = (path) => () => {
- router.push(path);
+ const onClick = (path) => async () => {
+ await router.push(path);
};
return (
diff --git a/src/pages/my/profile/index.page.js b/src/pages/my/profile/index.page.js
index 26049d79b..bed650899 100644
--- a/src/pages/my/profile/index.page.js
+++ b/src/pages/my/profile/index.page.js
@@ -1,24 +1,11 @@
-import React, { useContext } from 'react';
+import React from 'react';
-import { CommunityHead, PageLoader } from '~/components';
-import { AuthContext, MeContext } from '~/context';
+import { CommunityHead } from '~/components';
import Form from './form';
-import Layout from '~/pages/my/layout';
+import Layout from '../layout';
const PageContent = ({ title }) => {
- const { login, isAnonymous } = useContext(AuthContext);
- const { meData } = useContext(MeContext);
-
- if (isAnonymous) {
- login();
- return null;
- }
-
- if (!meData) {
- return ;
- }
-
return (
diff --git a/src/pages/my/settings/content/Content.component.js b/src/pages/my/settings/content/Content.component.js
index 7784f2dd1..12cd25657 100644
--- a/src/pages/my/settings/content/Content.component.js
+++ b/src/pages/my/settings/content/Content.component.js
@@ -1,4 +1,4 @@
-import React, { useContext, useState } from 'react';
+import React, { useState } from 'react';
import useSWR from 'swr';
import { Button, Modal, Skeleton, message } from 'antd';
import { ExclamationCircleOutlined } from '@ant-design/icons';
@@ -6,16 +6,17 @@ import { api } from '@tidb-community/datasource';
import * as Styled from './content.styled';
import Box from './box';
-import { AuthContext } from '~/context';
import { MODALS, SetPasswordModal, UpdateEmailModal, UpdatePasswordModal, UpdatePhoneModal } from './modals';
+import { login } from '~/hooks/account';
+import ErrorStatus from '~/components/errorPage/ErrorStatus';
const Content = () => {
const [visibleModal, setVisibleModal] = useState();
- const { data: settingsResp, error, mutate } = useSWR('account.settings');
- const { login } = useContext(AuthContext);
+ const { data: settingsResp, error, mutate, isValidating } = useSWR('account.settings');
- const isLoading = !error && !settingsResp;
- if (isLoading) return ;
+ if (isValidating) return ;
+ if (error) return ;
+ if (!settingsResp) return ;
const { data } = settingsResp;
const {
diff --git a/src/pages/my/settings/index.page.js b/src/pages/my/settings/index.page.js
index d7913c55e..1aac91705 100644
--- a/src/pages/my/settings/index.page.js
+++ b/src/pages/my/settings/index.page.js
@@ -1,38 +1,20 @@
-import React, { useContext } from 'react';
+import React from 'react';
-import { CommunityHead, PageLoader } from '~/components';
-import { AuthContext, MeContext } from '~/context';
+import { CommunityHead } from '~/components';
import Content from './content';
import Layout from '../layout';
-const PageContent = ({ title }) => {
- const { login, isAnonymous } = useContext(AuthContext);
- const { meData } = useContext(MeContext);
-
- if (isAnonymous) {
- login();
- return null;
- }
-
- if (!meData) {
- return ;
- }
-
- return (
-
-
-
- );
-};
-
const Page = () => {
const title = '账号设置';
return (
<>
-
+
+
+
+
>
);
};
diff --git a/src/pages/notifications/layout/Layout.component.tsx b/src/pages/notifications/layout/Layout.component.tsx
index e28ac23df..5be341215 100644
--- a/src/pages/notifications/layout/Layout.component.tsx
+++ b/src/pages/notifications/layout/Layout.component.tsx
@@ -4,7 +4,7 @@ import { Col, Row } from 'antd';
import * as Styled from './layout.styled';
import Menu, { MenuProps } from './menu';
import { AuthContext } from '~/context';
-import { SiteLayout } from '~/layouts';
+import { CoreLayout } from '~/layouts';
import { CommunityHead } from '~/components';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
@@ -20,7 +20,7 @@ const Layout = ({ children, ...menuProps }: PropsWithChildren) => {
return (
<>
-
+
@@ -32,7 +32,7 @@ const Layout = ({ children, ...menuProps }: PropsWithChildren) => {
-
+
>
);
};
diff --git a/src/pages/private-messages/layout/Layout.component.tsx b/src/pages/private-messages/layout/Layout.component.tsx
index ce7df5698..9b978dba7 100644
--- a/src/pages/private-messages/layout/Layout.component.tsx
+++ b/src/pages/private-messages/layout/Layout.component.tsx
@@ -4,7 +4,7 @@ import { Button, Col, Row } from 'antd';
import * as Styled from './layout.styled';
import Menu from './menu';
import { AuthContext } from '~/context';
-import { SiteLayout } from '~/layouts';
+import { CoreLayout } from '~/layouts';
import { MailOutlined } from '@ant-design/icons';
import { useRouter } from 'next/router';
@@ -20,7 +20,7 @@ const Layout: React.FC = ({ children }) => {
}
return (
<>
-
+
@@ -42,7 +42,7 @@ const Layout: React.FC = ({ children }) => {
-
+
>
);
};