diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml index 039e2e5e..af2fedac 100644 --- a/i18n/en_US.yaml +++ b/i18n/en_US.yaml @@ -1044,13 +1044,11 @@ ui: votes: votes answers: answers accepted: Accepted - page_404: - http_error: HTTP Error 404 - desc: "Unfortunately, this page doesn't exist." - back_home: Back to homepage - page_50X: - http_error: HTTP Error 500 - desc: The server encountered an error and could not complete your request. + page_error: + http_error: HTTP Error {{ code }} + desc_403: You don’t have permission to access this page. + desc_404: Unfortunately, this page doesn't exist. + desc_50X: The server encountered an error and could not complete your request. back_home: Back to homepage page_maintenance: desc: "We are under maintenance, we'll be back soon." diff --git a/i18n/zh_CN.yaml b/i18n/zh_CN.yaml index abd710dc..deaf4cc8 100644 --- a/i18n/zh_CN.yaml +++ b/i18n/zh_CN.yaml @@ -979,13 +979,11 @@ ui: votes: 个点赞 answers: 个回答 accepted: 已被采纳 - page_404: - http_error: HTTP Error 404 - desc: "很抱歉,此页面不存在。" - back_home: 回到主页 - page_50X: - http_error: HTTP Error 500 - desc: 服务器遇到了一个错误,无法完成你的请求。 + page_error: + http_error: HTTP Error {{ code }} + desc_403: 你无权访问此页面。 + desc_404: 很抱歉,此页面不存在。 + desc_50X: 服务器遇到了一个错误,无法完成你的请求。 back_home: 回到主页 page_maintenance: desc: "我们正在进行维护,我们将很快回来。" diff --git a/i18n/zh_TW.yaml b/i18n/zh_TW.yaml index 58bb99b5..20bacfc4 100644 --- a/i18n/zh_TW.yaml +++ b/i18n/zh_TW.yaml @@ -977,13 +977,11 @@ ui: votes: 得票 answers: 回答 accepted: 已採納 - page_404: - http_error: HTTP Error 404 - desc: "很抱歉,此頁面不存在。" - back_home: 回到首頁 - page_50X: - http_error: HTTP Error 500 - desc: 伺服器遇到了一個錯誤,無法完成你的請求。 + page_error: + http_error: HTTP Error {{ code }} + desc_403: 你无权访问此頁面。 + desc_404: 很抱歉,此頁面不存在。 + desc_50X: 伺服器遇到了一個錯誤,無法完成你的請求。 back_home: 回到首頁 page_maintenance: desc: "我們正在維護中,很快就會回來。" diff --git a/ui/src/components/HttpErrorContent/index.tsx b/ui/src/components/HttpErrorContent/index.tsx new file mode 100644 index 00000000..e1c40d25 --- /dev/null +++ b/ui/src/components/HttpErrorContent/index.tsx @@ -0,0 +1,31 @@ +import { memo } from 'react'; +import { Link } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; + +import { usePageTags } from '@/hooks'; + +const Index = ({ httpCode = '' }) => { + const { t } = useTranslation('translation', { keyPrefix: 'page_error' }); + + usePageTags({ + title: t(`http_${httpCode}`, { keyPrefix: 'page_title' }), + }); + return ( + <> +
+ (=‘x‘=) +
+

{t('http_error', { code: httpCode })}

