diff --git a/web/default/package.json b/web/default/package.json index d03288ed..15e48f48 100644 --- a/web/default/package.json +++ b/web/default/package.json @@ -5,10 +5,14 @@ "dependencies": { "axios": "^0.27.2", "history": "^5.3.0", + "i18next": "^24.2.2", + "i18next-browser-languagedetector": "^8.0.2", + "i18next-http-backend": "^3.0.2", "marked": "^4.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", + "react-i18next": "^15.4.0", "react-router-dom": "^6.3.0", "react-scripts": "5.0.1", "react-toastify": "^9.0.8", diff --git a/web/default/public/locales/en/translation.json b/web/default/public/locales/en/translation.json new file mode 100644 index 00000000..fc54a52e --- /dev/null +++ b/web/default/public/locales/en/translation.json @@ -0,0 +1,38 @@ +{ + "header": { + "home": "Home", + "channel": "Channel", + "token": "Token", + "redemption": "Redemption", + "topup": "Top Up", + "user": "User", + "dashboard": "Dashboard", + "log": "Log", + "setting": "Settings", + "about": "About", + "chat": "Chat", + "login": "Login", + "logout": "Logout", + "register": "Register" + }, + "topup": { + "title": "Top Up Center", + "get_code": { + "title": "Get Redemption Code", + "current_quota": "Current Available Quota", + "button": "Get Code Now" + }, + "redeem_code": { + "title": "Redeem Code", + "placeholder": "Please enter redemption code", + "paste": "Paste", + "paste_error": "Cannot access clipboard, please paste manually", + "submit": "Redeem Now", + "submitting": "Redeeming...", + "empty_code": "Please enter the redemption code!", + "success": "Top up successful!", + "request_failed": "Request failed", + "no_link": "Admin has not set up the top-up link!" + } + } +} diff --git a/web/default/public/locales/zh/translation.json b/web/default/public/locales/zh/translation.json new file mode 100644 index 00000000..51449786 --- /dev/null +++ b/web/default/public/locales/zh/translation.json @@ -0,0 +1,38 @@ +{ + "header": { + "home": "首页", + "channel": "渠道", + "token": "令牌", + "redemption": "兑换", + "topup": "充值", + "user": "用户", + "dashboard": "总览", + "log": "日志", + "setting": "设置", + "about": "关于", + "chat": "聊天", + "login": "登录", + "logout": "注销", + "register": "注册" + }, + "topup": { + "title": "充值中心", + "get_code": { + "title": "获取兑换码", + "current_quota": "当前可用额度", + "button": "立即获取兑换码" + }, + "redeem_code": { + "title": "兑换码充值", + "placeholder": "请输入兑换码", + "paste": "粘贴", + "paste_error": "无法访问剪贴板,请手动粘贴", + "submit": "立即兑换", + "submitting": "兑换中...", + "empty_code": "请输入兑换码!", + "success": "充值成功!", + "request_failed": "请求失败", + "no_link": "超级管理员未设置充值链接!" + } + } +} diff --git a/web/default/src/components/Header.js b/web/default/src/components/Header.js index dd2a5fdd..52d67042 100644 --- a/web/default/src/components/Header.js +++ b/web/default/src/components/Header.js @@ -1,6 +1,7 @@ import React, { useContext, useState } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { UserContext } from '../context/User'; +import { useTranslation } from 'react-i18next'; import { Button, @@ -23,55 +24,55 @@ import '../index.css'; // Header Buttons let headerButtons = [ { - name: '首页', + name: 'header.home', to: '/', icon: 'home', }, { - name: '渠道', + name: 'header.channel', to: '/channel', icon: 'sitemap', admin: true, }, { - name: '令牌', + name: 'header.token', to: '/token', icon: 'key', }, { - name: '兑换', + name: 'header.redemption', to: '/redemption', icon: 'dollar sign', admin: true, }, { - name: '充值', + name: 'header.topup', to: '/topup', icon: 'cart', }, { - name: '用户', + name: 'header.user', to: '/user', icon: 'user', admin: true, }, { - name: '总览', + name: 'header.dashboard', to: '/dashboard', icon: 'chart bar', }, { - name: '日志', + name: 'header.log', to: '/log', icon: 'book', }, { - name: '设置', + name: 'header.setting', to: '/setting', icon: 'setting', }, { - name: '关于', + name: 'header.about', to: '/about', icon: 'info circle', }, @@ -79,13 +80,14 @@ let headerButtons = [ if (localStorage.getItem('chat_link')) { headerButtons.splice(1, 0, { - name: '聊天', + name: 'header.chat', to: '/chat', icon: 'comments', }); } const Header = () => { + const { t, i18n } = useTranslation(); const [userState, userDispatch] = useContext(UserContext); let navigate = useNavigate(); @@ -112,13 +114,14 @@ const Header = () => { if (isMobile) { return (