chore: update part of i18n

This commit is contained in:
Steven 2023-08-18 09:00:42 +08:00
parent d939bb8250
commit bafb17015c
11 changed files with 64 additions and 26 deletions

View File

@ -1,4 +1,5 @@
import { Button, Link, Modal, ModalDialog } from "@mui/joy";
import { useTranslation } from "react-i18next";
import Icon from "./Icon";
interface Props {
@ -7,12 +8,13 @@ interface Props {
const AboutDialog: React.FC<Props> = (props: Props) => {
const { onClose } = props;
const { t } = useTranslation();
return (
<Modal open={true}>
<ModalDialog>
<div className="w-full flex flex-row justify-between items-center">
<span className="text-lg font-medium">About</span>
<span className="text-lg font-medium">{t("common.about")}</span>
<Button variant="plain" onClick={onClose}>
<Icon.X className="w-5 h-auto text-gray-600" />
</Button>

View File

@ -1,4 +1,5 @@
import { Button, Modal, ModalDialog } from "@mui/joy";
import { useTranslation } from "react-i18next";
import AnalyticsView from "./AnalyticsView";
import Icon from "./Icon";
@ -9,12 +10,13 @@ interface Props {
const AnalyticsDialog: React.FC<Props> = (props: Props) => {
const { shortcutId, onClose } = props;
const { t } = useTranslation();
return (
<Modal open={true}>
<ModalDialog>
<div className="w-full flex flex-row justify-between items-center">
<span className="text-lg font-medium">Analytics</span>
<span className="text-lg font-medium">{t("analytics.self")}</span>
<Button variant="plain" onClick={onClose}>
<Icon.X className="w-5 h-auto text-gray-600" />
</Button>

View File

@ -1,5 +1,6 @@
import classNames from "classnames";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import * as api from "../helpers/api";
import Icon from "./Icon";
@ -10,6 +11,7 @@ interface Props {
const AnalyticsView: React.FC<Props> = (props: Props) => {
const { shortcutId, className } = props;
const { t } = useTranslation();
const [analytics, setAnalytics] = useState<AnalysisData | null>(null);
const [selectedDeviceTab, setSelectedDeviceTab] = useState<"os" | "browser">("browser");
@ -24,12 +26,12 @@ const AnalyticsView: React.FC<Props> = (props: Props) => {
{analytics ? (
<>
<div className="w-full">
<p className="w-full h-8 px-2">Top Sources</p>
<p className="w-full h-8 px-2">{t("analytics.top-sources")}</p>
<div className="w-full mt-1 overflow-hidden shadow ring-1 ring-black ring-opacity-5 rounded-lg">
<div className="w-full divide-y divide-gray-300">
<div className="w-full flex flex-row justify-between items-center">
<span className="py-2 px-2 text-left font-semibold text-sm text-gray-500">Source</span>
<span className="py-2 pr-2 text-right font-semibold text-sm text-gray-500">Visitors</span>
<span className="py-2 px-2 text-left font-semibold text-sm text-gray-500">{t("analytics.source")}</span>
<span className="py-2 pr-2 text-right font-semibold text-sm text-gray-500">{t("analytics.visitors")}</span>
</div>
<div className="w-full divide-y divide-gray-200">
{analytics.referenceData.map((reference) => (
@ -53,7 +55,7 @@ const AnalyticsView: React.FC<Props> = (props: Props) => {
<div className="w-full">
<div className="w-full h-8 px-2 flex flex-row justify-between items-center">
<span>Devices</span>
<span>{t("analytics.devices")}</span>
<div>
<button
className={`whitespace-nowrap border-b-2 px-1 text-sm font-medium ${
@ -63,7 +65,7 @@ const AnalyticsView: React.FC<Props> = (props: Props) => {
}`}
onClick={() => setSelectedDeviceTab("browser")}
>
Browser
{t("analytics.browser")}
</button>
<span className="text-gray-200 font-mono mx-1">/</span>
<button
@ -83,8 +85,8 @@ const AnalyticsView: React.FC<Props> = (props: Props) => {
{selectedDeviceTab === "browser" ? (
<div className="w-full divide-y divide-gray-300">
<div className="w-full flex flex-row justify-between items-center">
<span className="py-2 px-2 text-left text-sm font-semibold text-gray-500">Browsers</span>
<span className="py-2 pr-2 text-right text-sm font-semibold text-gray-500">Visitors</span>
<span className="py-2 px-2 text-left text-sm font-semibold text-gray-500">{t("analytics.browsers")}</span>
<span className="py-2 pr-2 text-right text-sm font-semibold text-gray-500">{t("analytics.visitors")}</span>
</div>
<div className="w-full divide-y divide-gray-200">
{analytics.browserData.map((reference) => (
@ -98,8 +100,8 @@ const AnalyticsView: React.FC<Props> = (props: Props) => {
) : (
<div className="w-full divide-y divide-gray-300">
<div className="w-full flex flex-row justify-between items-center">
<span className="py-2 px-2 text-left text-sm font-semibold text-gray-500">Operating system</span>
<span className="py-2 pr-2 text-right text-sm font-semibold text-gray-500">Visitors</span>
<span className="py-2 px-2 text-left text-sm font-semibold text-gray-500">{t("analytics.operating-system")}</span>
<span className="py-2 pr-2 text-right text-sm font-semibold text-gray-500">{t("analytics.visitors")}</span>
</div>
<div className="w-full divide-y divide-gray-200">
{analytics.deviceData.map((device) => (
@ -117,7 +119,7 @@ const AnalyticsView: React.FC<Props> = (props: Props) => {
) : (
<div className="py-12 w-full flex flex-row justify-center items-center opacity-80">
<Icon.Loader className="mr-2 w-5 h-auto animate-spin" />
loading
{t("common.loading")}
</div>
)}
</div>

View File

@ -1,6 +1,7 @@
import { Button, Input, Modal, ModalDialog } from "@mui/joy";
import { useState } from "react";
import { toast } from "react-hot-toast";
import { useTranslation } from "react-i18next";
import useLoading from "../hooks/useLoading";
import useUserStore from "../stores/v1/user";
import Icon from "./Icon";
@ -11,6 +12,7 @@ interface Props {
const ChangePasswordDialog: React.FC<Props> = (props: Props) => {
const { onClose } = props;
const { t } = useTranslation();
const userStore = useUserStore();
const [newPassword, setNewPassword] = useState("");
const [newPasswordAgain, setNewPasswordAgain] = useState("");
@ -77,10 +79,10 @@ const ChangePasswordDialog: React.FC<Props> = (props: Props) => {
</div>
<div className="w-full flex flex-row justify-end items-center space-x-2">
<Button variant="plain" disabled={requestState.isLoading} onClick={handleCloseBtnClick}>
Cancel
{t("common.cancel")}
</Button>
<Button color="primary" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={handleSaveBtnClick}>
Save
{t("common.save")}
</Button>
</div>
</div>

View File

@ -2,6 +2,7 @@ import { Button, Input, Modal, ModalDialog, Radio, RadioGroup } from "@mui/joy";
import axios from "axios";
import { useState } from "react";
import { toast } from "react-hot-toast";
import { useTranslation } from "react-i18next";
import useLoading from "../hooks/useLoading";
import useUserStore from "../stores/v1/user";
import Icon from "./Icon";
@ -33,6 +34,7 @@ interface State {
const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
const { onClose, onConfirm } = props;
const { t } = useTranslation();
const currentUser = useUserStore().getCurrentUser();
const [state, setState] = useState({
description: "",
@ -119,10 +121,10 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
</div>
<div className="w-full flex flex-row justify-end items-center mt-4 space-x-2">
<Button color="neutral" variant="plain" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={onClose}>
Cancel
{t("common.cancel")}
</Button>
<Button color="primary" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={handleSaveBtnClick}>
Create
{t("common.create")}
</Button>
</div>
</div>

View File

@ -331,10 +331,10 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
<div className="w-full flex flex-row justify-end items-center mt-4 space-x-2">
<Button color="neutral" variant="plain" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={onClose}>
Cancel
{t("common.cancel")}
</Button>
<Button color="primary" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={handleSaveBtnClick}>
Save
{t("common.save")}
</Button>
</div>
</div>

View File

@ -2,6 +2,7 @@ import { Button, Input, Modal, ModalDialog, Radio, RadioGroup } from "@mui/joy";
import { isUndefined } from "lodash-es";
import { useEffect, useState } from "react";
import { toast } from "react-hot-toast";
import { useTranslation } from "react-i18next";
import useLoading from "../hooks/useLoading";
import useUserStore from "../stores/v1/user";
import Icon from "./Icon";
@ -20,6 +21,7 @@ const roles: Role[] = ["USER", "ADMIN"];
const CreateUserDialog: React.FC<Props> = (props: Props) => {
const { onClose, onConfirm, user } = props;
const { t } = useTranslation();
const userStore = useUserStore();
const [state, setState] = useState<State>({
userCreate: {
@ -185,10 +187,10 @@ const CreateUserDialog: React.FC<Props> = (props: Props) => {
</div>
<div className="w-full flex flex-row justify-end items-center mt-4 space-x-2">
<Button color="neutral" variant="plain" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={onClose}>
Cancel
{t("common.cancel")}
</Button>
<Button color="primary" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={handleSaveBtnClick}>
Save
{t("common.save")}
</Button>
</div>
</div>

View File

@ -1,6 +1,7 @@
import { Button, Input, Modal, ModalDialog } from "@mui/joy";
import { useState } from "react";
import { toast } from "react-hot-toast";
import { useTranslation } from "react-i18next";
import useLoading from "../hooks/useLoading";
import useUserStore from "../stores/v1/user";
import Icon from "./Icon";
@ -11,6 +12,7 @@ interface Props {
const EditUserinfoDialog: React.FC<Props> = (props: Props) => {
const { onClose } = props;
const { t } = useTranslation();
const userStore = useUserStore();
const currentUser = userStore.getCurrentUser();
const [email, setEmail] = useState(currentUser.email);
@ -73,10 +75,10 @@ const EditUserinfoDialog: React.FC<Props> = (props: Props) => {
</div>
<div className="w-full flex flex-row justify-end items-center space-x-2">
<Button variant="plain" disabled={requestState.isLoading} onClick={handleCloseBtnClick}>
Cancel
{t("common.cancel")}
</Button>
<Button color="primary" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={handleSaveBtnClick}>
Save
{t("common.save")}
</Button>
</div>
</div>

View File

@ -2,6 +2,7 @@ import { Button, Modal, ModalDialog } from "@mui/joy";
import { QRCodeCanvas } from "qrcode.react";
import { useRef } from "react";
import { toast } from "react-hot-toast";
import { useTranslation } from "react-i18next";
import { absolutifyLink } from "../helpers/utils";
import Icon from "./Icon";
@ -12,6 +13,7 @@ interface Props {
const GenerateQRCodeDialog: React.FC<Props> = (props: Props) => {
const { shortcut, onClose } = props;
const { t } = useTranslation();
const containerRef = useRef<HTMLDivElement | null>(null);
const shortcutLink = absolutifyLink(`/s/${shortcut.name}`);
@ -49,7 +51,7 @@ const GenerateQRCodeDialog: React.FC<Props> = (props: Props) => {
<div className="w-full flex flex-row justify-center items-center px-4">
<Button className="w-full" color="neutral" onClick={handleDownloadQRCodeClick}>
<Icon.Download className="w-4 h-auto mr-1" />
Download
{t("common.download")}
</Button>
</div>
</div>

View File

@ -1,4 +1,5 @@
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { shortcutService } from "../services";
import useUserStore from "../stores/v1/user";
import { showCommonDialog } from "./Alert";
@ -14,6 +15,7 @@ interface Props {
const ShortcutActionsDropdown = (props: Props) => {
const { shortcut } = props;
const { t } = useTranslation();
const currentUser = useUserStore().getCurrentUser();
const [showEditDialog, setShowEditDialog] = useState<boolean>(false);
const [showQRCodeDialog, setShowQRCodeDialog] = useState<boolean>(false);
@ -42,7 +44,7 @@ const ShortcutActionsDropdown = (props: Props) => {
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
onClick={() => setShowEditDialog(true)}
>
<Icon.Edit className="w-4 h-auto mr-2" /> Edit
<Icon.Edit className="w-4 h-auto mr-2" /> {t("common.edit")}
</button>
)}
<button
@ -55,7 +57,7 @@ const ShortcutActionsDropdown = (props: Props) => {
className="w-full px-2 flex flex-row justify-start items-center text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
onClick={() => setShowAnalyticsDialog(true)}
>
<Icon.BarChart2 className="w-4 h-auto mr-2" /> Analytics
<Icon.BarChart2 className="w-4 h-auto mr-2" /> {t("analytics.self")}
</button>
{havePermission && (
<button
@ -64,7 +66,7 @@ const ShortcutActionsDropdown = (props: Props) => {
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>
)}
</>

View File

@ -1,4 +1,24 @@
{
"common": {
"about": "About",
"loading": "Loading",
"cancel": "Cancel",
"save": "Save",
"create": "Create",
"download": "Download",
"edit": "Edit",
"delete": "Delete"
},
"analytics": {
"self": "Analytics",
"top-sources": "Top Sources",
"source": "Source",
"visitors": "Visitors",
"devices": "Devices",
"browser": "Browser",
"browsers": "Browsers",
"operating-system": "Operating System"
},
"shortcut": {
"visibility": {
"private": {