mac
5 months ago
13 changed files with 198 additions and 47 deletions
-
4package.json
-
BINsrc/assets/en.jpg
-
BINsrc/assets/zh.jpg
-
10src/components/CountdownTimer.tsx
-
69src/components/LanguageMenu.tsx
-
1src/index.tsx
-
21src/language/index.ts
-
24src/language/zh.json
-
37src/pages/create-proxy/index.tsx
-
16src/pages/forget/index.tsx
-
28src/pages/login/index.tsx
-
8src/router/index.tsx
-
27yarn.lock
After Width: 200 | Height: 132 | Size: 6.4 KiB |
After Width: 200 | Height: 133 | Size: 1.6 KiB |
@ -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 ( |
||||
|
<div> |
||||
|
<ConfigProvider |
||||
|
theme={{ |
||||
|
components: { |
||||
|
Popover: { |
||||
|
titleMinWidth: 100 |
||||
|
} |
||||
|
} |
||||
|
}} |
||||
|
> |
||||
|
<Popover |
||||
|
open={open} |
||||
|
onOpenChange={handleOpenChange} |
||||
|
content={<div className="tac"> |
||||
|
{ |
||||
|
lns.map((item, index) => ( |
||||
|
<div key={item.key} className={`tp ${index === lns.length - 1 && 'mt-1'}`} onClick={() => changeLanguage(item.key)}>{item.title}</div> |
||||
|
)) |
||||
|
} |
||||
|
</div>} |
||||
|
trigger="click" |
||||
|
> |
||||
|
<img className="tp" src={require(`../assets/${lang}.jpg`)} alt="" style={{ width, height: 'auto' }} /> |
||||
|
</Popover> |
||||
|
</ConfigProvider> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default LanguageMenu |
@ -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; |
@ -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": "验证码发送失败" |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue