这是indexloc提供的服务,不要输入任何密码
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { PfpProvider } from "./PfpContext";
import { LogoProvider } from "./LogoContext";
import { FullScreenLoader } from "./components/Preloader";
import { ThemeProvider } from "./ThemeContext";
import KeyboardShortcutsHelp from "@/components/KeyboardShortcutsHelp";

const Main = lazy(() => import("@/pages/Main"));
const InvitePage = lazy(() => import("@/pages/Invite"));
Expand Down Expand Up @@ -269,6 +270,7 @@ export default function App() {
/>
</Routes>
<ToastContainer />
<KeyboardShortcutsHelp />
</I18nextProvider>
</PfpProvider>
</LogoProvider>
Expand Down
60 changes: 60 additions & 0 deletions frontend/src/components/KeyboardShortcutsHelp/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useEffect, useState } from "react";
import { X } from "@phosphor-icons/react";
import { useTranslation } from "react-i18next";
import {
SHORTCUTS,
isMac,
KEYBOARD_SHORTCUTS_HELP_EVENT,
} from "@/utils/keyboardShortcuts";

export default function KeyboardShortcutsHelp() {
const [isOpen, setIsOpen] = useState(false);
const { t } = useTranslation();

useEffect(() => {
window.addEventListener(KEYBOARD_SHORTCUTS_HELP_EVENT, () =>
setIsOpen((prev) => !prev)
);
return () => {
window.removeEventListener(KEYBOARD_SHORTCUTS_HELP_EVENT, () =>
setIsOpen(false)
);
};
}, []);

if (!isOpen) return null;
return (
<div className="fixed inset-0 z-50 overflow-auto bg-black bg-opacity-50 flex items-center justify-center">
<div className="relative bg-theme-bg-secondary rounded-lg p-6 max-w-2xl w-full mx-4">
<div className="flex justify-between items-center mb-6">
<h2 className="text-xl font-semibold text-white">
{t("keyboard-shortcuts.title")}
</h2>
<button
onClick={() => setIsOpen(false)}
className="text-white hover:text-gray-300"
aria-label="Close"
>
<X size={24} />
</button>
</div>

<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{Object.entries(SHORTCUTS).map(([key, shortcut]) => (
<div
key={key}
className="flex items-center justify-between p-3 bg-theme-bg-hover rounded-lg"
>
<span className="text-white">
{t(`keyboard-shortcuts.shortcuts.${shortcut.translationKey}`)}
</span>
<kbd className="px-2 py-1 bg-theme-bg-secondary text-white rounded border border-gray-600">
{isMac ? key : key.replace("⌘", "Ctrl")}
</kbd>
</div>
))}
</div>
</div>
</div>
);
}
29 changes: 19 additions & 10 deletions frontend/src/components/PrivateRoute/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AUTH_TIMESTAMP, AUTH_TOKEN, AUTH_USER } from "@/utils/constants";
import { userFromStorage } from "@/utils/request";
import System from "@/models/system";
import UserMenu from "../UserMenu";
import { KeyboardShortcutWrapper } from "@/utils/keyboardShortcuts";

// Used only for Multi-user mode only as we permission specific pages based on auth role.
// When in single user mode we just bypass any authchecks.
Expand Down Expand Up @@ -95,11 +96,15 @@ export function AdminRoute({ Component, hideUserMenu = false }) {
const user = userFromStorage();
return isAuthd && (user?.role === "admin" || !multiUserMode) ? (
hideUserMenu ? (
<Component />
) : (
<UserMenu>
<KeyboardShortcutWrapper>
<Component />
</UserMenu>
</KeyboardShortcutWrapper>
) : (
<KeyboardShortcutWrapper>
<UserMenu>
<Component />
</UserMenu>
</KeyboardShortcutWrapper>
)
) : (
<Navigate to={paths.home()} />
Expand All @@ -119,9 +124,11 @@ export function ManagerRoute({ Component }) {

const user = userFromStorage();
return isAuthd && (user?.role !== "default" || !multiUserMode) ? (
<UserMenu>
<Component />
</UserMenu>
<KeyboardShortcutWrapper>
<UserMenu>
<Component />
</UserMenu>
</KeyboardShortcutWrapper>
) : (
<Navigate to={paths.home()} />
);
Expand All @@ -136,9 +143,11 @@ export default function PrivateRoute({ Component }) {
}

return isAuthd ? (
<UserMenu>
<Component />
</UserMenu>
<KeyboardShortcutWrapper>
<UserMenu>
<Component />
</UserMenu>
</KeyboardShortcutWrapper>
) : (
<Navigate to={paths.login(true)} />
);
Expand Down
1,414 changes: 683 additions & 731 deletions frontend/src/locales/ar/common.js

Large diffs are not rendered by default.

Loading