mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-22 12:20:34 +00:00
feat: add login page ip detect (#2819)
* feat: add login page ip detect * code perf
This commit is contained in:
@@ -39,6 +39,8 @@ export const iconPaths = {
|
||||
'common/inviteLight': () => import('./icons/common/inviteLight.svg'),
|
||||
'common/language/en': () => import('./icons/common/language/en.svg'),
|
||||
'common/language/zh': () => import('./icons/common/language/zh.svg'),
|
||||
'common/language/China': () => import('./icons/common/language/China.svg'),
|
||||
'common/language/America': () => import('./icons/common/language/America.svg'),
|
||||
'common/leftArrowLight': () => import('./icons/common/leftArrowLight.svg'),
|
||||
'common/line': () => import('./icons/common/line.svg'),
|
||||
'common/lineChange': () => import('./icons/common/lineChange.svg'),
|
||||
|
@@ -0,0 +1,56 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 10" fill="none">
|
||||
<path d="M14 0H0V9.31222H14V0Z" fill="#B31942"/>
|
||||
<path d="M0 1.07422H14H0ZM14 2.50687H0H14ZM0 3.93952H14H0ZM14 5.37217H0H14ZM0 6.80481H14H0ZM14 8.23746H0H14Z" fill="#000008"/>
|
||||
<path d="M0 1.07422H14M14 2.50687H0M0 3.93952H14M14 5.37217H0M0 6.80481H14M14 8.23746H0" stroke="white" stroke-width="0.716325"/>
|
||||
<path d="M7.07729 0H0V5.01427H7.07729V0Z" fill="#0A3161"/>
|
||||
<path d="M0.589645 0.214844L0.758063 0.733181L0.317139 0.412831H0.862151L0.421227 0.733181L0.589645 0.214844Z" fill="white"/>
|
||||
<path d="M0.589645 1.21777L0.758063 1.73611L0.317139 1.41576H0.862151L0.421227 1.73611L0.589645 1.21777Z" fill="white"/>
|
||||
<path d="M0.589645 2.2207L0.758063 2.73904L0.317139 2.41869H0.862151L0.421227 2.73904L0.589645 2.2207Z" fill="white"/>
|
||||
<path d="M0.589645 3.22363L0.758063 3.74197L0.317139 3.42162H0.862151L0.421227 3.74197L0.589645 3.22363Z" fill="white"/>
|
||||
<path d="M0.589645 4.22607L0.758063 4.74441L0.317139 4.42406H0.862151L0.421227 4.74441L0.589645 4.22607Z" fill="white"/>
|
||||
<path d="M1.17924 0.71582L1.34766 1.23416L0.906738 0.913808H1.45175L1.01083 1.23416L1.17924 0.71582Z" fill="white"/>
|
||||
<path d="M1.17924 1.71875L1.34766 2.23709L0.906738 1.91674H1.45175L1.01083 2.23709L1.17924 1.71875Z" fill="white"/>
|
||||
<path d="M1.17924 2.72168L1.34766 3.24002L0.906738 2.91967H1.45175L1.01083 3.24002L1.17924 2.72168Z" fill="white"/>
|
||||
<path d="M1.17924 3.72461L1.34766 4.24295L0.906738 3.9226H1.45175L1.01083 4.24295L1.17924 3.72461Z" fill="white"/>
|
||||
<path d="M1.76811 0.215332L1.93653 0.733669L1.49561 0.413319H2.04062L1.59969 0.733669L1.76811 0.215332Z" fill="white"/>
|
||||
<path d="M1.76811 1.21826L1.93653 1.7366L1.49561 1.41625H2.04062L1.59969 1.7366L1.76811 1.21826Z" fill="white"/>
|
||||
<path d="M1.76811 2.22119L1.93653 2.73953L1.49561 2.41918H2.04062L1.59969 2.73953L1.76811 2.22119Z" fill="white"/>
|
||||
<path d="M1.76811 3.22412L1.93653 3.74246L1.49561 3.42211H2.04062L1.59969 3.74246L1.76811 3.22412Z" fill="white"/>
|
||||
<path d="M1.76836 4.22656L1.93677 4.7449L1.49585 4.42455H2.04086L1.59994 4.7449L1.76836 4.22656Z" fill="white"/>
|
||||
<path d="M2.3582 0.716309L2.52662 1.23465L2.08569 0.914296H2.63071L2.18978 1.23465L2.3582 0.716309Z" fill="white"/>
|
||||
<path d="M2.3582 1.71924L2.52662 2.23758L2.08569 1.91723H2.63071L2.18978 2.23758L2.3582 1.71924Z" fill="white"/>
|
||||
<path d="M2.3582 2.72217L2.52662 3.24051L2.08569 2.92016H2.63071L2.18978 3.24051L2.3582 2.72217Z" fill="white"/>
|
||||
<path d="M2.3582 3.7251L2.52662 4.24343L2.08569 3.92308H2.63071L2.18978 4.24343L2.3582 3.7251Z" fill="white"/>
|
||||
<path d="M2.94682 0.21582L3.11524 0.734158L2.67432 0.413808H3.21933L2.7784 0.734158L2.94682 0.21582Z" fill="white"/>
|
||||
<path d="M2.94682 1.21875L3.11524 1.73709L2.67432 1.41674H3.21933L2.7784 1.73709L2.94682 1.21875Z" fill="white"/>
|
||||
<path d="M2.94682 2.22168L3.11524 2.74002L2.67432 2.41967H3.21933L2.7784 2.74002L2.94682 2.22168Z" fill="white"/>
|
||||
<path d="M2.94682 3.22461L3.11524 3.74295L2.67432 3.4226H3.21933L2.7784 3.74295L2.94682 3.22461Z" fill="white"/>
|
||||
<path d="M2.94731 4.22705L3.11573 4.74539L2.6748 4.42504H3.21982L2.77889 4.74539L2.94731 4.22705Z" fill="white"/>
|
||||
<path d="M3.53715 0.716797L3.70557 1.23513L3.26465 0.914784H3.80966L3.36874 1.23513L3.53715 0.716797Z" fill="white"/>
|
||||
<path d="M3.53715 1.71973L3.70557 2.23806L3.26465 1.91771H3.80966L3.36874 2.23806L3.53715 1.71973Z" fill="white"/>
|
||||
<path d="M3.53715 2.72266L3.70557 3.24099L3.26465 2.92064H3.80966L3.36874 3.24099L3.53715 2.72266Z" fill="white"/>
|
||||
<path d="M3.53715 3.72559L3.70557 4.24392L3.26465 3.92357H3.80966L3.36874 4.24392L3.53715 3.72559Z" fill="white"/>
|
||||
<path d="M4.12895 0.216309L4.29737 0.734646L3.85645 0.414296H4.40146L3.96053 0.734646L4.12895 0.216309Z" fill="white"/>
|
||||
<path d="M4.12895 1.21924L4.29737 1.73758L3.85645 1.41723H4.40146L3.96053 1.73758L4.12895 1.21924Z" fill="white"/>
|
||||
<path d="M4.12895 2.22217L4.29737 2.74051L3.85645 2.42016H4.40146L3.96053 2.74051L4.12895 2.22217Z" fill="white"/>
|
||||
<path d="M4.12895 3.2251L4.29737 3.74343L3.85645 3.42308H4.40146L3.96053 3.74343L4.12895 3.2251Z" fill="white"/>
|
||||
<path d="M4.12846 4.22754L4.29688 4.74588L3.85596 4.42553H4.40097L3.96005 4.74588L4.12846 4.22754Z" fill="white"/>
|
||||
<path d="M4.71831 0.716797L4.88673 1.23513L4.4458 0.914784H4.99081L4.54989 1.23513L4.71831 0.716797Z" fill="white"/>
|
||||
<path d="M4.71831 1.71973L4.88673 2.23806L4.4458 1.91771H4.99081L4.54989 2.23806L4.71831 1.71973Z" fill="white"/>
|
||||
<path d="M4.71831 2.72266L4.88673 3.24099L4.4458 2.92064H4.99081L4.54989 3.24099L4.71831 2.72266Z" fill="white"/>
|
||||
<path d="M4.71831 3.72559L4.88673 4.24392L4.4458 3.92357H4.99081L4.54989 4.24392L4.71831 3.72559Z" fill="white"/>
|
||||
<path d="M5.30839 0.21582L5.47681 0.734158L5.03589 0.413808H5.5809L5.13998 0.734158L5.30839 0.21582Z" fill="white"/>
|
||||
<path d="M5.30839 1.21875L5.47681 1.73709L5.03589 1.41674H5.5809L5.13998 1.73709L5.30839 1.21875Z" fill="white"/>
|
||||
<path d="M5.30839 2.22168L5.47681 2.74002L5.03589 2.41967H5.5809L5.13998 2.74002L5.30839 2.22168Z" fill="white"/>
|
||||
<path d="M5.30839 3.22461L5.47681 3.74295L5.03589 3.4226H5.5809L5.13998 3.74295L5.30839 3.22461Z" fill="white"/>
|
||||
<path d="M5.30815 4.22705L5.47657 4.74539L5.03564 4.42504H5.58066L5.13973 4.74539L5.30815 4.22705Z" fill="white"/>
|
||||
<path d="M5.89799 0.716309L6.06641 1.23465L5.62549 0.914296H6.1705L5.72958 1.23465L5.89799 0.716309Z" fill="white"/>
|
||||
<path d="M5.89799 1.71924L6.06641 2.23758L5.62549 1.91723H6.1705L5.72958 2.23758L5.89799 1.71924Z" fill="white"/>
|
||||
<path d="M5.89799 2.72217L6.06641 3.24051L5.62549 2.92016H6.1705L5.72958 3.24051L5.89799 2.72217Z" fill="white"/>
|
||||
<path d="M5.89799 3.72461L6.06641 4.24295L5.62549 3.9226H6.1705L5.72958 4.24295L5.89799 3.72461Z" fill="white"/>
|
||||
<path d="M6.48759 0.215332L6.65601 0.733669L6.21509 0.413319H6.7601L6.31918 0.733669L6.48759 0.215332Z" fill="white"/>
|
||||
<path d="M6.48735 1.21826L6.65577 1.7366L6.21484 1.41625H6.75986L6.31893 1.7366L6.48735 1.21826Z" fill="white"/>
|
||||
<path d="M6.48735 2.22119L6.65577 2.73953L6.21484 2.41918H6.75986L6.31893 2.73953L6.48735 2.22119Z" fill="white"/>
|
||||
<path d="M6.48735 3.22412L6.65577 3.74246L6.21484 3.42211H6.75986L6.31893 3.74246L6.48735 3.22412Z" fill="white"/>
|
||||
<path d="M6.48735 4.22656L6.65577 4.7449L6.21484 4.42455H6.75986L6.31893 4.7449L6.48735 4.22656Z" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 6.2 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 10" fill="none">
|
||||
<path d="M0 0H14V9.31222H0V0Z" fill="#EE1C25"/>
|
||||
<path d="M1.28535 3.71454L2.16821 1.06592L3.05108 3.71454L0.696777 2.09594H3.63965L1.28535 3.71454Z" fill="#FFFF00"/>
|
||||
<path d="M5.11473 1.11669L4.20615 1.31803L4.8122 0.611803L4.75276 1.5623L4.24856 0.720824L5.11473 1.11669Z" fill="#FFFF00"/>
|
||||
<path d="M6.03166 2.27839L5.11611 2.11159L5.94863 1.69569L5.5252 2.54873L5.38682 1.57757L6.03166 2.27839Z" fill="#FFFF00"/>
|
||||
<path d="M5.89789 3.90911L5.12998 3.3834L6.05973 3.34321L5.32522 3.94939L5.59495 3.00623L5.89789 3.90911Z" fill="#FFFF00"/>
|
||||
<path d="M4.74297 4.97429L4.23769 4.19279L5.11081 4.51482L4.19918 4.79026L4.81225 4.02447L4.74297 4.97429Z" fill="#FFFF00"/>
|
||||
</svg>
|
After Width: | Height: | Size: 763 B |
@@ -1,13 +1,16 @@
|
||||
{
|
||||
"Chinese_ip_tip": "It is detected that you are a mainland Chinese IP, click to jump to visit the mainland China version.",
|
||||
"Login": "Login",
|
||||
"forget_password": "Find password",
|
||||
"login_failed": "Login failed",
|
||||
"login_success": "Login successful",
|
||||
"no_remind": "Don't remind again",
|
||||
"password_condition": "Password maximum 60 characters",
|
||||
"policy_tip": "By useing, you agree to our",
|
||||
"privacy": "Privacy policy",
|
||||
"redirect": "Jump",
|
||||
"register": "Register",
|
||||
"root_password_placeholder": "The root user password is the value of the environment variable DEFAULT_ROOT_PSW",
|
||||
"terms": "Terms",
|
||||
"use_root_login": "Log in as root user"
|
||||
}
|
||||
}
|
||||
|
@@ -9,5 +9,8 @@
|
||||
"register": "注册账号",
|
||||
"root_password_placeholder": "root 用户密码为环境变量 DEFAULT_ROOT_PSW 的值",
|
||||
"terms": "服务协议",
|
||||
"use_root_login": "使用 root 用户登录"
|
||||
}
|
||||
"use_root_login": "使用 root 用户登录",
|
||||
"redirect": "跳转",
|
||||
"no_remind": "不再提醒",
|
||||
"Chinese_ip_tip": "检测到您是中国大陆 IP,点击跳转访问中国大陆版。"
|
||||
}
|
||||
|
40
projects/app/src/components/Select/I18nLngSelector.tsx
Normal file
40
projects/app/src/components/Select/I18nLngSelector.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import { langMap } from '@/web/common/utils/i18n';
|
||||
import { Avatar, Box, Flex } from '@chakra-ui/react';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
import { useI18nLng } from '@fastgpt/web/hooks/useI18n';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useMemo } from 'react';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
|
||||
const I18nLngSelector = () => {
|
||||
const { i18n } = useTranslation();
|
||||
const { onChangeLng } = useI18nLng();
|
||||
|
||||
const list = useMemo(() => {
|
||||
return Object.entries(langMap).map(([key, lang]) => ({
|
||||
label: (
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon borderRadius={'0'} mr={2} name={lang.avatar as any} w={'14px'} h={'9px'} />
|
||||
<Box>{lang.label}</Box>
|
||||
</Flex>
|
||||
),
|
||||
value: key
|
||||
}));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<MySelect
|
||||
_hover={{
|
||||
bg: 'myGray.200'
|
||||
}}
|
||||
value={i18n.language}
|
||||
list={list}
|
||||
onchange={(val: any) => {
|
||||
const lang = val;
|
||||
onChangeLng(lang);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default I18nLngSelector;
|
@@ -7,18 +7,13 @@ import { UserType } from '@fastgpt/global/support/user/type';
|
||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { UserUpdateParams } from '@/types/user';
|
||||
import { langMap } from '@/web/common/utils/i18n';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useI18nLng } from '@fastgpt/web/hooks/useI18n';
|
||||
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
import TimezoneSelect from '@fastgpt/web/components/common/MySelect/TimezoneSelect';
|
||||
import I18nLngSelector from '@/components/Select/I18nLngSelector';
|
||||
|
||||
const Individuation = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { t } = useTranslation();
|
||||
const { userInfo, updateUserInfo } = useUserStore();
|
||||
const { toast } = useToast();
|
||||
const { onChangeLng } = useI18nLng();
|
||||
|
||||
const { reset } = useForm<UserUpdateParams>({
|
||||
defaultValues: userInfo as UserType
|
||||
@@ -49,17 +44,7 @@ const Individuation = () => {
|
||||
<Flex alignItems={'center'} w={['85%', '350px']}>
|
||||
<Box flex={'0 0 80px'}>{t('common:user.Language')}: </Box>
|
||||
<Box flex={'1 0 0'}>
|
||||
<MySelect
|
||||
value={i18n.language}
|
||||
list={Object.entries(langMap).map(([key, lang]) => ({
|
||||
label: lang.label,
|
||||
value: key
|
||||
}))}
|
||||
onchange={(val: any) => {
|
||||
const lang = val;
|
||||
onChangeLng(lang);
|
||||
}}
|
||||
/>
|
||||
<I18nLngSelector />
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex mt={6} alignItems={'center'} w={['85%', '350px']}>
|
||||
|
@@ -9,6 +9,8 @@ import { useRouter } from 'next/router';
|
||||
import { Dispatch, useRef } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Divider from '@/pages/app/detail/components/WorkflowComponents/Flow/components/Divider';
|
||||
import I18nLngSelector from '@/components/Select/I18nLngSelector';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 8);
|
||||
|
||||
interface Props {
|
||||
@@ -24,6 +26,7 @@ const FormLayout = ({ children, setPageType, pageType }: Props) => {
|
||||
const { lastRoute = '/app/list' } = router.query as { lastRoute: string };
|
||||
const state = useRef(nanoid());
|
||||
const redirectUri = `${location.origin}/login/provider`;
|
||||
const { isPc } = useSystem();
|
||||
|
||||
const oAuthList = [
|
||||
...(feConfigs?.oauth?.wechat && pageType !== LoginPageTypeEnum.wechat
|
||||
@@ -72,22 +75,25 @@ const FormLayout = ({ children, setPageType, pageType }: Props) => {
|
||||
|
||||
return (
|
||||
<Flex flexDirection={'column'} h={'100%'}>
|
||||
<Flex alignItems={'center'}>
|
||||
<Flex
|
||||
w={['48px', '56px']}
|
||||
h={['48px', '56px']}
|
||||
bg={'myGray.25'}
|
||||
borderRadius={'xl'}
|
||||
borderWidth={'1.5px'}
|
||||
borderColor={'borderColor.base'}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
>
|
||||
<Image src={LOGO_ICON} w={['24px', '28px']} alt={'icon'} />
|
||||
<Flex alignItems={'center'} justify={'space-between'}>
|
||||
<Flex>
|
||||
<Flex
|
||||
w={['48px', '56px']}
|
||||
h={['48px', '56px']}
|
||||
bg={'myGray.25'}
|
||||
borderRadius={'xl'}
|
||||
borderWidth={'1.5px'}
|
||||
borderColor={'borderColor.base'}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
>
|
||||
<Image src={LOGO_ICON} w={['24px', '28px']} alt={'icon'} />
|
||||
</Flex>
|
||||
<Box ml={3} fontSize={['2xl', '3xl']} fontWeight={'bold'}>
|
||||
{feConfigs?.systemTitle}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box ml={3} fontSize={['2xl', '3xl']} fontWeight={'bold'}>
|
||||
{feConfigs?.systemTitle}
|
||||
</Box>
|
||||
{!isPc && <I18nLngSelector />}
|
||||
</Flex>
|
||||
{children}
|
||||
{show_oauth && (
|
||||
|
@@ -1,5 +1,15 @@
|
||||
import React, { useState, useCallback, useEffect } from 'react';
|
||||
import { Box, Center, Flex, useDisclosure } from '@chakra-ui/react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Center,
|
||||
Drawer,
|
||||
DrawerCloseButton,
|
||||
DrawerContent,
|
||||
DrawerOverlay,
|
||||
Flex,
|
||||
useDisclosure
|
||||
} from '@chakra-ui/react';
|
||||
import { LoginPageTypeEnum } from '@/web/support/user/login/constants';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import type { ResLogin } from '@/global/support/api/userRes.d';
|
||||
@@ -12,22 +22,31 @@ import { serviceSideProps } from '@/web/common/utils/i18n';
|
||||
import { clearToken, setToken } from '@/web/support/user/auth';
|
||||
import Script from 'next/script';
|
||||
import Loading from '@fastgpt/web/components/common/MyLoading';
|
||||
import { useMount } from 'ahooks';
|
||||
import { t } from 'i18next';
|
||||
import { useLocalStorageState, useMount } from 'ahooks';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import I18nLngSelector from '@/components/Select/I18nLngSelector';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
|
||||
const RegisterForm = dynamic(() => import('./components/RegisterForm'));
|
||||
const ForgetPasswordForm = dynamic(() => import('./components/ForgetPasswordForm'));
|
||||
const WechatForm = dynamic(() => import('./components/LoginForm/WechatForm'));
|
||||
const CommunityModal = dynamic(() => import('@/components/CommunityModal'));
|
||||
|
||||
const Login = () => {
|
||||
const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => {
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
const { lastRoute = '' } = router.query as { lastRoute: string };
|
||||
const { feConfigs } = useSystemStore();
|
||||
const [pageType, setPageType] = useState<`${LoginPageTypeEnum}`>();
|
||||
const { setUserInfo } = useUserStore();
|
||||
const { setLastChatId, setLastChatAppId } = useChatStore();
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const { isPc } = useSystem();
|
||||
const {
|
||||
isOpen: isOpenRedirect,
|
||||
onOpen: onOpenRedirect,
|
||||
onClose: onCloseRedirect
|
||||
} = useDisclosure();
|
||||
|
||||
const loginSuccess = useCallback(
|
||||
(res: ResLogin) => {
|
||||
@@ -69,6 +88,25 @@ const Login = () => {
|
||||
router.prefetch('/app/list');
|
||||
});
|
||||
|
||||
const [showRedirect, setShowRedirect] = useLocalStorageState<boolean>('showRedirect', {
|
||||
defaultValue: true
|
||||
});
|
||||
|
||||
const checkIpInChina = useCallback(() => {
|
||||
const onSuccess = (res: any) => {
|
||||
if (!res.country.iso_code) {
|
||||
return;
|
||||
}
|
||||
|
||||
const country = res.country.iso_code.toLowerCase();
|
||||
if (country === 'cn') {
|
||||
onOpenRedirect();
|
||||
}
|
||||
};
|
||||
const onError = (e: any) => console.log(e);
|
||||
geoip2 && geoip2.country(onSuccess, onError);
|
||||
}, [onOpenRedirect]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{feConfigs.googleClientVerKey && (
|
||||
@@ -76,6 +114,15 @@ const Login = () => {
|
||||
src={`https://www.recaptcha.net/recaptcha/api.js?render=${feConfigs.googleClientVerKey}`}
|
||||
></Script>
|
||||
)}
|
||||
|
||||
{ChineseRedirectUrl && showRedirect && (
|
||||
<Script
|
||||
src="//geoip-js.com/js/apis/geoip2/v2.1/geoip2.js"
|
||||
type="text/javascript"
|
||||
onLoad={checkIpInChina}
|
||||
></Script>
|
||||
)}
|
||||
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
@@ -85,6 +132,11 @@ const Login = () => {
|
||||
h={'100%'}
|
||||
px={[0, '10vw']}
|
||||
>
|
||||
{isPc && (
|
||||
<Box position={'absolute'} top={'24px'} right={'50px'}>
|
||||
<I18nLngSelector />
|
||||
</Box>
|
||||
)}
|
||||
<Flex
|
||||
flexDirection={'column'}
|
||||
w={['100%', 'auto']}
|
||||
@@ -123,13 +175,66 @@ const Login = () => {
|
||||
|
||||
{isOpen && <CommunityModal onClose={onClose} />}
|
||||
</Flex>
|
||||
{showRedirect && (
|
||||
<RedirectDrawer
|
||||
isOpen={isOpenRedirect}
|
||||
onClose={onCloseRedirect}
|
||||
onRedirect={() => router.push(ChineseRedirectUrl)}
|
||||
disableDrawer={() => setShowRedirect(false)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
function RedirectDrawer({
|
||||
isOpen,
|
||||
onClose,
|
||||
disableDrawer,
|
||||
onRedirect
|
||||
}: {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
disableDrawer: () => void;
|
||||
onRedirect: () => void;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Drawer placement="bottom" size={'xs'} isOpen={isOpen} onClose={onClose}>
|
||||
<DrawerOverlay backgroundColor={'rgba(0,0,0,0.2)'} />
|
||||
<DrawerContent py={'1.75rem'} px={'3rem'}>
|
||||
<DrawerCloseButton size={'sm'} />
|
||||
<Flex align={'center'} justify={'space-between'}>
|
||||
<Box>
|
||||
<Box color={'myGray.900'} fontWeight={'500'} fontSize={'1rem'}>
|
||||
{t('login:Chinese_ip_tip')}
|
||||
</Box>
|
||||
<Box
|
||||
color={'primary.700'}
|
||||
fontWeight={'500'}
|
||||
fontSize={'1rem'}
|
||||
textDecorationLine={'underline'}
|
||||
cursor={'pointer'}
|
||||
onClick={disableDrawer}
|
||||
>
|
||||
{t('login:no_remind')}
|
||||
</Box>
|
||||
</Box>
|
||||
<Button ml={'0.75rem'} onClick={onRedirect}>
|
||||
{t('login:redirect')}
|
||||
</Button>
|
||||
</Flex>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
||||
export async function getServerSideProps(context: any) {
|
||||
return {
|
||||
props: { ...(await serviceSideProps(context, ['app', 'user', 'login'])) }
|
||||
props: {
|
||||
ChineseRedirectUrl: process.env.CHINESE_IP_REDIRECT_URL,
|
||||
...(await serviceSideProps(context, ['app', 'user', 'login']))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
2
projects/app/src/types/index.d.ts
vendored
2
projects/app/src/types/index.d.ts
vendored
@@ -22,7 +22,7 @@ export type RequestPaging = { pageNum: number; pageSize: number; [key]: any };
|
||||
declare global {
|
||||
var qaQueueLen: number;
|
||||
var vectorQueueLen: number;
|
||||
|
||||
var geoip2: any;
|
||||
interface Window {
|
||||
grecaptcha: any;
|
||||
QRCode: any;
|
||||
|
@@ -7,12 +7,14 @@ export enum LangEnum {
|
||||
}
|
||||
export const langMap = {
|
||||
[LangEnum.en]: {
|
||||
label: 'English',
|
||||
icon: 'common/language/en'
|
||||
label: 'English(US)',
|
||||
icon: 'common/language/en',
|
||||
avatar: 'common/language/America'
|
||||
},
|
||||
[LangEnum.zh]: {
|
||||
label: '简体中文',
|
||||
icon: 'common/language/zh'
|
||||
icon: 'common/language/zh',
|
||||
avatar: 'common/language/China'
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user