diff --git a/web/src/components/AboutDialog.tsx b/web/src/components/AboutDialog.tsx index 14f74aa..bcb53eb 100644 --- a/web/src/components/AboutDialog.tsx +++ b/web/src/components/AboutDialog.tsx @@ -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) => { const { onClose } = props; + const { t } = useTranslation(); return (
- About + {t("common.about")} diff --git a/web/src/components/AnalyticsDialog.tsx b/web/src/components/AnalyticsDialog.tsx index 300a964..6a83367 100644 --- a/web/src/components/AnalyticsDialog.tsx +++ b/web/src/components/AnalyticsDialog.tsx @@ -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) => { const { shortcutId, onClose } = props; + const { t } = useTranslation(); return (
- Analytics + {t("analytics.self")} diff --git a/web/src/components/AnalyticsView.tsx b/web/src/components/AnalyticsView.tsx index cf4968d..e433bfa 100644 --- a/web/src/components/AnalyticsView.tsx +++ b/web/src/components/AnalyticsView.tsx @@ -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) => { const { shortcutId, className } = props; + const { t } = useTranslation(); const [analytics, setAnalytics] = useState(null); const [selectedDeviceTab, setSelectedDeviceTab] = useState<"os" | "browser">("browser"); @@ -24,12 +26,12 @@ const AnalyticsView: React.FC = (props: Props) => { {analytics ? ( <>
-

Top Sources

+

{t("analytics.top-sources")}

- Source - Visitors + {t("analytics.source")} + {t("analytics.visitors")}
{analytics.referenceData.map((reference) => ( @@ -53,7 +55,7 @@ const AnalyticsView: React.FC = (props: Props) => {
- Devices + {t("analytics.devices")}
/
diff --git a/web/src/components/CreateAccessTokenDialog.tsx b/web/src/components/CreateAccessTokenDialog.tsx index 77cf2c6..bf4c162 100644 --- a/web/src/components/CreateAccessTokenDialog.tsx +++ b/web/src/components/CreateAccessTokenDialog.tsx @@ -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) => { 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) => {
diff --git a/web/src/components/CreateShortcutDialog.tsx b/web/src/components/CreateShortcutDialog.tsx index a7514fc..03e07f0 100644 --- a/web/src/components/CreateShortcutDialog.tsx +++ b/web/src/components/CreateShortcutDialog.tsx @@ -331,10 +331,10 @@ const CreateShortcutDialog: React.FC = (props: Props) => {
diff --git a/web/src/components/CreateUserDialog.tsx b/web/src/components/CreateUserDialog.tsx index 609b014..fec0b42 100644 --- a/web/src/components/CreateUserDialog.tsx +++ b/web/src/components/CreateUserDialog.tsx @@ -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) => { const { onClose, onConfirm, user } = props; + const { t } = useTranslation(); const userStore = useUserStore(); const [state, setState] = useState({ userCreate: { @@ -185,10 +187,10 @@ const CreateUserDialog: React.FC = (props: Props) => {
diff --git a/web/src/components/EditUserinfoDialog.tsx b/web/src/components/EditUserinfoDialog.tsx index 4ec66ca..30e2a54 100644 --- a/web/src/components/EditUserinfoDialog.tsx +++ b/web/src/components/EditUserinfoDialog.tsx @@ -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) => { 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) => {
diff --git a/web/src/components/GenerateQRCodeDialog.tsx b/web/src/components/GenerateQRCodeDialog.tsx index 2609723..427ca05 100644 --- a/web/src/components/GenerateQRCodeDialog.tsx +++ b/web/src/components/GenerateQRCodeDialog.tsx @@ -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) => { const { shortcut, onClose } = props; + const { t } = useTranslation(); const containerRef = useRef(null); const shortcutLink = absolutifyLink(`/s/${shortcut.name}`); @@ -49,7 +51,7 @@ const GenerateQRCodeDialog: React.FC = (props: Props) => {
diff --git a/web/src/components/ShortcutActionsDropdown.tsx b/web/src/components/ShortcutActionsDropdown.tsx index 00be1e7..954a195 100644 --- a/web/src/components/ShortcutActionsDropdown.tsx +++ b/web/src/components/ShortcutActionsDropdown.tsx @@ -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(false); const [showQRCodeDialog, setShowQRCodeDialog] = useState(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)} > - Edit + {t("common.edit")} )} {havePermission && ( )} diff --git a/web/src/locales/en.json b/web/src/locales/en.json index 96e1e69..21ff9e1 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -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": {