+
{t(`desc_${httpCode}`)}
+
+ + {t('back_home')} + +
+ + ); +}; + +export default memo(Index); diff --git a/ui/src/components/index.ts b/ui/src/components/index.ts index aee1a19a..7618aada 100644 --- a/ui/src/components/index.ts +++ b/ui/src/components/index.ts @@ -35,6 +35,7 @@ import TagsLoader from './TagsLoader'; import Counts from './Counts'; import QuestionList from './QuestionList'; import HotQuestions from './HotQuestions'; +import HttpErrorContent from './HttpErrorContent'; export { Avatar, @@ -76,5 +77,6 @@ export { Counts, QuestionList, HotQuestions, + HttpErrorContent, }; export type { EditorRef, JSONSchema, UISchema }; diff --git a/ui/src/pages/404/index.jsx b/ui/src/pages/404/index.jsx index 933972d4..0f088abc 100644 --- a/ui/src/pages/404/index.jsx +++ b/ui/src/pages/404/index.jsx @@ -1,13 +1,10 @@ +/* eslint-disable import/no-unresolved */ import { useEffect } from 'react'; -import { Container, Button } from 'react-bootstrap'; -import { Link } from 'react-router-dom'; -import { useTranslation } from 'react-i18next'; +import { Container } from 'react-bootstrap'; -// eslint-disable-next-line import/no-unresolved -import { usePageTags } from '@/hooks'; +import { HttpErrorContent } from '@/components'; const Index = () => { - const { t } = useTranslation('translation', { keyPrefix: 'page_404' }); useEffect(() => { // auto height of container const pageWrap = document.querySelector('.page-wrap'); @@ -18,25 +15,11 @@ const Index = () => { }; }, []); - usePageTags({ - title: t('http_404', { keyPrefix: 'page_title' }), - }); return ( -
- (=‘x‘=) -
-

{t('http_error')}

-
{t('desc')}
-
- -
+
); }; diff --git a/ui/src/pages/50X/index.jsx b/ui/src/pages/50X/index.jsx index 33a8a693..fe142ad6 100644 --- a/ui/src/pages/50X/index.jsx +++ b/ui/src/pages/50X/index.jsx @@ -1,13 +1,10 @@ +/* eslint-disable import/no-unresolved */ import { useEffect } from 'react'; -import { Container, Button } from 'react-bootstrap'; -import { Link } from 'react-router-dom'; -import { useTranslation } from 'react-i18next'; +import { Container } from 'react-bootstrap'; -// eslint-disable-next-line import/no-unresolved -import { usePageTags } from '@/hooks'; +import { HttpErrorContent } from '@/components'; const Index = () => { - const { t } = useTranslation('translation', { keyPrefix: 'page_50X' }); useEffect(() => { // auto height of container const pageWrap = document.querySelector('.page-wrap'); @@ -18,26 +15,11 @@ const Index = () => { }; }, []); - usePageTags({ - title: t('http_50X', { keyPrefix: 'page_title' }), - }); return ( -
- (=T^T=) -
- -

{t('http_error')}

-
{t('desc')}
-
- -
+
); }; diff --git a/ui/src/pages/Layout/index.tsx b/ui/src/pages/Layout/index.tsx index a09bf113..c83dfb84 100644 --- a/ui/src/pages/Layout/index.tsx +++ b/ui/src/pages/Layout/index.tsx @@ -12,11 +12,10 @@ import { Customize, CustomizeTheme, PageTags, + HttpErrorContent, } from '@/components'; import { LoginToContinueModal } from '@/components/Modal'; import { useImgViewer } from '@/hooks'; -import Component404 from '@/pages/404'; -import Component50X from '@/pages/50X'; const Layout: FC = () => { const location = useLocation(); @@ -44,11 +43,14 @@ const Layout: FC = () => { {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
- {httpStatusCode === '404' ? ( - - ) : httpStatusCode === '50X' ? ( - + {httpStatusCode ? ( +
+ +
) : ( )} diff --git a/ui/src/stores/errorCode.ts b/ui/src/stores/errorCode.ts index 336a213b..6da8f8d0 100644 --- a/ui/src/stores/errorCode.ts +++ b/ui/src/stores/errorCode.ts @@ -1,6 +1,6 @@ import create from 'zustand'; -type codeType = '404' | '50X' | ''; +type codeType = '403' | '404' | '50X' | ''; interface NotFoundType { code: codeType; diff --git a/ui/src/utils/request.ts b/ui/src/utils/request.ts index 0e58da26..acb96556 100644 --- a/ui/src/utils/request.ts +++ b/ui/src/utils/request.ts @@ -55,7 +55,7 @@ class Request { const { status, data: respData } = error.response || {}; const { data = {}, msg = '', reason = '' } = respData || {}; - console.log('response error:', error); + // console.log('response error:', error); if (status === 400) { // show error message @@ -114,7 +114,6 @@ class Request { } if (status === 403) { // Permission interception - errorCode.getState().reset(); if (data?.type === 'url_expired') { // url expired floppyNavigation.navigate(RouteAlias.activationFailed, () => { @@ -137,6 +136,14 @@ class Request { return Promise.reject(false); } + if (isIgnoredPath(IGNORE_PATH_LIST)) { + return Promise.reject(false); + } + if (error.config?.url.includes('/admin/api')) { + errorCode.getState().update('403'); + return Promise.reject(false); + } + if (msg) { toastStore.getState().show({ msg,