chore: update i18n locales

This commit is contained in:
Steven 2023-09-05 22:10:23 +08:00
parent 126e4a62f8
commit 7348f47ef8
9 changed files with 35 additions and 18 deletions

View File

@ -75,6 +75,7 @@ func getUserSetting(ctx context.Context, s *store.Store, userID int32) (*apiv2pb
userSetting := &apiv2pb.UserSetting{ userSetting := &apiv2pb.UserSetting{
Id: userID, Id: userID,
Locale: apiv2pb.UserSetting_LOCALE_EN,
} }
for _, setting := range userSettings { for _, setting := range userSettings {
if setting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE { if setting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE {

View File

@ -8,7 +8,10 @@
"download": "Download", "download": "Download",
"edit": "Edit", "edit": "Edit",
"delete": "Delete", "delete": "Delete",
"language": "Language" "language": "Language",
"search": "Search",
"email": "Email",
"password": "Password"
}, },
"analytics": { "analytics": {
"self": "Analytics", "self": "Analytics",

View File

@ -8,7 +8,10 @@
"download": "下载", "download": "下载",
"edit": "编辑", "edit": "编辑",
"delete": "删除", "delete": "删除",
"language": "语言" "language": "语言",
"search": "搜索",
"email": "邮箱",
"password": "密码"
}, },
"analytics": { "analytics": {
"self": "分析", "self": "分析",

View File

@ -3,6 +3,7 @@ import axios from "axios";
import copy from "copy-to-clipboard"; import copy from "copy-to-clipboard";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
import { useTranslation } from "react-i18next";
import { ListUserAccessTokensResponse, UserAccessToken } from "@/types/proto/api/v2/user_service_pb"; import { ListUserAccessTokensResponse, UserAccessToken } from "@/types/proto/api/v2/user_service_pb";
import useUserStore from "../../stores/v1/user"; import useUserStore from "../../stores/v1/user";
import { showCommonDialog } from "../Alert"; import { showCommonDialog } from "../Alert";
@ -15,6 +16,7 @@ const listAccessTokens = async (userId: number) => {
}; };
const AccessTokenSection = () => { const AccessTokenSection = () => {
const { t } = useTranslation();
const currentUser = useUserStore().getCurrentUser(); const currentUser = useUserStore().getCurrentUser();
const [userAccessTokens, setUserAccessTokens] = useState<UserAccessToken[]>([]); const [userAccessTokens, setUserAccessTokens] = useState<UserAccessToken[]>([]);
const [showCreateDialog, setShowCreateDialog] = useState<boolean>(false); const [showCreateDialog, setShowCreateDialog] = useState<boolean>(false);
@ -68,7 +70,7 @@ const AccessTokenSection = () => {
setShowCreateDialog(true); setShowCreateDialog(true);
}} }}
> >
Create {t("common.create")}
</Button> </Button>
</div> </div>
</div> </div>
@ -91,7 +93,7 @@ const AccessTokenSection = () => {
Expires At Expires At
</th> </th>
<th scope="col" className="relative py-3.5 pl-3 pr-4"> <th scope="col" className="relative py-3.5 pl-3 pr-4">
<span className="sr-only">Delete</span> <span className="sr-only">{t("common.delete")}</span>
</th> </th>
</tr> </tr>
</thead> </thead>

View File

@ -1,10 +1,12 @@
import { Button } from "@mui/joy"; import { Button } from "@mui/joy";
import { useState } from "react"; import { useState } from "react";
import { useTranslation } from "react-i18next";
import useUserStore from "../../stores/v1/user"; import useUserStore from "../../stores/v1/user";
import ChangePasswordDialog from "../ChangePasswordDialog"; import ChangePasswordDialog from "../ChangePasswordDialog";
import EditUserinfoDialog from "../EditUserinfoDialog"; import EditUserinfoDialog from "../EditUserinfoDialog";
const AccountSection: React.FC = () => { const AccountSection: React.FC = () => {
const { t } = useTranslation();
const currentUser = useUserStore().getCurrentUser(); const currentUser = useUserStore().getCurrentUser();
const [showEditUserinfoDialog, setShowEditUserinfoDialog] = useState<boolean>(false); const [showEditUserinfoDialog, setShowEditUserinfoDialog] = useState<boolean>(false);
const [showChangePasswordDialog, setShowChangePasswordDialog] = useState<boolean>(false); const [showChangePasswordDialog, setShowChangePasswordDialog] = useState<boolean>(false);
@ -19,12 +21,12 @@ const AccountSection: React.FC = () => {
{isAdmin && <span className="ml-2 bg-blue-600 text-white px-2 leading-6 text-sm rounded-full">Admin</span>} {isAdmin && <span className="ml-2 bg-blue-600 text-white px-2 leading-6 text-sm rounded-full">Admin</span>}
</p> </p>
<p className="flex flex-row justify-start items-center"> <p className="flex flex-row justify-start items-center">
<span className="mr-3 text-gray-500">Email: </span> <span className="mr-3 text-gray-500">{t("common.email")}: </span>
{currentUser.email} {currentUser.email}
</p> </p>
<div className="flex flex-row justify-start items-center gap-2 mt-2"> <div className="flex flex-row justify-start items-center gap-2 mt-2">
<Button variant="outlined" color="neutral" onClick={() => setShowEditUserinfoDialog(true)}> <Button variant="outlined" color="neutral" onClick={() => setShowEditUserinfoDialog(true)}>
Edit {t("common.edit")}
</Button> </Button>
<Button variant="outlined" color="neutral" onClick={() => setShowChangePasswordDialog(true)}> <Button variant="outlined" color="neutral" onClick={() => setShowChangePasswordDialog(true)}>
Change password Change password

View File

@ -1,5 +1,6 @@
import { Button, Input } from "@mui/joy"; import { Button, Input } from "@mui/joy";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import CreateShortcutDialog from "../components/CreateShortcutDialog"; import CreateShortcutDialog from "../components/CreateShortcutDialog";
import FilterView from "../components/FilterView"; import FilterView from "../components/FilterView";
import Icon from "../components/Icon"; import Icon from "../components/Icon";
@ -17,6 +18,7 @@ interface State {
} }
const Home: React.FC = () => { const Home: React.FC = () => {
const { t } = useTranslation();
const loadingState = useLoading(); const loadingState = useLoading();
const currentUser = useUserStore().getCurrentUser(); const currentUser = useUserStore().getCurrentUser();
const viewStore = useViewStore(); const viewStore = useViewStore();
@ -49,7 +51,7 @@ const Home: React.FC = () => {
<div className="flex flex-row justify-start items-center"> <div className="flex flex-row justify-start items-center">
<Button className="hover:shadow" variant="soft" size="sm" onClick={() => setShowCreateShortcutDialog(true)}> <Button className="hover:shadow" variant="soft" size="sm" onClick={() => setShowCreateShortcutDialog(true)}>
<Icon.Plus className="w-5 h-auto" /> <Icon.Plus className="w-5 h-auto" />
<span className="hidden sm:block ml-0.5">Create</span> <span className="hidden sm:block ml-0.5">{t("common.create")}</span>
</Button> </Button>
</div> </div>
<div className="flex flex-row justify-end items-center"> <div className="flex flex-row justify-end items-center">
@ -57,7 +59,7 @@ const Home: React.FC = () => {
className="w-32 ml-2" className="w-32 ml-2"
type="text" type="text"
size="sm" size="sm"
placeholder="Search" placeholder={t("common.search")}
startDecorator={<Icon.Search className="w-4 h-auto" />} startDecorator={<Icon.Search className="w-4 h-auto" />}
endDecorator={<ViewSetting />} endDecorator={<ViewSetting />}
value={filter.search} value={filter.search}

View File

@ -127,7 +127,7 @@ const ShortcutDetail = () => {
}); });
}} }}
> >
<Icon.Edit className="w-4 h-auto mr-2" /> Edit <Icon.Edit className="w-4 h-auto mr-2" /> {t("common.edit")}
</button> </button>
<button <button
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded text-red-600 hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60" className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded text-red-600 hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
@ -135,7 +135,7 @@ const ShortcutDetail = () => {
handleDeleteShortcutButtonClick(shortcut); handleDeleteShortcutButtonClick(shortcut);
}} }}
> >
<Icon.Trash className="w-4 h-auto mr-2" /> Delete <Icon.Trash className="w-4 h-auto mr-2" /> {t("common.delete")}
</button> </button>
</> </>
} }
@ -177,7 +177,7 @@ const ShortcutDetail = () => {
<div className="w-full flex flex-col mt-8"> <div className="w-full flex flex-col mt-8">
<h3 id="analytics" className="pl-1 font-medium text-lg flex flex-row justify-start items-center"> <h3 id="analytics" className="pl-1 font-medium text-lg flex flex-row justify-start items-center">
<Icon.BarChart2 className="w-6 h-auto mr-1" /> <Icon.BarChart2 className="w-6 h-auto mr-1" />
Analytics {t("analytics.self")}
</h3> </h3>
<AnalyticsView className="mt-4 w-full grid grid-cols-1 sm:grid-cols-2 gap-2 sm:gap-4" shortcutId={shortcut.id} /> <AnalyticsView className="mt-4 w-full grid grid-cols-1 sm:grid-cols-2 gap-2 sm:gap-4" shortcutId={shortcut.id} />
</div> </div>

View File

@ -1,6 +1,7 @@
import { Button, Input } from "@mui/joy"; import { Button, Input } from "@mui/joy";
import React, { FormEvent, useEffect, useState } from "react"; import React, { FormEvent, useEffect, useState } from "react";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import * as api from "../helpers/api"; import * as api from "../helpers/api";
import useLoading from "../hooks/useLoading"; import useLoading from "../hooks/useLoading";
@ -8,6 +9,7 @@ import { useAppSelector } from "../stores";
import useUserStore from "../stores/v1/user"; import useUserStore from "../stores/v1/user";
const SignIn: React.FC = () => { const SignIn: React.FC = () => {
const { t } = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
const userStore = useUserStore(); const userStore = useUserStore();
const { const {
@ -79,7 +81,7 @@ const SignIn: React.FC = () => {
<form className="w-full mt-6" onSubmit={handleSigninBtnClick}> <form className="w-full mt-6" onSubmit={handleSigninBtnClick}>
<div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}> <div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}>
<div className="w-full flex flex-col mb-2"> <div className="w-full flex flex-col mb-2">
<span className="leading-8 mb-1 text-gray-600">Email</span> <span className="leading-8 mb-1 text-gray-600">{t("common.email")}</span>
<Input <Input
className="w-full py-3" className="w-full py-3"
type="email" type="email"
@ -89,7 +91,7 @@ const SignIn: React.FC = () => {
/> />
</div> </div>
<div className="w-full flex flex-col mb-2"> <div className="w-full flex flex-col mb-2">
<span className="leading-8 text-gray-600">Password</span> <span className="leading-8 text-gray-600">{t("common.password")}</span>
<Input className="w-full py-3" type="password" value={password} placeholder="····" onChange={handlePasswordInputChanged} /> <Input className="w-full py-3" type="password" value={password} placeholder="····" onChange={handlePasswordInputChanged} />
</div> </div>
</div> </div>

View File

@ -1,6 +1,7 @@
import { Button, Input } from "@mui/joy"; import { Button, Input } from "@mui/joy";
import React, { FormEvent, useEffect, useState } from "react"; import React, { FormEvent, useEffect, useState } from "react";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
import { useTranslation } from "react-i18next";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import * as api from "../helpers/api"; import * as api from "../helpers/api";
import useLoading from "../hooks/useLoading"; import useLoading from "../hooks/useLoading";
@ -8,6 +9,7 @@ import { globalService } from "../services";
import useUserStore from "../stores/v1/user"; import useUserStore from "../stores/v1/user";
const SignUp: React.FC = () => { const SignUp: React.FC = () => {
const { t } = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
const userStore = useUserStore(); const userStore = useUserStore();
const { const {
@ -84,7 +86,7 @@ const SignUp: React.FC = () => {
<form className="w-full mt-4" onSubmit={handleSignupBtnClick}> <form className="w-full mt-4" onSubmit={handleSignupBtnClick}>
<div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}> <div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}>
<div className="w-full flex flex-col mb-2"> <div className="w-full flex flex-col mb-2">
<span className="leading-8 mb-1 text-gray-600">Email</span> <span className="leading-8 mb-1 text-gray-600">{t("common.email")}</span>
<Input <Input
className="w-full py-3" className="w-full py-3"
type="email" type="email"
@ -98,7 +100,7 @@ const SignUp: React.FC = () => {
<Input className="w-full py-3" type="text" value={nickname} placeholder="steven" onChange={handleNicknameInputChanged} /> <Input className="w-full py-3" type="text" value={nickname} placeholder="steven" onChange={handleNicknameInputChanged} />
</div> </div>
<div className="w-full flex flex-col mb-2"> <div className="w-full flex flex-col mb-2">
<span className="leading-8 text-gray-600">Password</span> <span className="leading-8 text-gray-600">{t("common.password")}</span>
<Input className="w-full py-3" type="password" value={password} placeholder="····" onChange={handlePasswordInputChanged} /> <Input className="w-full py-3" type="password" value={password} placeholder="····" onChange={handlePasswordInputChanged} />
</div> </div>
</div> </div>