From 89733665998b19156aefbd455ad77b56805ffc08 Mon Sep 17 00:00:00 2001 From: mac Date: Fri, 12 Jul 2024 13:41:17 +0800 Subject: [PATCH] commit --- package.json | 4 +- src/assets/en.jpg | Bin 0 -> 6576 bytes src/assets/zh.jpg | Bin 0 -> 1604 bytes src/components/CountdownTimer.tsx | 10 ++--- src/components/LanguageMenu.tsx | 69 ++++++++++++++++++++++++++++++ src/index.tsx | 1 + src/language/index.ts | 21 +++++++++ src/language/zh.json | 24 +++++++++++ src/pages/create-proxy/index.tsx | 37 ++++++++-------- src/pages/forget/index.tsx | 16 ++++--- src/pages/login/index.tsx | 28 ++++++------ src/router/index.tsx | 8 +++- yarn.lock | 27 ++++++++++++ 13 files changed, 198 insertions(+), 47 deletions(-) create mode 100644 src/assets/en.jpg create mode 100644 src/assets/zh.jpg create mode 100644 src/components/LanguageMenu.tsx create mode 100644 src/language/index.ts create mode 100644 src/language/zh.json diff --git a/package.json b/package.json index 3035dab..200016c 100644 --- a/package.json +++ b/package.json @@ -14,12 +14,14 @@ "axios": "^1.7.2", "echarts": "^5.5.0", "echarts-for-react": "^3.0.2", + "i18next": "^23.11.5", "js-md5": "^0.8.3", "mobx": "^6.12.4", "mobx-react": "^9.1.1", "qrcode": "^1.5.3", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-i18next": "^14.1.2", "react-icons": "^5.2.1", "react-router-dom": "^6.23.1", "react-scripts": "5.0.1", @@ -56,4 +58,4 @@ "devDependencies": { "@types/qrcode": "^1.5.5" } -} \ No newline at end of file +} diff --git a/src/assets/en.jpg b/src/assets/en.jpg new file mode 100644 index 0000000000000000000000000000000000000000..405cd07e172327845b647bc34908083bb740b6a6 GIT binary patch literal 6576 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 Pq-29dDP4r@|K9`vYJGXV literal 0 HcmV?d00001 diff --git a/src/components/CountdownTimer.tsx b/src/components/CountdownTimer.tsx index bf95ab0..29a9d1d 100644 --- a/src/components/CountdownTimer.tsx +++ b/src/components/CountdownTimer.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react'; +import { useTranslation } from 'react-i18next'; interface CountdownTimerProps { initialSeconds: number, @@ -15,10 +16,10 @@ export interface CountdownTimerRef { const CountdownTimer = forwardRef((props, ref) => { const { initialSeconds, onComplete } = props - + const { t } = useTranslation() const [seconds, setSeconds] = useState(initialSeconds); const [isActive, setIsActive] = useState(false); - const [title, setTitle] = useState('发送验证码') + const [title, setTitle] = useState(t('Send verification code')) useImperativeHandle(ref, () => ({ handleStop, @@ -29,7 +30,7 @@ const CountdownTimer = forwardRef((props const handleStop = () => { setIsActive(false); - setTitle('发送验证码') + setTitle(t('Send verification code')) }; const handleStart = () => { @@ -54,11 +55,10 @@ const CountdownTimer = forwardRef((props }, 1000); } else { clearInterval(interval) - seconds <= 0 && setTitle('重新发送') + seconds <= 0 && setTitle(t('Resend')) setIsActive(false) // onComplete && onComplete(seconds) } - console.log(1); return () => clearInterval(interval); }, [isActive, seconds, onComplete]); diff --git a/src/components/LanguageMenu.tsx b/src/components/LanguageMenu.tsx new file mode 100644 index 0000000..0a84d1a --- /dev/null +++ b/src/components/LanguageMenu.tsx @@ -0,0 +1,69 @@ +import { useState } from "react" +import { TRADER_LANGUAGE } from "../language" +import { ConfigProvider, Popover } from "antd" +import { useTranslation } from "react-i18next" + +interface LanguageMenuProps { + width?: number +} + +const LanguageMenu = (props: LanguageMenuProps) => { + + const { width = 50 } = props + const [open, setOpen] = useState(false); + const { i18n } = useTranslation() + + const [lang, setLang] = useState(window.localStorage.getItem(TRADER_LANGUAGE) || 'zh') + const [lns, setLns] = useState([ + { + key: 'zh', + title: '中文简体' + }, + { + key: 'en', + title: 'English' + } + ]) + + const handleOpenChange = (newOpen: boolean) => { + setOpen(newOpen); + }; + + const changeLanguage = (key: string) => { + setLang(key) + window.localStorage.setItem(TRADER_LANGUAGE, key) + i18n.changeLanguage(key) + handleOpenChange(false) + } + + return ( +
+ + + { + lns.map((item, index) => ( +
changeLanguage(item.key)}>{item.title}
+ )) + } +
} + trigger="click" + > + + + + + ) +} + +export default LanguageMenu \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index 5f4fa73..cfeb1fc 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,6 +4,7 @@ import App from './App'; import reportWebVitals from './reportWebVitals'; import './styles/global.scss' import { ConfigProvider } from 'antd'; +import './language' const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement diff --git a/src/language/index.ts b/src/language/index.ts new file mode 100644 index 0000000..b73b4f2 --- /dev/null +++ b/src/language/index.ts @@ -0,0 +1,21 @@ +import zh from "./zh.json"; +import i18n from "i18next"; +import { initReactI18next } from "react-i18next"; + +export const TRADER_LANGUAGE = "TRADER_LANGUAGE"; + +const resources = { + zh: { + translation: { ...zh }, + }, +}; + +i18n.use(initReactI18next).init({ + resources, + lng: window.sessionStorage.getItem(TRADER_LANGUAGE) || "zh", + interpolation: { + escapeValue: false, + }, +}); + +export default i18n; \ No newline at end of file diff --git a/src/language/zh.json b/src/language/zh.json new file mode 100644 index 0000000..fb1822d --- /dev/null +++ b/src/language/zh.json @@ -0,0 +1,24 @@ +{ + "account": "账号", + "password": "密码", + "Verification Code": "验证码", + "Sign in": "登录", + "Forget password?": "忘记密码?", + "Create a proxy account": "创建代理账户", + "Invalid account": "无效的账号", + "login successful": "登录成功", + "Password sent to email": "密码发送至邮箱", + "Retrieve immediately": "立即找回", + "Already have an account? Sign in": "已有账号,登录", + "name": "姓名", + "invitation code": "邀请码", + "email": "邮箱", + "invalid email": "无效的邮箱", + "Login password, (letters + numbers) length 8-32": "登录密码,(字母+数字)长度8-32", + "Register now": "立即注册", + "Send verification code": "发送验证码", + "Resend": "重新发送", + "Register Successful": "注册成功", + "Verification code sent successfully": "验证码发送成功", + "Failed to send verification code": "验证码发送失败" +} \ No newline at end of file diff --git a/src/pages/create-proxy/index.tsx b/src/pages/create-proxy/index.tsx index 6d3d768..8a50d8a 100644 --- a/src/pages/create-proxy/index.tsx +++ b/src/pages/create-proxy/index.tsx @@ -5,6 +5,7 @@ import { useRouter } from '../../hooks/useRouter' import { http_register, http_send_email } from '../../http/api'; import CountdownTimer, { CountdownTimerRef } from '../../components/CountdownTimer'; import { useEffect, useRef } from 'react'; +import { useTranslation } from 'react-i18next'; interface FieldType { name: string; @@ -19,14 +20,14 @@ const CreateProxy = () => { const { push, location } = useRouter() const [form] = Form.useForm(); const countdownRef = useRef(null) - console.log(location.search); + const { t } = useTranslation() const onFinish: FormProps['onFinish'] = async (values) => { try { const res: any = await http_register(values) if (res.code === 0) { notification.success({ - message: '注册成功' + message: t('Register Successful') }) push('/login', null, true) } @@ -37,11 +38,11 @@ const CreateProxy = () => { const validatePassword = (_: any, value: string) => { if (!value) { - return Promise.reject(new Error("请输入密码")); + return Promise.reject(new Error(t('password'))); } const regex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,32}$/; if (!regex.test(value)) { - return Promise.reject(new Error("密码必须包含字母和数字,长度为8-32位")); + return Promise.reject(new Error(t('Login password, (letters + numbers) length 8-32'))); } return Promise.resolve(); }; @@ -57,11 +58,11 @@ const CreateProxy = () => { }) if (res.code === 0) { notification.success({ - message: '验证码发送成功' + message: t('Verification code sent successfully') }) } else { notification.error({ - message: '验证码发送失败' + message: t('Failed to send verification code') }) countdownRef.current?.handleStop() } @@ -86,30 +87,30 @@ const CreateProxy = () => {
-
创建代理账户
+
{t('Create a proxy account')}
- - + + - - + + - - + + + }} placeholder={t('Login password, (letters + numbers) length 8-32')} /> - +
- + @@ -117,11 +118,11 @@ const CreateProxy = () => { - + - +
diff --git a/src/pages/forget/index.tsx b/src/pages/forget/index.tsx index 0e3aae5..d5b67d4 100644 --- a/src/pages/forget/index.tsx +++ b/src/pages/forget/index.tsx @@ -4,6 +4,7 @@ import Button from '../../components/Button' import { useRouter } from '../../hooks/useRouter' import { useEffect, useState } from 'react'; import { http_code, http_forget } from '../../http/api'; +import { useTranslation } from 'react-i18next'; interface FieldType { email: string; @@ -16,6 +17,7 @@ const ForGet = () => { const [form] = Form.useForm() const [codeId, setCodeId] = useState('') const [codeUrl, setCodeUrl] = useState('') + const { t } = useTranslation() const onFinish: FormProps['onFinish'] = async (values) => { const res: any = await http_forget({ @@ -26,7 +28,7 @@ const ForGet = () => { if (res.code === 0) { form.resetFields() notification.success({ - message: '密码已发送至您的邮箱!' + message: t('Password sent to email') }) } }; @@ -52,20 +54,20 @@ const ForGet = () => {
- - + + - +
- +
- + -
push(-1)} className='tac tp'>已有账号,登录
+
push(-1)} className='tac tp'>{t('Already have an account? Sign in')}
diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index 1a25092..2892241 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -5,6 +5,7 @@ import { useRouter } from '../../hooks/useRouter' import store from '../../store' import { useEffect, useState } from 'react' import { http_code, http_login } from '../../http/api' +import { useTranslation } from 'react-i18next' type FieldType = { email: string; password: string; @@ -16,6 +17,7 @@ const Login = () => { const { push } = useRouter() const [codeId, setCodeId] = useState('') const [codeUrl, setCodeUrl] = useState('') + const { t } = useTranslation() const onFinish: FormProps['onFinish'] = async (values) => { const res: any = await http_login({ @@ -24,7 +26,7 @@ const Login = () => { }) if (res.code === 0) { notification.success({ - message: '登录成功' + message: t('login successful') }) store.setToken(res.data.token) push('/', null, true) @@ -42,10 +44,6 @@ const Login = () => { } } - const login = async () => { - - } - useEffect(() => { getCode() }, []) @@ -66,49 +64,49 @@ const Login = () => { rules={[ { type: 'email', - message: '请输入有效的邮箱!', + message: t('Invalid account'), }, { required: true, - message: '请输入邮箱!', + message: t('account'), }, ]} > - + - +
- +
- + -
push('/forget')}>忘记密码?
+
push('/forget')}>{t('Forget password?')}
- +
diff --git a/src/router/index.tsx b/src/router/index.tsx index d00d15a..7ee8867 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -10,6 +10,7 @@ import { unLoginPath } from "./routes"; import { Divider, Modal } from "antd"; import { NotifyStatus_Type } from "../types"; import { http_notify } from "../http/api"; +import LanguageMenu from "../components/LanguageMenu"; const LayoutRouter = () => { @@ -75,7 +76,12 @@ const LayoutRouter = () => { <> { !token ? ( - + <> + {/*
+ +
*/} + + ) : (
diff --git a/yarn.lock b/yarn.lock index 945be30..d95772f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5445,6 +5445,13 @@ html-minifier-terser@^6.0.2: relateurl "^0.2.7" terser "^5.10.0" +html-parse-stringify@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" + integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== + dependencies: + void-elements "3.1.0" + html-webpack-plugin@^5.5.0: version "5.6.0" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz#50a8fa6709245608cb00e811eacecb8e0d7b7ea0" @@ -5539,6 +5546,13 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +i18next@^23.11.5: + version "23.11.5" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.11.5.tgz#d71eb717a7e65498d87d0594f2664237f9e361ef" + integrity sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA== + dependencies: + "@babel/runtime" "^7.23.2" + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -8633,6 +8647,14 @@ react-error-overlay@^6.0.11: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== +react-i18next@^14.1.2: + version "14.1.2" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-14.1.2.tgz#cd57a755f25a32a5fcc3dbe546cf3cc62b4f3ebd" + integrity sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg== + dependencies: + "@babel/runtime" "^7.23.9" + html-parse-stringify "^3.0.1" + react-icons@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.2.1.tgz#28c2040917b2a2eda639b0f797bff1888e018e4a" @@ -10159,6 +10181,11 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +void-elements@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== + w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"