mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-16 12:23:12 +00:00
chore: update part of i18n
This commit is contained in:
parent
d939bb8250
commit
bafb17015c
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
)}
|
||||
</>
|
||||
|
@ -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": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user